ultimate-jekyll-manager 1.9.24 → 1.9.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,9 @@
1
1
  #!/usr/bin/env node
2
- const argv = require('yargs')(process.argv.slice(2)).parseSync();
2
+ // Value-less flags must be declared boolean — otherwise yargs treats the next
3
+ // positional as the flag's VALUE (`mgr test --extended some/target` became
4
+ // extended='some/target' with NO target, silently running EVERYTHING in
5
+ // normal mode). Mirrors the same fix in BEM's CLI.
6
+ const argv = require('yargs')(process.argv.slice(2)).boolean(['extended']).parseSync();
3
7
  const cli = new (require('../dist/cli.js'))(argv);
4
8
  (async function() {
5
9
  'use strict';
@@ -55,6 +55,11 @@ const FILE_MAP = {
55
55
  'src/**/*': {
56
56
  overwrite: false,
57
57
  },
58
+ // Consumer-owned after seeding (e.g. test/_init.js fixture hooks) — copy when
59
+ // missing, never clobber the consumer's version on setup reruns
60
+ 'test/**/*': {
61
+ overwrite: false,
62
+ },
58
63
  'src/**/*.{html,md,json}': {
59
64
  skip: (file) => {
60
65
  // Get the name
@@ -604,6 +609,9 @@ function defaultsWatcher(complete) {
604
609
  // Default Task
605
610
  module.exports = series(defaults, defaultsWatcher);
606
611
 
612
+ // Exposed for the build-layer FILE_MAP test (defaults-file-options.test.js)
613
+ module.exports.getFileOptions = getFileOptions;
614
+
607
615
  function getFileOptions(filePath) {
608
616
  const defaults = {
609
617
  overwrite: true,
@@ -0,0 +1,59 @@
1
+ // getFileOptions from src/gulp/tasks/defaults.js — the FILE_MAP rules that decide
2
+ // which shipped defaults may overwrite consumer files on `npx mgr setup` reruns.
3
+ // Regression here silently clobbers consumer-owned files (test/_init.js was reset
4
+ // to the stub on every setup because no rule matched it and the fall-through
5
+ // default is overwrite: true).
6
+
7
+ module.exports = {
8
+ layer: 'build',
9
+ description: 'defaults FILE_MAP (gulp/tasks/defaults.js getFileOptions)',
10
+ type: 'group',
11
+ tests: [
12
+ {
13
+ name: 'consumer-owned seeds are copy-once (test/, hooks/, src/)',
14
+ run: async (ctx) => {
15
+ const { getFileOptions } = require('../../../gulp/tasks/defaults.js');
16
+
17
+ // The regression case: consumer fixture hook must survive setup reruns
18
+ ctx.expect(getFileOptions('test/_init.js').overwrite).toBe(false);
19
+ ctx.expect(getFileOptions('test/README.md').overwrite).toBe(false);
20
+
21
+ ctx.expect(getFileOptions('hooks/build/pre.js').overwrite).toBe(false);
22
+ ctx.expect(getFileOptions('src/assets/js/main.js').overwrite).toBe(false);
23
+ ctx.expect(getFileOptions('src/service-worker.js').overwrite).toBe(false);
24
+ },
25
+ },
26
+ {
27
+ name: 'framework-owned files always overwrite',
28
+ run: async (ctx) => {
29
+ const { getFileOptions } = require('../../../gulp/tasks/defaults.js');
30
+
31
+ const workflow = getFileOptions('.github/workflows/build.yml');
32
+ ctx.expect(workflow.overwrite).toBe(true);
33
+ ctx.expect(!!workflow.template).toBe(true);
34
+
35
+ // Last-match-wins: team images override the earlier src/**/* (false) rule
36
+ ctx.expect(getFileOptions('src/assets/images/team/rare-ivy/profile.jpg').overwrite).toBe(true);
37
+ },
38
+ },
39
+ {
40
+ name: 'merge and skip rules resolve as declared',
41
+ run: async (ctx) => {
42
+ const { getFileOptions } = require('../../../gulp/tasks/defaults.js');
43
+
44
+ ctx.expect(getFileOptions('CLAUDE.md').mergeLines).toBe(true);
45
+
46
+ const config = getFileOptions('config/ultimate-jekyll-manager.json');
47
+ ctx.expect(config.overwrite).toBe(true);
48
+ ctx.expect(config.merge).toBe(true);
49
+
50
+ ctx.expect(getFileOptions('test/.DS_Store').skip).toBe(true);
51
+
52
+ // Unmatched files fall through to overwrite: true — any new consumer-owned
53
+ // default MUST get an explicit rule or setup will clobber it
54
+ ctx.expect(getFileOptions('dist/robots.txt').overwrite).toBe(true);
55
+ ctx.expect(getFileOptions('dist/robots.txt').rule).toBeNull();
56
+ },
57
+ },
58
+ ],
59
+ };
@@ -22,6 +22,19 @@ serve → build → developmentRebuild
22
22
 
23
23
  Pure helpers are exposed under [src/gulp/tasks/utils/](../src/gulp/tasks/utils/) (`merge-jekyll-configs`, `_validate-yaml`, `template-transform`, `collectTextNodes`, `dictionary`, `github-cache`, `formatDocument`) — these are the highest-value test targets (zero I/O, callable directly in `build`-layer tests).
24
24
 
25
+ ## Defaults distribution (`defaults` task)
26
+
27
+ The `defaults` task copies `dist/defaults/**` from the framework into the consumer project on every build/setup. Per-file behavior is decided by `FILE_MAP` in [defaults.js](../src/gulp/tasks/defaults.js) (`getFileOptions` — **last matching glob wins**), in four classes:
28
+
29
+ | Class | Behavior | Rules |
30
+ |---|---|---|
31
+ | Copy-once (consumer-owned) | Seeded when missing, NEVER overwritten | `**/*.md`, `hooks/**/*`, `src/**/*`, `test/**/*` (e.g. `test/_init.js`) |
32
+ | Always-overwrite (framework-owned) | Replaced every run | `.github/workflows/build.yml`, `src/assets/images/team/**/*`, and **any file with no matching rule** (fall-through default) |
33
+ | Merge | Combined with the consumer's version | `config/ultimate-jekyll-manager.json` (deep config merge), `CLAUDE.md` / `_.env` / `_.gitignore` (marker-based line merge) |
34
+ | Skip | Never copied | `**/.DS_Store`, `**/__temp/**/*` |
35
+
36
+ ⚠️ The fall-through default is `overwrite: true` — when adding a new consumer-owned file to `src/defaults/`, it MUST get an explicit copy-once rule or setup reruns will clobber the consumer's edits. The rule classes are locked by the build-layer test `defaults-file-options.test.js`.
37
+
25
38
  ## Config flow
26
39
 
27
40
  Three config files in the consumer project feed the build:
@@ -241,6 +241,8 @@ Same protocol as EM (`__EM_TEST__`) and BXM (`__BXM_TEST__`). One marker per fra
241
241
 
242
242
  The runner loads an optional `test/_init.js` from **both** test roots — the framework (`<UJM>/test/_init.js`) and the consumer project (`<cwd>/test/_init.js`) — and runs it **once, before any suite** (it is NOT itself run as a test; the `_`-prefix keeps it out of discovery). Mirrors the same hook in BEM/EM/BXM so all four frameworks share one shape.
243
243
 
244
+ The stub shipped in `src/defaults/test/_init.js` is **seeded once and never overwritten** — the file is consumer-owned, so setup reruns preserve whatever fixture logic the project puts in it (`test/**/*` is copy-once in the defaults task's `FILE_MAP`; see [build-system.md](build-system.md#defaults-distribution-defaults-task)).
245
+
244
246
  The module **must export a function** — `module.exports = (ctx) => ({ ... })` — called with `{ projectRoot }` and returning the hook object. It may declare:
245
247
 
246
248
  - `async setup({ projectRoot })` — runs once before the suites, e.g. to scaffold a fixture file the boot layer needs.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultimate-jekyll-manager",
3
- "version": "1.9.24",
3
+ "version": "1.9.26",
4
4
  "description": "Ultimate Jekyll dependency manager",
5
5
  "main": "dist/index.js",
6
6
  "files": [