mirror of
https://github.com/max-sixty/worktrunk.git
synced 2026-09-14 20:00:38 +08:00
2203c414f5
`wt config create --project` writes a comment into the user's `.config/wt.toml` — and `wt config create --help` prints the same text — carrying a raw, unresolvable Zola link: ``` # When many repositories share one self-hosted host, name it once in user config with a [pattern-keyed `[projects]` entry](@/config.md#user-project-specific-settings) instead of repeating this block in each repo. ``` Every other cross-reference in that file is a plain URL (`… see \`wt hook\` (https://worktrunk.dev/hook/) …`), because `transform_config_source_to_toml` converts the `after_long_help` markdown to plain text on the way into `dev/wt.example.toml`. This one link isn't converted: `convert_markdown_links_for_config` matched link text with `[^\]]+`, which stops at the first `]` — here the one closing the nested `` `[projects]` `` span — so the regex failed to match and the markdown survived verbatim. The line arrived with #3701; it's the only link in either generated example file with a bracketed span in its text. ## The fix **One rule for `]` in link text.** `ZOLA_LINK_PATTERN`, earlier in the same file, already solves this problem for the skill mirrors — it alternates a backticked code span with any non-`]`-non-backtick char, which is why `skills/worktrunk/reference/config.md` renders this very sentence with a resolved URL while the TOML example didn't. `convert_markdown_links_for_config` now uses that same class rather than a second, weaker one. Brackets in these link texts always sit inside a code span, so the class fits the shape exactly, and it covers `[[…]]` array-of-tables names as well — these sections already document `[[projects."…".post-start]]` pipelines, so a link naming one is the next form to arrive. Regenerating produces the intended form: ``` # When many repositories share one self-hosted host, name it once in user config with a pattern-keyed `[projects]` entry (https://worktrunk.dev/config/#user-project-specific-settings) instead of repeating this block in each repo. ``` **A shape the regex declines now fails loudly.** Widening the class fixes the shapes we know about; it can't fix the next one. `finalize_skill_content` already handled that risk with a guardrail — after the rewrite it scans for a stray `](@/…md` and panics with the offending line, precisely because "the regex declined on an unexpected character in the link text" is the expected failure mode. `transform_config_source_to_toml` had no equivalent, which is why this one reached `dev/wt.example.toml` and the `--help` output. That check is now extracted into `assert_no_untransformed_zola_links` and called from both surfaces, so the next unsupported shape is a test failure naming the line rather than a raw `@/config.md` target in a user's config file. ## Why nothing caught it `test_project_config_source_generates_example_toml` compares `dev/wt.example.toml` against the output of this same transform, so an unconverted link is "in sync" by construction — the sync test can't see the difference between a link that converted and one the regex declined to match. Two tests close that gap: - `test_config_markdown_links_convert_to_plain_text` asserts the transform's output directly. It fails on `main`'s regex with exactly the reported symptom, and pins the forms already working (Zola page, Zola page + anchor, absolute URL, two links on one line, the `[[…]]` array-of-tables name) plus the case that must *not* convert — a bare `` `[forge]` `` span is not a link and has to survive verbatim. - `test_untransformed_zola_link_fails_the_config_transform` covers the backstop itself: an unbalanced backtick in link text makes the rewrite decline, and the assertion turns that into a panic naming the line. ## Files - `tests/integration_tests/readme_sync.rs` — the shared link-text class, the guardrail extraction and its second call site, and both tests. - `dev/wt.example.toml` — regenerated by the sync test (one line). - `tests/snapshots/…help_config_create.snap` — the same line, as `wt config create --help` renders it. Ran locally on the final state: `readme_sync::` (15), `test_help` (47), `cargo clippy --tests --all-features`, and `cargo fmt --check`. All green; the generated files are byte-identical under the new class, so the sync tests pass without regenerating. The full gate runs in CI. --------- Co-authored-by: worktrunk-bot <254187624+worktrunk-bot@users.noreply.github.com>
62 lines
3.1 KiB
TOML
62 lines
3.1 KiB
TOML
# # Project Configuration
|
|
#
|
|
# Project configuration lets teams share repository-specific settings — hooks, dev server URLs, and other defaults. The file lives in `.config/wt.toml` and is typically checked into version control.
|
|
#
|
|
# To create a starter file with commented-out examples, run `wt config create --project`.
|
|
#
|
|
# ## Hooks
|
|
#
|
|
# Project hooks apply to this repository only. See `wt hook` (https://worktrunk.dev/hook/) for hook types, execution order, and examples.
|
|
#
|
|
# pre-start = "npm ci"
|
|
# post-start = "npm run dev"
|
|
# pre-merge = "npm test"
|
|
#
|
|
# ## Dev server URL
|
|
#
|
|
# URL column in `wt list` (dimmed when port not listening):
|
|
#
|
|
# [list]
|
|
# url = "http://localhost:{{ branch | hash_port }}"
|
|
#
|
|
# ## Forge platform
|
|
#
|
|
# The forge is read from the remote's hostname: any host carrying `github`, `gitlab`, or `gitea` anywhere in it, plus the Azure DevOps service domains. Name the forge explicitly for a host carrying none of those, such as a Forgejo instance at `forge.example.com`:
|
|
#
|
|
# [forge]
|
|
# platform = "github" # or "gitlab", "gitea" (experimental), "azure-devops" (experimental)
|
|
# hostname = "github.example.com" # Example: API host (GHE / self-hosted GitLab)
|
|
#
|
|
# When many repositories share one self-hosted host, name it once in user config with a pattern-keyed `[projects]` entry (https://worktrunk.dev/config/#user-project-specific-settings) instead of repeating this block in each repo. A repository's own `[forge]` still wins, field by field.
|
|
#
|
|
# ## Commit-message append [experimental]
|
|
#
|
|
# `template-append` adds project-wide conventions to the LLM commit and squash prompts, shared so every teammate's LLM sees the same style guide:
|
|
#
|
|
# [commit.generation]
|
|
# template-append = """
|
|
# - Use conventional commits (feat:, fix:, docs:, …)
|
|
# - Reference the relevant issue ID in the body
|
|
# """
|
|
#
|
|
# The first time the fragment is used (and whenever it changes), `wt` prompts the user to approve it — the same one-shot gate as project-defined hooks. Only `template-append` is honored from the project file; the LLM command and the main prompt template stay in user config (https://worktrunk.dev/config/), since they describe per-developer environment (which CLI is installed, which agent the developer prefers). How the fragment renders: the LLM commits guide (https://worktrunk.dev/llm-commits/#appending-to-the-prompt).
|
|
#
|
|
# ## Copy-ignored excludes
|
|
#
|
|
# Additional excludes for `wt step copy-ignored`:
|
|
#
|
|
# [step.copy-ignored]
|
|
# exclude = [".cache/", ".turbo/"]
|
|
#
|
|
# Built-in excludes (VCS metadata and tool-state directories) always apply; the `wt step copy-ignored` docs (https://worktrunk.dev/step/#wt-step-copy-ignored) list them. User config and project config exclusions are combined.
|
|
#
|
|
# ## Aliases
|
|
#
|
|
# Command templates that run as `wt <name>`. See the Extending Worktrunk guide (https://worktrunk.dev/extending/#aliases) for usage and flags.
|
|
#
|
|
# [aliases]
|
|
# deploy = "make deploy BRANCH={{ branch }}"
|
|
# url = "echo http://localhost:{{ branch | hash_port }}"
|
|
#
|
|
# Aliases defined here are shared with teammates. For personal aliases, use the user config (https://worktrunk.dev/config/#aliases) `[aliases]` section instead.
|