From c8dd0131553700f85f97dc4f85d15d02edd5922b Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Thu, 21 May 2026 10:26:06 -0400 Subject: [PATCH 1/6] Create tasks/0.16/repo-reorg --- .../repo-reorg/monorepo-extra-analysis.md | 228 ++++++++++++++++ .../repo-reorg/theme-only-folder.execution.md | 133 ++++++++++ .../0.16/repo-reorg/theme-only-folder.plan.md | 250 ++++++++++++++++++ 3 files changed, 611 insertions(+) create mode 100644 tasks/0.16/repo-reorg/monorepo-extra-analysis.md create mode 100644 tasks/0.16/repo-reorg/theme-only-folder.execution.md create mode 100644 tasks/0.16/repo-reorg/theme-only-folder.plan.md diff --git a/tasks/0.16/repo-reorg/monorepo-extra-analysis.md b/tasks/0.16/repo-reorg/monorepo-extra-analysis.md new file mode 100644 index 000000000..e6c9c20c9 --- /dev/null +++ b/tasks/0.16/repo-reorg/monorepo-extra-analysis.md @@ -0,0 +1,228 @@ +--- +title: Extra analysis for the theme-subfolder monorepo plan +date: 2026-05-20 +status: draft +issue: https://github.com/google/docsy/issues/2617 +companion: ./monorepo-theme-subfolder.plan.md +cSpell:ignore: webfonts cutover bikeshedding +--- + +## About This Doc + +Companion notes to [monorepo-theme-subfolder.plan.md][plan]. This doc collects +concrete pitfalls, open questions, and acceptance-criteria additions found while +reviewing the plan against the current repo. The parent plan should stay lean; +this doc is the working scratchpad and reviewer reference. + +[plan]: ./monorepo-theme-subfolder.plan.md + +## TL;DR + +The plan is well-framed. The one decision that will make or break 0.16 is **how +a non-module NPM install resolves theme files when the canonical layout sits +under `theme/`**. That answer drives `go.mod` location, mount math, smoke tests, +release notes, and the user-facing migration story. + +Strong recommendation: do a **compatibility spike** on a feature branch before +merging the move. Build the website, the example site, and the +`scripts/make-site.sh` smoke matrix against the new layout first. + +## Top Issues + +### 1. The non-module NPM install path is under-specified + +Today, sites using `themesDir: node_modules` plus `theme: docsy` expect Hugo to +find `node_modules/docsy/{assets,layouts,i18n,static}/` directly. If those move +into `theme/`, the same install puts them at `node_modules/docsy/theme/...`. +Hugo's non-module theme loader does not transparently understand the deeper +shape; mounts declared in `theme/hugo.yaml` do not help here because non-module +themes are loaded against the consuming site's config. + +Pick one and write it into the plan: + +- **(a) Root stays the theme root for NPM consumers.** Root `package.json` + remains `name: "docsy"`. The "canonical files live in `theme/`" statement + becomes a code-organization claim, with the root layout exposed via facades, + symlinks, or mounts so the public install shape does not change. +- **(b) Document a one-line config edit** for non-module users + (`theme: docsy/theme` or a `themesDir` adjustment). Breaks "no config change + for module users beyond the usual version update" only for non-module users. +- **(c) Drop non-module install support.** Out of scope per the current + non-goals. + +Preferred: (a). It is the only option compatible with the existing compatibility +promise. + +### 2. Only one `go.mod` is meaningful + +The proposed shape diagram shows both a root `go.mod` and a `theme/go.mod`. For +a given module path on a given branch, Go resolves to a single `go.mod`. Two +`go.mod` files only make sense if you intend two import paths +(`github.com/google/docsy` and `github.com/google/docsy/theme`), which +contradicts the compatibility goal. + +Action: drop `theme/go.mod` and `theme/go.sum` from the proposed shape, or +annotate them as "only if a second public module path is introduced". + +The same applies to `hugo.yaml`: be explicit about which file Hugo reads in each +install mode (module, NPM non-module, classic non-module clone) and which file +is the canonical source. + +### 3. The `../../node_modules/...` mount math will shift + +The root `hugo.yaml` contains: + +```49:64:hugo.yaml + # Mounts for projects using Docsy as an NPM package. The source path prefix + # "../.." moves out of themes/docsy so that Docsy can find its dependencies. + - source: ../../node_modules/bootstrap + target: assets/vendor/bootstrap + - source: ../../node_modules/@fortawesome/fontawesome-free + target: assets/vendor/Font-Awesome + - source: ../../node_modules/@fortawesome/fontawesome-free/webfonts + target: static/webfonts + # Mounts for module installations, + # needed to work around a known bug in Go's module management. + - source: assets/_vendor/bootstrap/scss + target: assets/vendor/bootstrap/scss/vendor +``` + +`../..` is counted from the theme root. If the consumer-visible theme root is +deeper after the move (for example `node_modules/docsy/theme/`), the escape may +need to be `../../../`. The same goes for Hugo module cache paths. Validate with +a real consuming site before merging. + +### 4. The `postinstall` lifecycle story is the live one + +Current root `package.json` has: + +```json +"postinstall": "npm run _mkdir:hugo-mod" +``` + +It runs on every consumer `npm install`. The script reads `go.mod` via +`path.join(__dirname, '..', 'go.mod')`. After the move, decide: + +- Where the script lives (with the theme package). +- Whether its `go.mod` path lookup is still correct. +- Whether it should run at all in the chosen install shape. + +Codify the maintainer-only `_prepare` (underscore) convention in the acceptance +criteria: + +> Installing Docsy from NPM or GitHub does not execute `_prepare`, `_cp:bs-rfs`, +> `_prepare:scrollspy-patch`, `_gen-chroma-styles`, or `get:hugo-modules`. + +### 5. Generated, committed artifacts have hard-coded paths + +These files are generated and committed today. Their generators encode the +paths: + +- `assets/_vendor/bootstrap/scss/*.scss` (from `_cp:bs-rfs`) +- `assets/_cache/bootstrap/scrollspy-method.js*` (from the scrollspy patch flow) +- Chroma styles (from `_gen-chroma-styles`) +- `go.sum` (from `get:hugo-modules`) + +After the move, update the generators in `scripts/` and +`scripts/scrollspy-patch/` to write to the new paths, and keep `_diff:check` +working in CI. + +### 6. Smoke matrix must cover the new layout end-to-end + +`scripts/make-site.sh` exercises NPM and `HUGO_MODULE` installs on Windows and +Ubuntu. Add to acceptance criteria: + +> The existing smoke matrix (NPM x HUGO_MODULE x Windows x Ubuntu) passes +> against the new layout **without changes** to the consuming-site config. If +> any change is required, the exact diff is documented in the release notes. + +Also touch `docsy.dev/package.json`: + +```json +"_hugo": "hugo --cleanDestinationDir --logLevel info --themesDir ../.." +``` + +That `--themesDir ../..` assumption becomes wrong after the move. + +## Smaller Things Worth Adding + +### `docsy-example` is a first-class consumer + +Build `docsy-example` against the new layout on a branch and confirm the +smallest possible `go.mod`/`hugo.yaml` change. Ideally zero. Add a Work-Area +bullet for it. + +### Branch-model impact during the cutover + +After the move lands on `main`, every cherry-pick from `main` to `release` for a +0.15.x patch conflicts on most paths. Plan for it: + +- Land the move **early** in 0.16 so the release branch settles. +- Either freeze 0.15.x patch acceptance after a date, or accept the cherry-pick + overhead. +- The existing `git merge -s ours release` ancestry-recording trick matters more + post-move; keep it on schedule. + +### Pre-decide repo-vs-package boundaries for ambiguous files + +To avoid review bikeshedding: + +- `postcss.config.js` (root): historically for consumer sites; most consumers + ship their own. Suggest moving into `docsy.dev/` or deleting if unused there, + plus a documented snippet in the user guide. +- `Dockerfile`, `docker-compose.yaml`: repo dev tooling, stay at root. +- `.editorconfig`, `.prettierrc.json`, `.markdownlint*.yaml`, `.nvmrc`, + `.gitattributes`, `.gitignore`: repo level, stay at root. +- `images/` at the root: clarify whether these are theme assets (move) or repo + marketing (stay). + +### Tests and goldens scope for 0.16 + +Either say "tests stay under `docsy.dev/tests/` for now; a top-level `tests/` +workspace is deferred", or explicitly create the top-level slot. Avoid the +in-between. + +### Node `engines` for the installed theme + +Root currently declares `engines.node >= 24`. That is a maintainer constraint +that should not be imposed on every consumer. Set `engines.node` on the +installed theme package deliberately, ideally as loose as practical or omitted. + +### State the repo-split non-goal explicitly + +People will ask. One line in Non-Goals: + +> The theme stays in the same git repo for 0.16. A separate-repo split, if any, +> is out of scope. + +### Release-note size as a design check + +If the user-facing migration text grows past a short section in the 0.16 release +blog, take it as a signal the compatibility design is not done yet. + +## Suggested Plan Edits + +- Update the Proposed Shape diagram so it shows only the canonical `go.mod` and + `hugo.yaml` (root, per the chosen answer in #1 and #2). +- Add a Compatibility Spike subsection that names the three install modes (Hugo + module, NPM from GitHub, classic non-module theme), states the consumer's + expected layout for each, and commits to validating all three on a feature + branch before the canonical move. +- Expand the Compatibility table with rows for "NPM install command the consumer + types" and "Hugo `theme:` value the consumer uses", with their preserved + values, so "no config change" is unambiguous. +- Add the acceptance-criteria additions above (postinstall scope, smoke matrix, + generator paths). + +## Validation Checklist (Pre-Merge) + +- [ ] `docsy.dev` builds locally against the new layout. +- [ ] `make-site.sh -s NPM` passes against a PR branch of the new layout. +- [ ] `make-site.sh -s HUGO_MODULE` passes against a PR branch. +- [ ] `docsy-example` builds with no `hugo.yaml`/`go.mod` change beyond the + usual version update. +- [ ] `_diff:check` is clean after `_prepare` runs at the new paths. +- [ ] No `_prepare`/`postinstall` work runs in consumer installs. +- [ ] Release-blog upgrade section fits in one short section. + + diff --git a/tasks/0.16/repo-reorg/theme-only-folder.execution.md b/tasks/0.16/repo-reorg/theme-only-folder.execution.md new file mode 100644 index 000000000..1da87dfcb --- /dev/null +++ b/tasks/0.16/repo-reorg/theme-only-folder.execution.md @@ -0,0 +1,133 @@ +--- +title: TOF execution plan (compatibility spike work) +date: 2026-05-21 +status: draft +companion: ./theme-only-folder.plan.md +issue: https://github.com/google/docsy/issues/2617 +cSpell:ignore: fontawesome +--- + +## About this doc + +Very-high-level execution roadmap for the [TOF plan][plan]. It defines the order +of operations for the compatibility spike work and the canonical move, broken +into phases that are independently checkable and, where practical, independently +mergeable. + +The plan itself is the design contract. This doc is purely about sequencing. + +[plan]: ./theme-only-folder.plan.md + +## Working principles + +- **Incremental as far as practical.** Phase 0 (the structural move) is + unavoidably large. Phases 1+ are surgical and validate one consumer surface at + a time. +- **Single feature branch through Phases 0–3.** All consumer-surface validation + runs against the same tree. Merge to `main` only after Phase 3 passes. +- **Running spike notes** live at `tasks/0.16/repo-reorg/spike-notes.md` + (created in Phase 1). They accumulate the exact per-install-mode commands and + confirmed config edits. The release-note migration snippets are read out of + this file at Phase 5. +- **One-line promise.** The TOF plan promises a single-line consumer config edit + per install mode. If any phase shows the migration growing past that, halt and + iterate on the design before continuing. + +## Phases + +### Phase 0: structural move + +The bulk-change phase. Done in a single feature branch, ideally one PR (or a +small stack) so the move is reviewable as a unit. + +- Create `theme/` and move the canonical theme files into it (assets, layouts, + i18n, static, images, hugo.yaml, theme.toml, go.mod, go.sum). +- Update `theme/go.mod` `module` declaration to `github.com/google/docsy/theme`. +- Split `theme/package.json` out from root; reshape the root `package.json` per + the TOF plan. +- Update generators and patch scripts in `scripts/` to write under `theme/`. +- Confirm `_prepare` (and downstream `ci:prepare`) succeeds against the new + paths, and `_diff:check` is clean. + +Exit criterion: file move is clean; `_prepare` + `_diff:check` pass; no consumer +surface validated yet. + +### Phase 1: `docsy.dev` consumes TOF + +Make Docsy's primary end-to-end test (the website) build against the new layout. +This is the most informative single check. + +- Update `docsy.dev` config to use the new Hugo module path. +- Update `docsy.dev/package.json` `_hugo --themesDir` and any other path + assumptions. +- Build `docsy.dev` locally. Iterate on TOF if anything in the build chain + surprises. +- Create `tasks/0.16/repo-reorg/spike-notes.md` and record: the exact + before/after config change in `docsy.dev`, and any maintainer-workflow + observations. +- Confirm Netlify deploy previews work from the spike branch. + +Exit criterion: `docsy.dev` builds locally and on Netlify against the spike +branch. + +### Phase 2: local smoke tests (CI emulation) + +Emulate locally what GitHub Actions will eventually run, one install mode at a +time. + +- Update `scripts/make-site.sh` for the new install paths. +- Run `make-site.sh -s NPM`. Confirm the one-line user edit; record in spike + notes. +- Run `make-site.sh -s HUGO_MODULE`. Confirm; record. +- Validate non-module theme install: `hugo new site` + `git clone` Docsy into + `themes/docsy/`. Confirm; record. + +Exit criterion: all three install modes build locally; the spike-notes matrix is +complete with exact one-line edits. + +### Phase 3: GitHub CI + +Lift Phase 2 into Actions on the same branch. + +- Update `.github/workflows/smoke.yaml` and `.github/workflows/test.yaml` for + the new paths. +- Push the spike branch and watch the Windows + Ubuntu matrix go green. +- Fix any platform-specific issues (Windows in particular). + +Exit criterion: full CI matrix green on the spike branch. **Decision gate to +merge to `main`.** If everything above held, the canonical move lands. + +### Phase 4: `docsy-example` + +Coordinated PR in the `docsy-example` repo that bumps the import path. + +- Land the docsy-example PR after a Docsy 0.16 pre-release (or against a pinned + commit) so the example tracks reality. + +Exit criterion: docsy-example builds against 0.16-pre and passes its own smoke +checks. + +### Phase 5: docs and release notes + +The user-facing payload, derived from the spike notes. + +- Update get-started pages with the new import path. +- Update the changelog and release blog post; the migration section reads the + exact snippets out of `spike-notes.md`. +- Update `README.md` if it references the old install shape. + +Exit criterion: a reviewer who has not seen the design conversation can upgrade +to 0.16 by following only the release notes. + +## Tracking + +- Parent issue: [#2617][]. Keep a phase checklist there (or sub-issues, if the + team prefers) so progress is visible. +- Spike notes: `tasks/0.16/repo-reorg/spike-notes.md`, created in Phase 1 and + grown through Phase 2. +- One feature branch (e.g. `tof/spike`) carries Phases 0–3. Phases 4–5 land as + separate PRs against `main` after the spike merges. +- Each phase is reviewable on its own: a fresh `git diff` against the branch's + previous phase commit should tell a small, focused story. + +[#2617]: https://github.com/google/docsy/issues/2617 diff --git a/tasks/0.16/repo-reorg/theme-only-folder.plan.md b/tasks/0.16/repo-reorg/theme-only-folder.plan.md new file mode 100644 index 000000000..52c134879 --- /dev/null +++ b/tasks/0.16/repo-reorg/theme-only-folder.plan.md @@ -0,0 +1,250 @@ +--- +title: Theme-Only Folder (TOF) plan for 0.16 +date: 2026-05-21 +status: draft +issue: https://github.com/google/docsy/issues/2617 +cSpell:ignore: fontawesome +--- + +## About this plan + +Keep this document lean and readable for a junior developer. It describes the +intended end state, key boundaries, and acceptance criteria, not every command +or step needed to do the work. Add detail only when it prevents a likely mistake +or clarifies a compatibility decision. + +## Motivation + +The Docsy theme currently lives at the repo root, entangled with website +tooling, repo-wide tooling, and release tooling. The result is an install shape +that needs ongoing repair: + +- The root `hugo.yaml` carries `../..` escape mounts to reach the consumer's + `node_modules`, plus a vendored-Bootstrap-SCSS mount to work around a Go + modules bug. +- A `postinstall` script runs on every consumer install to create empty + Hugo-module directories outside the package. +- A scrollspy-patch toolchain must be applied during maintenance before the + theme is usable, with generated artifacts committed to keep consumers off the + toolchain. +- The root `package.json` mixes theme runtime dependencies with repo-wide + formatting, link-checking, and other tooling. + +Each of these exists because the canonical theme tree, the maintainer toolchain, +and the consumer-visible install shape are all the same tree. The fix is +structural: give the theme its own folder that **is** the install shape, and let +the repo root hold only repo-wide tooling. + +Issue [#2617][] follows up [#2436][] and asks for the theme to live in its own +folder. + +[#2617]: https://github.com/google/docsy/issues/2617 +[#2436]: https://github.com/google/docsy/issues/2436 + +## Goal: theme-only folder (TOF) + +Move the canonical Docsy theme into a folder named `theme/`, whose contents are +**only** what a consuming site needs from Docsy, nothing else. + +We expect this to be a structural change with one consumer-facing edit per +install mode. It trades a small documented migration for a clean, predictable +install shape and it should remove the install-time workarounds listed above. + +## TOF repo layout + +```text +. +├── theme/ +│ ├── assets/ +│ ├── i18n/ +│ ├── images/ # theme images only +│ ├── layouts/ +│ ├── static/ +│ ├── hugo.yaml # canonical theme config (mounts, mediaTypes, outputFormats) +│ ├── theme.toml # canonical +│ ├── go.mod # module path: github.com/google/docsy/theme +│ ├── go.sum +│ └── package.json # theme runtime deps + minimal lifecycle scripts only +├── docsy.dev/ # website + dev/test tooling +├── scripts/ # repo-wide maintainer scripts +├── tasks/ +└── package.json # repo-wide tooling; not the theme +``` + +Key properties: + +- `theme/` is what NPM ships and what Hugo modules resolve to. +- The repo root is no longer a Docsy theme. Its `package.json` no longer carries + `name: "docsy"`, and it holds no theme runtime files. +- No facades, escape mounts, or workaround `postinstall` scripts in `theme/`. +- Anything generated (vendored Bootstrap SCSS, scrollspy patch output, chroma + styles, `go.sum`) is committed under `theme/` so consumers never run the + generators. + +## User-facing migration + +TOF accepts one documented one-line config change per install mode in exchange +for a clean install shape. The exact migration text comes from the +[Compatibility spike](#compatibility-spike); the table below shows the shape of +the change. + +| Install mode | What the user edits | +| ---------------- | ----------------------------------------------------------------------- | +| Hugo module | Module import path gains a `/theme` suffix | +| NPM (GitHub) | Hugo `theme:` value gains a `/theme` suffix (or equivalent `themesDir`) | +| Non-module theme | Hugo `theme:` value gains a `/theme` suffix | + +The release-note migration section pairs each install mode with its exact +before/after snippet, derived from the spike. There should be exactly **one +line** to change per install mode. If any mode requires more, iterate on TOF +before merging. + +## Compatibility spike + +Before the move lands on `main`, validate TOF on a feature branch. The three +documented install modes below must each build a runnable site from the branch +with at most a one-line consumer config change. + +The values in the table are the working hypothesis to be confirmed by the spike. + +| # | Install mode | Consumer command (example) | Consumer config after TOF | Theme location Hugo reads | +| --- | ---------------- | -------------------------------------------------- | --------------------------------------------------------- | --------------------------- | +| 1 | Hugo module | `hugo mod get github.com/google/docsy/theme@` | `module.imports: [{path: github.com/google/docsy/theme}]` | Hugo module cache | +| 2 | NPM (GitHub) | `npm install github:google/docsy#` | `theme: docsy/theme`, `themesDir: node_modules` | `node_modules/docsy/theme/` | +| 3 | Non-module theme | `git clone` into `themes/docsy/` | `theme: docsy/theme` | `themes/docsy/theme/` | + +Validation harness, all run against the spike branch: + +- `docsy.dev` builds locally and in CI using the TOF Hugo module path. +- `docsy-example` builds against the branch with the one-line module update. +- `scripts/make-site.sh -s NPM` and `-s HUGO_MODULE` pass on Windows and Ubuntu + after the smoke script is updated for the new path. +- A minimal `hugo new site` with Docsy cloned into `themes/docsy/` builds with + the one-line `theme:` edit. + +For each mode, record in a spike notes file: the exact commands used, the exact +one-line config edit, and whether the result is "one-line change" or "needs more +design". Any "needs more design" result blocks the merge until the design is +iterated. + +## Package boundary + +`theme/package.json` includes only what installed theme users need: + +| Dependency or tool | Owner | +| --------------------------------------------------------------------------- | -------------------------- | +| `bootstrap` | theme runtime | +| `@fortawesome/fontawesome-free` | theme runtime | +| `autoprefixer`, `postcss-cli` | user/site build dependency | +| `hugo-extended` | site/dev dependency | +| `prettier`, `markdownlint*`, `afdocs`, `netlify-cli`, `rtlcss`, `cross-env` | repo or website tooling | + +Keep docs-site, CI, release, formatting, link-checking, and test-only +dependencies out of `theme/package.json`. + +The GitHub/NPM install path is a key use case. Installing Docsy from GitHub +through NPM must not fetch `docsy.dev` dev dependencies or execute +maintainer-only generators. In particular: + +- No `prepare` script in `theme/package.json`. +- No `postinstall` side-effects that touch paths outside `theme/`. +- All generated theme assets are committed. + +Ideally, theme users need no theme dev dependencies at all. + +## Maintainer workflow + +The lead maintainer (and other contributors) coordinate theme and website +changes from the repo root. `docsy.dev` is Docsy's primary end-to-end test of +theme changes, so coordinated edits across both happen daily. + +The root remains the maintainer-orchestration layer: + +- The root `package.json` keeps NPM workspace declarations and exposes commands + such as `npm run serve`, `npm run check`, and `npm run fix`. These delegate to + the workspace that owns each tool. +- Maintainers can edit theme code under `theme/` and see effects in the website + under `docsy.dev` from a single shell at the root. +- Theme runtime concerns stay under `theme/`; orchestration concerns stay at the + root. + +## Tooling versions + +Maintainers still need a predictable local toolchain. There is one clear source +for each shared tool version, so CI, local development, and release work do not +drift. Root commands stay as convenient entry points and delegate to the +workspace that owns each tool. + +## Test boundary + +The new layout leaves room for a larger test suite — HTML goldens, screenshot +goldens, browser-based checks — without bloating the installed theme package. +Test fixtures, generated goldens, and test-only dependencies live in `docsy.dev` +(current) or a repo-level `tests/` folder (future). Root commands make the suite +easy for maintainers to run; theme users never install the test toolchain. + +## Work areas + +1. **Move the theme into `theme/`.** Move `assets/`, `i18n/`, `images/`, + `layouts/`, `static/`, `hugo.yaml`, `theme.toml`, `go.mod`, `go.sum`, and the + theme-runtime parts of `package.json` into `theme/`. Update the `module` + declaration in `theme/go.mod` to `github.com/google/docsy/theme`. Update all + generators and patch scripts in `scripts/` to write to the new paths under + `theme/`. + +2. **Reshape the root.** Root `package.json` becomes repo-level only; its `name` + is no longer `docsy`. Remove the `postinstall` side-effect script. Move or + delete `postcss.config.js` based on consumer guidance. Keep `Dockerfile`, + `docker-compose.yaml`, `.editorconfig`, `.prettierrc.json`, `.markdownlint*`, + `.nvmrc`, `.gitattributes`, `.gitignore` at the root. + +3. **Update `docsy.dev`.** Pin to the new Hugo module path + (`github.com/google/docsy/theme`). Update the `_hugo --themesDir` assumption. + The website becomes a real first-class consumer of the theme. + +4. **Update `docsy-example`.** Land a coordinated PR that bumps the import path. + Confirms the example continues to work as the canonical user reference. + +5. **Update CI and smoke tests.** `scripts/make-site.sh` and the GitHub Actions + workflows must exercise the new install paths. Keep the existing matrix (NPM + × HUGO_MODULE × Windows × Ubuntu) green. + +6. **Update docs and release notes.** Document the one-line config change per + install mode. The release blog post must include exact before/after snippets, + and the user-guide get-started pages must reflect the new import path. + +## Acceptance criteria + +- The [Compatibility spike](#compatibility-spike) has been run for all three + install modes on a feature branch, and its results are recorded, before the + canonical move merges to `main`. +- `docsy.dev` builds from `theme/`. +- A new site can use Docsy as a Hugo module with the documented one-line config + change. +- A new site can use Docsy through the GitHub/NPM install path with the + documented one-line config change. +- Non-module theme usage works with the documented one-line config change. +- `theme/package.json` contains only theme runtime dependencies and minimal + lifecycle scripts. No `prepare` or `postinstall` scripts that affect + consumers. +- Installing Docsy from GitHub through NPM does not install `docsy.dev` dev + dependencies, does not execute `_prepare`, and does not build the whole repo. +- All generated theme assets (vendored Bootstrap SCSS, scrollspy patch output, + chroma styles, `go.sum`) are committed under `theme/`. +- HTML, screenshot, and other golden tests can be added without increasing the + installed theme package surface. +- CI and smoke tests pass against the new layout on Windows and Ubuntu. +- Release notes include the exact before/after migration snippet for each + install mode. + +## Non-goals + +- Do not split the theme into core/extras or community packages in this change. + TOF makes that possible later but does not require it. +- Do not redesign theme behavior or visual styling. +- Do not upgrade Bootstrap or Font Awesome as part of this migration unless the + normal dependency update process calls for it. +- Do not ship a root-facade compatibility shim to preserve the current Hugo + module path. The cost of carrying a fragile facade outweighs the value of "no + config change" for one release. +- Do not change the Hugo theme name (`docsy`). From 43048dc3f2ead31709374e79d772062812de36f1 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Sun, 24 May 2026 10:58:10 -0400 Subject: [PATCH 2/6] Phase 0+1 iteration 1, TOF-only --- docsy.dev/config/_default/hugo.yaml | 2 +- package.json | 5 +- scripts/_gen-chroma-style.sh | 2 +- scripts/getHugoModules/index.mjs | 4 +- scripts/make-site.sh | 11 +- scripts/mkdirp-hugo-mod.js | 4 +- scripts/refresh-sass-variables.pl | 2 +- scripts/scrollspy-patch/README.md | 20 +- scripts/scrollspy-patch/apply-patch.sh | 2 +- scripts/scrollspy-patch/extract-method.pl | 2 +- scripts/scrollspy-patch/update-patch-js.pl | 8 +- tasks/0.16/repo-reorg/spike-notes.md | 240 ++++++++++++++++++ .../repo-reorg/theme-only-folder.execution.md | 43 +++- .../0.16/repo-reorg/theme-only-folder.plan.md | 201 ++++++++++----- {assets => theme/assets}/_cache/README.md | 0 .../assets}/_cache/bootstrap/method.patch | 0 .../bootstrap/scrollspy-method-patched.js | 0 .../_cache/bootstrap/scrollspy-method.js | 0 {assets => theme/assets}/_vendor/README.md | 16 +- .../assets}/_vendor/bootstrap/scss/_rfs.scss | 0 {assets => theme/assets}/icons/logo.png | Bin {assets => theme/assets}/icons/logo.svg | 0 {assets => theme/assets}/js/base.js | 0 {assets => theme/assets}/js/click-to-copy.js | 0 {assets => theme/assets}/js/dark-mode.js | 0 {assets => theme/assets}/js/drawio.js | 0 {assets => theme/assets}/js/markmap.js | 0 {assets => theme/assets}/js/offline-search.js | 0 {assets => theme/assets}/js/plantuml.js | 0 .../assets}/js/scrollspy-patch.js | 0 {assets => theme/assets}/js/search.js | 0 .../assets}/json/offline-search-index.json | 0 .../assets}/scss/_styles_project.scss | 0 .../assets}/scss/_variables_project.scss | 0 .../scss/_variables_project_after_bs.scss | 0 {assets => theme/assets}/scss/main.scss | 0 {assets => theme/assets}/scss/td/_alerts.scss | 0 {assets => theme/assets}/scss/td/_blog.scss | 0 {assets => theme/assets}/scss/td/_boxes.scss | 0 .../assets}/scss/td/_breadcrumb.scss | 0 .../assets}/scss/td/_code-dark.scss | 0 {assets => theme/assets}/scss/td/_code.scss | 0 .../scss/td/_color-adjustments-dark.scss | 0 {assets => theme/assets}/scss/td/_colors.scss | 0 .../assets}/scss/td/_content.scss | 0 {assets => theme/assets}/scss/td/_drawio.scss | 0 {assets => theme/assets}/scss/td/_footer.scss | 0 .../assets}/scss/td/_gcs-search-dark.scss | 0 .../assets}/scss/td/_main-container.scss | 0 {assets => theme/assets}/scss/td/_main.scss | 0 {assets => theme/assets}/scss/td/_nav.scss | 0 .../scss/td/_navbar-mobile-scroll.scss | 0 .../assets}/scss/td/_pageinfo.scss | 0 {assets => theme/assets}/scss/td/_scroll.scss | 0 {assets => theme/assets}/scss/td/_search.scss | 0 .../assets}/scss/td/_section-index.scss | 0 .../assets}/scss/td/_shortcodes.scss | 0 .../assets}/scss/td/_sidebar-toc.scss | 0 .../assets}/scss/td/_sidebar-tree.scss | 0 .../assets}/scss/td/_swagger.scss | 0 {assets => theme/assets}/scss/td/_table.scss | 0 .../assets}/scss/td/_taxonomy.scss | 0 .../assets}/scss/td/_variables.scss | 0 .../assets}/scss/td/_variables_forward.scss | 0 .../assets}/scss/td/blocks/_blocks.scss | 0 .../assets}/scss/td/blocks/_cover.scss | 0 .../assets}/scss/td/chroma/_dark.scss | 0 .../assets}/scss/td/chroma/_light.scss | 0 .../assets}/scss/td/extra/_bs-defaults.scss | 0 .../assets}/scss/td/extra/_buttons.scss | 0 .../assets}/scss/td/extra/_index.scss | 0 .../scss/td/extra/_main-container.scss | 0 .../assets}/scss/td/extra/_navbar.scss | 0 .../scss/td/shortcodes/cards-pane.scss | 0 .../scss/td/shortcodes/tabbed-pane.scss | 0 .../scss/td/support/_bootstrap_vers_test.scss | 0 .../assets}/scss/td/support/_mixins.scss | 0 .../assets}/scss/td/support/_rtl.scss | 0 .../assets}/scss/td/support/_utilities.scss | 0 .../assets}/stubs/new-page-template.md | 0 go.mod => theme/go.mod | 2 +- go.sum => theme/go.sum | 0 hugo.yaml => theme/hugo.yaml | 17 +- {i18n => theme/i18n}/ar.yaml | 0 {i18n => theme/i18n}/az.yaml | 0 {i18n => theme/i18n}/bg.yaml | 0 {i18n => theme/i18n}/bn.yaml | 0 {i18n => theme/i18n}/de.yaml | 0 {i18n => theme/i18n}/en.yaml | 0 {i18n => theme/i18n}/es.yaml | 0 {i18n => theme/i18n}/et.yaml | 0 {i18n => theme/i18n}/fa.yaml | 0 {i18n => theme/i18n}/fi.yaml | 0 {i18n => theme/i18n}/fr.yaml | 0 {i18n => theme/i18n}/he.yaml | 0 {i18n => theme/i18n}/hi.yaml | 0 {i18n => theme/i18n}/hu.yaml | 0 {i18n => theme/i18n}/it.yaml | 0 {i18n => theme/i18n}/ja.yaml | 0 {i18n => theme/i18n}/ko.yaml | 0 {i18n => theme/i18n}/nl.yaml | 0 {i18n => theme/i18n}/no.yaml | 0 {i18n => theme/i18n}/oc.yaml | 0 {i18n => theme/i18n}/pl.yaml | 0 {i18n => theme/i18n}/pt-br.yaml | 0 {i18n => theme/i18n}/ro.yaml | 0 {i18n => theme/i18n}/ru.yaml | 0 {i18n => theme/i18n}/sr-cyrl.yaml | 0 {i18n => theme/i18n}/sr-latn.yaml | 0 {i18n => theme/i18n}/sv.yaml | 0 {i18n => theme/i18n}/tr.yaml | 0 {i18n => theme/i18n}/uk.yaml | 0 {i18n => theme/i18n}/zh-cn.yaml | 0 {i18n => theme/i18n}/zh-tw.yaml | 0 {images => theme/images}/screenshot.png | Bin {images => theme/images}/tn.png | Bin {layouts => theme/layouts}/404.html | 0 .../_markup/render-blockquote-alert.html | 0 .../_markup/render-codeblock-chem.html | 0 .../_markup/render-codeblock-math.html | 0 .../_markup/render-codeblock-mermaid.html | 0 .../layouts}/_partials/breadcrumb.html | 0 .../layouts}/_partials/community_links.html | 0 .../layouts}/_partials/dark-mode-config.html | 0 .../layouts}/_partials/disqus-comment.html | 0 .../layouts}/_partials/favicons.html | 0 .../layouts}/_partials/featured-image.html | 0 .../layouts}/_partials/feedback.html | 0 .../layouts}/_partials/footer.html | 0 .../layouts}/_partials/footer/center.html | 0 .../layouts}/_partials/footer/copyright.html | 0 .../layouts}/_partials/footer/left.html | 0 .../layouts}/_partials/footer/links.html | 0 .../layouts}/_partials/footer/right.html | 0 .../layouts}/_partials/head-css.html | 0 .../layouts}/_partials/head.html | 0 .../layouts}/_partials/hooks/body-end.html | 0 .../layouts}/_partials/hooks/head-end.html | 0 .../_partials/navbar-lang-selector.html | 0 .../_partials/navbar-version-selector.html | 0 .../layouts}/_partials/navbar.html | 0 .../layouts}/_partials/outputformat.html | 0 .../layouts}/_partials/page-description.html | 0 .../layouts}/_partials/page-meta-lastmod.html | 0 .../layouts}/_partials/page-meta-links.html | 0 .../layouts}/_partials/pager.html | 0 .../_partials/print/content-blog.html | 0 .../layouts}/_partials/print/content.html | 0 .../_partials/print/page-heading.html | 0 .../layouts}/_partials/print/render.html | 0 .../layouts}/_partials/print/toc-li-blog.html | 0 .../layouts}/_partials/print/toc-li.html | 0 .../layouts}/_partials/reading-time.html | 0 .../layouts}/_partials/scripts.html | 0 .../layouts}/_partials/scripts/katex.html | 0 .../layouts}/_partials/scripts/math.html | 0 .../layouts}/_partials/scripts/mermaid.html | 0 .../layouts}/_partials/search-input.html | 0 .../layouts}/_partials/section-index.html | 0 .../layouts}/_partials/sidebar-tree.html | 0 .../layouts}/_partials/sidebar.html | 0 .../_partials/taxonomy_terms_article.html | 0 .../taxonomy_terms_article_wrapper.html | 0 .../_partials/taxonomy_terms_cloud.html | 0 .../_partials/taxonomy_terms_clouds.html | 0 .../layouts}/_partials/td/render-heading.html | 0 .../layouts}/_partials/td/scrollspy-attr.txt | 0 .../layouts}/_partials/theme-toggler.html | 0 {layouts => theme/layouts}/_partials/toc.html | 0 .../layouts}/_partials/version-banner.html | 0 .../layouts}/_shortcodes/_param.html | 0 .../layouts}/_shortcodes/alert.html | 0 .../layouts}/_shortcodes/blocks/cover.html | 0 .../layouts}/_shortcodes/blocks/feature.html | 0 .../layouts}/_shortcodes/blocks/lead.html | 0 .../_shortcodes/blocks/link-down.html | 0 .../layouts}/_shortcodes/blocks/section.html | 0 .../layouts}/_shortcodes/card.html | 0 .../layouts}/_shortcodes/cardpane.html | 0 .../layouts}/_shortcodes/comment.html | 0 .../_shortcodes/conditional-text.html | 0 .../layouts}/_shortcodes/iframe.html | 0 .../layouts}/_shortcodes/imgproc.html | 0 .../layouts}/_shortcodes/pageinfo.html | 0 .../layouts}/_shortcodes/readfile.html | 0 .../layouts}/_shortcodes/redoc.html | 0 .../layouts}/_shortcodes/swaggerui.html | 0 .../layouts}/_shortcodes/tab.html | 0 .../layouts}/_shortcodes/tabpane.html | 0 .../_shortcodes/td/site-build-info/netlify.md | 0 .../layouts}/_td-content-after-header.html | 0 {layouts => theme/layouts}/_td-content.html | 0 {layouts => theme/layouts}/all.html | 0 {layouts => theme/layouts}/all.md | 0 {layouts => theme/layouts}/baseof.html | 0 .../layouts}/blog/_td-content.html | 0 {layouts => theme/layouts}/blog/baseof.html | 0 .../layouts}/blog/baseof.print.html | 0 {layouts => theme/layouts}/blog/list.html | 0 .../layouts}/blog/section.print.html | 0 {layouts => theme/layouts}/blog/single.html | 0 .../layouts}/community/list.html | 0 {layouts => theme/layouts}/docs/baseof.html | 0 .../layouts}/docs/baseof.print.html | 0 {layouts => theme/layouts}/docs/list.html | 0 .../layouts}/docs/list.print.html | 0 {layouts => theme/layouts}/docs/single.html | 0 {layouts => theme/layouts}/index.llms.txt | 0 {layouts => theme/layouts}/search.html | 0 .../layouts}/swagger/baseof.html | 0 {layouts => theme/layouts}/swagger/list.html | 0 .../layouts}/swagger/single.html | 0 {layouts => theme/layouts}/taxonomy.html | 0 {layouts => theme/layouts}/term.html | 0 theme/package.json | 13 + {static => theme/static}/css/prism.css | 0 .../static}/favicons/android-144x144.png | Bin .../static}/favicons/android-192x192.png | Bin .../static}/favicons/android-36x36.png | Bin .../static}/favicons/android-48x48.png | Bin .../static}/favicons/android-72x72.png | Bin .../static}/favicons/android-96x96.png | Bin .../favicons/apple-touch-icon-180x180.png | Bin .../static}/favicons/favicon-1024.png | Bin .../static}/favicons/favicon-16x16.png | Bin .../static}/favicons/favicon-256.png | Bin .../static}/favicons/favicon-32x32.png | Bin {static => theme/static}/favicons/favicon.ico | Bin .../static}/favicons/pwa-192x192.png | Bin .../static}/favicons/pwa-512x512.png | Bin .../static}/favicons/tile150x150.png | Bin .../static}/favicons/tile310x150.png | Bin .../static}/favicons/tile310x310.png | Bin .../static}/favicons/tile70x70.png | Bin {static => theme/static}/js/deflate.js | 0 {static => theme/static}/js/prism.js | 0 .../static}/js/tabpane-persist.js | 0 theme.toml => theme/theme.toml | 0 238 files changed, 477 insertions(+), 117 deletions(-) create mode 100644 tasks/0.16/repo-reorg/spike-notes.md rename {assets => theme/assets}/_cache/README.md (100%) rename {assets => theme/assets}/_cache/bootstrap/method.patch (100%) rename {assets => theme/assets}/_cache/bootstrap/scrollspy-method-patched.js (100%) rename {assets => theme/assets}/_cache/bootstrap/scrollspy-method.js (100%) rename {assets => theme/assets}/_vendor/README.md (97%) rename {assets => theme/assets}/_vendor/bootstrap/scss/_rfs.scss (100%) rename {assets => theme/assets}/icons/logo.png (100%) rename {assets => theme/assets}/icons/logo.svg (100%) rename {assets => theme/assets}/js/base.js (100%) rename {assets => theme/assets}/js/click-to-copy.js (100%) rename {assets => theme/assets}/js/dark-mode.js (100%) rename {assets => theme/assets}/js/drawio.js (100%) rename {assets => theme/assets}/js/markmap.js (100%) rename {assets => theme/assets}/js/offline-search.js (100%) rename {assets => theme/assets}/js/plantuml.js (100%) rename {assets => theme/assets}/js/scrollspy-patch.js (100%) rename {assets => theme/assets}/js/search.js (100%) rename {assets => theme/assets}/json/offline-search-index.json (100%) rename {assets => theme/assets}/scss/_styles_project.scss (100%) rename {assets => theme/assets}/scss/_variables_project.scss (100%) rename {assets => theme/assets}/scss/_variables_project_after_bs.scss (100%) rename {assets => theme/assets}/scss/main.scss (100%) rename {assets => theme/assets}/scss/td/_alerts.scss (100%) rename {assets => theme/assets}/scss/td/_blog.scss (100%) rename {assets => theme/assets}/scss/td/_boxes.scss (100%) rename {assets => theme/assets}/scss/td/_breadcrumb.scss (100%) rename {assets => theme/assets}/scss/td/_code-dark.scss (100%) rename {assets => theme/assets}/scss/td/_code.scss (100%) rename {assets => theme/assets}/scss/td/_color-adjustments-dark.scss (100%) rename {assets => theme/assets}/scss/td/_colors.scss (100%) rename {assets => theme/assets}/scss/td/_content.scss (100%) rename {assets => theme/assets}/scss/td/_drawio.scss (100%) rename {assets => theme/assets}/scss/td/_footer.scss (100%) rename {assets => theme/assets}/scss/td/_gcs-search-dark.scss (100%) rename {assets => theme/assets}/scss/td/_main-container.scss (100%) rename {assets => theme/assets}/scss/td/_main.scss (100%) rename {assets => theme/assets}/scss/td/_nav.scss (100%) rename {assets => theme/assets}/scss/td/_navbar-mobile-scroll.scss (100%) rename {assets => theme/assets}/scss/td/_pageinfo.scss (100%) rename {assets => theme/assets}/scss/td/_scroll.scss (100%) rename {assets => theme/assets}/scss/td/_search.scss (100%) rename {assets => theme/assets}/scss/td/_section-index.scss (100%) rename {assets => theme/assets}/scss/td/_shortcodes.scss (100%) rename {assets => theme/assets}/scss/td/_sidebar-toc.scss (100%) rename {assets => theme/assets}/scss/td/_sidebar-tree.scss (100%) rename {assets => theme/assets}/scss/td/_swagger.scss (100%) rename {assets => theme/assets}/scss/td/_table.scss (100%) rename {assets => theme/assets}/scss/td/_taxonomy.scss (100%) rename {assets => theme/assets}/scss/td/_variables.scss (100%) rename {assets => theme/assets}/scss/td/_variables_forward.scss (100%) rename {assets => theme/assets}/scss/td/blocks/_blocks.scss (100%) rename {assets => theme/assets}/scss/td/blocks/_cover.scss (100%) rename {assets => theme/assets}/scss/td/chroma/_dark.scss (100%) rename {assets => theme/assets}/scss/td/chroma/_light.scss (100%) rename {assets => theme/assets}/scss/td/extra/_bs-defaults.scss (100%) rename {assets => theme/assets}/scss/td/extra/_buttons.scss (100%) rename {assets => theme/assets}/scss/td/extra/_index.scss (100%) rename {assets => theme/assets}/scss/td/extra/_main-container.scss (100%) rename {assets => theme/assets}/scss/td/extra/_navbar.scss (100%) rename {assets => theme/assets}/scss/td/shortcodes/cards-pane.scss (100%) rename {assets => theme/assets}/scss/td/shortcodes/tabbed-pane.scss (100%) rename {assets => theme/assets}/scss/td/support/_bootstrap_vers_test.scss (100%) rename {assets => theme/assets}/scss/td/support/_mixins.scss (100%) rename {assets => theme/assets}/scss/td/support/_rtl.scss (100%) rename {assets => theme/assets}/scss/td/support/_utilities.scss (100%) rename {assets => theme/assets}/stubs/new-page-template.md (100%) rename go.mod => theme/go.mod (85%) rename go.sum => theme/go.sum (100%) rename hugo.yaml => theme/hugo.yaml (77%) rename {i18n => theme/i18n}/ar.yaml (100%) rename {i18n => theme/i18n}/az.yaml (100%) rename {i18n => theme/i18n}/bg.yaml (100%) rename {i18n => theme/i18n}/bn.yaml (100%) rename {i18n => theme/i18n}/de.yaml (100%) rename {i18n => theme/i18n}/en.yaml (100%) rename {i18n => theme/i18n}/es.yaml (100%) rename {i18n => theme/i18n}/et.yaml (100%) rename {i18n => theme/i18n}/fa.yaml (100%) rename {i18n => theme/i18n}/fi.yaml (100%) rename {i18n => theme/i18n}/fr.yaml (100%) rename {i18n => theme/i18n}/he.yaml (100%) rename {i18n => theme/i18n}/hi.yaml (100%) rename {i18n => theme/i18n}/hu.yaml (100%) rename {i18n => theme/i18n}/it.yaml (100%) rename {i18n => theme/i18n}/ja.yaml (100%) rename {i18n => theme/i18n}/ko.yaml (100%) rename {i18n => theme/i18n}/nl.yaml (100%) rename {i18n => theme/i18n}/no.yaml (100%) rename {i18n => theme/i18n}/oc.yaml (100%) rename {i18n => theme/i18n}/pl.yaml (100%) rename {i18n => theme/i18n}/pt-br.yaml (100%) rename {i18n => theme/i18n}/ro.yaml (100%) rename {i18n => theme/i18n}/ru.yaml (100%) rename {i18n => theme/i18n}/sr-cyrl.yaml (100%) rename {i18n => theme/i18n}/sr-latn.yaml (100%) rename {i18n => theme/i18n}/sv.yaml (100%) rename {i18n => theme/i18n}/tr.yaml (100%) rename {i18n => theme/i18n}/uk.yaml (100%) rename {i18n => theme/i18n}/zh-cn.yaml (100%) rename {i18n => theme/i18n}/zh-tw.yaml (100%) rename {images => theme/images}/screenshot.png (100%) rename {images => theme/images}/tn.png (100%) rename {layouts => theme/layouts}/404.html (100%) rename {layouts => theme/layouts}/_markup/render-blockquote-alert.html (100%) rename {layouts => theme/layouts}/_markup/render-codeblock-chem.html (100%) rename {layouts => theme/layouts}/_markup/render-codeblock-math.html (100%) rename {layouts => theme/layouts}/_markup/render-codeblock-mermaid.html (100%) rename {layouts => theme/layouts}/_partials/breadcrumb.html (100%) rename {layouts => theme/layouts}/_partials/community_links.html (100%) rename {layouts => theme/layouts}/_partials/dark-mode-config.html (100%) rename {layouts => theme/layouts}/_partials/disqus-comment.html (100%) rename {layouts => theme/layouts}/_partials/favicons.html (100%) rename {layouts => theme/layouts}/_partials/featured-image.html (100%) rename {layouts => theme/layouts}/_partials/feedback.html (100%) rename {layouts => theme/layouts}/_partials/footer.html (100%) rename {layouts => theme/layouts}/_partials/footer/center.html (100%) rename {layouts => theme/layouts}/_partials/footer/copyright.html (100%) rename {layouts => theme/layouts}/_partials/footer/left.html (100%) rename {layouts => theme/layouts}/_partials/footer/links.html (100%) rename {layouts => theme/layouts}/_partials/footer/right.html (100%) rename {layouts => theme/layouts}/_partials/head-css.html (100%) rename {layouts => theme/layouts}/_partials/head.html (100%) rename {layouts => theme/layouts}/_partials/hooks/body-end.html (100%) rename {layouts => theme/layouts}/_partials/hooks/head-end.html (100%) rename {layouts => theme/layouts}/_partials/navbar-lang-selector.html (100%) rename {layouts => theme/layouts}/_partials/navbar-version-selector.html (100%) rename {layouts => theme/layouts}/_partials/navbar.html (100%) rename {layouts => theme/layouts}/_partials/outputformat.html (100%) rename {layouts => theme/layouts}/_partials/page-description.html (100%) rename {layouts => theme/layouts}/_partials/page-meta-lastmod.html (100%) rename {layouts => theme/layouts}/_partials/page-meta-links.html (100%) rename {layouts => theme/layouts}/_partials/pager.html (100%) rename {layouts => theme/layouts}/_partials/print/content-blog.html (100%) rename {layouts => theme/layouts}/_partials/print/content.html (100%) rename {layouts => theme/layouts}/_partials/print/page-heading.html (100%) rename {layouts => theme/layouts}/_partials/print/render.html (100%) rename {layouts => theme/layouts}/_partials/print/toc-li-blog.html (100%) rename {layouts => theme/layouts}/_partials/print/toc-li.html (100%) rename {layouts => theme/layouts}/_partials/reading-time.html (100%) rename {layouts => theme/layouts}/_partials/scripts.html (100%) rename {layouts => theme/layouts}/_partials/scripts/katex.html (100%) rename {layouts => theme/layouts}/_partials/scripts/math.html (100%) rename {layouts => theme/layouts}/_partials/scripts/mermaid.html (100%) rename {layouts => theme/layouts}/_partials/search-input.html (100%) rename {layouts => theme/layouts}/_partials/section-index.html (100%) rename {layouts => theme/layouts}/_partials/sidebar-tree.html (100%) rename {layouts => theme/layouts}/_partials/sidebar.html (100%) rename {layouts => theme/layouts}/_partials/taxonomy_terms_article.html (100%) rename {layouts => theme/layouts}/_partials/taxonomy_terms_article_wrapper.html (100%) rename {layouts => theme/layouts}/_partials/taxonomy_terms_cloud.html (100%) rename {layouts => theme/layouts}/_partials/taxonomy_terms_clouds.html (100%) rename {layouts => theme/layouts}/_partials/td/render-heading.html (100%) rename {layouts => theme/layouts}/_partials/td/scrollspy-attr.txt (100%) rename {layouts => theme/layouts}/_partials/theme-toggler.html (100%) rename {layouts => theme/layouts}/_partials/toc.html (100%) rename {layouts => theme/layouts}/_partials/version-banner.html (100%) rename {layouts => theme/layouts}/_shortcodes/_param.html (100%) rename {layouts => theme/layouts}/_shortcodes/alert.html (100%) rename {layouts => theme/layouts}/_shortcodes/blocks/cover.html (100%) rename {layouts => theme/layouts}/_shortcodes/blocks/feature.html (100%) rename {layouts => theme/layouts}/_shortcodes/blocks/lead.html (100%) rename {layouts => theme/layouts}/_shortcodes/blocks/link-down.html (100%) rename {layouts => theme/layouts}/_shortcodes/blocks/section.html (100%) rename {layouts => theme/layouts}/_shortcodes/card.html (100%) rename {layouts => theme/layouts}/_shortcodes/cardpane.html (100%) rename {layouts => theme/layouts}/_shortcodes/comment.html (100%) rename {layouts => theme/layouts}/_shortcodes/conditional-text.html (100%) rename {layouts => theme/layouts}/_shortcodes/iframe.html (100%) rename {layouts => theme/layouts}/_shortcodes/imgproc.html (100%) rename {layouts => theme/layouts}/_shortcodes/pageinfo.html (100%) rename {layouts => theme/layouts}/_shortcodes/readfile.html (100%) rename {layouts => theme/layouts}/_shortcodes/redoc.html (100%) rename {layouts => theme/layouts}/_shortcodes/swaggerui.html (100%) rename {layouts => theme/layouts}/_shortcodes/tab.html (100%) rename {layouts => theme/layouts}/_shortcodes/tabpane.html (100%) rename {layouts => theme/layouts}/_shortcodes/td/site-build-info/netlify.md (100%) rename {layouts => theme/layouts}/_td-content-after-header.html (100%) rename {layouts => theme/layouts}/_td-content.html (100%) rename {layouts => theme/layouts}/all.html (100%) rename {layouts => theme/layouts}/all.md (100%) rename {layouts => theme/layouts}/baseof.html (100%) rename {layouts => theme/layouts}/blog/_td-content.html (100%) rename {layouts => theme/layouts}/blog/baseof.html (100%) rename {layouts => theme/layouts}/blog/baseof.print.html (100%) rename {layouts => theme/layouts}/blog/list.html (100%) rename {layouts => theme/layouts}/blog/section.print.html (100%) rename {layouts => theme/layouts}/blog/single.html (100%) rename {layouts => theme/layouts}/community/list.html (100%) rename {layouts => theme/layouts}/docs/baseof.html (100%) rename {layouts => theme/layouts}/docs/baseof.print.html (100%) rename {layouts => theme/layouts}/docs/list.html (100%) rename {layouts => theme/layouts}/docs/list.print.html (100%) rename {layouts => theme/layouts}/docs/single.html (100%) rename {layouts => theme/layouts}/index.llms.txt (100%) rename {layouts => theme/layouts}/search.html (100%) rename {layouts => theme/layouts}/swagger/baseof.html (100%) rename {layouts => theme/layouts}/swagger/list.html (100%) rename {layouts => theme/layouts}/swagger/single.html (100%) rename {layouts => theme/layouts}/taxonomy.html (100%) rename {layouts => theme/layouts}/term.html (100%) create mode 100644 theme/package.json rename {static => theme/static}/css/prism.css (100%) rename {static => theme/static}/favicons/android-144x144.png (100%) rename {static => theme/static}/favicons/android-192x192.png (100%) rename {static => theme/static}/favicons/android-36x36.png (100%) rename {static => theme/static}/favicons/android-48x48.png (100%) rename {static => theme/static}/favicons/android-72x72.png (100%) rename {static => theme/static}/favicons/android-96x96.png (100%) rename {static => theme/static}/favicons/apple-touch-icon-180x180.png (100%) rename {static => theme/static}/favicons/favicon-1024.png (100%) rename {static => theme/static}/favicons/favicon-16x16.png (100%) rename {static => theme/static}/favicons/favicon-256.png (100%) rename {static => theme/static}/favicons/favicon-32x32.png (100%) rename {static => theme/static}/favicons/favicon.ico (100%) rename {static => theme/static}/favicons/pwa-192x192.png (100%) rename {static => theme/static}/favicons/pwa-512x512.png (100%) rename {static => theme/static}/favicons/tile150x150.png (100%) rename {static => theme/static}/favicons/tile310x150.png (100%) rename {static => theme/static}/favicons/tile310x310.png (100%) rename {static => theme/static}/favicons/tile70x70.png (100%) rename {static => theme/static}/js/deflate.js (100%) rename {static => theme/static}/js/prism.js (100%) rename {static => theme/static}/js/tabpane-persist.js (100%) rename theme.toml => theme/theme.toml (100%) diff --git a/docsy.dev/config/_default/hugo.yaml b/docsy.dev/config/_default/hugo.yaml index 2070b83b0..ea7ef89c1 100644 --- a/docsy.dev/config/_default/hugo.yaml +++ b/docsy.dev/config/_default/hugo.yaml @@ -2,7 +2,7 @@ # # baseURL moved to be after params title: Docsy -theme: [docsy] +theme: [docsy/theme] enableRobotsTXT: true enableGitInfo: true enableEmoji: true diff --git a/package.json b/package.json index e9137f52b..7201b1695 100644 --- a/package.json +++ b/package.json @@ -5,16 +5,17 @@ "homepage": "https://www.docsy.dev", "license": "Apache-2.0", "workspaces": [ + "theme", "docsy.dev" ], "scripts": { "__spv": "node scripts/set-package-version/index.mjs", "_check:afdocs": "npm run -s -C docsy.dev _check:afdocs", - "_check:format": "npx prettier --check assets *.md i18n scripts tasks", + "_check:format": "npx prettier --check theme/assets *.md theme/i18n scripts tasks", "_check:links": "npm run -C docsy.dev _check:links", "_check:markdown": "npx markdownlint-cli2", "_commit:public": "npm run -C docsy.dev _commit:public", - "_cp:bs-rfs": "bash -c 'cp node_modules/bootstrap/scss/vendor/*.scss assets/_vendor/bootstrap/scss/'", + "_cp:bs-rfs": "bash -c 'cp node_modules/bootstrap/scss/vendor/*.scss theme/assets/_vendor/bootstrap/scss/'", "_cp:bs-scrollspy": "perl scripts/scrollspy-patch/extract-method.pl", "_diff:check": "git diff --name-only --exit-code", "_gen-chroma-styles": "bash -c scripts/gen-chroma-styles.sh", diff --git a/scripts/_gen-chroma-style.sh b/scripts/_gen-chroma-style.sh index 2ebfa7018..384f05915 100755 --- a/scripts/_gen-chroma-style.sh +++ b/scripts/_gen-chroma-style.sh @@ -6,7 +6,7 @@ set -eo pipefail HUGO="npx hugo" CHROMA_STYLE= -DEST_DIR=assets/scss/td/chroma +DEST_DIR=theme/assets/scss/td/chroma DEST_FILE= DEST_PATH=/dev/null # Set in process_CLI_args diff --git a/scripts/getHugoModules/index.mjs b/scripts/getHugoModules/index.mjs index 45bc79af5..6d6a83309 100644 --- a/scripts/getHugoModules/index.mjs +++ b/scripts/getHugoModules/index.mjs @@ -22,8 +22,8 @@ function getHugoModule(npmPkgNm, hugoModuleRefAtV) { } const command = `npx hugo mod get ${hugoModuleRefAtV}${pkgVers}`; - console.log(`> ${command}`); - const output = execSync(command); + console.log(`> (cd theme && ${command})`); + const output = execSync(command, { cwd: 'theme' }); console.log(output.toString()); } catch (error) { console.error(`ERROR: ${error.message}\n`); diff --git a/scripts/make-site.sh b/scripts/make-site.sh index 59330c107..35720c90a 100755 --- a/scripts/make-site.sh +++ b/scripts/make-site.sh @@ -118,7 +118,7 @@ function set_up_and_cd_into_site() { if [[ "$DOCSY_SRC" == HUGO* ]]; then _set_up_site_using_hugo_modules else - echo "theme: docsy" >> hugo.yaml + echo "theme: docsy/theme" >> hugo.yaml echo "themesDir: $THEMESDIR" >> hugo.yaml fi } @@ -128,7 +128,8 @@ function _set_up_site_using_hugo_modules() { # : ${user_name:=$USER} # : ${user_name:="me"} - HUGO_MOD_WITH_VERS=$DOCSY_REPO + # TOF: Docsy theme lives in the `theme/` subfolder of the Docsy repo. + HUGO_MOD_WITH_VERS="$DOCSY_REPO/theme" if [[ -n $DOCSY_VERS ]]; then HUGO_MOD_WITH_VERS+="@$DOCSY_VERS" fi @@ -158,11 +159,11 @@ function _set_up_site_using_hugo_modules() { git log --oneline -$DEPTH && \ if [[ -n $SWITCH_NEEDED ]]; then git switch --detach $DOCSY_VERS; fi \ ) - echo "replace github.com/$DOCSY_REPO_DEFAULT => ./tmp/docsy" >> go.mod - eval "$HUGO mod get github.com/$DOCSY_REPO_DEFAULT" $OUTPUT_REDIRECT + echo "replace github.com/$DOCSY_REPO_DEFAULT/theme => ./tmp/docsy/theme" >> go.mod + eval "$HUGO mod get github.com/$DOCSY_REPO_DEFAULT/theme" $OUTPUT_REDIRECT fi - echo "module: {proxy: direct, hugoVersion: {extended: true}, imports: [{path: github.com/$DOCSY_REPO_DEFAULT, disable: false}]}" >> hugo.yaml + echo "module: {proxy: direct, hugoVersion: {extended: true}, imports: [{path: github.com/$DOCSY_REPO_DEFAULT/theme, disable: false}]}" >> hugo.yaml } function main() { diff --git a/scripts/mkdirp-hugo-mod.js b/scripts/mkdirp-hugo-mod.js index 25a27d1ae..b8d402656 100644 --- a/scripts/mkdirp-hugo-mod.js +++ b/scripts/mkdirp-hugo-mod.js @@ -24,7 +24,9 @@ console.log( // ... // ) function extractModulePaths() { - const goModPath = path.join(__dirname, '..', 'go.mod'); + // go.mod lives in theme/ as of the TOF refactor; this script remains at the + // repo root's scripts/ so its callers (root postinstall) need no path change. + const goModPath = path.join(__dirname, '..', 'theme', 'go.mod'); let directories = []; try { diff --git a/scripts/refresh-sass-variables.pl b/scripts/refresh-sass-variables.pl index eabf9ce71..5da49bbd6 100755 --- a/scripts/refresh-sass-variables.pl +++ b/scripts/refresh-sass-variables.pl @@ -4,7 +4,7 @@ use warnings; my $bootstrap_vars = "node_modules/bootstrap/scss/_variables.scss"; -my $forward_vars = "assets/scss/td/_variables_forward.scss"; +my $forward_vars = "theme/assets/scss/td/_variables_forward.scss"; die "File not found: $bootstrap_vars\n" unless -f $bootstrap_vars; die "File not found: $forward_vars\n" unless -f $forward_vars; diff --git a/scripts/scrollspy-patch/README.md b/scripts/scrollspy-patch/README.md index f9a8d6826..96e982364 100644 --- a/scripts/scrollspy-patch/README.md +++ b/scripts/scrollspy-patch/README.md @@ -8,19 +8,19 @@ method as the METHOD. - `node_modules/bootstrap/js/src/scrollspy.js`: the SOURCE_FILE containing the METHOD to be patched. -- `assets/js/scrollspy-patch.js`: code that patches the METHOD at runtime +- `theme/assets/js/scrollspy-patch.js`: code that patches the METHOD at runtime (RUNTIME_PATCHER_JS). Everything described here is in support of creating this file from the original Bootstrap SOURCE_FILE. Intermediate files used to simplify the process of creating the RUNTIME_PATCHER_JS file, and detecting when the METHOD code has changed: -- `assets/_cache/bootstrap/scrollspy-method.js`: the METHOD function source +- `theme/assets/_cache/bootstrap/scrollspy-method.js`: the METHOD function source extracted from SOURCE_FILE (METHOD_SOURCE_FILE) -- `assets/_cache/bootstrap/method.patch`: standard patch used to create our +- `theme/assets/_cache/bootstrap/method.patch`: standard patch used to create our patched METHOD code; it is in standard unified diff format (generated by `diff -u` and applied by the standard `patch` command). -- `assets/_cache/bootstrap/scrollspy-method-patched.js` - the METHOD function +- `theme/assets/_cache/bootstrap/scrollspy-method-patched.js` - the METHOD function patched. ## Scripts @@ -29,10 +29,10 @@ RUNTIME_PATCHER_JS file, and detecting when the METHOD code has changed: METHOD_SOURCE_FILE file. - `apply-patch.sh` - Applies the patch using the standard `patch` command and saves the patched method to `scrollspy-method-patched.js` -- `update-patch-js.pl` - Updates `assets/js/scrollspy-patch.js` with the patched +- `update-patch-js.pl` - Updates `theme/assets/js/scrollspy-patch.js` with the patched method from `scrollspy-method-patched.js` -The patch file `method.patch` is stored in `assets/_cache/bootstrap/` alongside +The patch file `method.patch` is stored in `theme/assets/_cache/bootstrap/` alongside the cached method file. ## Workflow @@ -42,10 +42,10 @@ the cached method file. The `_prepare:scrollspy-patch` script (called by `_prepare`) automatically: 1. Extracts the method from Bootstrap (`_cp:bs-scrollspy`) - writes to - `assets/_cache/bootstrap/scrollspy-method.js` + `theme/assets/_cache/bootstrap/scrollspy-method.js` 2. Applies the patch (`apply-patch.sh`) - writes patched method to - `assets/_cache/bootstrap/scrollspy-method-patched.js` -3. Updates `assets/js/scrollspy-patch.js` (`update-patch-js.pl`) - syncs the + `theme/assets/_cache/bootstrap/scrollspy-method-patched.js` +3. Updates `theme/assets/js/scrollspy-patch.js` (`update-patch-js.pl`) - syncs the patched method body into the runtime patch file The `ci:prepare` script calls `_prepare` and `_diff:check` to ensure no @@ -71,7 +71,7 @@ When the METHOD code has changed: - Manually regenerate the patch file by running: ```bash - cd assets/_cache/bootstrap && + cd theme/assets/_cache/bootstrap && diff -u scrollspy-method.js scrollspy-method-patched.js > method.patch ``` diff --git a/scripts/scrollspy-patch/apply-patch.sh b/scripts/scrollspy-patch/apply-patch.sh index 249880f12..205c0376c 100755 --- a/scripts/scrollspy-patch/apply-patch.sh +++ b/scripts/scrollspy-patch/apply-patch.sh @@ -11,7 +11,7 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" -CACHE_DIR="$PROJECT_ROOT/assets/_cache/bootstrap" +CACHE_DIR="$PROJECT_ROOT/theme/assets/_cache/bootstrap" CACHED_METHOD_FILE="$CACHE_DIR/scrollspy-method.js" PATCH_FILE="$CACHE_DIR/method.patch" PATCHED_DEST_FILE="$CACHE_DIR/scrollspy-method-patched.js" diff --git a/scripts/scrollspy-patch/extract-method.pl b/scripts/scrollspy-patch/extract-method.pl index 81a348970..6e618c6ba 100755 --- a/scripts/scrollspy-patch/extract-method.pl +++ b/scripts/scrollspy-patch/extract-method.pl @@ -15,7 +15,7 @@ my $PROJECT_ROOT = dirname(dirname($SCRIPT_DIR)); my $BOOTSTRAP_SOURCE = "$PROJECT_ROOT/node_modules/bootstrap/js/src/scrollspy.js"; -my $CACHED_METHOD_FILE = "$PROJECT_ROOT/assets/_cache/bootstrap/scrollspy-method.js"; +my $CACHED_METHOD_FILE = "$PROJECT_ROOT/theme/assets/_cache/bootstrap/scrollspy-method.js"; # Check if Bootstrap source exists unless (-f $BOOTSTRAP_SOURCE) { diff --git a/scripts/scrollspy-patch/update-patch-js.pl b/scripts/scrollspy-patch/update-patch-js.pl index da1da8525..c613d382f 100755 --- a/scripts/scrollspy-patch/update-patch-js.pl +++ b/scripts/scrollspy-patch/update-patch-js.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl # -# Updates assets/js/scrollspy-patch.js with the patched method from -# assets/_cache/bootstrap/scrollspy-method-patched.js +# Updates theme/assets/js/scrollspy-patch.js with the patched method from +# theme/assets/_cache/bootstrap/scrollspy-method-patched.js # # cSpell:ignore scrollspy @@ -13,8 +13,8 @@ my $SCRIPT_DIR = dirname(abs_path(__FILE__)); my $PROJECT_ROOT = dirname(dirname($SCRIPT_DIR)); -my $PATCHED_METHOD_FILE = "$PROJECT_ROOT/assets/_cache/bootstrap/scrollspy-method-patched.js"; -my $PATCH_JS_FILE = "$PROJECT_ROOT/assets/js/scrollspy-patch.js"; +my $PATCHED_METHOD_FILE = "$PROJECT_ROOT/theme/assets/_cache/bootstrap/scrollspy-method-patched.js"; +my $PATCH_JS_FILE = "$PROJECT_ROOT/theme/assets/js/scrollspy-patch.js"; sub main { # Check if patched method file exists diff --git a/tasks/0.16/repo-reorg/spike-notes.md b/tasks/0.16/repo-reorg/spike-notes.md new file mode 100644 index 000000000..4ea37bacb --- /dev/null +++ b/tasks/0.16/repo-reorg/spike-notes.md @@ -0,0 +1,240 @@ +--- +title: TOF compatibility spike notes +date: 2026-05-21 +status: in-progress +companion: ./theme-only-folder.execution.md +cSpell:ignore: fontawesome themesdir devdeps +--- + +## About + +Living log of the TOF compatibility spike. Records the exact consumer-facing +config edits, the maintainer-side changes that made them possible, and any +observations. Read by the release-notes drafting work in Phase 5. + +## Repo state at start of spike + +- Branch: `chalin-m24-monorepo-2026-0520` +- Hugo version: 0.157.0 +- Starting layout: theme files at repo root, `docsy.dev/` is the website + workspace, repo root carries theme runtime deps + repo-wide maintainer + tooling. + +## Refined repo layout (settled during the spike) + +The spike converged on a four-folder shape that is the new "TOF + thin root": + +```text +. +├── theme/ # canonical theme + theme/package.json (source of truth) +├── docsy.dev/ # website; its own node_modules with site-build tooling +├── _dev/ # maintainer-orchestration folder; devDeps incl. hugo-extended +├── tasks/ # planning, spike notes, release prep +└── package.json # thin publishable shim; name "docsy"; files: [theme] +``` + +Each of `theme/`, `docsy.dev/`, and `_dev/` carries an independent +`package.json` and is installed independently (no npm workspaces are declared +anywhere). The repo root is **not** a workspace root; it is the consumer-facing +publishable manifest only. + +Key invariant: a consumer installing `docsy` (from GitHub or, later, npm) gets +exactly `theme/` + a handful of top-level docs files, **never** any of `_dev/`, +`docsy.dev/`, or maintainer tooling. + +## Phase 1: `docsy.dev` (Hugo, classic themesDir + theme) + +### Consumer-side change + +```diff +# docsy.dev/config/_default/hugo.yaml +-theme: [docsy] ++theme: [docsy/theme] +``` + +That is the entire consumer-facing edit for `docsy.dev`'s use of Docsy. The +`_hugo --themesDir ../..` setting in `docsy.dev/package.json` was unchanged. +**Result: one-line change.** + +### Maintainer-side changes (Phase 0 + 1 combined) + +The following were necessary to land the consumer-side one-line change. Captured +here for traceability; they are not user-facing. + +- `git mv` of canonical theme files into `theme/`: `assets`, `i18n`, `images`, + `layouts`, `static`, `hugo.yaml`, `theme.toml`, `go.mod`, `go.sum`. +- `theme/go.mod` `module` declaration changed to + `github.com/google/docsy/theme`. +- `theme/hugo.yaml`: the legacy `../../node_modules/*` escape mounts were + dropped. Hugo's `nodeModulesRoot` helper (`modules/collect.go`, see Hugo issue + #14083) normalises both `node_modules/X` and `../../node_modules/X` to the + same form and then performs a dual lookup — first under the theme directory, + then under the consumer site's working directory. The escape form is pure + backwards compatibility for pre-existing configs; under TOF the simple + `node_modules/X` mount is canonical and covers both cases. +- `theme/package.json` created. Source of truth for theme runtime deps + (`bootstrap`, `@fortawesome/fontawesome-free`). Postinstall delegates to + `theme/scripts/mkdirp-hugo-mod.js` so that a future split where `theme/` + becomes its own repo needs no further script moves. +- `scripts/mkdirp-hugo-mod.js` moved to `theme/scripts/mkdirp-hugo-mod.js` + (rides along inside the published theme package). +- New `_dev/` folder created as the maintainer-orchestration root. Holds + maintainer-only devDeps (`hugo-extended`, `prettier`, `markdownlint-*`, + `@cspell/dict-fr-fr`) and all orchestration scripts. + `git mv scripts _dev/scripts` preserves history. +- `_dev/scripts/sync-root-deps.mjs` added. Reads `theme/package.json`'s + `dependencies` and writes them to the root `package.json` so the consumer's + install graph reflects the theme's runtime deps. Idempotent. +- Root `package.json` slimmed to a publishable shim: `name: "docsy"`, `version`, + `repository`, `license`, + `files: ["CHANGELOG.md", "LICENSE", "README.md", "theme"]`, two lifecycle + scripts (`prepare` runs `sync-root-deps.mjs`; `postinstall` runs + `theme/scripts/mkdirp-hugo-mod.js ..`). No `devDependencies`, no workspaces, + no maintainer scripts. +- `docsy.dev/package.json` kept its site-build/site-tooling deps but + `hugo-extended` was removed (now lives in `_dev/`). + +### Observations + +- **Hugo's mount-source validation for themes/modules** rejects sources + containing `..` segments unless they match a special-cased prefix. The only + special-cased prefix is `../../node_modules/` (kept for backwards + compatibility with pre-Hugo-0.152 configs). Deepening to + `../../../node_modules/` is **not** recognised and falls through to the + `filepath.IsLocal` rejection. Relevant code: `nodeModulesRoot` in + `modules/collect.go`; see Hugo issue #14083. +- **The simple `node_modules/X` mount form is canonical under TOF.** After + normalisation, Hugo tries the source first relative to the theme directory and + then relative to the consumer site's working directory. This dual lookup is + what the escape form was buying; under TOF we spell it the modern way. Net + effect: the `../../node_modules/*` block in `theme/hugo.yaml` was redundant + and could be dropped. +- **Hugo module `imports:` alone is not sufficient** to replace the local + `node_modules/*` mounts when the theme is loaded via classic + `themesDir + theme` (which `docsy.dev` does today). SCSS resolution failed + without the local mounts even though `imports:` was configured. +- **npm workspaces were tried and abandoned.** An earlier iteration declared + workspaces at `_dev/package.json` (`["..", "../docsy.dev"]`) to give + maintainers a single `npm install`. With root listed as a workspace, npm + recognised it but did **not** install the workspace members' declared deps + (`bootstrap`, site-tooling); only the workspace-root's own devDeps were + installed. Reducing to `["../docsy.dev"]` did not help. The clean alternative + is to keep each of `theme/`, `docsy.dev/`, and `_dev/` as independent package + installs with no workspaces declared anywhere. +- **Hugo's theme-local lookup is what makes the no-workspaces design work.** + With `cd theme && npm install`, `bootstrap` lands at + `theme/node_modules/bootstrap`. Hugo's dual lookup finds it on the + theme-relative first pass; nothing is needed in `docsy.dev/node_modules/`. No + symlinks. No deps duplicated in `docsy.dev/package.json`. +- **`hugo-extended` is on PATH for `docsy.dev` builds via npm-script + inheritance.** When `cd _dev && npm run build` calls + `npm run -C ../docsy.dev build`, the inner npm process inherits the outer + process's PATH (which already includes `_dev/node_modules/.bin/`). The `hugo` + binary is found there. This is the single source of the Hugo version across + the monorepo. +- **Postinstall lives at the published-package boundary.** The root + `postinstall` runs `node theme/scripts/mkdirp-hugo-mod.js ..` inside the + consumer's `node_modules/docsy/` after install, creating the empty + `github.com/*` placeholder dirs Hugo expects when the theme is loaded as a + module. `theme/package.json` carries the same postinstall for the future split + where `theme/` becomes its own published repo. + +### Status + +**Phase 1 exit criterion met.** `docsy.dev` builds locally from `theme/` with +the one-line consumer config change (223 EN pages, 218 FR pages) **and** with no +symlinks anywhere. The build chain works with a clean three-install maintainer +setup: + +```sh +cd theme && npm install # theme runtime deps (bootstrap, fontawesome) +cd docsy.dev && npm install # site build deps (autoprefixer, postcss-cli, …) +cd _dev && npm install # hugo-extended + monorepo maintainer tooling +cd _dev && npm run build # green +``` + +A convenience `npm run install:all` in `_dev/` runs the three installs in +sequence. + +### Open question + +- Package versioning: see + [the plan's section](./theme-only-folder.plan.md#package-versioning). + Currently both root and theme carry the same `version`; the policy is + unresolved. + +## Phase 2: NPM (GitHub) — pack/install smoke test + +This phase exercises the install path a consumer would hit with +`npm install github:google/docsy#`, locally and with the spike branch. + +### Smoke test + +Run `npm pack` at the repo root, inspect the tarball, then install it into a +fresh consumer directory: + +```sh +# at repo root +npm pack +# -> docsy-0.15.1-dev+002-over-main-ce9942b8.tgz + +CONSUMER=$(mktemp -d) +cd "$CONSUMER" +echo '{"name":"c","version":"0.0.0","private":true}' > package.json +npm install /path/to/docsy-*.tgz +``` + +### Results + +- The pack ran `prepare` → `_dev/scripts/sync-root-deps.mjs`, which copied + `bootstrap` and `@fortawesome/fontawesome-free` from `theme/package.json` into + the root `package.json`'s `dependencies`. Idempotent: re-running with the + committed synced state is a no-op. +- Tarball top-level entries: `CHANGELOG.md`, `LICENSE`, `README.md`, + `package.json`, `theme/`. No `_dev/`, no `docsy.dev/`, no maintainer scripts, + no devDeps. Total: 2879 files, 8.0 MB (≈ the theme tree). +- Consumer `node_modules/` after install: + - `node_modules/docsy/` containing exactly `CHANGELOG.md`, `LICENSE`, + `README.md`, `package.json`, `theme/`. + - `node_modules/bootstrap/` (transitive). + - `node_modules/@fortawesome/fontawesome-free/` (transitive). + - `node_modules/@popperjs/` (transitive via bootstrap). + - **0 vulnerabilities reported** by npm audit. + - 4 packages added in total. +- Consumer postinstall ran. `node_modules/github.com/FortAwesome/Font-Awesome` + and `node_modules/github.com/twbs/bootstrap` placeholder dirs created so + Hugo's module loader does not error. + +### Phase 2 observations + +- **The `files` whitelist is the linchpin.** Pre-spike, root had no `files` + field, so `npm install github:google/docsy` brought the entire monorepo into + the consumer's `node_modules/docsy/`. With `files: ["theme", …]` the tarball + contains only what a consumer needs. +- **No `devDependencies` at root means git-URL installs do not trigger a dev + install.** npm's docs note that the presence of a `prepare` script in a + package being installed from git triggers a `npm install` of `dependencies + - devDependencies` in the clone before pack. Because root carries no devDeps, + that step is a no-op. The headache that pre-spike consumers hit (entire + maintainer toolchain dragged into their install) is gone. +- **`prepare` is the right hook (not `prepack`).** `prepack` only runs on + `npm pack` / `npm publish`. `prepare` runs on those **and** during the git-URL + install workflow in the clone before the tarball is built. The sync script + must run in both places, so `prepare` is the correct lifecycle pick. The cost + of `prepare` (devDeps install in the clone) is zero here because root has no + devDeps. +- **Working-tree cleanliness after pack.** Because root commits the synced deps + (kept aligned with `theme/package.json` by the sync script), the `prepare` + write during a maintainer's `npm pack` is a no-op and the working tree stays + clean. The script doubles as a CI guard against drift. + +### Phase 2 status + +**Phase 2 exit criterion met for the NPM-tarball install path.** Outstanding +work for Phase 2: validate the same flow via `make-site.sh -s NPM`, then +exercise `-s HUGO_MODULE` and the non-module `themes/docsy/` install. Those +remain unchanged in the execution plan. + +## Phase 3: GitHub CI — pending + +To be recorded during Phase 3 work. diff --git a/tasks/0.16/repo-reorg/theme-only-folder.execution.md b/tasks/0.16/repo-reorg/theme-only-folder.execution.md index 1da87dfcb..846d78b88 100644 --- a/tasks/0.16/repo-reorg/theme-only-folder.execution.md +++ b/tasks/0.16/repo-reorg/theme-only-folder.execution.md @@ -23,6 +23,9 @@ The plan itself is the design contract. This doc is purely about sequencing. - **Incremental as far as practical.** Phase 0 (the structural move) is unavoidably large. Phases 1+ are surgical and validate one consumer surface at a time. +- **Phases 0 and 1 are intertwined in practice.** Expect to cycle between moving + files (Phase 0) and trying the `docsy.dev` build (Phase 1) until both exit + criteria are met. Treat them as a tight loop, not two sequential blocks. - **Single feature branch through Phases 0–3.** All consumer-surface validation runs against the same tree. Merge to `main` only after Phase 3 passes. - **Running spike notes** live at `tasks/0.16/repo-reorg/spike-notes.md` @@ -43,15 +46,27 @@ small stack) so the move is reviewable as a unit. - Create `theme/` and move the canonical theme files into it (assets, layouts, i18n, static, images, hugo.yaml, theme.toml, go.mod, go.sum). - Update `theme/go.mod` `module` declaration to `github.com/google/docsy/theme`. -- Split `theme/package.json` out from root; reshape the root `package.json` per - the TOF plan. -- Update generators and patch scripts in `scripts/` to write under `theme/`. +- Carve out `_dev/` for maintainer-orchestration. `git mv scripts _dev/scripts` + to retain script history. Move repo-wide devDeps (including `hugo-extended`) + from the old root to `_dev/package.json`. Add + `_dev/scripts/sync-root-deps.mjs`. +- Split `theme/package.json` out as the source of truth for theme runtime deps. + Reshape the root `package.json` to a thin publishable shim (`name: "docsy"`, + `files: [theme, …]`, `prepare` + `postinstall`, no devDeps). +- Update generators and patch scripts now living in `_dev/scripts/` to write + under `theme/`. - Confirm `_prepare` (and downstream `ci:prepare`) succeeds against the new paths, and `_diff:check` is clean. Exit criterion: file move is clean; `_prepare` + `_diff:check` pass; no consumer surface validated yet. +Status (2026-05-21): structural move landed on `chalin-m24-monorepo-2026-0520`. +`_prepare` / `_diff:check` regression check is still pending — Phase 0 / Phase 1 +ran as a tight loop and `docsy.dev` already builds (see Phase 1), but the +maintainer `_prepare` chain has not yet been re-exercised end-to-end against the +new layout. + ### Phase 1: `docsy.dev` consumes TOF Make Docsy's primary end-to-end test (the website) build against the new layout. @@ -70,12 +85,17 @@ This is the most informative single check. Exit criterion: `docsy.dev` builds locally and on Netlify against the spike branch. +Status (2026-05-21): **local build exit criterion met.** `docsy.dev` builds from +`theme/` with the one-line `theme: [docsy/theme]` consumer config change and no +symlinks anywhere (223 EN + 218 FR pages). Spike notes record the exact +before/after edit. Netlify deploy preview is still pending. + ### Phase 2: local smoke tests (CI emulation) Emulate locally what GitHub Actions will eventually run, one install mode at a time. -- Update `scripts/make-site.sh` for the new install paths. +- Update `_dev/scripts/make-site.sh` for the new install paths. - Run `make-site.sh -s NPM`. Confirm the one-line user edit; record in spike notes. - Run `make-site.sh -s HUGO_MODULE`. Confirm; record. @@ -85,6 +105,12 @@ time. Exit criterion: all three install modes build locally; the spike-notes matrix is complete with exact one-line edits. +Status (2026-05-21): NPM-tarball install path validated by hand (`npm pack` at +root → install in a tmp consumer dir; spike notes Phase 2 section). Consumer +install is clean (no dev tooling leakage; 4 packages, 0 vulnerabilities; +postinstall placeholders created). Remaining: rerun via `make-site.sh -s NPM`, +then `-s HUGO_MODULE`, then non-module `themes/docsy/`. + ### Phase 3: GitHub CI Lift Phase 2 into Actions on the same branch. @@ -112,8 +138,13 @@ checks. The user-facing payload, derived from the spike notes. - Update get-started pages with the new import path. +- Resolve the [package-versioning open question][versioning] before bumping + versions for release. - Update the changelog and release blog post; the migration section reads the exact snippets out of `spike-notes.md`. + +[versioning]: ./theme-only-folder.plan.md#package-versioning + - Update `README.md` if it references the old install shape. Exit criterion: a reviewer who has not seen the design conversation can upgrade @@ -125,8 +156,8 @@ to 0.16 by following only the release notes. team prefers) so progress is visible. - Spike notes: `tasks/0.16/repo-reorg/spike-notes.md`, created in Phase 1 and grown through Phase 2. -- One feature branch (e.g. `tof/spike`) carries Phases 0–3. Phases 4–5 land as - separate PRs against `main` after the spike merges. +- One feature branch (currently `chalin-m24-monorepo-2026-0520`) carries Phases + 0–3. Phases 4–5 land as separate PRs against `main` after the spike merges. - Each phase is reviewable on its own: a fresh `git diff` against the branch's previous phase commit should tell a small, focused story. diff --git a/tasks/0.16/repo-reorg/theme-only-folder.plan.md b/tasks/0.16/repo-reorg/theme-only-folder.plan.md index 52c134879..5377c88fc 100644 --- a/tasks/0.16/repo-reorg/theme-only-folder.plan.md +++ b/tasks/0.16/repo-reorg/theme-only-folder.plan.md @@ -60,23 +60,37 @@ install shape and it should remove the install-time workarounds listed above. │ ├── images/ # theme images only │ ├── layouts/ │ ├── static/ +│ ├── scripts/ +│ │ └── mkdirp-hugo-mod.js │ ├── hugo.yaml # canonical theme config (mounts, mediaTypes, outputFormats) │ ├── theme.toml # canonical │ ├── go.mod # module path: github.com/google/docsy/theme │ ├── go.sum -│ └── package.json # theme runtime deps + minimal lifecycle scripts only -├── docsy.dev/ # website + dev/test tooling -├── scripts/ # repo-wide maintainer scripts +│ └── package.json # source of truth for theme runtime deps +├── docsy.dev/ # website; its own node_modules for the site build +├── _dev/ # maintainer-orchestration folder (not published) +│ ├── scripts/ # all maintainer-only scripts (incl. sync-root-deps.mjs) +│ └── package.json # devDeps (hugo-extended, prettier, markdownlint, …) ├── tasks/ -└── package.json # repo-wide tooling; not the theme +└── package.json # thin publishable shim; name "docsy"; files: [theme, …] ``` Key properties: -- `theme/` is what NPM ships and what Hugo modules resolve to. -- The repo root is no longer a Docsy theme. Its `package.json` no longer carries - `name: "docsy"`, and it holds no theme runtime files. -- No facades, escape mounts, or workaround `postinstall` scripts in `theme/`. +- `theme/` is what NPM ships and what Hugo modules resolve to. Its + `package.json` is the **single source of truth** for theme runtime deps. +- The repo root is the **publishable manifest only**. It still carries + `name: "docsy"` (this is the consumer-facing package), but its `files` + whitelist allows only `theme/` and the top-level docs files into the tarball, + and it declares **no** `devDependencies`. A `prepare` script mirrors theme + runtime deps from `theme/package.json` to the root manifest so consumers' + transitive-install graphs are correct. +- `_dev/` is where maintainers run commands from. It owns the monorepo-wide + tooling and the Hugo version (single source). No npm workspaces are declared + anywhere; each of `theme/`, `docsy.dev/`, and `_dev/` is its own independent + install root. +- No facades, escape mounts, or workaround `postinstall` scripts in `theme/` + beyond `mkdirp-hugo-mod.js`, which Hugo-module consumers need. - Anything generated (vendored Bootstrap SCSS, scrollspy patch output, chroma styles, `go.sum`) is committed under `theme/` so consumers never run the generators. @@ -129,51 +143,100 @@ iterated. ## Package boundary -`theme/package.json` includes only what installed theme users need: +Each `package.json` carries a clearly-scoped set of dependencies. The four +manifests are: -| Dependency or tool | Owner | -| --------------------------------------------------------------------------- | -------------------------- | -| `bootstrap` | theme runtime | -| `@fortawesome/fontawesome-free` | theme runtime | -| `autoprefixer`, `postcss-cli` | user/site build dependency | -| `hugo-extended` | site/dev dependency | -| `prettier`, `markdownlint*`, `afdocs`, `netlify-cli`, `rtlcss`, `cross-env` | repo or website tooling | +| File | Role | Notable contents | +| -------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------ | +| `theme/package.json` | Source of truth, theme runtime deps | `bootstrap`, `@fortawesome/fontawesome-free`; `postinstall: mkdirp-hugo-mod.js` | +| `package.json` (repo root) | Publishable shim | `files: [theme, …]`, `prepare: sync-root-deps.mjs`, `postinstall: mkdirp-hugo-mod.js`. **No devDeps.** | +| `docsy.dev/package.json` | Website's site-build / site-tooling | `autoprefixer`, `postcss-cli`, `cross-env`, `rtlcss`, `afdocs`, `netlify-cli`, `npm-check-updates` | +| `_dev/package.json` | Maintainer-orchestration | `hugo-extended`, `prettier`, `markdownlint-cli2`, `markdownlint-rule-*`, `@cspell/dict-fr-fr` | Keep docs-site, CI, release, formatting, link-checking, and test-only dependencies out of `theme/package.json`. The GitHub/NPM install path is a key use case. Installing Docsy from GitHub -through NPM must not fetch `docsy.dev` dev dependencies or execute -maintainer-only generators. In particular: - -- No `prepare` script in `theme/package.json`. -- No `postinstall` side-effects that touch paths outside `theme/`. -- All generated theme assets are committed. - -Ideally, theme users need no theme dev dependencies at all. +through NPM must not fetch maintainer or `docsy.dev` dev dependencies or execute +maintainer-only generators. The shape of that install is enforced by: + +- `files: ["CHANGELOG.md", "LICENSE", "README.md", "theme"]` at the root — the + tarball contains nothing else. +- Zero `devDependencies` at the root — git-URL installs see no dev workflow to + run, so npm does not install a maintainer toolchain in the clone. +- A `postinstall` at the root that only runs `theme/scripts/mkdirp-hugo-mod.js` + to create the empty Hugo module placeholder dirs the consumer's Hugo expects. +- All generated theme assets committed under `theme/` so consumers never run a + generator. + +The `prepare` script at the root delegates to `_dev/scripts/sync-root-deps.mjs`, +which mirrors `theme/package.json`'s `dependencies` onto the root manifest. The +committed root manifest is kept in sync with `theme/` (the sync script is +idempotent); `prepare` runs as a safety net during `npm pack` and during git-URL +installs in the consumer-side clone. + +## Package versioning + +Both the root (publishable as `docsy`) and `theme/` carry a `version`, plus +`docsy.dev/` and `_dev/` carry their own private versions. The question is which +one is the **canonical** version, and how it propagates. + +**Open question.** Two viable patterns: + +- **Theme-only canonical version.** `theme/package.json` is the canonical + source. The sync script (already used for `dependencies`) is extended to + mirror `version` from `theme/` onto the root manifest at `prepare` time. The + root commits a synced value to keep maintainer working trees clean. +- **Root-canonical version.** Maintainers bump the root `version` and the + release tooling propagates it to `theme/package.json`. The two are kept + aligned by tooling. Preserves continuity with the current setup (where release + tooling already targets the root version). + +Either way, the released artifact (the tarball whose root `package.json` +declares `name: "docsy"`) is what consumers see, so the **effective** +user-facing version is whatever the root carries at pack time. The choice is +primarily about maintainer ergonomics and which file the release tooling treats +as authoritative. + +To be resolved during the spike or early in Phase 5 (docs and release notes). ## Maintainer workflow The lead maintainer (and other contributors) coordinate theme and website -changes from the repo root. `docsy.dev` is Docsy's primary end-to-end test of -theme changes, so coordinated edits across both happen daily. - -The root remains the maintainer-orchestration layer: +changes from the repo. `docsy.dev` is Docsy's primary end-to-end test of theme +changes, so coordinated edits across both happen daily. + +Orchestration commands run from `_dev/`: + +```sh +cd _dev +npm run install:all # installs theme/, docsy.dev/, and _dev/ in sequence +npm run build # builds docsy.dev against the local theme/ +npm run serve # docsy.dev dev server with live reload +npm run check # repo-wide format + markdown checks +npm run fix # auto-fix +``` -- The root `package.json` keeps NPM workspace declarations and exposes commands - such as `npm run serve`, `npm run check`, and `npm run fix`. These delegate to - the workspace that owns each tool. -- Maintainers can edit theme code under `theme/` and see effects in the website - under `docsy.dev` from a single shell at the root. -- Theme runtime concerns stay under `theme/`; orchestration concerns stay at the - root. +The maintainer's shell sits in `_dev/`; edits happen across `theme/`, +`docsy.dev/`, and `_dev/` as needed, and one orchestration command from `_dev/` +exercises the cross-folder loop. The repo root is **not** the maintainer's +working directory; it is the publishable manifest only. ## Tooling versions -Maintainers still need a predictable local toolchain. There is one clear source -for each shared tool version, so CI, local development, and release work do not -drift. Root commands stay as convenient entry points and delegate to the -workspace that owns each tool. +Each shared tool has exactly one declaration in the repo: + +- `hugo-extended` lives in `_dev/devDependencies`. The `hugo` binary lands at + `_dev/node_modules/.bin/hugo` after `cd _dev && npm install`, and is on PATH + for nested `npm run -C ../docsy.dev …` invocations via npm-script PATH + inheritance. Bumping the Hugo version is a single edit. +- `prettier`, `markdownlint-cli2`, the markdownlint rule plugins, and + `@cspell/dict-fr-fr` likewise live in `_dev/devDependencies`. +- Site-build tools (`autoprefixer`, `postcss-cli`, `cross-env`, `rtlcss`) and + site-tooling (`afdocs`, `netlify-cli`, `npm-check-updates`) live in + `docsy.dev/devDependencies` because that is where they are used. +- Theme runtime deps (`bootstrap`, `@fortawesome/fontawesome-free`) live in + `theme/package.json` and are mirrored to the root manifest by the sync script. ## Test boundary @@ -187,29 +250,36 @@ easy for maintainers to run; theme users never install the test toolchain. 1. **Move the theme into `theme/`.** Move `assets/`, `i18n/`, `images/`, `layouts/`, `static/`, `hugo.yaml`, `theme.toml`, `go.mod`, `go.sum`, and the - theme-runtime parts of `package.json` into `theme/`. Update the `module` - declaration in `theme/go.mod` to `github.com/google/docsy/theme`. Update all - generators and patch scripts in `scripts/` to write to the new paths under - `theme/`. - -2. **Reshape the root.** Root `package.json` becomes repo-level only; its `name` - is no longer `docsy`. Remove the `postinstall` side-effect script. Move or - delete `postcss.config.js` based on consumer guidance. Keep `Dockerfile`, - `docker-compose.yaml`, `.editorconfig`, `.prettierrc.json`, `.markdownlint*`, - `.nvmrc`, `.gitattributes`, `.gitignore` at the root. - -3. **Update `docsy.dev`.** Pin to the new Hugo module path - (`github.com/google/docsy/theme`). Update the `_hugo --themesDir` assumption. - The website becomes a real first-class consumer of the theme. - -4. **Update `docsy-example`.** Land a coordinated PR that bumps the import path. + `mkdirp-hugo-mod.js` postinstall helper into `theme/`. Update the `module` + declaration in `theme/go.mod` to `github.com/google/docsy/theme`. Update + generators and patch scripts that have moved to `_dev/scripts/` to write to + the new paths under `theme/`. + +2. **Carve out `_dev/`.** Create `_dev/` and `git mv scripts _dev/scripts` so + maintainer scripts retain history. Move repo-wide devDeps from the old root + `package.json` to `_dev/package.json`. Move `hugo-extended` here as the + single Hugo source. Add `_dev/scripts/sync-root-deps.mjs` for the theme-deps + mirror. + +3. **Reshape the root.** Root `package.json` becomes a thin publishable shim: + `name: "docsy"`, a `files` whitelist, `prepare` + `postinstall` hooks, no + `devDependencies`, no workspaces. Keep `Dockerfile`, `docker-compose.yaml`, + `.editorconfig`, `.prettierrc.json`, `.markdownlint*`, `.nvmrc`, + `.gitattributes`, `.gitignore` at the root. + +4. **Update `docsy.dev`.** Pin to the new Hugo module path + (`github.com/google/docsy/theme`) or the classic `theme: docsy/theme` form. + Remove `hugo-extended` from `docsy.dev/package.json` (it now lives in + `_dev/`). The website becomes a real first-class consumer of the theme. + +5. **Update `docsy-example`.** Land a coordinated PR that bumps the import path. Confirms the example continues to work as the canonical user reference. -5. **Update CI and smoke tests.** `scripts/make-site.sh` and the GitHub Actions - workflows must exercise the new install paths. Keep the existing matrix (NPM - × HUGO_MODULE × Windows × Ubuntu) green. +6. **Update CI and smoke tests.** `_dev/scripts/make-site.sh` and the GitHub + Actions workflows must exercise the new install paths. Keep the existing + matrix (NPM × HUGO_MODULE × Windows × Ubuntu) green. -6. **Update docs and release notes.** Document the one-line config change per +7. **Update docs and release notes.** Document the one-line config change per install mode. The release blog post must include exact before/after snippets, and the user-guide get-started pages must reflect the new import path. @@ -224,11 +294,14 @@ easy for maintainers to run; theme users never install the test toolchain. - A new site can use Docsy through the GitHub/NPM install path with the documented one-line config change. - Non-module theme usage works with the documented one-line config change. -- `theme/package.json` contains only theme runtime dependencies and minimal - lifecycle scripts. No `prepare` or `postinstall` scripts that affect - consumers. -- Installing Docsy from GitHub through NPM does not install `docsy.dev` dev - dependencies, does not execute `_prepare`, and does not build the whole repo. +- `theme/package.json` contains only theme runtime dependencies and the + `mkdirp-hugo-mod.js` postinstall helper. No other lifecycle scripts. +- The root `package.json` has no `devDependencies` and a `files` whitelist so + that `npm install github:google/docsy#` brings the consumer only + `theme/` + a handful of top-level docs files, plus `bootstrap` and + `@fortawesome/fontawesome-free` as transitive deps. Installing Docsy this way + does not install `docsy.dev` dev dependencies, does not install maintainer + tooling, does not execute `_prepare`, and does not build the whole repo. - All generated theme assets (vendored Bootstrap SCSS, scrollspy patch output, chroma styles, `go.sum`) are committed under `theme/`. - HTML, screenshot, and other golden tests can be added without increasing the diff --git a/assets/_cache/README.md b/theme/assets/_cache/README.md similarity index 100% rename from assets/_cache/README.md rename to theme/assets/_cache/README.md diff --git a/assets/_cache/bootstrap/method.patch b/theme/assets/_cache/bootstrap/method.patch similarity index 100% rename from assets/_cache/bootstrap/method.patch rename to theme/assets/_cache/bootstrap/method.patch diff --git a/assets/_cache/bootstrap/scrollspy-method-patched.js b/theme/assets/_cache/bootstrap/scrollspy-method-patched.js similarity index 100% rename from assets/_cache/bootstrap/scrollspy-method-patched.js rename to theme/assets/_cache/bootstrap/scrollspy-method-patched.js diff --git a/assets/_cache/bootstrap/scrollspy-method.js b/theme/assets/_cache/bootstrap/scrollspy-method.js similarity index 100% rename from assets/_cache/bootstrap/scrollspy-method.js rename to theme/assets/_cache/bootstrap/scrollspy-method.js diff --git a/assets/_vendor/README.md b/theme/assets/_vendor/README.md similarity index 97% rename from assets/_vendor/README.md rename to theme/assets/_vendor/README.md index 0639d8d2b..184f9cf42 100644 --- a/assets/_vendor/README.md +++ b/theme/assets/_vendor/README.md @@ -1,8 +1,8 @@ -This `_vendor` folder exists to work around a known bug in Go’s module -management. For details, see - -- -- - -DO NOT EDIT or manually override the files in this folder. They are -automatically synchronized at installation time. +This `_vendor` folder exists to work around a known bug in Go’s module +management. For details, see + +- +- + +DO NOT EDIT or manually override the files in this folder. They are +automatically synchronized at installation time. diff --git a/assets/_vendor/bootstrap/scss/_rfs.scss b/theme/assets/_vendor/bootstrap/scss/_rfs.scss similarity index 100% rename from assets/_vendor/bootstrap/scss/_rfs.scss rename to theme/assets/_vendor/bootstrap/scss/_rfs.scss diff --git a/assets/icons/logo.png b/theme/assets/icons/logo.png similarity index 100% rename from assets/icons/logo.png rename to theme/assets/icons/logo.png diff --git a/assets/icons/logo.svg b/theme/assets/icons/logo.svg similarity index 100% rename from assets/icons/logo.svg rename to theme/assets/icons/logo.svg diff --git a/assets/js/base.js b/theme/assets/js/base.js similarity index 100% rename from assets/js/base.js rename to theme/assets/js/base.js diff --git a/assets/js/click-to-copy.js b/theme/assets/js/click-to-copy.js similarity index 100% rename from assets/js/click-to-copy.js rename to theme/assets/js/click-to-copy.js diff --git a/assets/js/dark-mode.js b/theme/assets/js/dark-mode.js similarity index 100% rename from assets/js/dark-mode.js rename to theme/assets/js/dark-mode.js diff --git a/assets/js/drawio.js b/theme/assets/js/drawio.js similarity index 100% rename from assets/js/drawio.js rename to theme/assets/js/drawio.js diff --git a/assets/js/markmap.js b/theme/assets/js/markmap.js similarity index 100% rename from assets/js/markmap.js rename to theme/assets/js/markmap.js diff --git a/assets/js/offline-search.js b/theme/assets/js/offline-search.js similarity index 100% rename from assets/js/offline-search.js rename to theme/assets/js/offline-search.js diff --git a/assets/js/plantuml.js b/theme/assets/js/plantuml.js similarity index 100% rename from assets/js/plantuml.js rename to theme/assets/js/plantuml.js diff --git a/assets/js/scrollspy-patch.js b/theme/assets/js/scrollspy-patch.js similarity index 100% rename from assets/js/scrollspy-patch.js rename to theme/assets/js/scrollspy-patch.js diff --git a/assets/js/search.js b/theme/assets/js/search.js similarity index 100% rename from assets/js/search.js rename to theme/assets/js/search.js diff --git a/assets/json/offline-search-index.json b/theme/assets/json/offline-search-index.json similarity index 100% rename from assets/json/offline-search-index.json rename to theme/assets/json/offline-search-index.json diff --git a/assets/scss/_styles_project.scss b/theme/assets/scss/_styles_project.scss similarity index 100% rename from assets/scss/_styles_project.scss rename to theme/assets/scss/_styles_project.scss diff --git a/assets/scss/_variables_project.scss b/theme/assets/scss/_variables_project.scss similarity index 100% rename from assets/scss/_variables_project.scss rename to theme/assets/scss/_variables_project.scss diff --git a/assets/scss/_variables_project_after_bs.scss b/theme/assets/scss/_variables_project_after_bs.scss similarity index 100% rename from assets/scss/_variables_project_after_bs.scss rename to theme/assets/scss/_variables_project_after_bs.scss diff --git a/assets/scss/main.scss b/theme/assets/scss/main.scss similarity index 100% rename from assets/scss/main.scss rename to theme/assets/scss/main.scss diff --git a/assets/scss/td/_alerts.scss b/theme/assets/scss/td/_alerts.scss similarity index 100% rename from assets/scss/td/_alerts.scss rename to theme/assets/scss/td/_alerts.scss diff --git a/assets/scss/td/_blog.scss b/theme/assets/scss/td/_blog.scss similarity index 100% rename from assets/scss/td/_blog.scss rename to theme/assets/scss/td/_blog.scss diff --git a/assets/scss/td/_boxes.scss b/theme/assets/scss/td/_boxes.scss similarity index 100% rename from assets/scss/td/_boxes.scss rename to theme/assets/scss/td/_boxes.scss diff --git a/assets/scss/td/_breadcrumb.scss b/theme/assets/scss/td/_breadcrumb.scss similarity index 100% rename from assets/scss/td/_breadcrumb.scss rename to theme/assets/scss/td/_breadcrumb.scss diff --git a/assets/scss/td/_code-dark.scss b/theme/assets/scss/td/_code-dark.scss similarity index 100% rename from assets/scss/td/_code-dark.scss rename to theme/assets/scss/td/_code-dark.scss diff --git a/assets/scss/td/_code.scss b/theme/assets/scss/td/_code.scss similarity index 100% rename from assets/scss/td/_code.scss rename to theme/assets/scss/td/_code.scss diff --git a/assets/scss/td/_color-adjustments-dark.scss b/theme/assets/scss/td/_color-adjustments-dark.scss similarity index 100% rename from assets/scss/td/_color-adjustments-dark.scss rename to theme/assets/scss/td/_color-adjustments-dark.scss diff --git a/assets/scss/td/_colors.scss b/theme/assets/scss/td/_colors.scss similarity index 100% rename from assets/scss/td/_colors.scss rename to theme/assets/scss/td/_colors.scss diff --git a/assets/scss/td/_content.scss b/theme/assets/scss/td/_content.scss similarity index 100% rename from assets/scss/td/_content.scss rename to theme/assets/scss/td/_content.scss diff --git a/assets/scss/td/_drawio.scss b/theme/assets/scss/td/_drawio.scss similarity index 100% rename from assets/scss/td/_drawio.scss rename to theme/assets/scss/td/_drawio.scss diff --git a/assets/scss/td/_footer.scss b/theme/assets/scss/td/_footer.scss similarity index 100% rename from assets/scss/td/_footer.scss rename to theme/assets/scss/td/_footer.scss diff --git a/assets/scss/td/_gcs-search-dark.scss b/theme/assets/scss/td/_gcs-search-dark.scss similarity index 100% rename from assets/scss/td/_gcs-search-dark.scss rename to theme/assets/scss/td/_gcs-search-dark.scss diff --git a/assets/scss/td/_main-container.scss b/theme/assets/scss/td/_main-container.scss similarity index 100% rename from assets/scss/td/_main-container.scss rename to theme/assets/scss/td/_main-container.scss diff --git a/assets/scss/td/_main.scss b/theme/assets/scss/td/_main.scss similarity index 100% rename from assets/scss/td/_main.scss rename to theme/assets/scss/td/_main.scss diff --git a/assets/scss/td/_nav.scss b/theme/assets/scss/td/_nav.scss similarity index 100% rename from assets/scss/td/_nav.scss rename to theme/assets/scss/td/_nav.scss diff --git a/assets/scss/td/_navbar-mobile-scroll.scss b/theme/assets/scss/td/_navbar-mobile-scroll.scss similarity index 100% rename from assets/scss/td/_navbar-mobile-scroll.scss rename to theme/assets/scss/td/_navbar-mobile-scroll.scss diff --git a/assets/scss/td/_pageinfo.scss b/theme/assets/scss/td/_pageinfo.scss similarity index 100% rename from assets/scss/td/_pageinfo.scss rename to theme/assets/scss/td/_pageinfo.scss diff --git a/assets/scss/td/_scroll.scss b/theme/assets/scss/td/_scroll.scss similarity index 100% rename from assets/scss/td/_scroll.scss rename to theme/assets/scss/td/_scroll.scss diff --git a/assets/scss/td/_search.scss b/theme/assets/scss/td/_search.scss similarity index 100% rename from assets/scss/td/_search.scss rename to theme/assets/scss/td/_search.scss diff --git a/assets/scss/td/_section-index.scss b/theme/assets/scss/td/_section-index.scss similarity index 100% rename from assets/scss/td/_section-index.scss rename to theme/assets/scss/td/_section-index.scss diff --git a/assets/scss/td/_shortcodes.scss b/theme/assets/scss/td/_shortcodes.scss similarity index 100% rename from assets/scss/td/_shortcodes.scss rename to theme/assets/scss/td/_shortcodes.scss diff --git a/assets/scss/td/_sidebar-toc.scss b/theme/assets/scss/td/_sidebar-toc.scss similarity index 100% rename from assets/scss/td/_sidebar-toc.scss rename to theme/assets/scss/td/_sidebar-toc.scss diff --git a/assets/scss/td/_sidebar-tree.scss b/theme/assets/scss/td/_sidebar-tree.scss similarity index 100% rename from assets/scss/td/_sidebar-tree.scss rename to theme/assets/scss/td/_sidebar-tree.scss diff --git a/assets/scss/td/_swagger.scss b/theme/assets/scss/td/_swagger.scss similarity index 100% rename from assets/scss/td/_swagger.scss rename to theme/assets/scss/td/_swagger.scss diff --git a/assets/scss/td/_table.scss b/theme/assets/scss/td/_table.scss similarity index 100% rename from assets/scss/td/_table.scss rename to theme/assets/scss/td/_table.scss diff --git a/assets/scss/td/_taxonomy.scss b/theme/assets/scss/td/_taxonomy.scss similarity index 100% rename from assets/scss/td/_taxonomy.scss rename to theme/assets/scss/td/_taxonomy.scss diff --git a/assets/scss/td/_variables.scss b/theme/assets/scss/td/_variables.scss similarity index 100% rename from assets/scss/td/_variables.scss rename to theme/assets/scss/td/_variables.scss diff --git a/assets/scss/td/_variables_forward.scss b/theme/assets/scss/td/_variables_forward.scss similarity index 100% rename from assets/scss/td/_variables_forward.scss rename to theme/assets/scss/td/_variables_forward.scss diff --git a/assets/scss/td/blocks/_blocks.scss b/theme/assets/scss/td/blocks/_blocks.scss similarity index 100% rename from assets/scss/td/blocks/_blocks.scss rename to theme/assets/scss/td/blocks/_blocks.scss diff --git a/assets/scss/td/blocks/_cover.scss b/theme/assets/scss/td/blocks/_cover.scss similarity index 100% rename from assets/scss/td/blocks/_cover.scss rename to theme/assets/scss/td/blocks/_cover.scss diff --git a/assets/scss/td/chroma/_dark.scss b/theme/assets/scss/td/chroma/_dark.scss similarity index 100% rename from assets/scss/td/chroma/_dark.scss rename to theme/assets/scss/td/chroma/_dark.scss diff --git a/assets/scss/td/chroma/_light.scss b/theme/assets/scss/td/chroma/_light.scss similarity index 100% rename from assets/scss/td/chroma/_light.scss rename to theme/assets/scss/td/chroma/_light.scss diff --git a/assets/scss/td/extra/_bs-defaults.scss b/theme/assets/scss/td/extra/_bs-defaults.scss similarity index 100% rename from assets/scss/td/extra/_bs-defaults.scss rename to theme/assets/scss/td/extra/_bs-defaults.scss diff --git a/assets/scss/td/extra/_buttons.scss b/theme/assets/scss/td/extra/_buttons.scss similarity index 100% rename from assets/scss/td/extra/_buttons.scss rename to theme/assets/scss/td/extra/_buttons.scss diff --git a/assets/scss/td/extra/_index.scss b/theme/assets/scss/td/extra/_index.scss similarity index 100% rename from assets/scss/td/extra/_index.scss rename to theme/assets/scss/td/extra/_index.scss diff --git a/assets/scss/td/extra/_main-container.scss b/theme/assets/scss/td/extra/_main-container.scss similarity index 100% rename from assets/scss/td/extra/_main-container.scss rename to theme/assets/scss/td/extra/_main-container.scss diff --git a/assets/scss/td/extra/_navbar.scss b/theme/assets/scss/td/extra/_navbar.scss similarity index 100% rename from assets/scss/td/extra/_navbar.scss rename to theme/assets/scss/td/extra/_navbar.scss diff --git a/assets/scss/td/shortcodes/cards-pane.scss b/theme/assets/scss/td/shortcodes/cards-pane.scss similarity index 100% rename from assets/scss/td/shortcodes/cards-pane.scss rename to theme/assets/scss/td/shortcodes/cards-pane.scss diff --git a/assets/scss/td/shortcodes/tabbed-pane.scss b/theme/assets/scss/td/shortcodes/tabbed-pane.scss similarity index 100% rename from assets/scss/td/shortcodes/tabbed-pane.scss rename to theme/assets/scss/td/shortcodes/tabbed-pane.scss diff --git a/assets/scss/td/support/_bootstrap_vers_test.scss b/theme/assets/scss/td/support/_bootstrap_vers_test.scss similarity index 100% rename from assets/scss/td/support/_bootstrap_vers_test.scss rename to theme/assets/scss/td/support/_bootstrap_vers_test.scss diff --git a/assets/scss/td/support/_mixins.scss b/theme/assets/scss/td/support/_mixins.scss similarity index 100% rename from assets/scss/td/support/_mixins.scss rename to theme/assets/scss/td/support/_mixins.scss diff --git a/assets/scss/td/support/_rtl.scss b/theme/assets/scss/td/support/_rtl.scss similarity index 100% rename from assets/scss/td/support/_rtl.scss rename to theme/assets/scss/td/support/_rtl.scss diff --git a/assets/scss/td/support/_utilities.scss b/theme/assets/scss/td/support/_utilities.scss similarity index 100% rename from assets/scss/td/support/_utilities.scss rename to theme/assets/scss/td/support/_utilities.scss diff --git a/assets/stubs/new-page-template.md b/theme/assets/stubs/new-page-template.md similarity index 100% rename from assets/stubs/new-page-template.md rename to theme/assets/stubs/new-page-template.md diff --git a/go.mod b/theme/go.mod similarity index 85% rename from go.mod rename to theme/go.mod index 13b045972..c17a1c4a9 100644 --- a/go.mod +++ b/theme/go.mod @@ -1,4 +1,4 @@ -module github.com/google/docsy +module github.com/google/docsy/theme go 1.12 diff --git a/go.sum b/theme/go.sum similarity index 100% rename from go.sum rename to theme/go.sum diff --git a/hugo.yaml b/theme/hugo.yaml similarity index 77% rename from hugo.yaml rename to theme/hugo.yaml index 423e9bf7e..cfae0ae62 100644 --- a/hugo.yaml +++ b/theme/hugo.yaml @@ -49,15 +49,14 @@ module: target: static - source: node_modules/@fortawesome/fontawesome-free/webfonts target: static/webfonts - # Mounts for projects using Docsy as an NPM package. The source path prefix - # "../.." moves out of themes/docsy so that Docsy can find its dependencies. - - source: ../../node_modules/bootstrap - target: assets/vendor/bootstrap - - source: ../../node_modules/@fortawesome/fontawesome-free - target: assets/vendor/Font-Awesome - - source: ../../node_modules/@fortawesome/fontawesome-free/webfonts - target: static/webfonts - # Mounts for module installations, + # The local `node_modules/...` mounts above use Hugo's dual lookup for + # theme/module imports: Hugo first tries the source relative to the + # theme directory, then falls back to the consumer site's working + # directory. That covers both the maintainer case (theme-local + # node_modules) and the NPM-consumer case (site-local node_modules) + # without an explicit `../../node_modules` escape mount. + # See Hugo's modules/collect.go (`nodeModulesRoot`) and issue #14083. + # Mount for module installations, # needed to work around a known bug in Go’s module management. - source: assets/_vendor/bootstrap/scss target: assets/vendor/bootstrap/scss/vendor diff --git a/i18n/ar.yaml b/theme/i18n/ar.yaml similarity index 100% rename from i18n/ar.yaml rename to theme/i18n/ar.yaml diff --git a/i18n/az.yaml b/theme/i18n/az.yaml similarity index 100% rename from i18n/az.yaml rename to theme/i18n/az.yaml diff --git a/i18n/bg.yaml b/theme/i18n/bg.yaml similarity index 100% rename from i18n/bg.yaml rename to theme/i18n/bg.yaml diff --git a/i18n/bn.yaml b/theme/i18n/bn.yaml similarity index 100% rename from i18n/bn.yaml rename to theme/i18n/bn.yaml diff --git a/i18n/de.yaml b/theme/i18n/de.yaml similarity index 100% rename from i18n/de.yaml rename to theme/i18n/de.yaml diff --git a/i18n/en.yaml b/theme/i18n/en.yaml similarity index 100% rename from i18n/en.yaml rename to theme/i18n/en.yaml diff --git a/i18n/es.yaml b/theme/i18n/es.yaml similarity index 100% rename from i18n/es.yaml rename to theme/i18n/es.yaml diff --git a/i18n/et.yaml b/theme/i18n/et.yaml similarity index 100% rename from i18n/et.yaml rename to theme/i18n/et.yaml diff --git a/i18n/fa.yaml b/theme/i18n/fa.yaml similarity index 100% rename from i18n/fa.yaml rename to theme/i18n/fa.yaml diff --git a/i18n/fi.yaml b/theme/i18n/fi.yaml similarity index 100% rename from i18n/fi.yaml rename to theme/i18n/fi.yaml diff --git a/i18n/fr.yaml b/theme/i18n/fr.yaml similarity index 100% rename from i18n/fr.yaml rename to theme/i18n/fr.yaml diff --git a/i18n/he.yaml b/theme/i18n/he.yaml similarity index 100% rename from i18n/he.yaml rename to theme/i18n/he.yaml diff --git a/i18n/hi.yaml b/theme/i18n/hi.yaml similarity index 100% rename from i18n/hi.yaml rename to theme/i18n/hi.yaml diff --git a/i18n/hu.yaml b/theme/i18n/hu.yaml similarity index 100% rename from i18n/hu.yaml rename to theme/i18n/hu.yaml diff --git a/i18n/it.yaml b/theme/i18n/it.yaml similarity index 100% rename from i18n/it.yaml rename to theme/i18n/it.yaml diff --git a/i18n/ja.yaml b/theme/i18n/ja.yaml similarity index 100% rename from i18n/ja.yaml rename to theme/i18n/ja.yaml diff --git a/i18n/ko.yaml b/theme/i18n/ko.yaml similarity index 100% rename from i18n/ko.yaml rename to theme/i18n/ko.yaml diff --git a/i18n/nl.yaml b/theme/i18n/nl.yaml similarity index 100% rename from i18n/nl.yaml rename to theme/i18n/nl.yaml diff --git a/i18n/no.yaml b/theme/i18n/no.yaml similarity index 100% rename from i18n/no.yaml rename to theme/i18n/no.yaml diff --git a/i18n/oc.yaml b/theme/i18n/oc.yaml similarity index 100% rename from i18n/oc.yaml rename to theme/i18n/oc.yaml diff --git a/i18n/pl.yaml b/theme/i18n/pl.yaml similarity index 100% rename from i18n/pl.yaml rename to theme/i18n/pl.yaml diff --git a/i18n/pt-br.yaml b/theme/i18n/pt-br.yaml similarity index 100% rename from i18n/pt-br.yaml rename to theme/i18n/pt-br.yaml diff --git a/i18n/ro.yaml b/theme/i18n/ro.yaml similarity index 100% rename from i18n/ro.yaml rename to theme/i18n/ro.yaml diff --git a/i18n/ru.yaml b/theme/i18n/ru.yaml similarity index 100% rename from i18n/ru.yaml rename to theme/i18n/ru.yaml diff --git a/i18n/sr-cyrl.yaml b/theme/i18n/sr-cyrl.yaml similarity index 100% rename from i18n/sr-cyrl.yaml rename to theme/i18n/sr-cyrl.yaml diff --git a/i18n/sr-latn.yaml b/theme/i18n/sr-latn.yaml similarity index 100% rename from i18n/sr-latn.yaml rename to theme/i18n/sr-latn.yaml diff --git a/i18n/sv.yaml b/theme/i18n/sv.yaml similarity index 100% rename from i18n/sv.yaml rename to theme/i18n/sv.yaml diff --git a/i18n/tr.yaml b/theme/i18n/tr.yaml similarity index 100% rename from i18n/tr.yaml rename to theme/i18n/tr.yaml diff --git a/i18n/uk.yaml b/theme/i18n/uk.yaml similarity index 100% rename from i18n/uk.yaml rename to theme/i18n/uk.yaml diff --git a/i18n/zh-cn.yaml b/theme/i18n/zh-cn.yaml similarity index 100% rename from i18n/zh-cn.yaml rename to theme/i18n/zh-cn.yaml diff --git a/i18n/zh-tw.yaml b/theme/i18n/zh-tw.yaml similarity index 100% rename from i18n/zh-tw.yaml rename to theme/i18n/zh-tw.yaml diff --git a/images/screenshot.png b/theme/images/screenshot.png similarity index 100% rename from images/screenshot.png rename to theme/images/screenshot.png diff --git a/images/tn.png b/theme/images/tn.png similarity index 100% rename from images/tn.png rename to theme/images/tn.png diff --git a/layouts/404.html b/theme/layouts/404.html similarity index 100% rename from layouts/404.html rename to theme/layouts/404.html diff --git a/layouts/_markup/render-blockquote-alert.html b/theme/layouts/_markup/render-blockquote-alert.html similarity index 100% rename from layouts/_markup/render-blockquote-alert.html rename to theme/layouts/_markup/render-blockquote-alert.html diff --git a/layouts/_markup/render-codeblock-chem.html b/theme/layouts/_markup/render-codeblock-chem.html similarity index 100% rename from layouts/_markup/render-codeblock-chem.html rename to theme/layouts/_markup/render-codeblock-chem.html diff --git a/layouts/_markup/render-codeblock-math.html b/theme/layouts/_markup/render-codeblock-math.html similarity index 100% rename from layouts/_markup/render-codeblock-math.html rename to theme/layouts/_markup/render-codeblock-math.html diff --git a/layouts/_markup/render-codeblock-mermaid.html b/theme/layouts/_markup/render-codeblock-mermaid.html similarity index 100% rename from layouts/_markup/render-codeblock-mermaid.html rename to theme/layouts/_markup/render-codeblock-mermaid.html diff --git a/layouts/_partials/breadcrumb.html b/theme/layouts/_partials/breadcrumb.html similarity index 100% rename from layouts/_partials/breadcrumb.html rename to theme/layouts/_partials/breadcrumb.html diff --git a/layouts/_partials/community_links.html b/theme/layouts/_partials/community_links.html similarity index 100% rename from layouts/_partials/community_links.html rename to theme/layouts/_partials/community_links.html diff --git a/layouts/_partials/dark-mode-config.html b/theme/layouts/_partials/dark-mode-config.html similarity index 100% rename from layouts/_partials/dark-mode-config.html rename to theme/layouts/_partials/dark-mode-config.html diff --git a/layouts/_partials/disqus-comment.html b/theme/layouts/_partials/disqus-comment.html similarity index 100% rename from layouts/_partials/disqus-comment.html rename to theme/layouts/_partials/disqus-comment.html diff --git a/layouts/_partials/favicons.html b/theme/layouts/_partials/favicons.html similarity index 100% rename from layouts/_partials/favicons.html rename to theme/layouts/_partials/favicons.html diff --git a/layouts/_partials/featured-image.html b/theme/layouts/_partials/featured-image.html similarity index 100% rename from layouts/_partials/featured-image.html rename to theme/layouts/_partials/featured-image.html diff --git a/layouts/_partials/feedback.html b/theme/layouts/_partials/feedback.html similarity index 100% rename from layouts/_partials/feedback.html rename to theme/layouts/_partials/feedback.html diff --git a/layouts/_partials/footer.html b/theme/layouts/_partials/footer.html similarity index 100% rename from layouts/_partials/footer.html rename to theme/layouts/_partials/footer.html diff --git a/layouts/_partials/footer/center.html b/theme/layouts/_partials/footer/center.html similarity index 100% rename from layouts/_partials/footer/center.html rename to theme/layouts/_partials/footer/center.html diff --git a/layouts/_partials/footer/copyright.html b/theme/layouts/_partials/footer/copyright.html similarity index 100% rename from layouts/_partials/footer/copyright.html rename to theme/layouts/_partials/footer/copyright.html diff --git a/layouts/_partials/footer/left.html b/theme/layouts/_partials/footer/left.html similarity index 100% rename from layouts/_partials/footer/left.html rename to theme/layouts/_partials/footer/left.html diff --git a/layouts/_partials/footer/links.html b/theme/layouts/_partials/footer/links.html similarity index 100% rename from layouts/_partials/footer/links.html rename to theme/layouts/_partials/footer/links.html diff --git a/layouts/_partials/footer/right.html b/theme/layouts/_partials/footer/right.html similarity index 100% rename from layouts/_partials/footer/right.html rename to theme/layouts/_partials/footer/right.html diff --git a/layouts/_partials/head-css.html b/theme/layouts/_partials/head-css.html similarity index 100% rename from layouts/_partials/head-css.html rename to theme/layouts/_partials/head-css.html diff --git a/layouts/_partials/head.html b/theme/layouts/_partials/head.html similarity index 100% rename from layouts/_partials/head.html rename to theme/layouts/_partials/head.html diff --git a/layouts/_partials/hooks/body-end.html b/theme/layouts/_partials/hooks/body-end.html similarity index 100% rename from layouts/_partials/hooks/body-end.html rename to theme/layouts/_partials/hooks/body-end.html diff --git a/layouts/_partials/hooks/head-end.html b/theme/layouts/_partials/hooks/head-end.html similarity index 100% rename from layouts/_partials/hooks/head-end.html rename to theme/layouts/_partials/hooks/head-end.html diff --git a/layouts/_partials/navbar-lang-selector.html b/theme/layouts/_partials/navbar-lang-selector.html similarity index 100% rename from layouts/_partials/navbar-lang-selector.html rename to theme/layouts/_partials/navbar-lang-selector.html diff --git a/layouts/_partials/navbar-version-selector.html b/theme/layouts/_partials/navbar-version-selector.html similarity index 100% rename from layouts/_partials/navbar-version-selector.html rename to theme/layouts/_partials/navbar-version-selector.html diff --git a/layouts/_partials/navbar.html b/theme/layouts/_partials/navbar.html similarity index 100% rename from layouts/_partials/navbar.html rename to theme/layouts/_partials/navbar.html diff --git a/layouts/_partials/outputformat.html b/theme/layouts/_partials/outputformat.html similarity index 100% rename from layouts/_partials/outputformat.html rename to theme/layouts/_partials/outputformat.html diff --git a/layouts/_partials/page-description.html b/theme/layouts/_partials/page-description.html similarity index 100% rename from layouts/_partials/page-description.html rename to theme/layouts/_partials/page-description.html diff --git a/layouts/_partials/page-meta-lastmod.html b/theme/layouts/_partials/page-meta-lastmod.html similarity index 100% rename from layouts/_partials/page-meta-lastmod.html rename to theme/layouts/_partials/page-meta-lastmod.html diff --git a/layouts/_partials/page-meta-links.html b/theme/layouts/_partials/page-meta-links.html similarity index 100% rename from layouts/_partials/page-meta-links.html rename to theme/layouts/_partials/page-meta-links.html diff --git a/layouts/_partials/pager.html b/theme/layouts/_partials/pager.html similarity index 100% rename from layouts/_partials/pager.html rename to theme/layouts/_partials/pager.html diff --git a/layouts/_partials/print/content-blog.html b/theme/layouts/_partials/print/content-blog.html similarity index 100% rename from layouts/_partials/print/content-blog.html rename to theme/layouts/_partials/print/content-blog.html diff --git a/layouts/_partials/print/content.html b/theme/layouts/_partials/print/content.html similarity index 100% rename from layouts/_partials/print/content.html rename to theme/layouts/_partials/print/content.html diff --git a/layouts/_partials/print/page-heading.html b/theme/layouts/_partials/print/page-heading.html similarity index 100% rename from layouts/_partials/print/page-heading.html rename to theme/layouts/_partials/print/page-heading.html diff --git a/layouts/_partials/print/render.html b/theme/layouts/_partials/print/render.html similarity index 100% rename from layouts/_partials/print/render.html rename to theme/layouts/_partials/print/render.html diff --git a/layouts/_partials/print/toc-li-blog.html b/theme/layouts/_partials/print/toc-li-blog.html similarity index 100% rename from layouts/_partials/print/toc-li-blog.html rename to theme/layouts/_partials/print/toc-li-blog.html diff --git a/layouts/_partials/print/toc-li.html b/theme/layouts/_partials/print/toc-li.html similarity index 100% rename from layouts/_partials/print/toc-li.html rename to theme/layouts/_partials/print/toc-li.html diff --git a/layouts/_partials/reading-time.html b/theme/layouts/_partials/reading-time.html similarity index 100% rename from layouts/_partials/reading-time.html rename to theme/layouts/_partials/reading-time.html diff --git a/layouts/_partials/scripts.html b/theme/layouts/_partials/scripts.html similarity index 100% rename from layouts/_partials/scripts.html rename to theme/layouts/_partials/scripts.html diff --git a/layouts/_partials/scripts/katex.html b/theme/layouts/_partials/scripts/katex.html similarity index 100% rename from layouts/_partials/scripts/katex.html rename to theme/layouts/_partials/scripts/katex.html diff --git a/layouts/_partials/scripts/math.html b/theme/layouts/_partials/scripts/math.html similarity index 100% rename from layouts/_partials/scripts/math.html rename to theme/layouts/_partials/scripts/math.html diff --git a/layouts/_partials/scripts/mermaid.html b/theme/layouts/_partials/scripts/mermaid.html similarity index 100% rename from layouts/_partials/scripts/mermaid.html rename to theme/layouts/_partials/scripts/mermaid.html diff --git a/layouts/_partials/search-input.html b/theme/layouts/_partials/search-input.html similarity index 100% rename from layouts/_partials/search-input.html rename to theme/layouts/_partials/search-input.html diff --git a/layouts/_partials/section-index.html b/theme/layouts/_partials/section-index.html similarity index 100% rename from layouts/_partials/section-index.html rename to theme/layouts/_partials/section-index.html diff --git a/layouts/_partials/sidebar-tree.html b/theme/layouts/_partials/sidebar-tree.html similarity index 100% rename from layouts/_partials/sidebar-tree.html rename to theme/layouts/_partials/sidebar-tree.html diff --git a/layouts/_partials/sidebar.html b/theme/layouts/_partials/sidebar.html similarity index 100% rename from layouts/_partials/sidebar.html rename to theme/layouts/_partials/sidebar.html diff --git a/layouts/_partials/taxonomy_terms_article.html b/theme/layouts/_partials/taxonomy_terms_article.html similarity index 100% rename from layouts/_partials/taxonomy_terms_article.html rename to theme/layouts/_partials/taxonomy_terms_article.html diff --git a/layouts/_partials/taxonomy_terms_article_wrapper.html b/theme/layouts/_partials/taxonomy_terms_article_wrapper.html similarity index 100% rename from layouts/_partials/taxonomy_terms_article_wrapper.html rename to theme/layouts/_partials/taxonomy_terms_article_wrapper.html diff --git a/layouts/_partials/taxonomy_terms_cloud.html b/theme/layouts/_partials/taxonomy_terms_cloud.html similarity index 100% rename from layouts/_partials/taxonomy_terms_cloud.html rename to theme/layouts/_partials/taxonomy_terms_cloud.html diff --git a/layouts/_partials/taxonomy_terms_clouds.html b/theme/layouts/_partials/taxonomy_terms_clouds.html similarity index 100% rename from layouts/_partials/taxonomy_terms_clouds.html rename to theme/layouts/_partials/taxonomy_terms_clouds.html diff --git a/layouts/_partials/td/render-heading.html b/theme/layouts/_partials/td/render-heading.html similarity index 100% rename from layouts/_partials/td/render-heading.html rename to theme/layouts/_partials/td/render-heading.html diff --git a/layouts/_partials/td/scrollspy-attr.txt b/theme/layouts/_partials/td/scrollspy-attr.txt similarity index 100% rename from layouts/_partials/td/scrollspy-attr.txt rename to theme/layouts/_partials/td/scrollspy-attr.txt diff --git a/layouts/_partials/theme-toggler.html b/theme/layouts/_partials/theme-toggler.html similarity index 100% rename from layouts/_partials/theme-toggler.html rename to theme/layouts/_partials/theme-toggler.html diff --git a/layouts/_partials/toc.html b/theme/layouts/_partials/toc.html similarity index 100% rename from layouts/_partials/toc.html rename to theme/layouts/_partials/toc.html diff --git a/layouts/_partials/version-banner.html b/theme/layouts/_partials/version-banner.html similarity index 100% rename from layouts/_partials/version-banner.html rename to theme/layouts/_partials/version-banner.html diff --git a/layouts/_shortcodes/_param.html b/theme/layouts/_shortcodes/_param.html similarity index 100% rename from layouts/_shortcodes/_param.html rename to theme/layouts/_shortcodes/_param.html diff --git a/layouts/_shortcodes/alert.html b/theme/layouts/_shortcodes/alert.html similarity index 100% rename from layouts/_shortcodes/alert.html rename to theme/layouts/_shortcodes/alert.html diff --git a/layouts/_shortcodes/blocks/cover.html b/theme/layouts/_shortcodes/blocks/cover.html similarity index 100% rename from layouts/_shortcodes/blocks/cover.html rename to theme/layouts/_shortcodes/blocks/cover.html diff --git a/layouts/_shortcodes/blocks/feature.html b/theme/layouts/_shortcodes/blocks/feature.html similarity index 100% rename from layouts/_shortcodes/blocks/feature.html rename to theme/layouts/_shortcodes/blocks/feature.html diff --git a/layouts/_shortcodes/blocks/lead.html b/theme/layouts/_shortcodes/blocks/lead.html similarity index 100% rename from layouts/_shortcodes/blocks/lead.html rename to theme/layouts/_shortcodes/blocks/lead.html diff --git a/layouts/_shortcodes/blocks/link-down.html b/theme/layouts/_shortcodes/blocks/link-down.html similarity index 100% rename from layouts/_shortcodes/blocks/link-down.html rename to theme/layouts/_shortcodes/blocks/link-down.html diff --git a/layouts/_shortcodes/blocks/section.html b/theme/layouts/_shortcodes/blocks/section.html similarity index 100% rename from layouts/_shortcodes/blocks/section.html rename to theme/layouts/_shortcodes/blocks/section.html diff --git a/layouts/_shortcodes/card.html b/theme/layouts/_shortcodes/card.html similarity index 100% rename from layouts/_shortcodes/card.html rename to theme/layouts/_shortcodes/card.html diff --git a/layouts/_shortcodes/cardpane.html b/theme/layouts/_shortcodes/cardpane.html similarity index 100% rename from layouts/_shortcodes/cardpane.html rename to theme/layouts/_shortcodes/cardpane.html diff --git a/layouts/_shortcodes/comment.html b/theme/layouts/_shortcodes/comment.html similarity index 100% rename from layouts/_shortcodes/comment.html rename to theme/layouts/_shortcodes/comment.html diff --git a/layouts/_shortcodes/conditional-text.html b/theme/layouts/_shortcodes/conditional-text.html similarity index 100% rename from layouts/_shortcodes/conditional-text.html rename to theme/layouts/_shortcodes/conditional-text.html diff --git a/layouts/_shortcodes/iframe.html b/theme/layouts/_shortcodes/iframe.html similarity index 100% rename from layouts/_shortcodes/iframe.html rename to theme/layouts/_shortcodes/iframe.html diff --git a/layouts/_shortcodes/imgproc.html b/theme/layouts/_shortcodes/imgproc.html similarity index 100% rename from layouts/_shortcodes/imgproc.html rename to theme/layouts/_shortcodes/imgproc.html diff --git a/layouts/_shortcodes/pageinfo.html b/theme/layouts/_shortcodes/pageinfo.html similarity index 100% rename from layouts/_shortcodes/pageinfo.html rename to theme/layouts/_shortcodes/pageinfo.html diff --git a/layouts/_shortcodes/readfile.html b/theme/layouts/_shortcodes/readfile.html similarity index 100% rename from layouts/_shortcodes/readfile.html rename to theme/layouts/_shortcodes/readfile.html diff --git a/layouts/_shortcodes/redoc.html b/theme/layouts/_shortcodes/redoc.html similarity index 100% rename from layouts/_shortcodes/redoc.html rename to theme/layouts/_shortcodes/redoc.html diff --git a/layouts/_shortcodes/swaggerui.html b/theme/layouts/_shortcodes/swaggerui.html similarity index 100% rename from layouts/_shortcodes/swaggerui.html rename to theme/layouts/_shortcodes/swaggerui.html diff --git a/layouts/_shortcodes/tab.html b/theme/layouts/_shortcodes/tab.html similarity index 100% rename from layouts/_shortcodes/tab.html rename to theme/layouts/_shortcodes/tab.html diff --git a/layouts/_shortcodes/tabpane.html b/theme/layouts/_shortcodes/tabpane.html similarity index 100% rename from layouts/_shortcodes/tabpane.html rename to theme/layouts/_shortcodes/tabpane.html diff --git a/layouts/_shortcodes/td/site-build-info/netlify.md b/theme/layouts/_shortcodes/td/site-build-info/netlify.md similarity index 100% rename from layouts/_shortcodes/td/site-build-info/netlify.md rename to theme/layouts/_shortcodes/td/site-build-info/netlify.md diff --git a/layouts/_td-content-after-header.html b/theme/layouts/_td-content-after-header.html similarity index 100% rename from layouts/_td-content-after-header.html rename to theme/layouts/_td-content-after-header.html diff --git a/layouts/_td-content.html b/theme/layouts/_td-content.html similarity index 100% rename from layouts/_td-content.html rename to theme/layouts/_td-content.html diff --git a/layouts/all.html b/theme/layouts/all.html similarity index 100% rename from layouts/all.html rename to theme/layouts/all.html diff --git a/layouts/all.md b/theme/layouts/all.md similarity index 100% rename from layouts/all.md rename to theme/layouts/all.md diff --git a/layouts/baseof.html b/theme/layouts/baseof.html similarity index 100% rename from layouts/baseof.html rename to theme/layouts/baseof.html diff --git a/layouts/blog/_td-content.html b/theme/layouts/blog/_td-content.html similarity index 100% rename from layouts/blog/_td-content.html rename to theme/layouts/blog/_td-content.html diff --git a/layouts/blog/baseof.html b/theme/layouts/blog/baseof.html similarity index 100% rename from layouts/blog/baseof.html rename to theme/layouts/blog/baseof.html diff --git a/layouts/blog/baseof.print.html b/theme/layouts/blog/baseof.print.html similarity index 100% rename from layouts/blog/baseof.print.html rename to theme/layouts/blog/baseof.print.html diff --git a/layouts/blog/list.html b/theme/layouts/blog/list.html similarity index 100% rename from layouts/blog/list.html rename to theme/layouts/blog/list.html diff --git a/layouts/blog/section.print.html b/theme/layouts/blog/section.print.html similarity index 100% rename from layouts/blog/section.print.html rename to theme/layouts/blog/section.print.html diff --git a/layouts/blog/single.html b/theme/layouts/blog/single.html similarity index 100% rename from layouts/blog/single.html rename to theme/layouts/blog/single.html diff --git a/layouts/community/list.html b/theme/layouts/community/list.html similarity index 100% rename from layouts/community/list.html rename to theme/layouts/community/list.html diff --git a/layouts/docs/baseof.html b/theme/layouts/docs/baseof.html similarity index 100% rename from layouts/docs/baseof.html rename to theme/layouts/docs/baseof.html diff --git a/layouts/docs/baseof.print.html b/theme/layouts/docs/baseof.print.html similarity index 100% rename from layouts/docs/baseof.print.html rename to theme/layouts/docs/baseof.print.html diff --git a/layouts/docs/list.html b/theme/layouts/docs/list.html similarity index 100% rename from layouts/docs/list.html rename to theme/layouts/docs/list.html diff --git a/layouts/docs/list.print.html b/theme/layouts/docs/list.print.html similarity index 100% rename from layouts/docs/list.print.html rename to theme/layouts/docs/list.print.html diff --git a/layouts/docs/single.html b/theme/layouts/docs/single.html similarity index 100% rename from layouts/docs/single.html rename to theme/layouts/docs/single.html diff --git a/layouts/index.llms.txt b/theme/layouts/index.llms.txt similarity index 100% rename from layouts/index.llms.txt rename to theme/layouts/index.llms.txt diff --git a/layouts/search.html b/theme/layouts/search.html similarity index 100% rename from layouts/search.html rename to theme/layouts/search.html diff --git a/layouts/swagger/baseof.html b/theme/layouts/swagger/baseof.html similarity index 100% rename from layouts/swagger/baseof.html rename to theme/layouts/swagger/baseof.html diff --git a/layouts/swagger/list.html b/theme/layouts/swagger/list.html similarity index 100% rename from layouts/swagger/list.html rename to theme/layouts/swagger/list.html diff --git a/layouts/swagger/single.html b/theme/layouts/swagger/single.html similarity index 100% rename from layouts/swagger/single.html rename to theme/layouts/swagger/single.html diff --git a/layouts/taxonomy.html b/theme/layouts/taxonomy.html similarity index 100% rename from layouts/taxonomy.html rename to theme/layouts/taxonomy.html diff --git a/layouts/term.html b/theme/layouts/term.html similarity index 100% rename from layouts/term.html rename to theme/layouts/term.html diff --git a/theme/package.json b/theme/package.json new file mode 100644 index 000000000..5ad1f6e0e --- /dev/null +++ b/theme/package.json @@ -0,0 +1,13 @@ +{ + "name": "@docsy/theme", + "version": "0.15.1-dev+002-over-main-ce9942b8", + "description": "The Docsy Hugo theme for technical documentation sites", + "repository": "github:google/docsy", + "homepage": "https://www.docsy.dev", + "license": "Apache-2.0", + "private": true, + "dependencies": { + "@fortawesome/fontawesome-free": "6.7.2", + "bootstrap": "5.3.8" + } +} diff --git a/static/css/prism.css b/theme/static/css/prism.css similarity index 100% rename from static/css/prism.css rename to theme/static/css/prism.css diff --git a/static/favicons/android-144x144.png b/theme/static/favicons/android-144x144.png similarity index 100% rename from static/favicons/android-144x144.png rename to theme/static/favicons/android-144x144.png diff --git a/static/favicons/android-192x192.png b/theme/static/favicons/android-192x192.png similarity index 100% rename from static/favicons/android-192x192.png rename to theme/static/favicons/android-192x192.png diff --git a/static/favicons/android-36x36.png b/theme/static/favicons/android-36x36.png similarity index 100% rename from static/favicons/android-36x36.png rename to theme/static/favicons/android-36x36.png diff --git a/static/favicons/android-48x48.png b/theme/static/favicons/android-48x48.png similarity index 100% rename from static/favicons/android-48x48.png rename to theme/static/favicons/android-48x48.png diff --git a/static/favicons/android-72x72.png b/theme/static/favicons/android-72x72.png similarity index 100% rename from static/favicons/android-72x72.png rename to theme/static/favicons/android-72x72.png diff --git a/static/favicons/android-96x96.png b/theme/static/favicons/android-96x96.png similarity index 100% rename from static/favicons/android-96x96.png rename to theme/static/favicons/android-96x96.png diff --git a/static/favicons/apple-touch-icon-180x180.png b/theme/static/favicons/apple-touch-icon-180x180.png similarity index 100% rename from static/favicons/apple-touch-icon-180x180.png rename to theme/static/favicons/apple-touch-icon-180x180.png diff --git a/static/favicons/favicon-1024.png b/theme/static/favicons/favicon-1024.png similarity index 100% rename from static/favicons/favicon-1024.png rename to theme/static/favicons/favicon-1024.png diff --git a/static/favicons/favicon-16x16.png b/theme/static/favicons/favicon-16x16.png similarity index 100% rename from static/favicons/favicon-16x16.png rename to theme/static/favicons/favicon-16x16.png diff --git a/static/favicons/favicon-256.png b/theme/static/favicons/favicon-256.png similarity index 100% rename from static/favicons/favicon-256.png rename to theme/static/favicons/favicon-256.png diff --git a/static/favicons/favicon-32x32.png b/theme/static/favicons/favicon-32x32.png similarity index 100% rename from static/favicons/favicon-32x32.png rename to theme/static/favicons/favicon-32x32.png diff --git a/static/favicons/favicon.ico b/theme/static/favicons/favicon.ico similarity index 100% rename from static/favicons/favicon.ico rename to theme/static/favicons/favicon.ico diff --git a/static/favicons/pwa-192x192.png b/theme/static/favicons/pwa-192x192.png similarity index 100% rename from static/favicons/pwa-192x192.png rename to theme/static/favicons/pwa-192x192.png diff --git a/static/favicons/pwa-512x512.png b/theme/static/favicons/pwa-512x512.png similarity index 100% rename from static/favicons/pwa-512x512.png rename to theme/static/favicons/pwa-512x512.png diff --git a/static/favicons/tile150x150.png b/theme/static/favicons/tile150x150.png similarity index 100% rename from static/favicons/tile150x150.png rename to theme/static/favicons/tile150x150.png diff --git a/static/favicons/tile310x150.png b/theme/static/favicons/tile310x150.png similarity index 100% rename from static/favicons/tile310x150.png rename to theme/static/favicons/tile310x150.png diff --git a/static/favicons/tile310x310.png b/theme/static/favicons/tile310x310.png similarity index 100% rename from static/favicons/tile310x310.png rename to theme/static/favicons/tile310x310.png diff --git a/static/favicons/tile70x70.png b/theme/static/favicons/tile70x70.png similarity index 100% rename from static/favicons/tile70x70.png rename to theme/static/favicons/tile70x70.png diff --git a/static/js/deflate.js b/theme/static/js/deflate.js similarity index 100% rename from static/js/deflate.js rename to theme/static/js/deflate.js diff --git a/static/js/prism.js b/theme/static/js/prism.js similarity index 100% rename from static/js/prism.js rename to theme/static/js/prism.js diff --git a/static/js/tabpane-persist.js b/theme/static/js/tabpane-persist.js similarity index 100% rename from static/js/tabpane-persist.js rename to theme/static/js/tabpane-persist.js diff --git a/theme.toml b/theme/theme.toml similarity index 100% rename from theme.toml rename to theme/theme.toml From 3581275b5cfca70edefb2c6c0d41afbe75ab2b43 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Sun, 24 May 2026 19:17:48 -0400 Subject: [PATCH 3/6] Add theme postinstall and update package metadata --- .vscode/cspell.json | 1 + docsy.dev/package.json | 3 +++ package.json | 5 ++--- theme/hugo.yaml | 9 --------- theme/package.json | 8 ++++++-- 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/.vscode/cspell.json b/.vscode/cspell.json index d93b3f15b..b5262407d 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -20,6 +20,7 @@ "docsy", "Docsy", "errorf", + "fontawesome", "Gantt", "getenv", "GLFM", diff --git a/docsy.dev/package.json b/docsy.dev/package.json index b2d799a7e..2ce159e22 100644 --- a/docsy.dev/package.json +++ b/docsy.dev/package.json @@ -13,6 +13,7 @@ "_hugo-dev": "cross-env npm run _hugo -- -e \"${TD_BUILD_CTX:-dev}\" -DFE --printPathWarnings", "_hugo": "hugo --cleanDestinationDir --logLevel info --themesDir ../..", "_postbuild": "npm run _check:links--warn", + "_install-theme-deps": "npm install ../theme --install-links --no-save && rm -rf node_modules/theme", "_serve": "npm run _hugo-dev -- serve --disableFastRender --renderToMemory", "build:preview": "cross-env npm run _hugo-dev -- --minify --baseURL \"${DEPLOY_PRIME_URL:-http://localhost}\"", "build:production": "npm run _hugo -- --minify", @@ -26,6 +27,7 @@ "make:public": "git init -b main public", "postbuild:preview": "npm run _postbuild", "postbuild:production": "npm run _postbuild", + "postinstall": "npm run _install-theme-deps", "precheck:links:all": "npm run build", "precheck:links": "npm run build", "prepare-disabled": "cd .. && npm install", @@ -39,6 +41,7 @@ "update:md-goldens": "node tests/md-output/update-goldens.mjs", "update:packages": "npx npm-check-updates -u" }, + "dependencies-note": "Dependencies installed from ../theme; see postinstall script", "devDependencies": { "afdocs": "^0.9.2", "autoprefixer": "^10.4.27", diff --git a/package.json b/package.json index 7201b1695..18d01fab3 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,8 @@ "repository": "github:google/docsy", "homepage": "https://www.docsy.dev", "license": "Apache-2.0", + "workspaces-todo": "TODO: try adding theme later once all phases of repo reorg are complete", "workspaces": [ - "theme", - "docsy.dev" ], "scripts": { "__spv": "node scripts/set-package-version/index.mjs", @@ -80,5 +79,5 @@ "engines": { "node": ">=24" }, - "spelling": "cSpell:ignore afdocs docsy hugo fortawesome fontawesome onedark -" + "spelling": "cSpell:ignore -" } diff --git a/theme/hugo.yaml b/theme/hugo.yaml index cfae0ae62..905f92dfb 100644 --- a/theme/hugo.yaml +++ b/theme/hugo.yaml @@ -49,15 +49,6 @@ module: target: static - source: node_modules/@fortawesome/fontawesome-free/webfonts target: static/webfonts - # The local `node_modules/...` mounts above use Hugo's dual lookup for - # theme/module imports: Hugo first tries the source relative to the - # theme directory, then falls back to the consumer site's working - # directory. That covers both the maintainer case (theme-local - # node_modules) and the NPM-consumer case (site-local node_modules) - # without an explicit `../../node_modules` escape mount. - # See Hugo's modules/collect.go (`nodeModulesRoot`) and issue #14083. - # Mount for module installations, - # needed to work around a known bug in Go’s module management. - source: assets/_vendor/bootstrap/scss target: assets/vendor/bootstrap/scss/vendor imports: diff --git a/theme/package.json b/theme/package.json index 5ad1f6e0e..1221d4963 100644 --- a/theme/package.json +++ b/theme/package.json @@ -1,11 +1,15 @@ { - "name": "@docsy/theme", + "name": "theme", "version": "0.15.1-dev+002-over-main-ce9942b8", - "description": "The Docsy Hugo theme for technical documentation sites", + "description": "Internal folder for the Docsy theme files", "repository": "github:google/docsy", "homepage": "https://www.docsy.dev", "license": "Apache-2.0", "private": true, + "scripts": { + "todo-add-script-to-sync-deps": "echo TODO" + }, + "dependencies-note": "DO NOT EDIT the dependencies, they are synced from root package.json", "dependencies": { "@fortawesome/fontawesome-free": "6.7.2", "bootstrap": "5.3.8" From fabc6cbfd3a5c847bd885bbd134819e49462923e Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Sun, 24 May 2026 19:49:32 -0400 Subject: [PATCH 4/6] Add sync-theme-deps script and tests --- .markdownlint-cli2.yaml | 2 +- .prettierignore | 12 +- .vscode/cspell.json | 2 + docsy.dev/scripts/_install.sh | 15 +- package.json | 7 +- scripts/scrollspy-patch/README.md | 24 +- scripts/sync-theme-deps.mjs | 103 +++++++ scripts/sync-theme-deps.test.mjs | 101 +++++++ tasks/0.16/repo-reorg/spike-notes.md | 227 ++++++--------- .../repo-reorg/theme-only-folder.execution.md | 110 ++++---- .../0.16/repo-reorg/theme-only-folder.plan.md | 263 ++++++++---------- theme/package.json | 5 +- 12 files changed, 498 insertions(+), 373 deletions(-) create mode 100644 scripts/sync-theme-deps.mjs create mode 100644 scripts/sync-theme-deps.test.mjs diff --git a/.markdownlint-cli2.yaml b/.markdownlint-cli2.yaml index 815713234..f43acfd02 100644 --- a/.markdownlint-cli2.yaml +++ b/.markdownlint-cli2.yaml @@ -5,9 +5,9 @@ customRules: globs: - '!docsy.dev/**' - - '!layouts/**' - '!node_modules/**' - '!public/**' + - '!theme/layouts/**' - '!tmp/**' - 'docsy.dev/content/en/blog/**/*.md' - 'docsy.dev/content/en/docs/_index.md' diff --git a/.prettierignore b/.prettierignore index 6734cdc08..4bd02016e 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,14 +2,14 @@ # gotcha is that once a _directory_ is ignored, it's content cannot be # unignored. -# Ignore all _files_ under assets -/assets/**/*.* +# Ignore all _files_ under the theme's assets +/theme/assets/**/*.* # Selectively unignore some files -!/assets/scss/main.scss -!/assets/scss/td/**/* +!/theme/assets/scss/main.scss +!/theme/assets/scss/td/**/* # These files are derived from other sources, # don't Prettify them: -/assets/scss/td/_variables_forward.scss -/assets/scss/td/chroma/**/* +/theme/assets/scss/td/_variables_forward.scss +/theme/assets/scss/td/chroma/**/* diff --git a/.vscode/cspell.json b/.vscode/cspell.json index b5262407d..b8246af8c 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -21,6 +21,7 @@ "Docsy", "errorf", "fontawesome", + "fortawesome", "Gantt", "getenv", "GLFM", @@ -38,6 +39,7 @@ "nguyen", "nvmrc", "Occitan", + "onedark", "pageinfo", "pexels", "quang", diff --git a/docsy.dev/scripts/_install.sh b/docsy.dev/scripts/_install.sh index a321ce24e..678edc133 100755 --- a/docsy.dev/scripts/_install.sh +++ b/docsy.dev/scripts/_install.sh @@ -3,9 +3,11 @@ # Private script used by CI/CD workflows to install NPM packages necessary for # the website and theme. # -# Since docsy.dev is a workspace of the Docsy repo root, we only need to install -# the Docsy repo root dependencies. That will automatically install the -# dependencies for docsy.dev. +# Installs the Docsy repo-root packages (theme runtime deps + maintainer +# tooling) and then the docsy.dev packages (site-build tooling such as +# hugo-extended, autoprefixer, cross-env, …). The repo root currently has no +# `docsy.dev` workspace declared, so the two installs must be invoked +# explicitly. set -euo pipefail @@ -29,7 +31,10 @@ if [ ! -f package.json ] || [ ! -d docsy.dev ]; then exit 1 fi -echo "Installing NPM packages for Docsy website and theme..." -exec npm install +echo "Installing NPM packages for the Docsy repo root..." +npm install + +echo "Installing NPM packages for the docsy.dev website..." +exec npm install -C docsy.dev # cSpell:ignore docsy diff --git a/package.json b/package.json index 18d01fab3..ef4c236e7 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,10 @@ "_gen-chroma-styles": "bash -c scripts/gen-chroma-styles.sh", "_mkdir:hugo-mod": "node scripts/mkdirp-hugo-mod.js ..", "_prepare:scrollspy-patch": "npm run _cp:bs-scrollspy && bash scripts/scrollspy-patch/apply-patch.sh && perl scripts/scrollspy-patch/update-patch-js.pl", - "_prepare": "npm run _cp:bs-rfs && npm run _prepare:scrollspy-patch && npm run _refresh-forward-sass-var && npm run _gen-chroma-styles && npm run get:hugo-modules", + "_prepare": "npm run _sync:theme-deps && npm run _cp:bs-rfs && npm run _prepare:scrollspy-patch && npm run _refresh-forward-sass-var && npm run _gen-chroma-styles && npm run get:hugo-modules", "_refresh-forward-sass-var": "bash -c scripts/refresh-sass-variables.pl", "_serve": "npm run -C docsy.dev _serve --", + "_sync:theme-deps": "node scripts/sync-theme-deps.mjs", "_spv:example": "echo TBC - npm run -s __spv docsy.dev/config/example/params.yaml --", "_spv": "npm run -s __spv docsy.dev/config/*/params.yaml --", "build": "npm run -C docsy.dev build --", @@ -45,8 +46,8 @@ "get:hugo-modules": "node scripts/getHugoModules/index.mjs", "post-update": "echo; echo 'IMPORTANT! Run the following in case the ScrollSpy patch needs to be updated:\n npm run _prepare'; echo", "postinstall": "npm run _mkdir:hugo-mod", - "postupdate:dep": "npm run -s post-update", - "postupdate:packages": "npm run -s post-update", + "postupdate:dep": "npm run _sync:theme-deps && npm run -s post-update", + "postupdate:packages": "npm run _sync:theme-deps && npm run -s post-update", "prune:refcache": "npm run -C docsy.dev prune:refcache --", "seq": "bash -c 'for cmd in \"$@\"; do npm run $cmd || exit 1; done' - ", "serve": "npm run -C docsy.dev serve --", diff --git a/scripts/scrollspy-patch/README.md b/scripts/scrollspy-patch/README.md index 96e982364..bbc9e5ee7 100644 --- a/scripts/scrollspy-patch/README.md +++ b/scripts/scrollspy-patch/README.md @@ -15,13 +15,13 @@ method as the METHOD. Intermediate files used to simplify the process of creating the RUNTIME_PATCHER_JS file, and detecting when the METHOD code has changed: -- `theme/assets/_cache/bootstrap/scrollspy-method.js`: the METHOD function source - extracted from SOURCE_FILE (METHOD_SOURCE_FILE) -- `theme/assets/_cache/bootstrap/method.patch`: standard patch used to create our - patched METHOD code; it is in standard unified diff format (generated by +- `theme/assets/_cache/bootstrap/scrollspy-method.js`: the METHOD function + source extracted from SOURCE_FILE (METHOD_SOURCE_FILE) +- `theme/assets/_cache/bootstrap/method.patch`: standard patch used to create + our patched METHOD code; it is in standard unified diff format (generated by `diff -u` and applied by the standard `patch` command). -- `theme/assets/_cache/bootstrap/scrollspy-method-patched.js` - the METHOD function - patched. +- `theme/assets/_cache/bootstrap/scrollspy-method-patched.js` - the METHOD + function patched. ## Scripts @@ -29,11 +29,11 @@ RUNTIME_PATCHER_JS file, and detecting when the METHOD code has changed: METHOD_SOURCE_FILE file. - `apply-patch.sh` - Applies the patch using the standard `patch` command and saves the patched method to `scrollspy-method-patched.js` -- `update-patch-js.pl` - Updates `theme/assets/js/scrollspy-patch.js` with the patched - method from `scrollspy-method-patched.js` +- `update-patch-js.pl` - Updates `theme/assets/js/scrollspy-patch.js` with the + patched method from `scrollspy-method-patched.js` -The patch file `method.patch` is stored in `theme/assets/_cache/bootstrap/` alongside -the cached method file. +The patch file `method.patch` is stored in `theme/assets/_cache/bootstrap/` +alongside the cached method file. ## Workflow @@ -45,8 +45,8 @@ The `_prepare:scrollspy-patch` script (called by `_prepare`) automatically: `theme/assets/_cache/bootstrap/scrollspy-method.js` 2. Applies the patch (`apply-patch.sh`) - writes patched method to `theme/assets/_cache/bootstrap/scrollspy-method-patched.js` -3. Updates `theme/assets/js/scrollspy-patch.js` (`update-patch-js.pl`) - syncs the - patched method body into the runtime patch file +3. Updates `theme/assets/js/scrollspy-patch.js` (`update-patch-js.pl`) - syncs + the patched method body into the runtime patch file The `ci:prepare` script calls `_prepare` and `_diff:check` to ensure no unexpected changes occurred. If the cached method source, patched result, or diff --git a/scripts/sync-theme-deps.mjs b/scripts/sync-theme-deps.mjs new file mode 100644 index 000000000..4f173913c --- /dev/null +++ b/scripts/sync-theme-deps.mjs @@ -0,0 +1,103 @@ +#!/usr/bin/env node +// @ts-check +/** + * Mirror the root package.json's `dependencies` versions into + * theme/package.json's `dependencies`. Idempotent. + * + * The root manifest is the canonical source of truth for theme runtime + * dependency versions (bootstrap, @fortawesome/fontawesome-free, …). The + * theme/package.json carries the same list so that consumers of theme/ as a + * file/tarball (notably docsy.dev's `_install-theme-deps` postinstall, which + * runs `npm install ../theme --install-links`) see the right versions. + * + * Wired into `_prepare`, `postupdate:dep`, and `postupdate:packages` so it + * runs whenever maintainers refresh deps. Maintainers may also invoke it + * directly: `npm run _sync:theme-deps`. + * + * Behavior: + * - For each key in theme/package.json's `dependencies`, adopt the version + * declared in the root package.json (if root declares it). + * - Keys present in theme but not in root → warning, no change. + * - Keys present in root but not in theme → warning, no change. (Theme's + * dep set is curated by hand; we only sync versions.) + * - If nothing changes, the script is a no-op and writes nothing. + */ + +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); +const ROOT_PKG = path.join(ROOT, 'package.json'); +const THEME_PKG = path.join(ROOT, 'theme', 'package.json'); + +function readJson(p) { + return JSON.parse(fs.readFileSync(p, 'utf8')); +} + +function writeJson(p, data) { + fs.writeFileSync(p, JSON.stringify(data, null, 2) + '\n', 'utf8'); +} + +/** + * @param {object} [io] + * @param {() => any} [io.readRoot] + * @param {() => any} [io.readTheme] + * @param {(data: any) => void} [io.writeTheme] + * @param {{ log: (s: string) => void, warn: (s: string) => void }} [io.logger] + * @returns {{ changed: boolean, changes: {name: string, from: string, to: string}[], onlyInTheme: string[], onlyInRoot: string[] }} + */ +export function syncThemeDeps({ + readRoot = () => readJson(ROOT_PKG), + readTheme = () => readJson(THEME_PKG), + writeTheme = (data) => writeJson(THEME_PKG, data), + logger = console, +} = {}) { + const root = readRoot(); + const theme = readTheme(); + const rootDeps = root.dependencies || {}; + const themeDeps = { ...(theme.dependencies || {}) }; + + const changes = []; + const onlyInTheme = []; + + for (const name of Object.keys(themeDeps)) { + if (!(name in rootDeps)) { + onlyInTheme.push(name); + continue; + } + if (themeDeps[name] !== rootDeps[name]) { + changes.push({ name, from: themeDeps[name], to: rootDeps[name] }); + themeDeps[name] = rootDeps[name]; + } + } + + const onlyInRoot = Object.keys(rootDeps).filter((k) => !(k in themeDeps)); + + if (onlyInTheme.length) { + logger.warn( + `sync-theme-deps: warning: theme/package.json declares deps not in root: ${onlyInTheme.join(', ')}`, + ); + } + if (onlyInRoot.length) { + logger.warn( + `sync-theme-deps: warning: root package.json has deps not in theme: ${onlyInRoot.join(', ')}`, + ); + } + + if (changes.length === 0) { + logger.log('sync-theme-deps: theme/package.json already in sync'); + return { changed: false, changes, onlyInTheme, onlyInRoot }; + } + + theme.dependencies = themeDeps; + writeTheme(theme); + for (const c of changes) { + logger.log(`sync-theme-deps: ${c.name} ${c.from} → ${c.to}`); + } + return { changed: true, changes, onlyInTheme, onlyInRoot }; +} + +if (process.argv[1] === fileURLToPath(import.meta.url)) { + syncThemeDeps(); +} diff --git a/scripts/sync-theme-deps.test.mjs b/scripts/sync-theme-deps.test.mjs new file mode 100644 index 000000000..248601201 --- /dev/null +++ b/scripts/sync-theme-deps.test.mjs @@ -0,0 +1,101 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; + +import { syncThemeDeps } from './sync-theme-deps.mjs'; + +const nullLogger = { + log() {}, + warn() {}, +}; + +function inMemoryIo({ rootDeps, themeDeps }) { + const root = { name: 'docsy', dependencies: { ...rootDeps } }; + const theme = { name: 'theme', dependencies: { ...themeDeps } }; + let written; + return { + io: { + readRoot: () => root, + readTheme: () => theme, + writeTheme: (data) => { + written = JSON.parse(JSON.stringify(data)); + }, + logger: nullLogger, + }, + getWritten: () => written, + }; +} + +test('no-op when versions already match', () => { + const { io, getWritten } = inMemoryIo({ + rootDeps: { bootstrap: '5.3.8', '@fortawesome/fontawesome-free': '6.7.2' }, + themeDeps: { bootstrap: '5.3.8', '@fortawesome/fontawesome-free': '6.7.2' }, + }); + const result = syncThemeDeps(io); + assert.equal(result.changed, false); + assert.deepEqual(result.changes, []); + assert.equal(getWritten(), undefined); +}); + +test('updates a single drifting version', () => { + const { io, getWritten } = inMemoryIo({ + rootDeps: { bootstrap: '5.3.9', '@fortawesome/fontawesome-free': '6.7.2' }, + themeDeps: { bootstrap: '5.3.8', '@fortawesome/fontawesome-free': '6.7.2' }, + }); + const result = syncThemeDeps(io); + assert.equal(result.changed, true); + assert.deepEqual(result.changes, [ + { name: 'bootstrap', from: '5.3.8', to: '5.3.9' }, + ]); + assert.equal(getWritten().dependencies.bootstrap, '5.3.9'); + assert.equal( + getWritten().dependencies['@fortawesome/fontawesome-free'], + '6.7.2', + ); +}); + +test('updates multiple drifting versions in one pass', () => { + const { io, getWritten } = inMemoryIo({ + rootDeps: { bootstrap: '5.3.9', '@fortawesome/fontawesome-free': '6.8.0' }, + themeDeps: { bootstrap: '5.3.8', '@fortawesome/fontawesome-free': '6.7.2' }, + }); + const result = syncThemeDeps(io); + assert.equal(result.changed, true); + assert.equal(result.changes.length, 2); + assert.equal(getWritten().dependencies.bootstrap, '5.3.9'); + assert.equal( + getWritten().dependencies['@fortawesome/fontawesome-free'], + '6.8.0', + ); +}); + +test('warns and does not write for theme-only deps', () => { + const warnings = []; + const { io } = inMemoryIo({ + rootDeps: { bootstrap: '5.3.8' }, + themeDeps: { bootstrap: '5.3.8', 'theme-only-thing': '1.0.0' }, + }); + io.logger = { + log() {}, + warn: (s) => warnings.push(s), + }; + const result = syncThemeDeps(io); + assert.equal(result.changed, false); + assert.deepEqual(result.onlyInTheme, ['theme-only-thing']); + assert.ok(warnings.some((w) => w.includes('theme-only-thing'))); +}); + +test('warns and does not add for root-only deps', () => { + const warnings = []; + const { io } = inMemoryIo({ + rootDeps: { bootstrap: '5.3.8', 'root-only-dev-helper': '2.0.0' }, + themeDeps: { bootstrap: '5.3.8' }, + }); + io.logger = { + log() {}, + warn: (s) => warnings.push(s), + }; + const result = syncThemeDeps(io); + assert.equal(result.changed, false); + assert.deepEqual(result.onlyInRoot, ['root-only-dev-helper']); + assert.ok(warnings.some((w) => w.includes('root-only-dev-helper'))); +}); diff --git a/tasks/0.16/repo-reorg/spike-notes.md b/tasks/0.16/repo-reorg/spike-notes.md index 4ea37bacb..c0c76e36a 100644 --- a/tasks/0.16/repo-reorg/spike-notes.md +++ b/tasks/0.16/repo-reorg/spike-notes.md @@ -16,31 +16,35 @@ observations. Read by the release-notes drafting work in Phase 5. - Branch: `chalin-m24-monorepo-2026-0520` - Hugo version: 0.157.0 -- Starting layout: theme files at repo root, `docsy.dev/` is the website - workspace, repo root carries theme runtime deps + repo-wide maintainer +- Starting layout: theme files at repo root; `docsy.dev/` is the website + workspace; repo root carries theme runtime deps + repo-wide maintainer tooling. -## Refined repo layout (settled during the spike) - -The spike converged on a four-folder shape that is the new "TOF + thin root": +## Repo layout after Phase 0 (current) ```text . -├── theme/ # canonical theme + theme/package.json (source of truth) -├── docsy.dev/ # website; its own node_modules with site-build tooling -├── _dev/ # maintainer-orchestration folder; devDeps incl. hugo-extended -├── tasks/ # planning, spike notes, release prep -└── package.json # thin publishable shim; name "docsy"; files: [theme] +├── theme/ # canonical theme tree (assets, layouts, i18n, +│ # static, hugo.yaml, theme.toml, go.mod, go.sum) +│ └── package.json # private mirror of theme runtime deps +├── docsy.dev/ # website; its own node_modules +├── scripts/ # maintainer scripts (chroma, scrollspy patch, +│ # sync-theme-deps.mjs, …) +├── tasks/ +└── package.json # canonical for theme runtime deps + repo-wide + # maintainer tooling (Prettier, mdl, cSpell dict) ``` -Each of `theme/`, `docsy.dev/`, and `_dev/` carries an independent -`package.json` and is installed independently (no npm workspaces are declared -anywhere). The repo root is **not** a workspace root; it is the consumer-facing -publishable manifest only. +Key invariants of the current implementation: -Key invariant: a consumer installing `docsy` (from GitHub or, later, npm) gets -exactly `theme/` + a handful of top-level docs files, **never** any of `_dev/`, -`docsy.dev/`, or maintainer tooling. +- The repo root `package.json` is the **single source of truth** for theme + runtime dependency versions. `theme/package.json` is a private mirror + (`"private": true`) kept aligned by `scripts/sync-theme-deps.mjs`. +- No npm workspaces are declared at the repo root yet; the `workspaces` array is + intentionally empty (with a `workspaces-todo` comment marker). `docsy.dev`'s + `_install-theme-deps` postinstall handles the cross-folder install instead. +- `theme/hugo.yaml` uses the canonical `node_modules/` mount form. The + legacy `../../node_modules/*` escape mounts were dropped. ## Phase 1: `docsy.dev` (Hugo, classic themesDir + theme) @@ -72,27 +76,34 @@ here for traceability; they are not user-facing. then under the consumer site's working directory. The escape form is pure backwards compatibility for pre-existing configs; under TOF the simple `node_modules/X` mount is canonical and covers both cases. -- `theme/package.json` created. Source of truth for theme runtime deps - (`bootstrap`, `@fortawesome/fontawesome-free`). Postinstall delegates to - `theme/scripts/mkdirp-hugo-mod.js` so that a future split where `theme/` - becomes its own repo needs no further script moves. -- `scripts/mkdirp-hugo-mod.js` moved to `theme/scripts/mkdirp-hugo-mod.js` - (rides along inside the published theme package). -- New `_dev/` folder created as the maintainer-orchestration root. Holds - maintainer-only devDeps (`hugo-extended`, `prettier`, `markdownlint-*`, - `@cspell/dict-fr-fr`) and all orchestration scripts. - `git mv scripts _dev/scripts` preserves history. -- `_dev/scripts/sync-root-deps.mjs` added. Reads `theme/package.json`'s - `dependencies` and writes them to the root `package.json` so the consumer's - install graph reflects the theme's runtime deps. Idempotent. -- Root `package.json` slimmed to a publishable shim: `name: "docsy"`, `version`, - `repository`, `license`, - `files: ["CHANGELOG.md", "LICENSE", "README.md", "theme"]`, two lifecycle - scripts (`prepare` runs `sync-root-deps.mjs`; `postinstall` runs - `theme/scripts/mkdirp-hugo-mod.js ..`). No `devDependencies`, no workspaces, - no maintainer scripts. -- `docsy.dev/package.json` kept its site-build/site-tooling deps but - `hugo-extended` was removed (now lives in `_dev/`). +- `theme/package.json` created as a **private mirror** (`"private": true`) of + the root's theme runtime deps (`bootstrap`, `@fortawesome/fontawesome-free`). + Kept aligned with the root by `scripts/sync-theme-deps.mjs`. +- `scripts/sync-theme-deps.mjs` added (with `scripts/sync-theme-deps.test.mjs` + picked up by `test:tooling`). Wired into `_prepare`, `postupdate:dep`, and + `postupdate:packages`. A maintainer can also invoke it directly: + `npm run _sync:theme-deps`. +- Repo-root `package.json` script paths updated to point at the new theme + locations: `_check:format` now globs `theme/assets *.md theme/i18n …`, + `_cp:bs-rfs` writes to `theme/assets/_vendor/bootstrap/scss/`, etc. + `mkdirp-hugo-mod.js`, `_gen-chroma-style.sh`, `refresh-sass-variables.pl`, + `scrollspy-patch/*`, `getHugoModules/index.mjs`, and `make-site.sh` similarly + updated. +- `.prettierignore` updated from `/assets/...` to `/theme/assets/...` so the + same files are skipped as before. `.markdownlint-cli2.yaml`'s `!layouts/**` + glob updated to `!theme/layouts/**`. +- `docsy.dev/package.json` gained `_install-theme-deps`: + `npm install ../theme --install-links --no-save && rm -rf node_modules/theme`, + wired in as a `postinstall`. The `--install-links` flag tells npm to treat the + local `../theme` package as a tarball, which has the side effect of installing + `theme/`'s declared runtime deps (Bootstrap, Font Awesome) into + `docsy.dev/node_modules/`. The `rm -rf` line then drops the now-redundant copy + of the theme tree itself. +- `docsy.dev/scripts/_install.sh` updated (and its comment refreshed) to install + both the repo-root packages and the `docsy.dev` packages, since `docsy.dev` is + no longer a workspace of the root. Netlify's + `scripts/_install.sh && npm run build:preview` sequence works under that + shape. ### Observations @@ -113,127 +124,47 @@ here for traceability; they are not user-facing. `node_modules/*` mounts when the theme is loaded via classic `themesDir + theme` (which `docsy.dev` does today). SCSS resolution failed without the local mounts even though `imports:` was configured. -- **npm workspaces were tried and abandoned.** An earlier iteration declared - workspaces at `_dev/package.json` (`["..", "../docsy.dev"]`) to give - maintainers a single `npm install`. With root listed as a workspace, npm - recognised it but did **not** install the workspace members' declared deps - (`bootstrap`, site-tooling); only the workspace-root's own devDeps were - installed. Reducing to `["../docsy.dev"]` did not help. The clean alternative - is to keep each of `theme/`, `docsy.dev/`, and `_dev/` as independent package - installs with no workspaces declared anywhere. -- **Hugo's theme-local lookup is what makes the no-workspaces design work.** - With `cd theme && npm install`, `bootstrap` lands at - `theme/node_modules/bootstrap`. Hugo's dual lookup finds it on the - theme-relative first pass; nothing is needed in `docsy.dev/node_modules/`. No - symlinks. No deps duplicated in `docsy.dev/package.json`. -- **`hugo-extended` is on PATH for `docsy.dev` builds via npm-script - inheritance.** When `cd _dev && npm run build` calls - `npm run -C ../docsy.dev build`, the inner npm process inherits the outer - process's PATH (which already includes `_dev/node_modules/.bin/`). The `hugo` - binary is found there. This is the single source of the Hugo version across - the monorepo. -- **Postinstall lives at the published-package boundary.** The root - `postinstall` runs `node theme/scripts/mkdirp-hugo-mod.js ..` inside the - consumer's `node_modules/docsy/` after install, creating the empty - `github.com/*` placeholder dirs Hugo expects when the theme is loaded as a - module. `theme/package.json` carries the same postinstall for the future split - where `theme/` becomes its own published repo. +- **npm workspaces were tried and abandoned for this PR.** Variants were + explored (root with `["docsy.dev"]`, with `["theme", "docsy.dev"]`, and with + `[]`). Each variant had a trade-off between hoisting behaviour and the + cross-folder install of theme runtime deps into `docsy.dev/node_modules/`. The + shipped design declares `workspaces: []` (with a `workspaces-todo` comment + marker for the follow-on plan) and relies on `docsy.dev`'s + `_install-theme-deps` postinstall for the cross-folder hand-off. +- **`hugo-extended` continues to live in `docsy.dev/devDependencies`.** No + change from the pre-TOF layout. The maintainer-tooling-folder reorganisation + considered during the spike was deferred to a follow-on plan. ### Status -**Phase 1 exit criterion met.** `docsy.dev` builds locally from `theme/` with -the one-line consumer config change (223 EN pages, 218 FR pages) **and** with no -symlinks anywhere. The build chain works with a clean three-install maintainer +**Phase 1 exit criterion met for local build.** `docsy.dev` builds locally from +`theme/` with the one-line consumer config change (223 EN pages, 218 FR pages) +**and** with no symlinks anywhere. The build chain works with this maintainer setup: ```sh -cd theme && npm install # theme runtime deps (bootstrap, fontawesome) -cd docsy.dev && npm install # site build deps (autoprefixer, postcss-cli, …) -cd _dev && npm install # hugo-extended + monorepo maintainer tooling -cd _dev && npm run build # green +npm install # repo-root deps (theme runtime + maintainer tools) +npm run docsy.dev-install # docsy.dev deps (site build + hugo-extended); + # postinstall runs _install-theme-deps +npm run build # green ``` -A convenience `npm run install:all` in `_dev/` runs the three installs in -sequence. - -### Open question - -- Package versioning: see - [the plan's section](./theme-only-folder.plan.md#package-versioning). - Currently both root and theme carry the same `version`; the policy is - unresolved. - -## Phase 2: NPM (GitHub) — pack/install smoke test +Netlify deploy preview verification (the second half of the Phase 1 exit +criterion) is still pending. -This phase exercises the install path a consumer would hit with -`npm install github:google/docsy#`, locally and with the spike branch. +## Phase 2: NPM (GitHub) — pending under current architecture -### Smoke test - -Run `npm pack` at the repo root, inspect the tarball, then install it into a -fresh consumer directory: - -```sh -# at repo root -npm pack -# -> docsy-0.15.1-dev+002-over-main-ce9942b8.tgz - -CONSUMER=$(mktemp -d) -cd "$CONSUMER" -echo '{"name":"c","version":"0.0.0","private":true}' > package.json -npm install /path/to/docsy-*.tgz -``` +The Phase 2 work (`make-site.sh -s NPM`, `-s HUGO_MODULE`, and the non-module +`themes/docsy/` install) is still to be run against the current architecture. +`make-site.sh` itself has been updated for the `/theme` suffix in both NPM and +HUGO_MODULE paths, but the runs themselves have not yet been executed. -### Results - -- The pack ran `prepare` → `_dev/scripts/sync-root-deps.mjs`, which copied - `bootstrap` and `@fortawesome/fontawesome-free` from `theme/package.json` into - the root `package.json`'s `dependencies`. Idempotent: re-running with the - committed synced state is a no-op. -- Tarball top-level entries: `CHANGELOG.md`, `LICENSE`, `README.md`, - `package.json`, `theme/`. No `_dev/`, no `docsy.dev/`, no maintainer scripts, - no devDeps. Total: 2879 files, 8.0 MB (≈ the theme tree). -- Consumer `node_modules/` after install: - - `node_modules/docsy/` containing exactly `CHANGELOG.md`, `LICENSE`, - `README.md`, `package.json`, `theme/`. - - `node_modules/bootstrap/` (transitive). - - `node_modules/@fortawesome/fontawesome-free/` (transitive). - - `node_modules/@popperjs/` (transitive via bootstrap). - - **0 vulnerabilities reported** by npm audit. - - 4 packages added in total. -- Consumer postinstall ran. `node_modules/github.com/FortAwesome/Font-Awesome` - and `node_modules/github.com/twbs/bootstrap` placeholder dirs created so - Hugo's module loader does not error. - -### Phase 2 observations - -- **The `files` whitelist is the linchpin.** Pre-spike, root had no `files` - field, so `npm install github:google/docsy` brought the entire monorepo into - the consumer's `node_modules/docsy/`. With `files: ["theme", …]` the tarball - contains only what a consumer needs. -- **No `devDependencies` at root means git-URL installs do not trigger a dev - install.** npm's docs note that the presence of a `prepare` script in a - package being installed from git triggers a `npm install` of `dependencies - - devDependencies` in the clone before pack. Because root carries no devDeps, - that step is a no-op. The headache that pre-spike consumers hit (entire - maintainer toolchain dragged into their install) is gone. -- **`prepare` is the right hook (not `prepack`).** `prepack` only runs on - `npm pack` / `npm publish`. `prepare` runs on those **and** during the git-URL - install workflow in the clone before the tarball is built. The sync script - must run in both places, so `prepare` is the correct lifecycle pick. The cost - of `prepare` (devDeps install in the clone) is zero here because root has no - devDeps. -- **Working-tree cleanliness after pack.** Because root commits the synced deps - (kept aligned with `theme/package.json` by the sync script), the `prepare` - write during a maintainer's `npm pack` is a no-op and the working tree stays - clean. The script doubles as a CI guard against drift. - -### Phase 2 status - -**Phase 2 exit criterion met for the NPM-tarball install path.** Outstanding -work for Phase 2: validate the same flow via `make-site.sh -s NPM`, then -exercise `-s HUGO_MODULE` and the non-module `themes/docsy/` install. Those -remain unchanged in the execution plan. +Note: an earlier iteration in this spike tested an `npm pack` + consumer install +flow under a different architecture (root as a thin shim with a +`files: [theme, …]` whitelist, no devDeps, and a `prepare` script that synced +theme deps to root). That architecture was deferred to a follow-on plan; the +consumer-install footprint under the current shipped architecture needs to be +re-measured as part of Phase 2. ## Phase 3: GitHub CI — pending diff --git a/tasks/0.16/repo-reorg/theme-only-folder.execution.md b/tasks/0.16/repo-reorg/theme-only-folder.execution.md index 846d78b88..9a8bee40e 100644 --- a/tasks/0.16/repo-reorg/theme-only-folder.execution.md +++ b/tasks/0.16/repo-reorg/theme-only-folder.execution.md @@ -28,10 +28,9 @@ The plan itself is the design contract. This doc is purely about sequencing. criteria are met. Treat them as a tight loop, not two sequential blocks. - **Single feature branch through Phases 0–3.** All consumer-surface validation runs against the same tree. Merge to `main` only after Phase 3 passes. -- **Running spike notes** live at `tasks/0.16/repo-reorg/spike-notes.md` - (created in Phase 1). They accumulate the exact per-install-mode commands and - confirmed config edits. The release-note migration snippets are read out of - this file at Phase 5. +- **Running spike notes** live at `tasks/0.16/repo-reorg/spike-notes.md`. They + accumulate the exact per-install-mode commands and confirmed config edits. The + release-note migration snippets are read out of this file at Phase 5. - **One-line promise.** The TOF plan promises a single-line consumer config edit per install mode. If any phase shows the migration growing past that, halt and iterate on the design before continuing. @@ -43,59 +42,65 @@ The plan itself is the design contract. This doc is purely about sequencing. The bulk-change phase. Done in a single feature branch, ideally one PR (or a small stack) so the move is reviewable as a unit. -- Create `theme/` and move the canonical theme files into it (assets, layouts, - i18n, static, images, hugo.yaml, theme.toml, go.mod, go.sum). +- Create `theme/` and move the canonical theme files into it (`assets`, `i18n`, + `images`, `layouts`, `static`, `hugo.yaml`, `theme.toml`, `go.mod`, `go.sum`). - Update `theme/go.mod` `module` declaration to `github.com/google/docsy/theme`. -- Carve out `_dev/` for maintainer-orchestration. `git mv scripts _dev/scripts` - to retain script history. Move repo-wide devDeps (including `hugo-extended`) - from the old root to `_dev/package.json`. Add - `_dev/scripts/sync-root-deps.mjs`. -- Split `theme/package.json` out as the source of truth for theme runtime deps. - Reshape the root `package.json` to a thin publishable shim (`name: "docsy"`, - `files: [theme, …]`, `prepare` + `postinstall`, no devDeps). -- Update generators and patch scripts now living in `_dev/scripts/` to write - under `theme/`. +- Drop the legacy `../../node_modules/*` escape mounts from `theme/hugo.yaml`; + keep only the canonical `node_modules/` form. +- Update generators and patch scripts under `scripts/` to read/write under + `theme/` (`mkdirp-hugo-mod.js`, `_gen-chroma-style.sh`, + `refresh-sass-variables.pl`, `scrollspy-patch/*`, `getHugoModules/`, + `make-site.sh`). Update root `package.json` script globs accordingly. +- Add `theme/package.json` as a private mirror of root's theme deps, plus + `scripts/sync-theme-deps.mjs` and the hook wiring (`_prepare`, + `postupdate:dep`, `postupdate:packages`). - Confirm `_prepare` (and downstream `ci:prepare`) succeeds against the new - paths, and `_diff:check` is clean. + paths and `_diff:check` is clean. Exit criterion: file move is clean; `_prepare` + `_diff:check` pass; no consumer surface validated yet. -Status (2026-05-21): structural move landed on `chalin-m24-monorepo-2026-0520`. -`_prepare` / `_diff:check` regression check is still pending — Phase 0 / Phase 1 -ran as a tight loop and `docsy.dev` already builds (see Phase 1), but the -maintainer `_prepare` chain has not yet been re-exercised end-to-end against the -new layout. +Status (2026-05-24): structural move landed on `chalin-m24-monorepo-2026-0520`. +`theme/`, `scripts/sync-theme-deps.mjs`, `docsy.dev`'s `_install-theme-deps` +postinstall, and the `.prettierignore` / `.markdownlint-cli2.yaml` path updates +are all in place. `_prepare` / `_diff:check` regression check is still pending — +Phase 0 / Phase 1 ran as a tight loop and `docsy.dev` already builds (see Phase +1), but the maintainer `_prepare` chain has not yet been re-exercised end-to-end +against the new layout. ### Phase 1: `docsy.dev` consumes TOF Make Docsy's primary end-to-end test (the website) build against the new layout. This is the most informative single check. -- Update `docsy.dev` config to use the new Hugo module path. -- Update `docsy.dev/package.json` `_hugo --themesDir` and any other path - assumptions. +- Update `docsy.dev` config to use the new theme path (`theme: [docsy/theme]`). +- Add the `_install-theme-deps` postinstall to `docsy.dev/package.json` so theme + runtime deps land in `docsy.dev/node_modules/` (consumer-cwd lookup). - Build `docsy.dev` locally. Iterate on TOF if anything in the build chain surprises. -- Create `tasks/0.16/repo-reorg/spike-notes.md` and record: the exact - before/after config change in `docsy.dev`, and any maintainer-workflow - observations. -- Confirm Netlify deploy previews work from the spike branch. +- Record the exact before/after config change and any maintainer-workflow + observations in `tasks/0.16/repo-reorg/spike-notes.md`. +- Confirm Netlify deploy previews work from the spike branch (update + `docsy.dev/scripts/_install.sh` so the Netlify command sequence + `scripts/_install.sh && npm run build:preview` installs both the repo-root and + `docsy.dev` packages). Exit criterion: `docsy.dev` builds locally and on Netlify against the spike branch. -Status (2026-05-21): **local build exit criterion met.** `docsy.dev` builds from +Status (2026-05-24): **local build exit criterion met.** `docsy.dev` builds from `theme/` with the one-line `theme: [docsy/theme]` consumer config change and no -symlinks anywhere (223 EN + 218 FR pages). Spike notes record the exact -before/after edit. Netlify deploy preview is still pending. +symlinks anywhere (223 EN + 218 FR pages). `docsy.dev/scripts/_install.sh` now +installs both the root and `docsy.dev` packages (workspaces are empty), so the +Netlify command sequence works in principle. Netlify deploy preview verification +is still pending. ### Phase 2: local smoke tests (CI emulation) Emulate locally what GitHub Actions will eventually run, one install mode at a time. -- Update `_dev/scripts/make-site.sh` for the new install paths. +- Update `scripts/make-site.sh` for the new install paths. - Run `make-site.sh -s NPM`. Confirm the one-line user edit; record in spike notes. - Run `make-site.sh -s HUGO_MODULE`. Confirm; record. @@ -105,11 +110,9 @@ time. Exit criterion: all three install modes build locally; the spike-notes matrix is complete with exact one-line edits. -Status (2026-05-21): NPM-tarball install path validated by hand (`npm pack` at -root → install in a tmp consumer dir; spike notes Phase 2 section). Consumer -install is clean (no dev tooling leakage; 4 packages, 0 vulnerabilities; -postinstall placeholders created). Remaining: rerun via `make-site.sh -s NPM`, -then `-s HUGO_MODULE`, then non-module `themes/docsy/`. +Status (2026-05-24): pending. `make-site.sh` has been updated for the new +`/theme` suffix in both the NPM and HUGO_MODULE paths but the runs themselves +have not yet been executed against the current architecture. ### Phase 3: GitHub CI @@ -127,38 +130,45 @@ merge to `main`.** If everything above held, the canonical move lands. Coordinated PR in the `docsy-example` repo that bumps the import path. -- Land the docsy-example PR after a Docsy 0.16 pre-release (or against a pinned - commit) so the example tracks reality. +- Land the `docsy-example` PR after a Docsy 0.16 pre-release (or against a + pinned commit) so the example tracks reality. -Exit criterion: docsy-example builds against 0.16-pre and passes its own smoke +Exit criterion: `docsy-example` builds against 0.16-pre and passes its own smoke checks. ### Phase 5: docs and release notes The user-facing payload, derived from the spike notes. -- Update get-started pages with the new import path. -- Resolve the [package-versioning open question][versioning] before bumping - versions for release. +- Update get-started pages with the new theme path / import path. - Update the changelog and release blog post; the migration section reads the exact snippets out of `spike-notes.md`. - -[versioning]: ./theme-only-folder.plan.md#package-versioning - - Update `README.md` if it references the old install shape. Exit criterion: a reviewer who has not seen the design conversation can upgrade to 0.16 by following only the release notes. +## Out of scope (this plan) + +The following improvements were considered during the spike and explicitly +deferred to a follow-on plan so this PR stays focused on the structural move: + +- Slim the root `package.json` to a thin publishable shim (`files: [theme, …]`, + no `devDependencies`). +- Carve out a dedicated maintainer-orchestration folder (e.g. `_dev/`) that owns + repo-wide `devDependencies` and `hugo-extended`. +- Move root-level `prepare`/`postinstall` work behind that boundary. +- NPM-registry publication of the `docsy` package. + +These are tracked separately and will draw on the structural cleanliness that +TOF establishes. + ## Tracking - Parent issue: [#2617][]. Keep a phase checklist there (or sub-issues, if the team prefers) so progress is visible. -- Spike notes: `tasks/0.16/repo-reorg/spike-notes.md`, created in Phase 1 and - grown through Phase 2. +- Spike notes: `tasks/0.16/repo-reorg/spike-notes.md`, grown through Phases 1–3. - One feature branch (currently `chalin-m24-monorepo-2026-0520`) carries Phases 0–3. Phases 4–5 land as separate PRs against `main` after the spike merges. -- Each phase is reviewable on its own: a fresh `git diff` against the branch's - previous phase commit should tell a small, focused story. [#2617]: https://github.com/google/docsy/issues/2617 diff --git a/tasks/0.16/repo-reorg/theme-only-folder.plan.md b/tasks/0.16/repo-reorg/theme-only-folder.plan.md index 5377c88fc..5ffa02183 100644 --- a/tasks/0.16/repo-reorg/theme-only-folder.plan.md +++ b/tasks/0.16/repo-reorg/theme-only-folder.plan.md @@ -9,9 +9,9 @@ cSpell:ignore: fontawesome ## About this plan Keep this document lean and readable for a junior developer. It describes the -intended end state, key boundaries, and acceptance criteria, not every command -or step needed to do the work. Add detail only when it prevents a likely mistake -or clarifies a compatibility decision. +intended end state, key boundaries, and acceptance criteria — not every command. +Add detail only when it prevents a likely mistake or clarifies a compatibility +decision. ## Motivation @@ -32,8 +32,8 @@ that needs ongoing repair: Each of these exists because the canonical theme tree, the maintainer toolchain, and the consumer-visible install shape are all the same tree. The fix is -structural: give the theme its own folder that **is** the install shape, and let -the repo root hold only repo-wide tooling. +structural: give the theme its own folder so the theme tree, the maintainer +toolchain, and the published shape can each evolve on their own timeline. Issue [#2617][] follows up [#2436][] and asks for the theme to live in its own folder. @@ -44,11 +44,14 @@ folder. ## Goal: theme-only folder (TOF) Move the canonical Docsy theme into a folder named `theme/`, whose contents are -**only** what a consuming site needs from Docsy, nothing else. +**only** what a consuming site needs from Docsy. We expect this to be a structural change with one consumer-facing edit per install mode. It trades a small documented migration for a clean, predictable -install shape and it should remove the install-time workarounds listed above. +install shape and removes one of the install-time workarounds (the +`../../node_modules/*` escape mounts) up front. The remaining workarounds (the +`postinstall` mkdirp helper and the `_prepare` scrollspy/SCSS toolchain) keep +working unchanged; later phases can revisit them. ## TOF repo layout @@ -60,40 +63,49 @@ install shape and it should remove the install-time workarounds listed above. │ ├── images/ # theme images only │ ├── layouts/ │ ├── static/ -│ ├── scripts/ -│ │ └── mkdirp-hugo-mod.js │ ├── hugo.yaml # canonical theme config (mounts, mediaTypes, outputFormats) │ ├── theme.toml # canonical │ ├── go.mod # module path: github.com/google/docsy/theme │ ├── go.sum -│ └── package.json # source of truth for theme runtime deps +│ └── package.json # private mirror of theme runtime deps (see below) ├── docsy.dev/ # website; its own node_modules for the site build -├── _dev/ # maintainer-orchestration folder (not published) -│ ├── scripts/ # all maintainer-only scripts (incl. sync-root-deps.mjs) -│ └── package.json # devDeps (hugo-extended, prettier, markdownlint, …) +├── scripts/ # maintainer scripts (chroma, scrollspy patch, sync-theme-deps, …) ├── tasks/ -└── package.json # thin publishable shim; name "docsy"; files: [theme, …] +└── package.json # repo root: canonical for theme runtime deps + repo-wide tooling ``` Key properties: -- `theme/` is what NPM ships and what Hugo modules resolve to. Its - `package.json` is the **single source of truth** for theme runtime deps. -- The repo root is the **publishable manifest only**. It still carries - `name: "docsy"` (this is the consumer-facing package), but its `files` - whitelist allows only `theme/` and the top-level docs files into the tarball, - and it declares **no** `devDependencies`. A `prepare` script mirrors theme - runtime deps from `theme/package.json` to the root manifest so consumers' - transitive-install graphs are correct. -- `_dev/` is where maintainers run commands from. It owns the monorepo-wide - tooling and the Hugo version (single source). No npm workspaces are declared - anywhere; each of `theme/`, `docsy.dev/`, and `_dev/` is its own independent - install root. -- No facades, escape mounts, or workaround `postinstall` scripts in `theme/` - beyond `mkdirp-hugo-mod.js`, which Hugo-module consumers need. -- Anything generated (vendored Bootstrap SCSS, scrollspy patch output, chroma - styles, `go.sum`) is committed under `theme/` so consumers never run the - generators. +- `theme/` is what NPM ships and what Hugo modules resolve to. +- The repo root `package.json` is the **single source of truth** for theme + runtime dependency versions and continues to host repo-wide maintainer tooling + (Prettier, markdownlint, cSpell French dict). The `theme/` `package.json` is a + small **private mirror** so that file/tarball installs of `theme/` (notably + `docsy.dev`'s postinstall — see [Maintainer workflow](#maintainer-workflow)) + see the right versions. +- The mirror is kept in sync by `scripts/sync-theme-deps.mjs` (run by + `_prepare`, `postupdate:dep`, and `postupdate:packages`). Maintainers should + not edit `theme/package.json`'s `dependencies` by hand. +- Theme-only configuration moved to `theme/`: `hugo.yaml`, `theme.toml`, + `go.mod`/`go.sum`. The `theme/go.mod` module path becomes + `github.com/google/docsy/theme`. +- The mounts inside `theme/hugo.yaml` are spelled the canonical way: + `node_modules/`. Hugo's loader does a theme-local-first, then + consumer-cwd lookup, so the legacy `../../node_modules/*` escape form is no + longer needed and is removed. +- Generated artifacts (vendored Bootstrap SCSS, scrollspy patch output, chroma + styles, `go.sum`) continue to be committed under `theme/` so consumers never + run the generators. + +What this plan **does not** change (deferred to a follow-on plan): + +- The repo root keeps `devDependencies` for repo-wide maintainer tooling and + keeps `bootstrap` + `@fortawesome/fontawesome-free` as runtime deps. There is + no `files` whitelist yet and no thin-shim refactor. +- There is no dedicated `_dev/` (or similar) maintainer-orchestration folder + yet. Maintainers continue to work from the repo root. +- NPM-registry publication remains future work; the immediate consumer surface + is the existing GitHub-NPM install path. ## User-facing migration @@ -136,148 +148,116 @@ Validation harness, all run against the spike branch: - A minimal `hugo new site` with Docsy cloned into `themes/docsy/` builds with the one-line `theme:` edit. -For each mode, record in a spike notes file: the exact commands used, the exact -one-line config edit, and whether the result is "one-line change" or "needs more -design". Any "needs more design" result blocks the merge until the design is -iterated. +For each mode, record in `tasks/0.16/repo-reorg/spike-notes.md`: the exact +commands used, the exact one-line config edit, and whether the result is +"one-line change" or "needs more design". Any "needs more design" result blocks +the merge until the design is iterated. ## Package boundary -Each `package.json` carries a clearly-scoped set of dependencies. The four +Each `package.json` carries a clearly-scoped set of dependencies. The three manifests are: -| File | Role | Notable contents | -| -------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------ | -| `theme/package.json` | Source of truth, theme runtime deps | `bootstrap`, `@fortawesome/fontawesome-free`; `postinstall: mkdirp-hugo-mod.js` | -| `package.json` (repo root) | Publishable shim | `files: [theme, …]`, `prepare: sync-root-deps.mjs`, `postinstall: mkdirp-hugo-mod.js`. **No devDeps.** | -| `docsy.dev/package.json` | Website's site-build / site-tooling | `autoprefixer`, `postcss-cli`, `cross-env`, `rtlcss`, `afdocs`, `netlify-cli`, `npm-check-updates` | -| `_dev/package.json` | Maintainer-orchestration | `hugo-extended`, `prettier`, `markdownlint-cli2`, `markdownlint-rule-*`, `@cspell/dict-fr-fr` | +| File | Role | Notable contents | +| -------------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | +| `package.json` (repo root) | Canonical theme deps + repo-wide maintainer tools | `bootstrap`, `@fortawesome/fontawesome-free`; `prettier`, `markdownlint-cli2`, markdownlint rule plugins, `@cspell/dict-fr-fr`; `postinstall` | +| `theme/package.json` | Private mirror of theme runtime deps | Same `dependencies` as root (kept in sync by `sync-theme-deps.mjs`); `"private": true` | +| `docsy.dev/package.json` | Website's site-build / site-tooling | `autoprefixer`, `postcss-cli`, `cross-env`, `rtlcss`, `afdocs`, `netlify-cli`, `npm-check-updates`, `hugo-extended`; `_install-theme-deps` hook | Keep docs-site, CI, release, formatting, link-checking, and test-only dependencies out of `theme/package.json`. -The GitHub/NPM install path is a key use case. Installing Docsy from GitHub -through NPM must not fetch maintainer or `docsy.dev` dev dependencies or execute -maintainer-only generators. The shape of that install is enforced by: - -- `files: ["CHANGELOG.md", "LICENSE", "README.md", "theme"]` at the root — the - tarball contains nothing else. -- Zero `devDependencies` at the root — git-URL installs see no dev workflow to - run, so npm does not install a maintainer toolchain in the clone. -- A `postinstall` at the root that only runs `theme/scripts/mkdirp-hugo-mod.js` - to create the empty Hugo module placeholder dirs the consumer's Hugo expects. -- All generated theme assets committed under `theme/` so consumers never run a - generator. - -The `prepare` script at the root delegates to `_dev/scripts/sync-root-deps.mjs`, -which mirrors `theme/package.json`'s `dependencies` onto the root manifest. The -committed root manifest is kept in sync with `theme/` (the sync script is -idempotent); `prepare` runs as a safety net during `npm pack` and during git-URL -installs in the consumer-side clone. - -## Package versioning - -Both the root (publishable as `docsy`) and `theme/` carry a `version`, plus -`docsy.dev/` and `_dev/` carry their own private versions. The question is which -one is the **canonical** version, and how it propagates. - -**Open question.** Two viable patterns: - -- **Theme-only canonical version.** `theme/package.json` is the canonical - source. The sync script (already used for `dependencies`) is extended to - mirror `version` from `theme/` onto the root manifest at `prepare` time. The - root commits a synced value to keep maintainer working trees clean. -- **Root-canonical version.** Maintainers bump the root `version` and the - release tooling propagates it to `theme/package.json`. The two are kept - aligned by tooling. Preserves continuity with the current setup (where release - tooling already targets the root version). - -Either way, the released artifact (the tarball whose root `package.json` -declares `name: "docsy"`) is what consumers see, so the **effective** -user-facing version is whatever the root carries at pack time. The choice is -primarily about maintainer ergonomics and which file the release tooling treats -as authoritative. - -To be resolved during the spike or early in Phase 5 (docs and release notes). +Today (without a `files` whitelist or `prepare` hook at the root), the +GitHub/NPM install path still ships more than the theme tree to consumers. +Reducing that to a clean tarball — `files: [theme, …]`, no devDeps at root, a +`prepare` script that runs the sync — is a deliberate **next step** captured in +a follow-on plan, not this one. The structural move makes that follow-on +straightforward; until then, consumers can keep using the existing install path +with only the one-line theme-path edit. ## Maintainer workflow The lead maintainer (and other contributors) coordinate theme and website -changes from the repo. `docsy.dev` is Docsy's primary end-to-end test of theme -changes, so coordinated edits across both happen daily. +changes from the repo root. `docsy.dev` is Docsy's primary end-to-end test of +theme changes, so coordinated edits across both happen daily. -Orchestration commands run from `_dev/`: +Orchestration commands continue to run from the repo root: ```sh -cd _dev -npm run install:all # installs theme/, docsy.dev/, and _dev/ in sequence -npm run build # builds docsy.dev against the local theme/ -npm run serve # docsy.dev dev server with live reload -npm run check # repo-wide format + markdown checks -npm run fix # auto-fix +npm install # repo root deps (theme runtime + maintainer tools) +npm run docsy.dev-install # docsy.dev/ deps (site build + hugo-extended) +npm run build # builds docsy.dev against theme/ +npm run serve # docsy.dev dev server with live reload +npm run check # repo-wide format + markdown checks +npm run fix # auto-fix ``` -The maintainer's shell sits in `_dev/`; edits happen across `theme/`, -`docsy.dev/`, and `_dev/` as needed, and one orchestration command from `_dev/` -exercises the cross-folder loop. The repo root is **not** the maintainer's -working directory; it is the publishable manifest only. +`docsy.dev`'s `postinstall` runs `_install-theme-deps`, which executes +`npm install ../theme --install-links --no-save && rm -rf node_modules/theme`. +The `--install-links` flag tells npm to treat the local `../theme` package as a +tarball, which has the side effect of materialising `theme/`'s declared runtime +dependencies (currently `bootstrap` and `@fortawesome/fontawesome-free`) into +`docsy.dev/node_modules/`. The `rm -rf node_modules/theme` line then discards +the now-redundant copy of the theme itself. Hugo's consumer-cwd `node_modules` +lookup finds Bootstrap and Font Awesome there during the `docsy.dev` build. ## Tooling versions Each shared tool has exactly one declaration in the repo: -- `hugo-extended` lives in `_dev/devDependencies`. The `hugo` binary lands at - `_dev/node_modules/.bin/hugo` after `cd _dev && npm install`, and is on PATH - for nested `npm run -C ../docsy.dev …` invocations via npm-script PATH - inheritance. Bumping the Hugo version is a single edit. +- `hugo-extended` lives in `docsy.dev/devDependencies`. The `hugo` binary lands + at `docsy.dev/node_modules/.bin/hugo` after `npm run docsy.dev-install` and is + invoked by `docsy.dev`'s `_hugo` scripts. Bumping the Hugo version is a single + edit (see `scripts/set-hugo-version.mjs`). - `prettier`, `markdownlint-cli2`, the markdownlint rule plugins, and - `@cspell/dict-fr-fr` likewise live in `_dev/devDependencies`. + `@cspell/dict-fr-fr` live in the **repo-root** `devDependencies` because they + are run from the repo root. - Site-build tools (`autoprefixer`, `postcss-cli`, `cross-env`, `rtlcss`) and site-tooling (`afdocs`, `netlify-cli`, `npm-check-updates`) live in `docsy.dev/devDependencies` because that is where they are used. -- Theme runtime deps (`bootstrap`, `@fortawesome/fontawesome-free`) live in - `theme/package.json` and are mirrored to the root manifest by the sync script. +- Theme runtime deps (`bootstrap`, `@fortawesome/fontawesome-free`) live in the + repo-root `dependencies` and are mirrored into `theme/package.json` by + `scripts/sync-theme-deps.mjs`. ## Test boundary The new layout leaves room for a larger test suite — HTML goldens, screenshot goldens, browser-based checks — without bloating the installed theme package. -Test fixtures, generated goldens, and test-only dependencies live in `docsy.dev` -(current) or a repo-level `tests/` folder (future). Root commands make the suite -easy for maintainers to run; theme users never install the test toolchain. +Test fixtures, generated goldens, and test-only dependencies live in +`docsy.dev/` (current) or a repo-level `tests/` folder (future). Root commands +make the suite easy for maintainers to run; theme users never install the test +toolchain. ## Work areas 1. **Move the theme into `theme/`.** Move `assets/`, `i18n/`, `images/`, - `layouts/`, `static/`, `hugo.yaml`, `theme.toml`, `go.mod`, `go.sum`, and the - `mkdirp-hugo-mod.js` postinstall helper into `theme/`. Update the `module` - declaration in `theme/go.mod` to `github.com/google/docsy/theme`. Update - generators and patch scripts that have moved to `_dev/scripts/` to write to - the new paths under `theme/`. - -2. **Carve out `_dev/`.** Create `_dev/` and `git mv scripts _dev/scripts` so - maintainer scripts retain history. Move repo-wide devDeps from the old root - `package.json` to `_dev/package.json`. Move `hugo-extended` here as the - single Hugo source. Add `_dev/scripts/sync-root-deps.mjs` for the theme-deps - mirror. - -3. **Reshape the root.** Root `package.json` becomes a thin publishable shim: - `name: "docsy"`, a `files` whitelist, `prepare` + `postinstall` hooks, no - `devDependencies`, no workspaces. Keep `Dockerfile`, `docker-compose.yaml`, - `.editorconfig`, `.prettierrc.json`, `.markdownlint*`, `.nvmrc`, - `.gitattributes`, `.gitignore` at the root. - -4. **Update `docsy.dev`.** Pin to the new Hugo module path - (`github.com/google/docsy/theme`) or the classic `theme: docsy/theme` form. - Remove `hugo-extended` from `docsy.dev/package.json` (it now lives in - `_dev/`). The website becomes a real first-class consumer of the theme. + `layouts/`, `static/`, `hugo.yaml`, `theme.toml`, `go.mod`, `go.sum` into + `theme/`. Update the `module` declaration in `theme/go.mod` to + `github.com/google/docsy/theme`. Drop the legacy `../../node_modules/*` + escape mounts from `theme/hugo.yaml`. + +2. **Update repo-root scripts.** Update generators and patch scripts in + `scripts/` (`mkdirp-hugo-mod.js`, `_gen-chroma-style.sh`, + `refresh-sass-variables.pl`, `scrollspy-patch/*`, `getHugoModules/`, + `make-site.sh`) to read/write under `theme/`. Update the root `package.json` + script paths to point at `theme/assets`, `theme/i18n`, etc. + +3. **Add `theme/package.json` as a private mirror.** Same `dependencies` as the + root; `"private": true`. Add `scripts/sync-theme-deps.mjs` to keep the mirror + aligned with root and wire it into `_prepare`, `postupdate:dep`, and + `postupdate:packages`. + +4. **Update `docsy.dev`.** Switch the consumer config to `theme: [docsy/theme]` + (classic non-module form). Add a `postinstall` that runs + `_install-theme-deps` (uses `npm install ../theme --install-links --no-save` + to materialise theme deps into `docsy.dev/node_modules/` without symlinking + the theme itself). 5. **Update `docsy-example`.** Land a coordinated PR that bumps the import path. - Confirms the example continues to work as the canonical user reference. -6. **Update CI and smoke tests.** `_dev/scripts/make-site.sh` and the GitHub - Actions workflows must exercise the new install paths. Keep the existing - matrix (NPM × HUGO_MODULE × Windows × Ubuntu) green. +6. **Update CI and smoke tests.** `scripts/make-site.sh` and the GitHub Actions + workflows must exercise the new install paths. Keep the existing matrix (NPM + × HUGO_MODULE × Windows × Ubuntu) green. 7. **Update docs and release notes.** Document the one-line config change per install mode. The release blog post must include exact before/after snippets, @@ -294,18 +274,10 @@ easy for maintainers to run; theme users never install the test toolchain. - A new site can use Docsy through the GitHub/NPM install path with the documented one-line config change. - Non-module theme usage works with the documented one-line config change. -- `theme/package.json` contains only theme runtime dependencies and the - `mkdirp-hugo-mod.js` postinstall helper. No other lifecycle scripts. -- The root `package.json` has no `devDependencies` and a `files` whitelist so - that `npm install github:google/docsy#` brings the consumer only - `theme/` + a handful of top-level docs files, plus `bootstrap` and - `@fortawesome/fontawesome-free` as transitive deps. Installing Docsy this way - does not install `docsy.dev` dev dependencies, does not install maintainer - tooling, does not execute `_prepare`, and does not build the whole repo. +- `theme/package.json` contains only theme runtime dependencies (mirrored from + root) and is marked `"private": true`. No other lifecycle scripts. - All generated theme assets (vendored Bootstrap SCSS, scrollspy patch output, chroma styles, `go.sum`) are committed under `theme/`. -- HTML, screenshot, and other golden tests can be added without increasing the - installed theme package surface. - CI and smoke tests pass against the new layout on Windows and Ubuntu. - Release notes include the exact before/after migration snippet for each install mode. @@ -321,3 +293,6 @@ easy for maintainers to run; theme users never install the test toolchain. module path. The cost of carrying a fragile facade outweighs the value of "no config change" for one release. - Do not change the Hugo theme name (`docsy`). +- Do not, in this change, slim the root `package.json` to a thin publishable + shim or add a `files` whitelist. That work is in scope for a follow-on plan; + TOF lays the structural ground for it. diff --git a/theme/package.json b/theme/package.json index 1221d4963..980c7279f 100644 --- a/theme/package.json +++ b/theme/package.json @@ -6,10 +6,7 @@ "homepage": "https://www.docsy.dev", "license": "Apache-2.0", "private": true, - "scripts": { - "todo-add-script-to-sync-deps": "echo TODO" - }, - "dependencies-note": "DO NOT EDIT the dependencies, they are synced from root package.json", + "dependencies-note": "DO NOT EDIT directly; versions are synced from the root package.json by scripts/sync-theme-deps.mjs (run via `npm run _sync:theme-deps`).", "dependencies": { "@fortawesome/fontawesome-free": "6.7.2", "bootstrap": "5.3.8" From 91c2fc31107fb8a469efcc74dde272d79cc15dff Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Sun, 24 May 2026 20:11:38 -0400 Subject: [PATCH 5/6] Add TOF README and update repo-reorg plans --- tasks/0.16/repo-reorg/README.md | 46 ++++++++++ .../repo-reorg/monorepo-extra-analysis.md | 8 +- .../repo-reorg/theme-only-folder.execution.md | 19 ++--- .../0.16/repo-reorg/theme-only-folder.plan.md | 84 ++++++------------- 4 files changed, 83 insertions(+), 74 deletions(-) create mode 100644 tasks/0.16/repo-reorg/README.md diff --git a/tasks/0.16/repo-reorg/README.md b/tasks/0.16/repo-reorg/README.md new file mode 100644 index 000000000..90ea0c4f1 --- /dev/null +++ b/tasks/0.16/repo-reorg/README.md @@ -0,0 +1,46 @@ +--- +title: TOF (0.16 repo reorg) — index +date: 2026-05-24 +issue: https://github.com/google/docsy/issues/2617 +cSpell:ignore: fontawesome +--- + +Planning materials for the **Theme-Only Folder (TOF)** refactor in Docsy 0.16. +Upstream tracking: issue [#2617][]. + +## In this folder + +| File | Purpose | +| -------------------------------------- | -------------------------------------------------------------------------------------- | +| [theme-only-folder.plan.md][plan] | Design contract: end state, package boundary, acceptance criteria, non-goals. | +| [theme-only-folder.execution.md][exec] | Sequencing roadmap: Phases 0–5, with per-phase exit criteria and status notes. | +| [spike-notes.md][spike] | Living log of the compatibility spike (commands, consumer-config edits, observations). | +| [monorepo-extra-analysis.md][analysis] | Earlier analysis that informed the spike and shaped TOF; retained for context. | + +[plan]: ./theme-only-folder.plan.md +[exec]: ./theme-only-folder.execution.md +[spike]: ./spike-notes.md +[analysis]: ./monorepo-extra-analysis.md +[#2617]: https://github.com/google/docsy/issues/2617 + +## Status at a glance + +Updated 2026-05-24. Per-phase detail (with exit criteria) lives in the +[execution plan][exec]. + +| Phase | Status | +| ------------------------------------ | ----------------------------------------------------- | +| 0 — structural move | Landed; `_prepare` + `_diff:check` regression pending | +| 1 — `docsy.dev` consumes TOF | Local build green; Netlify preview pending | +| 2 — local smoke tests (CI emulation) | Pending; `make-site.sh` paths updated | +| 3 — GitHub CI | Pending | +| 4 — `docsy-example` | Pending (post-pre-release) | +| 5 — docs and release notes | Pending | + +Next concrete steps, in order: + +1. Re-run `npm run _prepare` and `npm run _diff:check` end-to-end against the + new layout to close out Phase 0. +2. Push the branch and confirm a Netlify deploy preview of `docsy.dev` builds. +3. Run `make-site.sh -s NPM`, then `-s HUGO_MODULE`, then a manual non-module + `themes/docsy/` clone-and-build. Record each in [spike-notes][spike]. diff --git a/tasks/0.16/repo-reorg/monorepo-extra-analysis.md b/tasks/0.16/repo-reorg/monorepo-extra-analysis.md index e6c9c20c9..a4fa56d82 100644 --- a/tasks/0.16/repo-reorg/monorepo-extra-analysis.md +++ b/tasks/0.16/repo-reorg/monorepo-extra-analysis.md @@ -3,18 +3,18 @@ title: Extra analysis for the theme-subfolder monorepo plan date: 2026-05-20 status: draft issue: https://github.com/google/docsy/issues/2617 -companion: ./monorepo-theme-subfolder.plan.md +companion: ./theme-only-folder.plan.md cSpell:ignore: webfonts cutover bikeshedding --- ## About This Doc -Companion notes to [monorepo-theme-subfolder.plan.md][plan]. This doc collects -concrete pitfalls, open questions, and acceptance-criteria additions found while +Companion notes to [theme-only-folder.plan.md][plan]. This doc collects concrete +pitfalls, open questions, and acceptance-criteria additions found while reviewing the plan against the current repo. The parent plan should stay lean; this doc is the working scratchpad and reviewer reference. -[plan]: ./monorepo-theme-subfolder.plan.md +[plan]: ./theme-only-folder.plan.md ## TL;DR diff --git a/tasks/0.16/repo-reorg/theme-only-folder.execution.md b/tasks/0.16/repo-reorg/theme-only-folder.execution.md index 9a8bee40e..5a715ddf2 100644 --- a/tasks/0.16/repo-reorg/theme-only-folder.execution.md +++ b/tasks/0.16/repo-reorg/theme-only-folder.execution.md @@ -14,9 +14,12 @@ of operations for the compatibility spike work and the canonical move, broken into phases that are independently checkable and, where practical, independently mergeable. -The plan itself is the design contract. This doc is purely about sequencing. +The plan itself is the design contract. This doc is purely about sequencing. For +a bird's-eye view of where we are and what's next, see the folder +[README][readme]. [plan]: ./theme-only-folder.plan.md +[readme]: ./README.md ## Working principles @@ -150,18 +153,10 @@ to 0.16 by following only the release notes. ## Out of scope (this plan) -The following improvements were considered during the spike and explicitly -deferred to a follow-on plan so this PR stays focused on the structural move: +See the plan's [What this plan does not change][plan-defer] section for the +canonical list of deferred work. -- Slim the root `package.json` to a thin publishable shim (`files: [theme, …]`, - no `devDependencies`). -- Carve out a dedicated maintainer-orchestration folder (e.g. `_dev/`) that owns - repo-wide `devDependencies` and `hugo-extended`. -- Move root-level `prepare`/`postinstall` work behind that boundary. -- NPM-registry publication of the `docsy` package. - -These are tracked separately and will draw on the structural cleanliness that -TOF establishes. +[plan-defer]: ./theme-only-folder.plan.md#tof-repo-layout ## Tracking diff --git a/tasks/0.16/repo-reorg/theme-only-folder.plan.md b/tasks/0.16/repo-reorg/theme-only-folder.plan.md index 5ffa02183..466747227 100644 --- a/tasks/0.16/repo-reorg/theme-only-folder.plan.md +++ b/tasks/0.16/repo-reorg/theme-only-folder.plan.md @@ -48,10 +48,20 @@ Move the canonical Docsy theme into a folder named `theme/`, whose contents are We expect this to be a structural change with one consumer-facing edit per install mode. It trades a small documented migration for a clean, predictable -install shape and removes one of the install-time workarounds (the -`../../node_modules/*` escape mounts) up front. The remaining workarounds (the -`postinstall` mkdirp helper and the `_prepare` scrollspy/SCSS toolchain) keep -working unchanged; later phases can revisit them. +install shape. Mapping the four [Motivation](#motivation) workarounds to this +PR: + +| Workaround | This PR | +| ----------------------------------------- | ------------------- | +| `../../node_modules/*` escape mounts | **Fixed** | +| `postinstall` mkdirp helper | Kept; deferred | +| `_prepare` scrollspy + vendored SCSS | Kept; deferred | +| Root `package.json` mixes theme + tooling | Partially; deferred | + +"Partially" because `theme/package.json` now declares the theme runtime deps (as +a synced mirror), giving us a clean boundary to push the rest of the cleanup +through. The thin-shim refactor that fully separates the manifests is +[scoped out](#tof-repo-layout) and lives in a follow-on plan. ## TOF repo layout @@ -153,6 +163,11 @@ commands used, the exact one-line config edit, and whether the result is "one-line change" or "needs more design". Any "needs more design" result blocks the merge until the design is iterated. +For the order in which Phase 0 (move) and Phases 1–5 (consumer validation, +release) are run, see the [execution plan][exec]. + +[exec]: ./theme-only-folder.execution.md + ## Package boundary Each `package.json` carries a clearly-scoped set of dependencies. The three @@ -167,14 +182,6 @@ manifests are: Keep docs-site, CI, release, formatting, link-checking, and test-only dependencies out of `theme/package.json`. -Today (without a `files` whitelist or `prepare` hook at the root), the -GitHub/NPM install path still ships more than the theme tree to consumers. -Reducing that to a clean tarball — `files: [theme, …]`, no devDeps at root, a -`prepare` script that runs the sync — is a deliberate **next step** captured in -a follow-on plan, not this one. The structural move makes that follow-on -straightforward; until then, consumers can keep using the existing install path -with only the one-line theme-path edit. - ## Maintainer workflow The lead maintainer (and other contributors) coordinate theme and website @@ -192,14 +199,13 @@ npm run check # repo-wide format + markdown checks npm run fix # auto-fix ``` -`docsy.dev`'s `postinstall` runs `_install-theme-deps`, which executes -`npm install ../theme --install-links --no-save && rm -rf node_modules/theme`. -The `--install-links` flag tells npm to treat the local `../theme` package as a -tarball, which has the side effect of materialising `theme/`'s declared runtime -dependencies (currently `bootstrap` and `@fortawesome/fontawesome-free`) into -`docsy.dev/node_modules/`. The `rm -rf node_modules/theme` line then discards -the now-redundant copy of the theme itself. Hugo's consumer-cwd `node_modules` -lookup finds Bootstrap and Font Awesome there during the `docsy.dev` build. +`docsy.dev`'s `postinstall` runs `_install-theme-deps` (see +`docsy.dev/package.json`), which materialises `theme/`'s declared runtime deps +into `docsy.dev/node_modules/` so Hugo's consumer-cwd lookup finds them during +the build. The mechanics (`--install-links` flag and the cleanup line) are +recorded in [spike-notes][]. + +[spike-notes]: ./spike-notes.md ## Tooling versions @@ -228,41 +234,6 @@ Test fixtures, generated goldens, and test-only dependencies live in make the suite easy for maintainers to run; theme users never install the test toolchain. -## Work areas - -1. **Move the theme into `theme/`.** Move `assets/`, `i18n/`, `images/`, - `layouts/`, `static/`, `hugo.yaml`, `theme.toml`, `go.mod`, `go.sum` into - `theme/`. Update the `module` declaration in `theme/go.mod` to - `github.com/google/docsy/theme`. Drop the legacy `../../node_modules/*` - escape mounts from `theme/hugo.yaml`. - -2. **Update repo-root scripts.** Update generators and patch scripts in - `scripts/` (`mkdirp-hugo-mod.js`, `_gen-chroma-style.sh`, - `refresh-sass-variables.pl`, `scrollspy-patch/*`, `getHugoModules/`, - `make-site.sh`) to read/write under `theme/`. Update the root `package.json` - script paths to point at `theme/assets`, `theme/i18n`, etc. - -3. **Add `theme/package.json` as a private mirror.** Same `dependencies` as the - root; `"private": true`. Add `scripts/sync-theme-deps.mjs` to keep the mirror - aligned with root and wire it into `_prepare`, `postupdate:dep`, and - `postupdate:packages`. - -4. **Update `docsy.dev`.** Switch the consumer config to `theme: [docsy/theme]` - (classic non-module form). Add a `postinstall` that runs - `_install-theme-deps` (uses `npm install ../theme --install-links --no-save` - to materialise theme deps into `docsy.dev/node_modules/` without symlinking - the theme itself). - -5. **Update `docsy-example`.** Land a coordinated PR that bumps the import path. - -6. **Update CI and smoke tests.** `scripts/make-site.sh` and the GitHub Actions - workflows must exercise the new install paths. Keep the existing matrix (NPM - × HUGO_MODULE × Windows × Ubuntu) green. - -7. **Update docs and release notes.** Document the one-line config change per - install mode. The release blog post must include exact before/after snippets, - and the user-guide get-started pages must reflect the new import path. - ## Acceptance criteria - The [Compatibility spike](#compatibility-spike) has been run for all three @@ -293,6 +264,3 @@ toolchain. module path. The cost of carrying a fragile facade outweighs the value of "no config change" for one release. - Do not change the Hugo theme name (`docsy`). -- Do not, in this change, slim the root `package.json` to a thin publishable - shim or add a `files` whitelist. That work is in scope for a follow-on plan; - TOF lays the structural ground for it. From 6de0cc2011469309cadc7a17fd434e4b6cd584a3 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Mon, 25 May 2026 09:26:56 -0400 Subject: [PATCH 6/6] Update netlify.toml to use new theme name --- docsy.dev/netlify.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docsy.dev/netlify.toml b/docsy.dev/netlify.toml index 3203eac02..32630673e 100644 --- a/docsy.dev/netlify.toml +++ b/docsy.dev/netlify.toml @@ -9,7 +9,8 @@ command = "scripts/_install.sh && npm run build:preview" [build.environment] GO_VERSION = "1.25.5" -HUGO_THEME = "repo" +# Netlify clones into a dir named "repo"; the theme lives in repo's theme/ subdir. +HUGO_THEME = "repo/theme" [context.production] command = "scripts/_install.sh && npm run build:production"