browser-extension-manager 1.7.2 → 1.7.4
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
|
-
|
|
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';
|
package/dist/build.js
CHANGED
|
@@ -101,8 +101,11 @@ Manager.getManifest = function () {
|
|
|
101
101
|
Manager.prototype.getManifest = Manager.getManifest;
|
|
102
102
|
|
|
103
103
|
// getConfig: requires and parses browser-extension-manager.json
|
|
104
|
+
// Missing file (framework repo, or a consumer before first setup) → {} — same
|
|
105
|
+
// guard as getManifest above; JSON5.parse(undefined) throws a cryptic
|
|
106
|
+
// "invalid character 'u'" otherwise
|
|
104
107
|
Manager.getConfig = function () {
|
|
105
|
-
return JSON5.parse(jetpack.read(path.join(process.cwd(), 'config', 'browser-extension-manager.json')));
|
|
108
|
+
return JSON5.parse(jetpack.read(path.join(process.cwd(), 'config', 'browser-extension-manager.json')) || '{}');
|
|
106
109
|
}
|
|
107
110
|
Manager.prototype.getConfig = Manager.getConfig;
|
|
108
111
|
|
|
@@ -37,6 +37,11 @@ const FILE_MAP = {
|
|
|
37
37
|
'src/**/*': {
|
|
38
38
|
overwrite: false,
|
|
39
39
|
},
|
|
40
|
+
// Consumer-owned after seeding (e.g. test/_init.js fixture hooks) — copy when
|
|
41
|
+
// missing, never clobber the consumer's version on setup reruns
|
|
42
|
+
'test/**/*': {
|
|
43
|
+
overwrite: false,
|
|
44
|
+
},
|
|
40
45
|
'src/**/*.{html,md}': {
|
|
41
46
|
skip: (file) => {
|
|
42
47
|
// Get the name
|
|
@@ -520,6 +525,11 @@ function defaultsWatcher(complete) {
|
|
|
520
525
|
// Default Task
|
|
521
526
|
module.exports = series(defaults, defaultsWatcher);
|
|
522
527
|
|
|
528
|
+
// Exported for tests — the FILE_MAP rules are load-bearing (a missing rule means
|
|
529
|
+
// the fall-through overwrite: true silently clobbers consumer-owned files on
|
|
530
|
+
// setup reruns)
|
|
531
|
+
module.exports.getFileOptions = getFileOptions;
|
|
532
|
+
|
|
523
533
|
function getFileOptions(filePath) {
|
|
524
534
|
const defaults = {
|
|
525
535
|
overwrite: true,
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// getFileOptions from src/gulp/tasks/defaults.js — the FILE_MAP rules that decide
|
|
2
|
+
// which shipped defaults may overwrite consumer files on `npx bxm setup` reruns.
|
|
3
|
+
// Regression here silently clobbers consumer-owned files: test/_init.js had no
|
|
4
|
+
// matching rule, and the fall-through default is overwrite: true, so every setup
|
|
5
|
+
// rerun reset the consumer's fixture hook to the stub (same gap UJM fixed in 1.9.26).
|
|
6
|
+
|
|
7
|
+
module.exports = {
|
|
8
|
+
type: 'group',
|
|
9
|
+
layer: 'build',
|
|
10
|
+
description: 'defaults FILE_MAP (gulp/tasks/defaults.js getFileOptions)',
|
|
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/manifest.json').overwrite).toBe(false);
|
|
23
|
+
ctx.expect(getFileOptions('src/assets/css/main.scss').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
|
+
// .nvmrc is templated and framework-owned (overwrite stays the default true)
|
|
32
|
+
const nvmrc = getFileOptions('.nvmrc');
|
|
33
|
+
ctx.expect(nvmrc.overwrite).toBe(true);
|
|
34
|
+
ctx.expect(!!nvmrc.template).toBe(true);
|
|
35
|
+
|
|
36
|
+
// Unmatched files fall through to overwrite: true — any new consumer-owned
|
|
37
|
+
// default MUST get an explicit rule or setup will clobber it
|
|
38
|
+
const workflow = getFileOptions('.github/workflows/publish.yml');
|
|
39
|
+
ctx.expect(workflow.overwrite).toBe(true);
|
|
40
|
+
ctx.expect(workflow.rule).toBeNull();
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'merge and skip rules resolve as declared',
|
|
45
|
+
run: async (ctx) => {
|
|
46
|
+
const { getFileOptions } = require('../../../gulp/tasks/defaults.js');
|
|
47
|
+
|
|
48
|
+
// Last-match-wins: CLAUDE.md picks up mergeLines AFTER **/*.md set overwrite: false
|
|
49
|
+
const claude = getFileOptions('CLAUDE.md');
|
|
50
|
+
ctx.expect(claude.mergeLines).toBe(true);
|
|
51
|
+
ctx.expect(claude.rule).toBe('CLAUDE.md');
|
|
52
|
+
|
|
53
|
+
const config = getFileOptions('config/browser-extension-manager.json');
|
|
54
|
+
ctx.expect(config.overwrite).toBe(true);
|
|
55
|
+
ctx.expect(config.merge).toBe(true);
|
|
56
|
+
|
|
57
|
+
ctx.expect(getFileOptions('config/messages.json').overwrite).toBe(false);
|
|
58
|
+
|
|
59
|
+
ctx.expect(getFileOptions('test/.DS_Store').skip).toBe(true);
|
|
60
|
+
ctx.expect(getFileOptions('src/__temp/scratch.js').skip).toBe(true);
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
};
|
package/docs/defaults.md
CHANGED
|
@@ -12,12 +12,16 @@
|
|
|
12
12
|
|
|
13
13
|
```js
|
|
14
14
|
const FILE_MAP = {
|
|
15
|
-
'
|
|
15
|
+
'**/*.md': { overwrite: false }, // docs are consumer-owned after seeding
|
|
16
16
|
'hooks/**/*': { overwrite: false }, // never overwrite hooks
|
|
17
|
-
'
|
|
18
|
-
'
|
|
19
|
-
'.
|
|
20
|
-
'
|
|
17
|
+
'src/**/*': { overwrite: false }, // never overwrite user code
|
|
18
|
+
'test/**/*': { overwrite: false }, // consumer-owned after seeding (test/_init.js!)
|
|
19
|
+
'_.gitignore': { name: () => '.gitignore', mergeLines: true }, // rename + marker-based merge
|
|
20
|
+
'_.env': { name: () => '.env', mergeLines: true },
|
|
21
|
+
'CLAUDE.md': { mergeLines: true }, // framework section live-syncs; Custom section is consumer-owned
|
|
22
|
+
'config/browser-extension-manager.json': { overwrite: true, merge: true },
|
|
23
|
+
'.nvmrc': { template: cleanVersions }, // run templating against the source
|
|
24
|
+
'**/.DS_Store': { skip: true },
|
|
21
25
|
};
|
|
22
26
|
```
|
|
23
27
|
|
|
@@ -31,6 +35,8 @@ const FILE_MAP = {
|
|
|
31
35
|
| `template: data` | Run the source through templating with `data` as the var bag, then write. |
|
|
32
36
|
| `name: function` | Rename on copy — typically used to add a leading `.` (`_.gitignore` → `.gitignore`). |
|
|
33
37
|
|
|
38
|
+
⚠️ **Unmatched files fall through to `overwrite: true`** — any NEW consumer-owned default MUST get an explicit copy-once rule, or every `npx bxm setup` rerun clobbers the consumer's version (exactly how `test/_init.js` got reset before the `test/**/*` rule existed). Rules are last-match-wins — `CLAUDE.md` gains `mergeLines` after `**/*.md` already set copy-once. The rule classes are locked by `src/test/suites/build/defaults-file-options.test.js`.
|
|
39
|
+
|
|
34
40
|
## Why the underscore prefix?
|
|
35
41
|
|
|
36
42
|
Files like `_.gitignore`, `_.env` are stored with a `_` prefix in `src/defaults/` so they don't interfere with BXM's own development (the framework repo doesn't want its `.env` overwritten by the template). The `name` rule renames them to the real `.foo` filename on copy.
|