. "$BST_LIB" # BST-TIMEOUT: 1200 # ONE python3 start, and that is nearly the whole cost. # # The probe's own work is a stub-injected import, ~20 # # in-process builder calls that write two Info.plist files # # into a tmpdir, and 107 sha256 digests over the wheel's # # RECORD -- of which 102 are .mo/.po files a few kB each; # # the whole payload is under 500 kB. Everything else in # # this file reads the filesystem and dpkg with shell # # builtins or greps the single probe run's output. That is # # nothing beside the interpreter load, so the bound matches # # 99-python3-sphinxcontrib-jquery's 1200 for the same # # reason: the start dominates. # # NOT MEASURED ON TARGET YET: this port's first on-target # # run is the batch verify, and the measured elapsed replaces # # this note in the test plan rather than in this comment, # # which would cost an image build to keep the shipped suite # # byte-identical. # # python3-sphinxcontrib-applehelp 1.0.8 (poky/meta recipes-devtools/python/ # python3-sphinxcontrib-applehelp_1.0.8.bb, `inherit pypi python_flit_core', NO # meta-brintos bbappend) on the wasm32-hwjs glibc image -- THE SPHINX BUILDER # THAT EMITS AN APPLE HELP BOOK: the .help bundle layout, its Info.plist, the # access page macOS Help Viewer opens first, and the search index. One of the # five builders split out of Sphinx core into distributions of their own. # # ============================================================================ # THE ONE FACT THAT SHAPES THIS WHOLE SUITE: THE MODULE CANNOT BE IMPORTED HERE. # ============================================================================ # # sphinxcontrib/applehelp/__init__.py opens with NINE unconditional `sphinx' # imports at MODULE scope -- lines 11-19, `import sphinx' plus eight # `from sphinx...' -- and a tenth chosen on version at line 21. None is guarded # by TYPE_CHECKING and none is deferred into a function body. This image # installs no Sphinx: python3-sphinx exists in poky (recipes-devtools/python/ # python3-sphinx_7.2.6.bb) and is in neither core-image-brintos-emcraft nor any # port ticket. So on this rootfs # # python3 -c 'import sphinxcontrib.applehelp' # # raises ModuleNotFoundError: No module named 'sphinx', and `import-needs-sphinx' # below asserts exactly that. THAT CASE IS GREEN ON PURPOSE. It is not a defect # being tolerated and it is not a platform gap: it is the measured, expected # state of an image that installs a builder without installing the application # the builder plugs into, and it is the case that will go RED -- and so demand # that this decision be revisited -- on the day python3-sphinx lands. # # UPSTREAM IS NOT EVEN CONSISTENT WITH ITSELF ABOUT THIS, which is a difference # from 99-python3-sphinxcontrib-jquery worth naming rather than glossing. # jquery's METADATA carries a plain `Requires-Dist: Sphinx>=1.8'. applehelp's # carries Sphinx ONLY as an optional extra -- `Requires-Dist: Sphinx>=5 ; # extra == "standalone"' -- so its declared unconditional requirement set is # EMPTY while its module body imports Sphinx unconditionally. `dist-requires' # and `dist-requires-plain' assert both halves of that disagreement, and # `import-needs-sphinx' asserts which half the interpreter believes. # # What is asserted instead is the package's CONTRACT WITH SPHINX, against a stub # application and a stub `sphinx' package, which is the whole of what an # extension is: the builder class it defines, the dict setup() returns, the 18 # config values it registers with their defaults and types, the bundle path it # computes, the Info.plist it writes, and the two external tools it shells out # to. None of that needs Sphinx installed -- it needs the NAMES Sphinx would # have provided. See the probe's header for which four of those names the stub # implements faithfully and why, and why every other one is a recorder that # performs no work. # # ============================================================================ # THE INDEXING STEP IS macOS-ONLY, AND THE BOUNDARY IS WHAT IS ASSERTED. # ============================================================================ # # build_helpindex() shells out to /usr/bin/hiutil and do_codesign() to # /usr/bin/codesign. Neither exists on any Linux image and neither is portable # -- hiutil is part of Apple's Help Book tooling. `indexer-absent' and # `codesign-absent' assert their absence on this rootfs as a fact, and the port # is asserted UP TO that line. The line itself is then asserted to be a # documented refusal rather than a crash, in both of the two shapes upstream # defines: # # applehelp_disable_external_tools = True -- SkipProgressMessage carrying the # exact command a user must run by hand, absorbed by progress_message's # own __exit__ so nothing propagates to the caller. That absorption is # upstream's design, not the stub's licence: the stub reproduces it # because a stub that let the exception escape would report the documented # path as a crash. # the flag left False -- the tool is really invoked, subprocess raises # FileNotFoundError, and upstream converts it into its own typed # AppleHelpIndexerFailed / AppleHelpCodeSigningFailed naming the missing # tool. A traceback out of subprocess would be the failure; a typed # SphinxError subclass is the contract. # # ONE UPSTREAM QUIRK IS ASSERTED AS IT IS, NOT AS IT READS. # `applehelp_index_anchors' defaults to False, but build_helpindex() gates on # `is not None', so the DEFAULT configuration always appends `-a' to hiutil's # argv and the flag is unreachable in its off position from configuration alone. # `index-anchors-always' and the identical `helpindex-args-default' / # `helpindex-args-anchors' pair record the behaviour that exists. An upstream # repair would turn them red, which is the point: this is a tripwire, not an # endorsement. Nothing is filed against a third-party public repository for it # (docs/conventions/no-public-upstream-reports.md); the package is shipped as # poky ships it. # # ============================================================================ # WHY THERE IS NO bbappend, AND WHY THAT IS A DECISION RATHER THAN AN OMISSION. # ============================================================================ # # The built .deb reads `Depends: python3-core' -- python_flit_core's base # contributes that and nothing else. The obvious repair, # `RDEPENDS:${PN} += "python3-sphinx"', is deliberately NOT taken, and the # reason is not that it would be wrong about the module but that this ticket # cannot pay for it: python3-sphinx is in no image and no port ticket, and its # dependency tree includes packages this same Epic is still porting. A # dependency line that pulls unported code into a shared batch image is a broken # build for every member of that image, not a correction. It is also the # thinner claim here than it was for jquery, since upstream itself declares # Sphinx optional. So the shortfall is RECORDED -- in the image recipe, in this # header and in the test plan -- and `pkg-depends-no-sphinx' asserts the absence # as a tripwire: it goes red, together with `import-needs-sphinx', on the day # python3-sphinx is ported. # # `sphinxcontrib' is a PEP 420 IMPLICIT NAMESPACE PACKAGE -- the directory ships # NO __init__.py -- which is how this port and its sibling sphinxcontrib-* ports # in BRINTOS-2084 share one top-level name without any one of them owning it. A # release that started shipping sphinxcontrib/__init__.py would shadow all of # them, so the suite asserts the absence of that file and asserts, from the # interpreter, that what was built is a _NamespacePath. # # PURE PYTHON, 109 FILES. One .py (10771 bytes), its .pyc, one Jinja template, # four dist-info files, and 102 under locales/ -- 50 languages times a .mo and a # .po, plus the .pot template and a Transifex config. No compiled extension # exists in it, which is what makes it portable: this image's python3 # is one static binary with an empty lib-dynload and no dynamic loader # (BRINTOS-1476) and an empty Py* export surface (BRINTOS-2046), so a module # carrying an extension could not be imported at all. The wheel says so itself # -- `Root-Is-Purelib: true', tag `py3-none-any', generator `flit 3.9.0'. # BRINTOS-2046 does not reach this package. P=python3-sphinxcontrib-applehelp bst_ok $P/suite-canary require python3 $P/python3-present SITE=/usr/lib/python3.12/site-packages NSDIR=$SITE/sphinxcontrib PKGDIR=$NSDIR/applehelp DI=$SITE/sphinxcontrib_applehelp-1.0.8.dist-info PKGLIST=/var/lib/dpkg/info/python3-sphinxcontrib-applehelp.list PROBE=$BST_DATA/python3-sphinxcontrib-applehelp-probe.py tmp=${TMPDIR:-/tmp} W=$tmp/bst-scapplehelp.$$ mkdir -p "$W" || { bst_notok $P/workdir "cannot create $W"; exit 0; } # --- the tree the package installs ------------------------------------------ check $P/site-packages-dir test -d "$SITE" check $P/namespace-dir test -d "$NSDIR" check $P/namespace-no-init test ! -f "$NSDIR/__init__.py" check $P/package-dir test -d "$PKGDIR" check $P/src-init test -s "$PKGDIR/__init__.py" check $P/pycache-init test -s "$PKGDIR/__pycache__/__init__.cpython-312.pyc" check $P/template-dir test -d "$PKGDIR/templates" check $P/template-access test -s "$PKGDIR/templates/_access.html_t" check $P/locales-dir test -d "$PKGDIR/locales" check $P/locales-pot test -s "$PKGDIR/locales/sphinxcontrib.applehelp.pot" check $P/locales-ru-mo test -s "$PKGDIR/locales/ru/LC_MESSAGES/sphinxcontrib.applehelp.mo" # The access page is a Jinja template, not HTML: it must still carry the two # substitutions applehelp's build_access_page() supplies, or a built help book # opens on an empty page. check_out $P/template-toc '{{ toc|e }}' cat "$PKGDIR/templates/_access.html_t" check_out $P/template-title '{{ title|e }}' cat "$PKGDIR/templates/_access.html_t" # --- the shipped file list -------------------------------------------------- cat "$PKGLIST" > "$W/pkgf" 2>/dev/null || : > "$W/pkgf" check $P/pkg-list-present test -s "$W/pkgf" check_eq $P/pkg-no-so "" \ "$(grep -E '\.so($|\.)' "$W/pkgf" 2>/dev/null)" check_eq $P/pkg-no-bin "" \ "$(grep -E '^/usr/(bin|sbin)/' "$W/pkgf" 2>/dev/null)" # Nothing outside the five kinds this package is made of. A file of any other # kind is a packaging change nobody described. _bad= while IFS= read -r _f; do [ -f "$_f" ] || continue case "$_f" in *.py|*.pyc|*.mo|*.po|*.pot|*.html_t) continue ;; */locales/.tx/config) continue ;; */sphinxcontrib_applehelp-1.0.8.dist-info/LICENSE) continue ;; */sphinxcontrib_applehelp-1.0.8.dist-info/METADATA) continue ;; */sphinxcontrib_applehelp-1.0.8.dist-info/RECORD) continue ;; */sphinxcontrib_applehelp-1.0.8.dist-info/WHEEL) continue ;; esac _bad="$_bad $_f" done < "$W/pkgf" check_eq $P/pkg-only-expected "" "$_bad" # --- dist-info -------------------------------------------------------------- check $P/dist-info-dir test -d "$DI" check $P/dist-info-metadata test -s "$DI/METADATA" check $P/dist-info-record test -s "$DI/RECORD" check $P/dist-info-wheel test -s "$DI/WHEEL" check $P/dist-info-license test -s "$DI/LICENSE" check $P/no-entry-points test ! -f "$DI/entry_points.txt" check_out $P/dist-info-purelib "Root-Is-Purelib: true" cat "$DI/WHEEL" check_out $P/dist-info-tag-py3 "Tag: py3-none-any" cat "$DI/WHEEL" check_out $P/dist-info-generator "Generator: flit 3.9.0" cat "$DI/WHEEL" check_out $P/dist-info-name "Name: sphinxcontrib-applehelp" cat "$DI/METADATA" check_out $P/dist-info-version "Version: 1.0.8" cat "$DI/METADATA" check_out $P/dist-info-requires-python "Requires-Python: >=3.9" cat "$DI/METADATA" # Sphinx appears in METADATA only as an OPTIONAL extra. Both halves of the # disagreement with the module body are asserted; see the header. check_out $P/dist-info-sphinx-extra \ 'Requires-Dist: Sphinx>=5 ; extra == "standalone"' cat "$DI/METADATA" check_eq $P/dist-info-no-plain-sphinx "" \ "$(grep -E '^Requires-Dist: Sphinx[^;]*$' "$DI/METADATA" 2>/dev/null)" # --- dpkg ------------------------------------------------------------------- sed -n '/^Package: python3-sphinxcontrib-applehelp$/,/^$/p' /var/lib/dpkg/status > "$W/st" 2>/dev/null check $P/pkg-known test -s "$W/st" check_out $P/pkg-installed "Status: install ok installed" cat "$W/st" check_out $P/pkg-version "Version: 1.0.8-r0" cat "$W/st" check_out $P/pkg-arch "Architecture: wasm32" cat "$W/st" grep '^Depends:' "$W/st" > "$W/dep" 2>/dev/null || : > "$W/dep" check $P/pkg-depends-line test -s "$W/dep" check_out $P/pkg-depends-core "python3-core" cat "$W/dep" # The tripwire: green while this image has no Sphinx, red the day it does. check_eq $P/pkg-depends-no-sphinx "" \ "$(grep -E 'python3-sphinx([ ,]|$)' "$W/dep" 2>/dev/null)" check_eq $P/no-dev-package "" \ "$(sed -n '/^Package: python3-sphinxcontrib-applehelp-dev$/p' /var/lib/dpkg/status 2>/dev/null)" check_eq $P/no-dbg-package "" \ "$(sed -n '/^Package: python3-sphinxcontrib-applehelp-dbg$/p' /var/lib/dpkg/status 2>/dev/null)" # --- the two macOS-only tools are absent, as facts about this rootfs --------- check $P/indexer-absent test ! -e /usr/bin/hiutil check $P/codesign-absent test ! -e /usr/bin/codesign # --- the import, from the shell, before any stub exists --------------------- check_rc $P/import-needs-sphinx 1 python3 -c 'import sphinxcontrib.applehelp' check_rc $P/sphinx-absent 1 python3 -c 'import sphinx' check $P/import-namespace python3 -c 'import sphinxcontrib' # --- the probe -------------------------------------------------------------- if [ ! -f "$PROBE" ]; then bst_notok $P/probe-present "$PROBE did not ship" rm -rf "$W" exit 0 fi bst_ok $P/probe-present bst_probe $P/probe-run "$W/probe" 900 python3 "$PROBE" OUT="$W/probe" pv() { grep "^$1=" "$OUT" 2>/dev/null | head -n 1 | cut -d= -f2-; } if [ -s "$OUT" ]; then bst_ok $P/probe-output else bst_notok $P/probe-output "the probe emitted nothing -- python3 did not start, or died before its first line; every CASE below is unscorable" fi # The interpreter's own answer, measured inside the probe before it stubs # anything. It must agree with import-needs-sphinx above. check_eq $P/bare-import "ModuleNotFoundError:sphinx" "$(pv bare_import)" # --- identity --------------------------------------------------------------- check_eq $P/version "1.0.8" "$(pv version)" check_eq $P/version-info "1.0.8" "$(pv version_info)" check_eq $P/dist-version "1.0.8" "$(pv dist_version)" check_eq $P/dist-name "sphinxcontrib-applehelp" "$(pv dist_name)" check_eq $P/module-answered "$PKGDIR/__init__.py" "$(pv module_file)" check_eq $P/package-dir-answered "$PKGDIR" "$(pv package_dir)" check_eq $P/template-dir-answered "$PKGDIR/templates" "$(pv template_dir)" check_eq $P/dist-requires \ 'flake8\s;\sextra\s==\s"lint",mypy\s;\sextra\s==\s"lint",docutils-stubs\s;\sextra\s==\s"lint",Sphinx>=5\s;\sextra\s==\s"standalone",pytest\s;\sextra\s==\s"test"' \ "$(pv dist_requires)" check_eq $P/dist-requires-plain "" "$(pv dist_requires_plain)" check_eq $P/ep-count "0" "$(pv ep_count)" # --- the namespace package -------------------------------------------------- check_eq $P/ns-file "None" "$(pv ns_file)" check_eq $P/ns-path-type "_NamespacePath" "$(pv ns_path_type)" check_eq $P/ns-path "$NSDIR" "$(pv ns_path)" # --- the module's surface --------------------------------------------------- check_eq $P/api-surface \ "Any,AppleHelpBuilder,AppleHelpCodeSigningFailed,AppleHelpIndexerFailed,CalledProcessError,Matcher,PIPE,STDOUT,SkipProgressMessage,Sphinx,SphinxError,StandaloneHTMLBuilder,copy_asset,copy_asset_file,ensuredir,environ,get_translation,logger,logging,make_filename,package_dir,path,plistlib,progress_message,setup,shlex,sphinx,subprocess,template_dir" \ "$(pv api_surface)" check_eq $P/api-callables \ "Any,AppleHelpBuilder,AppleHelpCodeSigningFailed,AppleHelpIndexerFailed,CalledProcessError,Matcher,SkipProgressMessage,Sphinx,SphinxError,StandaloneHTMLBuilder,copy_asset,copy_asset_file,ensuredir,get_translation,make_filename,progress_message,setup" \ "$(pv api_callables)" # --- the builder class ------------------------------------------------------ check_eq $P/builder-name "applehelp" "$(pv builder_name)" check_eq $P/builder-base "StandaloneHTMLBuilder" "$(pv builder_base)" # `format' belongs to StandaloneHTMLBuilder, not to applehelp. Asserting a VALUE # here would assert the probe's stub; what is applehelp's own is that it does # not declare one. check_eq $P/builder-own-format "absent" "$(pv builder_own_format)" check_eq $P/builder-own-attrs \ "add_permalinks,build_access_page,build_helpbook,build_helpindex,build_info_plist,copy_applehelp_icon,copy_localized_files,copysource,do_codesign,embedded,epilog,handle_finish,init,name,search,supported_image_types" \ "$(pv builder_own_attrs)" check_eq $P/builder-copysource "False" "$(pv builder_copysource)" check_eq $P/builder-add-permalinks "False" "$(pv builder_add_permalinks)" check_eq $P/builder-embedded "True" "$(pv builder_embedded)" check_eq $P/builder-search "False" "$(pv builder_search)" check_eq $P/builder-images \ "image/png,image/gif,image/jpeg,image/tiff,image/jp2,image/svg+xml" \ "$(pv builder_images)" check_eq $P/builder-epilog 'The\shelp\sbook\sis\sin\s%(outdir)s.' \ "$(pv builder_epilog_head)" check_eq $P/err-indexer-base "SphinxError" "$(pv err_indexer_base)" check_eq $P/err-indexer-category 'Help\sindexer\sfailed' "$(pv err_indexer_category)" check_eq $P/err-codesign-base "SphinxError" "$(pv err_codesign_base)" check_eq $P/err-codesign-category 'Code\ssigning\sfailed' "$(pv err_codesign_category)" # --- setup(): what the extension asks of Sphinx ----------------------------- check_eq $P/setup-returns-dict "dict" "$(pv setup_type)" check_eq $P/setup-keys "parallel_read_safe,parallel_write_safe,version" \ "$(pv setup_keys)" check_eq $P/setup-version "1.0.8" "$(pv setup_version)" check_eq $P/setup-parallel-read "True" "$(pv setup_parallel_read)" check_eq $P/setup-parallel-write "True" "$(pv setup_parallel_write)" check_eq $P/setup-require-sphinx "5.0" "$(pv require_sphinx)" check_eq $P/setup-extension "sphinx.builders.html" "$(pv setup_extension)" check_eq $P/setup-builder "AppleHelpBuilder" "$(pv builders_added)" check_eq $P/setup-catalog-name "sphinxcontrib.applehelp" "$(pv catalog_name)" check_eq $P/setup-catalog-dir "$PKGDIR/locales" "$(pv catalog_dir)" # --- the 18 config values --------------------------------------------------- check_eq $P/cfg-count "18" "$(pv cfg_count)" check_eq $P/cfg-names \ "applehelp_bundle_id,applehelp_bundle_name,applehelp_bundle_version,applehelp_codesign_flags,applehelp_codesign_identity,applehelp_codesign_path,applehelp_dev_region,applehelp_disable_external_tools,applehelp_icon,applehelp_index_anchors,applehelp_indexer_path,applehelp_kb_product,applehelp_kb_url,applehelp_locale,applehelp_min_term_length,applehelp_remote_url,applehelp_stopwords,applehelp_title" \ "$(pv cfg_names)" # Every one of them rebuilds the `applehelp' target and nothing else. check_eq $P/cfg-rebuild "applehelp" "$(pv cfg_rebuilds)" check_eq $P/cfg-typed \ "applehelp_bundle_id:str,applehelp_icon:str,applehelp_index_anchors:str,applehelp_kb_url:str,applehelp_min_term_length:str,applehelp_remote_url:str" \ "$(pv cfg_typed)" check_eq $P/cfg-lambda-names \ "applehelp_bundle_name,applehelp_codesign_flags,applehelp_codesign_identity,applehelp_kb_product,applehelp_locale,applehelp_stopwords,applehelp_title" \ "$(pv cfg_lambda_names)" # The static defaults, exactly as registered. check_eq $P/dflt-bundle-id "None" "$(pv dflt_bundle_id)" check_eq $P/dflt-bundle-version "1" "$(pv dflt_bundle_version)" check_eq $P/dflt-dev-region "en-us" "$(pv dflt_dev_region)" check_eq $P/dflt-icon "None" "$(pv dflt_icon)" check_eq $P/dflt-index-anchors "False" "$(pv dflt_index_anchors)" check_eq $P/dflt-kb-url "None" "$(pv dflt_kb_url)" check_eq $P/dflt-min-term-length "None" "$(pv dflt_min_term_length)" check_eq $P/dflt-remote-url "None" "$(pv dflt_remote_url)" check_eq $P/dflt-indexer-path "/usr/bin/hiutil" "$(pv dflt_indexer_path)" check_eq $P/dflt-codesign-path "/usr/bin/codesign" "$(pv dflt_codesign_path)" check_eq $P/dflt-disable-external "False" "$(pv dflt_disable_external_tools)" # The seven callable defaults, resolved against the probe's fixture # configuration (project "Fixture Project", release 2.5, language unset). Four # of them run Sphinx's make_filename over the project name, which is why the # probe implements that one faithfully rather than recording it. check_eq $P/dflt-bundle-name "FixtureProject" "$(pv dflt_bundle_name)" check_eq $P/dflt-kb-product "FixtureProject-2.5" "$(pv dflt_kb_product)" check_eq $P/dflt-stopwords "en" "$(pv dflt_stopwords)" check_eq $P/dflt-locale "en" "$(pv dflt_locale)" check_eq $P/dflt-title 'Fixture\sProject\sHelp' "$(pv dflt_title)" # These two read the environment Xcode sets, and the probe sets it explicitly. check_eq $P/dflt-codesign-identity 'Fixture\sSigning\sIdentity' \ "$(pv dflt_codesign_identity)" check_eq $P/dflt-codesign-flags "['--timestamp',\\s'--deep']" \ "$(pv dflt_codesign_flags)" # --- init(): the bundle layout ---------------------------------------------- # applehelp_bundle_id is the one value a project MUST set; upstream refuses # rather than inventing one. check_eq $P/init-requires-bundle-id \ 'SphinxError:You\smust\sset\sapplehelp_bundle_id\sbefore\sbuilding\sApple\sHelp\soutput' \ "$(pv init_no_bundle_id)" check_eq $P/init-calls-super "True" "$(pv init_super_called)" check_eq $P/init-out-suffix ".html" "$(pv init_out_suffix)" check_eq $P/init-link-suffix ".html" "$(pv init_link_suffix)" check_eq $P/init-bundle-path "out/FixtureProject.help" "$(pv init_bundle_rel)" check_eq $P/init-outdir \ "out/FixtureProject.help/Contents/Resources/en.lproj" "$(pv init_outdir_rel)" # A non-default bundle name and locale must both reach the path. check_eq $P/init-outdir-localised \ "out/OtherBook.help/Contents/Resources/fr.lproj" "$(pv init_outdir_rel_fr)" check_eq $P/finish-calls-super "True" "$(pv finish_super_called)" check_eq $P/finish-tasks "copy_localized_files,build_helpbook" \ "$(pv finish_tasks)" # --- Info.plist, written for real and read back with plistlib --------------- check_eq $P/plist-keys \ "CFBundleDevelopmentRegion,CFBundleIdentifier,CFBundleInfoDictionaryVersion,CFBundlePackageType,CFBundleShortVersionString,CFBundleSignature,CFBundleVersion,HPDBookAccessPath,HPDBookIndexPath,HPDBookTitle,HPDBookType,HPDBookUsesExternalViewer" \ "$(pv plist_keys)" check_eq $P/plist-identifier "com.example.fixture" "$(pv plist_identifier)" check_eq $P/plist-dev-region "en-us" "$(pv plist_devregion)" check_eq $P/plist-dict-version "6.0" "$(pv plist_dictversion)" check_eq $P/plist-package-type "BNDL" "$(pv plist_packagetype)" check_eq $P/plist-short-version "2.5" "$(pv plist_shortversion)" check_eq $P/plist-signature "hbwr" "$(pv plist_signature)" check_eq $P/plist-version "1" "$(pv plist_version)" check_eq $P/plist-access-path "_access.html" "$(pv plist_accesspath)" check_eq $P/plist-index-path "search.helpindex" "$(pv plist_indexpath)" check_eq $P/plist-title 'Fixture\sProject\sHelp' "$(pv plist_title)" check_eq $P/plist-book-type "3" "$(pv plist_booktype)" check_eq $P/plist-ext-viewer "False" "$(pv plist_extviewer)" # The three optional key groups appear only when their config value is set. check_eq $P/plist-optional-keys \ "HPDBookIconPath,HPDBookKBProduct,HPDBookKBURL,HPDBookRemoteURL" \ "$(pv plist_optional_keys)" check_eq $P/plist-icon-path "icon.png" "$(pv plist_iconpath)" check_eq $P/plist-kb-product "fixture-kb" "$(pv plist_kbproduct)" check_eq $P/plist-kb-url "https://example.invalid/kb" "$(pv plist_kburl)" check_eq $P/plist-remote-url "https://example.invalid/remote" "$(pv plist_remoteurl)" # --- the access page: which template, where, with what context -------------- check_eq $P/access-template "$PKGDIR/templates/_access.html_t" "$(pv access_src)" check_eq $P/access-template-name "_access.html_t" "$(pv access_src_name)" check_eq $P/access-template-exists "yes" "$(pv access_src_exists)" check_eq $P/access-destination "lang" "$(pv access_dst_rel)" check_eq $P/access-context 'title=Fixture\sProject\sHelp;toc=index.html' \ "$(pv access_ctx)" # copy_localized_files() must do nothing when the .lproj source is absent, and # build a Matcher over exclude_patterns + '**/.*' when it is present. check_eq $P/localized-absent-noop "0" "$(pv localized_absent_copies)" check_eq $P/localized-present-copies "1" "$(pv localized_present_copies)" check_eq $P/localized-matcher '_build,*.tmp,**/.*' "$(pv localized_matcher)" # --- the macOS-only boundary ------------------------------------------------ check_eq $P/helpindex-skip-absorbed \ '/usr/bin/hiutil\s-Cf\s/LANG/search.helpindex\s/LANG\s-a\s-s\sen\s-l\sen' \ "$(pv helpindex_skip_absorbed)" check_eq $P/helpindex-skip-message 'generating\shelp\sindex' \ "$(pv helpindex_skip_msg_head)" check_eq $P/codesign-skip-absorbed \ "/usr/bin/codesign\\s-s\\s'Fixture\\sSigning\\sIdentity'\\s-f\\s--timestamp\\s--deep\\s/OUT/FixtureProject.help" \ "$(pv codesign_skip_absorbed)" check_eq $P/helpindex-args-default \ '/usr/bin/hiutil\s-Cf\s/LANG/search.helpindex\s/LANG\s-a\s-s\sen\s-l\sen' \ "$(pv helpindex_args_default)" # The upstream quirk, asserted as it is. See the header. check_eq $P/index-anchors-always "yes" "$(pv helpindex_anchors_always)" check_eq $P/helpindex-args-anchors \ '/usr/bin/hiutil\s-Cf\s/LANG/search.helpindex\s/LANG\s-a\s-s\sen\s-l\sen' \ "$(pv helpindex_args_anchors)" check_eq $P/helpindex-args-min-term \ '/usr/bin/hiutil\s-Cf\s/LANG/search.helpindex\s/LANG\s-a\s-m\s4\s-s\sen\s-l\sen' \ "$(pv helpindex_args_minterm)" check_eq $P/helpindex-args-stopwords \ '/usr/bin/hiutil\s-Cf\s/LANG/search.helpindex\s/LANG\s-a\s-s\sfr\s-l\sen' \ "$(pv helpindex_args_stopwords)" check_eq $P/codesign-args-default \ "/usr/bin/codesign\\s-s\\s'Fixture\\sSigning\\sIdentity'\\s-f\\s--timestamp\\s--deep\\s/OUT/FixtureProject.help" \ "$(pv codesign_args_default)" check_eq $P/codesign-args-flags \ "/usr/bin/codesign\\s-s\\s'Fixture\\sSigning\\sIdentity'\\s-f\\s--force\\s/OUT/FixtureProject.help" \ "$(pv codesign_args_flags)" # With the flag left False the tool is really invoked and is really absent. # Upstream must turn subprocess's OSError into its own typed error. check_eq $P/helpindex-missing-tool \ 'AppleHelpIndexerFailed:Command\snot\sfound:\s/usr/bin/hiutil' \ "$(pv helpindex_missing_tool)" check_eq $P/codesign-missing-tool \ 'AppleHelpCodeSigningFailed:Command\snot\sfound:\s/usr/bin/codesign' \ "$(pv codesign_missing_tool)" check_eq $P/indexer-path-absent "no" "$(pv indexer_path_present)" check_eq $P/codesign-path-absent "no" "$(pv codesign_path_present)" # --- the wheel's own RECORD, re-measured against the installed bytes -------- check_eq $P/record-rows "108" "$(pv record_rows)" check_eq $P/record-all-match "" "$(pv record_mismatched)" # --- the message catalogs --------------------------------------------------- check_eq $P/locales-is-catalog-dir "yes" "$(pv locales_dir_is_catalog)" check_eq $P/locales-lang-count "50" "$(pv locales_lang_count)" check_eq $P/locales-has-ru "yes" "$(pv locales_has_ru)" check_eq $P/locales-has-pot "yes" "$(pv locales_pot)" check_eq $P/locales-mo-parse "" "$(pv locales_mo_bad)" rm -rf "$W"