Skip to content

Config paths Phase 1: resolve the remaining path keys against their declaring file (bd-lwvumpfk) - #955

Merged
cscheid merged 4 commits into
mainfrom
feature/bd-lwvumpfk-config-paths-phase-1
Oct 28, 2026
Merged

cscheid merged 4 commits into
mainfrom
feature/bd-lwvumpfk-config-paths-phase-1

Conversation

@cscheid

@cscheid cscheid commented Oct 28, 2026

Copy link
Copy Markdown
Member

Follows #954 (merged). Braid: bd-lwvumpfk. Plan: claude-notes/plans/2026-10-28-config-path-late-binding.md, Phase 1.

What

Phase 0 (#954) introduced quarto_core::config_paths::resolve_config_path and made filters its first consumer. This PR migrates every remaining filesystem-space consumer that joined a config-authored path string onto the consuming document's directory, so a path declared in _quarto.yml or a _metadata.yml resolves against the file that declared it for every page, and a leading / means the project root.

  • Resolver additions (config_paths.rs): PathCtx::for_document, ConfigPath (a carrier that keeps a path unresolved inside a parsed type until the context is known; used by Listing.template and ComponentSource::File), resolve_config_file_with / ConfigPath::resolve_file_with (the existence policy with an explicit probe, for transforms that carry no runtime handle), and brand_path_resolver.
  • Migrated consumers: template-partials (HTML and Typst legs) and a missing template; shortcodes; language: <file>.yml; title-block-banner image probe and copy source; listing.template (bd-o1meelim: leading / = project root); epub-cover-image / epub-metadata / epub-embed-font / css flags; Typst template, bibliography, csl; reference-doc / template forwarding; highlight-style / syntax-highlighting theme files (pandoc and Typst legs); font-paths (the per-site leading-/ rule is gone); brand: read from merged metadata at its five call sites; book.chapters / appendices / references leading /.
  • Mechanism-3 consumers routed through the resolver with the stored form unchanged (include-*, css, components[].src, reference-doc, epub-*, Typst template and partials), so Phase 1b can flip the stored form in one commit. Still joining a marked value below quarto-core, for 1b to change at the hand-over: quarto-sass ThemeContext::resolve_path (theme) and pampa's citeproc base dir (HTML leg bibliography / csl).
  • quarto-sass API: resolve_brand, resolve_brand_variants and ThemeConfig::resolve_variants take a BrandPathResolver closure instead of a base directory; brand_base_dir(dir) is the old join form for callers with no provenance.
  • Contract inventory (claude-notes/designs/path-resolution-model.md) updated. Scope-outs, both URL-space emitters needing the resource-resolver exit rather than a filesystem join: revealjs logo (new strand bd-7328beha) and listing image (bd-epk8cmdl).

Behaviour changes

All in the "declared in a parent or other file" case; front-matter declarations are unchanged.

  • A project- or directory-level template-partials, shortcodes, highlight theme file, font-paths entry, banner image or listing template now reaches subdirectory pages; /x anchors at the project root.
  • brand: in a _metadata.yml or front matter resolves against that file, not the project root. One fixture (unreferenced_brand.rs) relied on the old reading and now spells its path ../_brand.yml. Open question flagged in the plan: Quarto 1's effective rule for most keys is "declaring dir if the file exists there, else the project root"; the resolver only falls back for a leading /. Adding a project-root fallback for existence-driven keys would be more lenient; not done here.
  • language: <file> tries one candidate at the declaring file instead of document dir then project root.
  • An unmarked (missing) Typst template: is reported at its declaration-resolved path instead of silently using the vendored template.

Tests

  • crates/quarto-core/tests/integration/config_path_consumers.rs: nine failing-first tests, one per consumer, in the subdir-page or leading-/ shape (all failed at the branch base for the predicted reason).
  • Unit tests updated for the new signatures (format_defaults, typst_highlight, typst_compile, title_banner, listing_render, include_resolve, components, quarto-sass brand tests); resolver unit tests extended (for_document, ConfigPath round trip).

Verification

  • cargo xtask verify --skip-hub-build: green, with the WASM artifact rebuilt first (npm run build:wasm) so the hub-client WASM tests ran against this change (17,463+ Rust tests; hub-client unit, integration and WASM suites).
  • cargo clippy -p quarto-core -p quarto-sass --all-targets -- -D warnings: clean. cargo check --workspace --tests: clean.
  • Windows cross-check of quarto-core is not possible from macOS (C build scripts); no cfg(windows) code was added in this PR.

🤖 Generated with Claude Code

cscheid and others added 4 commits October 28, 2026 10:32
…r declaring file (bd-lwvumpfk)

Phase 1 of the config-path convergence: three more consumers stop
joining a config string onto the consuming document's directory and
call resolve_config_path instead. config_paths gains
PathCtx::for_document and ConfigPath, a carrier for parsed types that
must keep a path unresolved until the context is known.

- template-partials (HTML leg) and a missing template: name the
  declaration-resolved file; a project-level partial now reaches
  subdirectory pages, and a leading / anchors at the project root.
- shortcodes: a project-level shortcode file resolves for every page.
- language: <file>.yml: resolves against the declaring file instead of
  guessing document dir then project root; a docs/_metadata.yml
  language file reaches docs/deep/ pages.

Failing-first tests in tests/integration/config_path_consumers.rs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… declaring file (bd-lwvumpfk)

config_paths gains resolve_config_file_with / ConfigPath::resolve_file_with,
the existence policy with an explicit probe for transforms (no runtime
handle) and tests. A project-level title-block-banner image is now
recognised as an image for subdirectory pages and copied beside them;
a listing template: resolves against the declaring file and a leading /
means the project root (bd-o1meelim), with the OS-absolute reading kept
as the fallback the existing unit tests pin.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…umpfk)

PandocWriteStage builds one PathCtx and threads it to every path
consumer on the pandoc legs: Typst template and template-partials
staging, epub cover/metadata/embed-font/css flags, Typst
bibliography/csl request files, the reference-doc/template and
highlight-style forwarding, the Typst .theme palette file, and
font-paths (TypstCompileStage too). Behaviour-preserving for marked
values; a project-level Typst partial, highlight theme file or font
path now resolves for subdirectory pages, and an unmarked (missing)
Typst template: is reported at its declaration-resolved path instead
of silently falling back to the vendored one.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e config-path resolver (bd-lwvumpfk)

- brand: quarto-sass takes a BrandPathResolver closure instead of a
  base directory (brand_base_dir keeps the old join form for callers
  without provenance); quarto-core builds the closure from the brand:
  value's span, so a brand declared in a _metadata.yml or front matter
  resolves against that file instead of the project root.
- include-in-header/-before-body/-after-body, css and components[].src
  go through resolve_config_path at the consumer (behaviour-preserving
  for marked values; ComponentSource::File now carries a ConfigPath).
- book.chapters/appendices/references: a leading / is the project
  root, and the stored file path is project-relative.
- Contract inventory updated; revealjs logo scoped out to bd-7328beha,
  listing images stay under bd-epk8cmdl (both URL space).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@posit-snyk-bot

posit-snyk-bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues
✅ Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants