Question about `source-service` options

I'm working on an example application, generating documentation for it through Xcode:

xcodebuild docbuild -scheme MeetingNotes -derivedDataPath ~/MeetingNotesBuild

Then doing the transforms to convert that archive into a set of HTML files for hosting on GitHub pages:

$(xcrun --find docc) process-archive \
transform-for-static-hosting ~/MeetingNotesBuild/Build/Products/Debug/MeetingNotes.doccarchive \
--output-path ${PACKAGE_PATH}/docs \
--hosting-base-path MeetingNotes 

All this works without issue, and now I'm trying to add the source-path options - and I'm not sure if I can through xcodebuild docbuild.

I tried tacking the parameters onto the transform-for-static-hosting subcommand of docc, but those options aren't available after a docarchive has been generated. I'm guessing from this that the options (which are documented to work primarily with docc convert) add some critical internal information during symbol generation.

Is there a way to pass those additional options through to xcodebuild docbuild?

I tried just tacking them on to the end, and trying to dig up any documentation on docbuild, but haven't been able to identify anything - or even find an --help CLI output on docbuild.

1 Like

As of Swift 5.8/Xcode 14, this should no longer be necessary since static hosting transformation was enabled by default as part of that release. Instead, you can use the DocC Archive Hosting Base Path variable during your initial xcodebuild invocation.

xcodebuild docbuild -scheme MeetingNotes \
  -derivedDataPath ~/MeetingNotesBuild \
  DOCC_HOSTING_BASE_PATH=MeetingNotes

There isn't a build setting for these values (Feedback welcome!) but you can always pass additional DocC flags to xcodebuild docbuild with the Other DocC Flags setting.

Something like this should work:

xcodebuild docbuild -scheme MeetingNotes \
  -derivedDataPath ~/MeetingNotesBuild \
  DOCC_HOSTING_BASE_PATH=MeetingNotes \
  OTHER_DOCC_FLAGS="--source-service github --source-service-base-url https://github.com/my-org/my-repo/tree/main --checkout-path $(SOURCE_ROOT)"
1 Like

Oohh - thanks @ethankusters !!

Now that you mention it, I recall the environment variable trick being mentioned earlier, but wasn't sure where to look any of this up. I'll give the expanded version a go!

1 Like

Quick bit of feedback - the OTHER_DOCC_FLAGS didn't appear to be having any effect (with Xcode 15beta5) when invoking xcodebuild docbuild - at least for the purposes of getting the source information annotated. The JSON data structures aren't getting annotated with the relevant source information as I'd expect, so nothing is being displayed. It's not breaking anything, just also not working.

I also wasn't able to get the command using DOCC_HOSTING_BASE_PATH working. I tried inline, and doing an export DOCC_HOSTING_BASE_PATH=MeetingNotes trial, with neither working. This could easily be me not grokking how to add Xcode additional config options - I haven't yet tried tucking those into the Xcode project directly as additional configurations.

The end result is the following command:

DOCC_HOSTING_BASE_PATH=MeetingNotes \
xcodebuild docbuild -scheme MeetingNotes \
  -derivedDataPath ~/MeetingNotesBuild 

didn't generate HTML output with the hosting path correctly prefixed in the resulting HTML within the docarchive, so for now I'm sticking with the "build the archive" and "transform to HTML" 2-step path.

Since this is all detail re: Xcode integration, I'll file a feedback with the specifics and various attempts and results.

Interesting. I wonder if you're hitting an incremental build issue – could you try running:

xcodebuild clean docbuild -scheme MeetingNotes \
  -derivedDataPath ~/MeetingNotesBuild \
  DOCC_HOSTING_BASE_PATH=MeetingNotes

and see if that works?

I'm not an expert on using xcodebuild from the command line (maybe @abertelrud can chime in here) but I think they need to be passed at the end of the invocation. They aren't environment variables – they're parsed separately.

Ah, yeah - that specific sequence (following the options as a sort of key/value pair) did set the hosting base path correctly.

I tried the fully expanded version (with the source flags):

xcodebuild docbuild -scheme MeetingNotes \
-derivedDataPath ~/MeetingNotesBuild \
DOCC_HOSTING_BASE_PATH=MeetingNotes \
OTHER_DOCC_FLAGS="--source-service github --source-service-base-url https://github.com/automerge/meetingnotes/tree/main --checkout-path ${PACKAGE_PATH}"

And then copied the contents from the inside of the docarchive (/Users/heckj/MeetingNotesBuild/Build/Products/Debug/MeetingNotes.doccarchive in this case) into the docs/ directory at the repo, and the result was correctly redirected for the base path.
The results are hosted at Documentation.

On the plus side, the HOSTING_BASE_PATH option worked exactly as you described when placed as an inline, key-value argument. On the down side, the contents don't appear to have any of the additional source location detail within the symbols. I dug around in one of the simpler enums (an error enum with a single case): data/documentation/meetingnotes/mergeerror.json, and there's none of the source location detail inside.

Thanks for clarifying how the options were supposed to be invoked - because of their structure, I assumed they were environment variable kinds of setup. Oh - and I did submit a feedback for Xcode docbuild for the missing link-to-source options (or perhaps just my misunderstanding of how to invoke it): FB12921882

Could you give this a try?

xcodebuild clean docbuild -scheme MeetingNotes \
  -derivedDataPath ~/MeetingNotesBuild \
  DOCC_HOSTING_BASE_PATH=MeetingNotes \
  OTHER_DOCC_FLAGS="--source-service github --source-service-base-url https://github.com/automerge/meetingnotes/tree/main --checkout-path \$(SOURCE_ROOT)"

When I ran the invocation you sent I saw this in the log:

Error: Missing value for '--checkout-path <checkout-path>'

And then when I scrolled up to the initial xcodebuild output, I saw:

Build settings from command line:
    DOCC_HOSTING_BASE_PATH = MeetingNotes
    OTHER_DOCC_FLAGS = --source-service github --source-service-base-url https://github.com/automerge/meetingnotes/tree/main --checkout-path

with no value following the --checkout-path arg.

I think my shell is expanding the $(PACKAGE_PATH) as an environment variable instead of using the Xcode build setting.

If I escape the $ with a forward slash, then it takes the value verbatim:

Build settings from command line:
    DOCC_HOSTING_BASE_PATH = MeetingNotes
    OTHER_DOCC_FLAGS = --source-service github --source-service-base-url https://github.com/automerge/meetingnotes/tree/main --checkout-path $(SOURCE_ROOT)

And then in my use, the PACKAGE_PATH setting didn't seem to exist, but SOURCE_ROOT got me the right result. Here's an excerpt from the resulting JSON for agendaitem.json:

"remoteSource": {
    "url": "https:\/\/github.com\/automerge\/meetingnotes\/tree\/main\/MeetingNotes\/MeetingNotesModel.swift#L6",
    "fileName": "MeetingNotesModel.swift"
},

Thank you!

2 Likes

Oh my - I see my misunderstanding, thank you for following this up and outlining what I was referencing. I didn't even begin to note that I was (or could) reference other Xcode internal configuration values with $(xxx), because I kept thinking of them only in terms of bash/shell variable expansions OUTSIDE of the Xcode world. But with handing it a CLI command, internal options become possible, don't they!

In any case, thank you - it works beautifully. I did a run, noted the the large number of .json files changed, did a quick checking, and the source annotations are all in there.

1 Like

Ah that's great news! So glad it finally worked. Looking forward to seeing the published documentation!