@bobfrankston/npmglobalize 1.0.150 → 1.0.152
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.
- package/cli.js +9 -0
- package/lib/config.js +1 -1
- package/lib/diagnose.d.ts +43 -0
- package/lib/diagnose.js +141 -0
- package/lib/types.d.ts +3 -0
- package/lib.d.ts +3 -0
- package/lib.js +60 -8
- package/package.json +3 -3
package/cli.js
CHANGED
|
@@ -75,6 +75,10 @@ Other Options:
|
|
|
75
75
|
(noEmit projects: removes TS ignores from .npmignore)
|
|
76
76
|
-asis Skip ignore file checks (or set "asis": true in .globalize.json5)
|
|
77
77
|
-rebase Automatically rebase if local is behind remote
|
|
78
|
+
-clean-nested-modules, -clean-nested
|
|
79
|
+
Before npm pack, wipe node_modules/ in each file: dep target.
|
|
80
|
+
Fixes arborist "Cannot read properties of null" crashes when
|
|
81
|
+
sibling file: deps have their own nested node_modules.
|
|
78
82
|
-show Show package.json dependency changes
|
|
79
83
|
-package, -pkg Update package.json scripts to use npmglobalize
|
|
80
84
|
-h, -help Show this help
|
|
@@ -318,6 +322,11 @@ function parseArgs(args) {
|
|
|
318
322
|
options.importgen = false;
|
|
319
323
|
options.explicitKeys.add('importgen');
|
|
320
324
|
break;
|
|
325
|
+
case '-clean-nested':
|
|
326
|
+
case '-clean-nested-modules':
|
|
327
|
+
options.cleanNestedModules = true;
|
|
328
|
+
options.explicitKeys.add('cleanNestedModules');
|
|
329
|
+
break;
|
|
321
330
|
default:
|
|
322
331
|
if (arg.startsWith('-')) {
|
|
323
332
|
unrecognized.push(arg);
|
package/lib/config.js
CHANGED
|
@@ -64,7 +64,7 @@ export function writeConfig(dir, config, explicitKeys) {
|
|
|
64
64
|
const existing = readConfig(dir);
|
|
65
65
|
// Filter out temporary flags and default values (unless explicitly set)
|
|
66
66
|
const filtered = {};
|
|
67
|
-
const omitKeys = new Set(['cleanup', 'init', 'dryRun', 'message', 'conform', 'asis', 'help', 'error', 'updateDeps', 'updateMajor', 'publishDeps', 'forcePublish', 'once']);
|
|
67
|
+
const omitKeys = new Set(['cleanup', 'init', 'dryRun', 'message', 'conform', 'asis', 'help', 'error', 'updateDeps', 'updateMajor', 'publishDeps', 'forcePublish', 'once', 'cleanNestedModules']);
|
|
68
68
|
for (const [key, value] of Object.entries(config)) {
|
|
69
69
|
if (omitKeys.has(key))
|
|
70
70
|
continue;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diagnose failures of npm commands run by npmglobalize.
|
|
3
|
+
*
|
|
4
|
+
* Pulls out common error shapes — especially ones whose root cause lives in
|
|
5
|
+
* a referenced (file:) module, not the current package — and turns them into
|
|
6
|
+
* a short summary + actionable hint instead of a raw arborist stack trace.
|
|
7
|
+
*
|
|
8
|
+
* Leaf module: no dependencies on lib.ts or other internal modules. Keeps
|
|
9
|
+
* the main publish flow in lib.ts readable.
|
|
10
|
+
*/
|
|
11
|
+
export interface DiagnosedError {
|
|
12
|
+
/** Short one-liner suitable for the Issues Summary. */
|
|
13
|
+
summary: string;
|
|
14
|
+
/** Multi-line block to print to console.error (without color). */
|
|
15
|
+
details: string[];
|
|
16
|
+
/** If the root cause is a file: sibling, its package name. */
|
|
17
|
+
referencedModule?: string;
|
|
18
|
+
/** One concrete next step the user can take. */
|
|
19
|
+
hint?: string;
|
|
20
|
+
}
|
|
21
|
+
/** Diagnose an `npm pack` failure. */
|
|
22
|
+
export declare function diagnoseNpmPackFailure(cwd: string, output: string, stderr: string, pkg: any): DiagnosedError;
|
|
23
|
+
/** Given a nested-node_modules path like
|
|
24
|
+
* `node_modules/@scope/sibling/node_modules/transitive`
|
|
25
|
+
* or `../sibling/node_modules/transitive`,
|
|
26
|
+
* find the outermost dep name and resolve it to a file: sibling declared
|
|
27
|
+
* in pkg.dependencies / pkg['.dependencies'] / etc. */
|
|
28
|
+
declare function resolveSiblingFromNestedPath(nestedPath: string, cwd: string, pkg: any): {
|
|
29
|
+
name: string;
|
|
30
|
+
filePath: string;
|
|
31
|
+
} | undefined;
|
|
32
|
+
/** Scan pkg deps for a file: entry whose resolved absolute path equals absTarget. */
|
|
33
|
+
declare function findFileDepByPath(pkg: any, cwd: string, absTarget: string): {
|
|
34
|
+
name: string;
|
|
35
|
+
filePath: string;
|
|
36
|
+
} | undefined;
|
|
37
|
+
/** Exposed for ad-hoc testing — not used by the main flow. */
|
|
38
|
+
export declare const _test: {
|
|
39
|
+
resolveSiblingFromNestedPath: typeof resolveSiblingFromNestedPath;
|
|
40
|
+
findFileDepByPath: typeof findFileDepByPath;
|
|
41
|
+
};
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=diagnose.d.ts.map
|
package/lib/diagnose.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diagnose failures of npm commands run by npmglobalize.
|
|
3
|
+
*
|
|
4
|
+
* Pulls out common error shapes — especially ones whose root cause lives in
|
|
5
|
+
* a referenced (file:) module, not the current package — and turns them into
|
|
6
|
+
* a short summary + actionable hint instead of a raw arborist stack trace.
|
|
7
|
+
*
|
|
8
|
+
* Leaf module: no dependencies on lib.ts or other internal modules. Keeps
|
|
9
|
+
* the main publish flow in lib.ts readable.
|
|
10
|
+
*/
|
|
11
|
+
import path from 'path';
|
|
12
|
+
/** Diagnose an `npm pack` failure. */
|
|
13
|
+
export function diagnoseNpmPackFailure(cwd, output, stderr, pkg) {
|
|
14
|
+
const blob = `${output}\n${stderr}`;
|
|
15
|
+
const lower = blob.toLowerCase();
|
|
16
|
+
// Pattern 1: arborist "missing from lockfile: <path>" + null-`package` TypeError.
|
|
17
|
+
// Root cause: a file: sibling has its own populated node_modules/<transitive>
|
|
18
|
+
// that is not in the current package's lockfile. See notes.md §TODO:
|
|
19
|
+
// "Isolate npm pack from sibling file: dep junctions".
|
|
20
|
+
const missingMatch = blob.match(/missing from lockfile:\s*(\S+)/i);
|
|
21
|
+
const hasNullPackage = /cannot read propert(y|ies) of null \(reading 'package'\)/i.test(blob);
|
|
22
|
+
if (missingMatch && (hasNullPackage || /shrinkwrap failed to load/i.test(blob))) {
|
|
23
|
+
const nestedPath = missingMatch[1];
|
|
24
|
+
const sibling = resolveSiblingFromNestedPath(nestedPath, cwd, pkg);
|
|
25
|
+
const details = [
|
|
26
|
+
`npm arborist crashed walking a nested node_modules tree.`,
|
|
27
|
+
`Missing from lockfile: ${nestedPath}`,
|
|
28
|
+
];
|
|
29
|
+
if (sibling) {
|
|
30
|
+
return {
|
|
31
|
+
summary: `npm pack failed — arborist crashed on sibling's node_modules`,
|
|
32
|
+
details,
|
|
33
|
+
referencedModule: sibling.name,
|
|
34
|
+
hint: `sibling ${sibling.name} has its own populated node_modules; see notes.md §TODO: Isolate npm pack from sibling file: dep junctions`,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
summary: `npm pack failed — arborist crashed on a nested node_modules`,
|
|
39
|
+
details,
|
|
40
|
+
hint: `likely a file: dep whose target has its own node_modules; see notes.md §TODO: Isolate npm pack from sibling file: dep junctions`,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
// Pattern 2: arborist null-`package` without an obvious path — same class,
|
|
44
|
+
// no identifiable referenced module.
|
|
45
|
+
if (hasNullPackage) {
|
|
46
|
+
return {
|
|
47
|
+
summary: `npm pack failed — arborist internal error`,
|
|
48
|
+
details: [extractArboristFrame(blob) || 'Cannot read properties of null (reading \'package\')'],
|
|
49
|
+
hint: `likely a symlinked file: dep with its own node_modules; try renaming node_modules/ and running \`npm pack --dry-run\``,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
// Pattern 3: shrinkwrap / lockfile parsing without the arborist crash.
|
|
53
|
+
if (/enolock|shrinkwrap failed to load|eresolve/i.test(lower)) {
|
|
54
|
+
return {
|
|
55
|
+
summary: `npm pack failed — lockfile problem`,
|
|
56
|
+
details: [extractFirstNpmError(blob) || blob.trim().slice(0, 400)],
|
|
57
|
+
hint: `run \`npm install\` in ${cwd}, then retry`,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// Pattern 4: file-locking on the tarball (AV, editor, explorer preview).
|
|
61
|
+
if (/\be(acces|busy|perm)\b/i.test(blob) && /\.tgz\b/i.test(blob)) {
|
|
62
|
+
return {
|
|
63
|
+
summary: `npm pack failed — tarball file locked`,
|
|
64
|
+
details: [extractFirstNpmError(blob) || blob.trim().slice(0, 400)],
|
|
65
|
+
hint: `close editors / antivirus holding the .tgz, then retry`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
// Fallthrough: raw output.
|
|
69
|
+
return {
|
|
70
|
+
summary: `npm pack failed`,
|
|
71
|
+
details: [
|
|
72
|
+
output.trim() ? `Output: ${output.trim()}` : '',
|
|
73
|
+
stderr.trim() ? `Error: ${stderr.trim()}` : '',
|
|
74
|
+
].filter(Boolean),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/** Given a nested-node_modules path like
|
|
78
|
+
* `node_modules/@scope/sibling/node_modules/transitive`
|
|
79
|
+
* or `../sibling/node_modules/transitive`,
|
|
80
|
+
* find the outermost dep name and resolve it to a file: sibling declared
|
|
81
|
+
* in pkg.dependencies / pkg['.dependencies'] / etc. */
|
|
82
|
+
function resolveSiblingFromNestedPath(nestedPath, cwd, pkg) {
|
|
83
|
+
const normalized = nestedPath.replace(/\\/g, '/');
|
|
84
|
+
// Prefer the sibling-relative shape first: `../iflow-direct/node_modules/undici-types`.
|
|
85
|
+
// The *outermost* thing is the sibling dir, not the nested transitive.
|
|
86
|
+
const siblingMatch = normalized.match(/^(?:\.\.\/)+((?:@[^/]+\/)?[^/]+)\/node_modules\//);
|
|
87
|
+
if (siblingMatch) {
|
|
88
|
+
const absSibling = path.resolve(cwd, normalized.split('/node_modules/')[0]);
|
|
89
|
+
const resolved = findFileDepByPath(pkg, cwd, absSibling);
|
|
90
|
+
if (resolved)
|
|
91
|
+
return resolved;
|
|
92
|
+
return { name: siblingMatch[1], filePath: absSibling };
|
|
93
|
+
}
|
|
94
|
+
// Otherwise use the first `node_modules/<name>` segment.
|
|
95
|
+
const nmMatch = normalized.match(/(?:^|\/)node_modules\/((?:@[^/]+\/)?[^/]+)/);
|
|
96
|
+
const candidateName = nmMatch?.[1];
|
|
97
|
+
if (!candidateName)
|
|
98
|
+
return undefined;
|
|
99
|
+
// Try to confirm it's a file: dep by checking pkg.dependencies and .dependencies.
|
|
100
|
+
const allDeps = {};
|
|
101
|
+
for (const key of ['dependencies', '.dependencies', 'devDependencies', '.devDependencies']) {
|
|
102
|
+
if (pkg && pkg[key] && typeof pkg[key] === 'object')
|
|
103
|
+
Object.assign(allDeps, pkg[key]);
|
|
104
|
+
}
|
|
105
|
+
const spec = allDeps[candidateName];
|
|
106
|
+
if (spec && spec.startsWith('file:')) {
|
|
107
|
+
return { name: candidateName, filePath: path.resolve(cwd, spec.slice('file:'.length)) };
|
|
108
|
+
}
|
|
109
|
+
// Even if not explicitly file:, still useful to name it.
|
|
110
|
+
return { name: candidateName, filePath: path.resolve(cwd, 'node_modules', candidateName) };
|
|
111
|
+
}
|
|
112
|
+
/** Scan pkg deps for a file: entry whose resolved absolute path equals absTarget. */
|
|
113
|
+
function findFileDepByPath(pkg, cwd, absTarget) {
|
|
114
|
+
const target = path.resolve(absTarget).toLowerCase();
|
|
115
|
+
for (const key of ['dependencies', '.dependencies', 'devDependencies', '.devDependencies']) {
|
|
116
|
+
const deps = pkg && pkg[key];
|
|
117
|
+
if (!deps || typeof deps !== 'object')
|
|
118
|
+
continue;
|
|
119
|
+
for (const [name, spec] of Object.entries(deps)) {
|
|
120
|
+
if (typeof spec !== 'string' || !spec.startsWith('file:'))
|
|
121
|
+
continue;
|
|
122
|
+
const abs = path.resolve(cwd, spec.slice('file:'.length)).toLowerCase();
|
|
123
|
+
if (abs === target)
|
|
124
|
+
return { name, filePath: abs };
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
/** Pull out the first arborist stack frame for display. */
|
|
130
|
+
function extractArboristFrame(blob) {
|
|
131
|
+
const m = blob.match(/at [^\n]*arborist[^\n]*/i);
|
|
132
|
+
return m ? m[0].trim() : undefined;
|
|
133
|
+
}
|
|
134
|
+
/** Pull out the first `npm error <message>` line. */
|
|
135
|
+
function extractFirstNpmError(blob) {
|
|
136
|
+
const m = blob.match(/npm error [^\n]+/i);
|
|
137
|
+
return m ? m[0].trim() : undefined;
|
|
138
|
+
}
|
|
139
|
+
/** Exposed for ad-hoc testing — not used by the main flow. */
|
|
140
|
+
export const _test = { resolveSiblingFromNestedPath, findFileDepByPath };
|
|
141
|
+
//# sourceMappingURL=diagnose.js.map
|
package/lib/types.d.ts
CHANGED
|
@@ -82,6 +82,9 @@ export interface GlobalizeOptions {
|
|
|
82
82
|
local?: boolean;
|
|
83
83
|
/** Freeze node_modules: replace symlinks/junctions with real copies for network share use */
|
|
84
84
|
freeze?: boolean;
|
|
85
|
+
/** Before `npm pack`, delete `node_modules/` inside each `file:` dep target.
|
|
86
|
+
* Works around arborist crashes when siblings have nested node_modules. */
|
|
87
|
+
cleanNestedModules?: boolean;
|
|
85
88
|
/** Internal: signals this call is from workspace orchestrator */
|
|
86
89
|
_fromWorkspace?: boolean;
|
|
87
90
|
/** Internal: signals this call is from CLI (version already printed) */
|
package/lib.d.ts
CHANGED
|
@@ -95,6 +95,9 @@ export interface GlobalizeOptions {
|
|
|
95
95
|
local?: boolean;
|
|
96
96
|
/** Freeze node_modules: replace symlinks/junctions with real copies for network share use */
|
|
97
97
|
freeze?: boolean;
|
|
98
|
+
/** Before `npm pack`, delete `node_modules/` inside each `file:` dep target.
|
|
99
|
+
* Works around arborist crashes when siblings have nested node_modules. */
|
|
100
|
+
cleanNestedModules?: boolean;
|
|
98
101
|
/** Internal: auto-initialize git repos without prompting (user chose "all") */
|
|
99
102
|
autoInit?: boolean;
|
|
100
103
|
/** Internal: signals this call is from workspace orchestrator */
|
package/lib.js
CHANGED
|
@@ -31,6 +31,7 @@ import libversion from 'libnpmversion';
|
|
|
31
31
|
import JSON5 from 'json5';
|
|
32
32
|
import { fileURLToPath } from 'url';
|
|
33
33
|
import { themeColors } from '@bobfrankston/themecolors';
|
|
34
|
+
import { diagnoseNpmPackFailure } from './lib/diagnose.js';
|
|
34
35
|
/** Semantic color functions — adapts to terminal light/dark theme */
|
|
35
36
|
const colors = themeColors();
|
|
36
37
|
const _buildIssues = [];
|
|
@@ -235,7 +236,7 @@ export function writeConfig(dir, config, explicitKeys) {
|
|
|
235
236
|
const existing = readConfig(dir);
|
|
236
237
|
// Filter out temporary flags and default values (unless explicitly set)
|
|
237
238
|
const filtered = {};
|
|
238
|
-
const omitKeys = new Set(['cleanup', 'init', 'dryRun', 'message', 'conform', 'asis', 'help', 'error', 'updateDeps', 'updateMajor', 'publishDeps', 'forcePublish', 'once']);
|
|
239
|
+
const omitKeys = new Set(['cleanup', 'init', 'dryRun', 'message', 'conform', 'asis', 'help', 'error', 'updateDeps', 'updateMajor', 'publishDeps', 'forcePublish', 'once', 'cleanNestedModules']);
|
|
239
240
|
for (const [key, value] of Object.entries(config)) {
|
|
240
241
|
if (omitKeys.has(key))
|
|
241
242
|
continue;
|
|
@@ -1261,6 +1262,39 @@ function waitForNpmVersion(pkgName, version, maxWaitMs = 90000) {
|
|
|
1261
1262
|
process.stdout.write(' timed out\n');
|
|
1262
1263
|
return false;
|
|
1263
1264
|
}
|
|
1265
|
+
/** Delete `node_modules/` inside each `file:` dep target.
|
|
1266
|
+
* Works around arborist crashes during `npm pack` when sibling `file:` deps
|
|
1267
|
+
* have their own populated `node_modules/`. Returns the names of cleaned deps. */
|
|
1268
|
+
function cleanNestedDepModules(pkg, cwd, verbose) {
|
|
1269
|
+
const cleaned = [];
|
|
1270
|
+
const seen = new Set();
|
|
1271
|
+
for (const key of ['.dependencies', '.devDependencies', 'dependencies', 'devDependencies']) {
|
|
1272
|
+
const deps = pkg?.[key];
|
|
1273
|
+
if (!deps || typeof deps !== 'object')
|
|
1274
|
+
continue;
|
|
1275
|
+
for (const [name, spec] of Object.entries(deps)) {
|
|
1276
|
+
if (seen.has(name))
|
|
1277
|
+
continue;
|
|
1278
|
+
if (typeof spec !== 'string' || !spec.startsWith('file:'))
|
|
1279
|
+
continue;
|
|
1280
|
+
const target = path.resolve(cwd, spec.slice('file:'.length));
|
|
1281
|
+
const nm = path.join(target, 'node_modules');
|
|
1282
|
+
if (!fs.existsSync(nm))
|
|
1283
|
+
continue;
|
|
1284
|
+
seen.add(name);
|
|
1285
|
+
try {
|
|
1286
|
+
fs.rmSync(nm, { recursive: true, force: true });
|
|
1287
|
+
cleaned.push(name);
|
|
1288
|
+
if (verbose)
|
|
1289
|
+
console.log(colors.dim(` cleaned ${nm}`));
|
|
1290
|
+
}
|
|
1291
|
+
catch (e) {
|
|
1292
|
+
console.error(colors.yellow(` warning: could not clean ${nm}: ${e.message}`));
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
return cleaned;
|
|
1297
|
+
}
|
|
1264
1298
|
/** Run npm install -g with retries for registry propagation delay */
|
|
1265
1299
|
function installGlobalWithRetry(pkgSpec, cwd, maxRetries = 3) {
|
|
1266
1300
|
let result = runCommand('npm', ['install', '-g', pkgSpec], { cwd, silent: false, showCommand: true });
|
|
@@ -2976,7 +3010,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2976
3010
|
console.log(colors.yellow('Local branch is behind remote.'));
|
|
2977
3011
|
if (rebase) {
|
|
2978
3012
|
console.log('Rebasing local changes (--rebase)...');
|
|
2979
|
-
const rebaseResult = runCommand('git', ['pull', '--rebase'], { cwd, silent: false });
|
|
3013
|
+
const rebaseResult = runCommand('git', ['pull', '--rebase', 'origin', currentGitStatus.currentBranch], { cwd, silent: false });
|
|
2980
3014
|
if (!rebaseResult.success) {
|
|
2981
3015
|
console.error(colors.red('ERROR: Rebase failed.'));
|
|
2982
3016
|
console.error('You may need to resolve conflicts manually.');
|
|
@@ -3872,7 +3906,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3872
3906
|
}
|
|
3873
3907
|
// Pull latest from remote before version bump to avoid push rejection
|
|
3874
3908
|
if (currentGitStatus.hasRemote && !dryRun) {
|
|
3875
|
-
const pullResult = runCommand('git', ['pull', '--rebase'], { cwd, silent: true });
|
|
3909
|
+
const pullResult = runCommand('git', ['pull', '--rebase', 'origin', currentGitStatus.currentBranch], { cwd, silent: true });
|
|
3876
3910
|
if (!pullResult.success) {
|
|
3877
3911
|
console.error(colors.yellow('Warning: git pull --rebase failed before version bump'));
|
|
3878
3912
|
if (verbose) {
|
|
@@ -3973,7 +4007,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3973
4007
|
// Version bump + tag succeeded locally; only the push failed.
|
|
3974
4008
|
// Auto-pull --rebase and retry the push.
|
|
3975
4009
|
console.log(colors.yellow('\nLocal branch is behind remote — pulling with rebase...'));
|
|
3976
|
-
const pullResult = runCommand('git', ['pull', '--rebase'], { cwd });
|
|
4010
|
+
const pullResult = runCommand('git', ['pull', '--rebase', 'origin', currentGitStatus.currentBranch], { cwd });
|
|
3977
4011
|
if (pullResult.success) {
|
|
3978
4012
|
console.log(colors.green(' ✓ Rebased onto remote'));
|
|
3979
4013
|
const pushResult = runCommand('git', ['push'], { cwd });
|
|
@@ -4236,13 +4270,31 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
4236
4270
|
if (verbose) {
|
|
4237
4271
|
console.log(colors.green(`✓ Authenticated as ${authStatus.username}`));
|
|
4238
4272
|
}
|
|
4273
|
+
// Optionally clean nested node_modules in file: dep targets before pack
|
|
4274
|
+
if (options.cleanNestedModules) {
|
|
4275
|
+
const cleaned = cleanNestedDepModules(pkg, cwd, verbose);
|
|
4276
|
+
if (cleaned.length > 0) {
|
|
4277
|
+
console.log(colors.yellow(` Cleaned node_modules in ${cleaned.length} file: dep target(s): ${cleaned.join(', ')}`));
|
|
4278
|
+
}
|
|
4279
|
+
else if (verbose) {
|
|
4280
|
+
console.log(colors.dim(' --clean-nested-modules: nothing to clean'));
|
|
4281
|
+
}
|
|
4282
|
+
}
|
|
4239
4283
|
// Create tarball first
|
|
4240
4284
|
const packResult = runCommand('npm', ['pack'], { cwd, silent: true });
|
|
4241
4285
|
if (!packResult.success) {
|
|
4242
|
-
|
|
4243
|
-
console.error(colors.
|
|
4244
|
-
|
|
4245
|
-
|
|
4286
|
+
const d = diagnoseNpmPackFailure(cwd, packResult.output, packResult.stderr, pkg);
|
|
4287
|
+
console.error(colors.red(`ERROR: ${d.summary}`));
|
|
4288
|
+
for (const line of d.details)
|
|
4289
|
+
console.error(colors.yellow(' ' + line));
|
|
4290
|
+
if (d.referencedModule)
|
|
4291
|
+
console.error(colors.yellow(` Caused by referenced module: ${d.referencedModule}`));
|
|
4292
|
+
if (d.hint)
|
|
4293
|
+
console.error(colors.yellow(` Hint: ${d.hint}`));
|
|
4294
|
+
if (d.summary.includes('arborist') && !options.cleanNestedModules) {
|
|
4295
|
+
console.error(colors.yellow(` Retry with --clean-nested-modules to wipe node_modules/ inside each file: dep target`));
|
|
4296
|
+
}
|
|
4297
|
+
recordBuildIssue(pkg.name || path.basename(cwd), 'error', d.referencedModule ? `${d.summary} (via ${d.referencedModule})` : d.summary);
|
|
4246
4298
|
return false;
|
|
4247
4299
|
}
|
|
4248
4300
|
// Get the tarball filename from npm pack output
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobfrankston/npmglobalize",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.152",
|
|
4
4
|
"description": "Transform file: dependencies to npm versions for publishing",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@bobfrankston/freezepak": "^0.1.7",
|
|
35
|
-
"@bobfrankston/importgen": "^0.1.
|
|
35
|
+
"@bobfrankston/importgen": "^0.1.34",
|
|
36
36
|
"@bobfrankston/themecolors": "^0.1.5",
|
|
37
37
|
"@bobfrankston/userconfig": "^1.0.7",
|
|
38
38
|
"@npmcli/package-json": "^7.0.4",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
".transformedSnapshot": {
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"@bobfrankston/freezepak": "^0.1.7",
|
|
63
|
-
"@bobfrankston/importgen": "^0.1.
|
|
63
|
+
"@bobfrankston/importgen": "^0.1.34",
|
|
64
64
|
"@bobfrankston/themecolors": "^0.1.5",
|
|
65
65
|
"@bobfrankston/userconfig": "^1.0.7",
|
|
66
66
|
"@npmcli/package-json": "^7.0.4",
|