@bobfrankston/npmglobalize 1.0.108 → 1.0.110
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 +10 -0
- package/ignorepatterns.json5 +0 -1
- package/lib.d.ts +2 -0
- package/lib.js +100 -15
- package/package.json +3 -1
package/cli.js
CHANGED
|
@@ -40,6 +40,8 @@ Install Options:
|
|
|
40
40
|
-link Global install via symlink (npm install -g .)
|
|
41
41
|
-local Local install only — skip transform/publish, just npm install -g .
|
|
42
42
|
-wsl Also install globally in WSL
|
|
43
|
+
-freeze Freeze node_modules (replace symlinks with real copies for network shares)
|
|
44
|
+
-nofreeze Disable freeze
|
|
43
45
|
-once Don't persist flags to .globalize.json5
|
|
44
46
|
|
|
45
47
|
Mode Options:
|
|
@@ -283,6 +285,14 @@ function parseArgs(args) {
|
|
|
283
285
|
case '-pkg':
|
|
284
286
|
options.package = true;
|
|
285
287
|
break;
|
|
288
|
+
case '-freeze':
|
|
289
|
+
options.freeze = true;
|
|
290
|
+
options.explicitKeys.add('freeze');
|
|
291
|
+
break;
|
|
292
|
+
case '-nofreeze':
|
|
293
|
+
options.freeze = false;
|
|
294
|
+
options.explicitKeys.add('freeze');
|
|
295
|
+
break;
|
|
286
296
|
case '-once':
|
|
287
297
|
options.once = true;
|
|
288
298
|
break;
|
package/ignorepatterns.json5
CHANGED
package/lib.d.ts
CHANGED
|
@@ -74,6 +74,8 @@ export interface GlobalizeOptions {
|
|
|
74
74
|
once?: boolean;
|
|
75
75
|
/** Local install only — skip transform/publish, just npm install -g . */
|
|
76
76
|
local?: boolean;
|
|
77
|
+
/** Freeze node_modules: replace symlinks/junctions with real copies for network share use */
|
|
78
|
+
freeze?: boolean;
|
|
77
79
|
/** Internal: signals this call is from workspace orchestrator */
|
|
78
80
|
_fromWorkspace?: boolean;
|
|
79
81
|
/** Internal: signals this call is from CLI (version already printed) */
|
package/lib.js
CHANGED
|
@@ -13,6 +13,7 @@ import fs from 'fs';
|
|
|
13
13
|
import path from 'path';
|
|
14
14
|
import { execSync, spawnSync } from 'child_process';
|
|
15
15
|
import { readConfig as readUserConfig, writeConfig as writeUserConfig, configDir } from '@bobfrankston/userconfig';
|
|
16
|
+
import { freezeDependencies } from '@bobfrankston/freezepak';
|
|
16
17
|
/** Wrapper for spawnSync that avoids DEP0190 (args + shell: true).
|
|
17
18
|
* When shell is true, joins cmd+args into a single command string. */
|
|
18
19
|
function spawnSafe(cmd, args, options = {}) {
|
|
@@ -198,7 +199,8 @@ export function writeConfig(dir, config, explicitKeys) {
|
|
|
198
199
|
install: false,
|
|
199
200
|
wsl: false,
|
|
200
201
|
force: false,
|
|
201
|
-
verbose: false
|
|
202
|
+
verbose: false,
|
|
203
|
+
freeze: false
|
|
202
204
|
};
|
|
203
205
|
// Read existing config to preserve values
|
|
204
206
|
const existing = readConfig(dir);
|
|
@@ -257,6 +259,8 @@ export function writeConfig(dir, config, explicitKeys) {
|
|
|
257
259
|
comment = ' // Local install only (skip transform/publish)';
|
|
258
260
|
else if (key === 'noPublish')
|
|
259
261
|
comment = ' // Transform but don\'t publish';
|
|
262
|
+
else if (key === 'freeze')
|
|
263
|
+
comment = ' // Freeze node_modules (replace symlinks with real copies)';
|
|
260
264
|
lines.push(` "${key}": ${jsonValue}${comma}${comment}`);
|
|
261
265
|
});
|
|
262
266
|
lines.push('');
|
|
@@ -276,6 +280,7 @@ export function writeConfig(dir, config, explicitKeys) {
|
|
|
276
280
|
lines.push(' // "fix": false // Auto-run npm audit fix');
|
|
277
281
|
lines.push(' // "local": false // Local install only (skip transform/publish)');
|
|
278
282
|
lines.push(' // "noPublish": false // Transform but don\'t publish');
|
|
283
|
+
lines.push(' // "freeze": false // Freeze node_modules (replace symlinks with real copies)');
|
|
279
284
|
lines.push('}');
|
|
280
285
|
fs.writeFileSync(configPath, lines.join('\n') + '\n');
|
|
281
286
|
}
|
|
@@ -1870,7 +1875,7 @@ async function doLocalInstall(cwd, options) {
|
|
|
1870
1875
|
}
|
|
1871
1876
|
export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
1872
1877
|
const { bump = 'patch', noPublish = false, cleanup = false, install = false, link = false, wsl = false, force = false, files = true, dryRun = false, quiet = true, verbose = false, init = false, gitVisibility = 'private', npmVisibility = 'private', message, conform = false, asis = false, updateDeps = false, updateMajor = false, publishDeps = true, // Default to publishing deps for safety
|
|
1873
|
-
forcePublish = false, fix = false, fixTags = false, rebase = false, show = false, local = false } = options;
|
|
1878
|
+
forcePublish = false, fix = false, fixTags = false, rebase = false, show = false, local = false, freeze = false } = options;
|
|
1874
1879
|
// Show tool version only for recursive dep calls (CLI already prints it at startup)
|
|
1875
1880
|
const toolVersion = getToolVersion();
|
|
1876
1881
|
if (!options._fromWorkspace && !options._fromCli) {
|
|
@@ -1927,6 +1932,8 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
1927
1932
|
settings.push('--show');
|
|
1928
1933
|
if (configOptions.local)
|
|
1929
1934
|
settings.push('-local');
|
|
1935
|
+
if (configOptions.freeze)
|
|
1936
|
+
settings.push('-freeze');
|
|
1930
1937
|
if (settings.length > 0) {
|
|
1931
1938
|
console.log(colors.dim(`Settings from .globalize.json5: ${settings.join(', ')}`));
|
|
1932
1939
|
}
|
|
@@ -2687,6 +2694,16 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2687
2694
|
}
|
|
2688
2695
|
if (noPublish) {
|
|
2689
2696
|
console.log('Transform complete (--nopublish mode).');
|
|
2697
|
+
if (freeze && !dryRun) {
|
|
2698
|
+
console.log('Freezing node_modules (replacing symlinks with real copies)...');
|
|
2699
|
+
try {
|
|
2700
|
+
freezeDependencies(cwd);
|
|
2701
|
+
console.log(colors.green('✓ node_modules frozen'));
|
|
2702
|
+
}
|
|
2703
|
+
catch (error) {
|
|
2704
|
+
console.error(colors.red(`✗ Freeze failed: ${error.message}`));
|
|
2705
|
+
}
|
|
2706
|
+
}
|
|
2690
2707
|
if (files && transformResult.transformed) {
|
|
2691
2708
|
console.log('Restoring file: dependencies...');
|
|
2692
2709
|
const finalPkg = readPackageJson(cwd);
|
|
@@ -2705,6 +2722,16 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2705
2722
|
// Skip if private
|
|
2706
2723
|
if (pkg.private) {
|
|
2707
2724
|
console.log('Package is private - skipping npm publish.');
|
|
2725
|
+
if (freeze && !dryRun) {
|
|
2726
|
+
console.log('Freezing node_modules (replacing symlinks with real copies)...');
|
|
2727
|
+
try {
|
|
2728
|
+
freezeDependencies(cwd);
|
|
2729
|
+
console.log(colors.green('✓ node_modules frozen'));
|
|
2730
|
+
}
|
|
2731
|
+
catch (error) {
|
|
2732
|
+
console.error(colors.red(`✗ Freeze failed: ${error.message}`));
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2708
2735
|
if (files && transformResult.transformed) {
|
|
2709
2736
|
console.log('Restoring file: dependencies...');
|
|
2710
2737
|
const finalPkg = readPackageJson(cwd);
|
|
@@ -2870,6 +2897,19 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2870
2897
|
console.log(' [dry-run] Would commit changes');
|
|
2871
2898
|
}
|
|
2872
2899
|
}
|
|
2900
|
+
// Pull latest from remote before version bump to avoid push rejection
|
|
2901
|
+
if (currentGitStatus.hasRemote && !dryRun) {
|
|
2902
|
+
const pullResult = runCommand('git', ['pull', '--rebase'], { cwd, silent: true });
|
|
2903
|
+
if (!pullResult.success) {
|
|
2904
|
+
console.error(colors.yellow('Warning: git pull --rebase failed before version bump'));
|
|
2905
|
+
if (verbose) {
|
|
2906
|
+
console.error(' ' + pullResult.stderr);
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
else if (verbose) {
|
|
2910
|
+
console.log(' Pulled latest from remote');
|
|
2911
|
+
}
|
|
2912
|
+
}
|
|
2873
2913
|
// Version bump
|
|
2874
2914
|
console.log(`Bumping version (${bump})...`);
|
|
2875
2915
|
if (!dryRun) {
|
|
@@ -2915,6 +2955,7 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2915
2955
|
console.log(colors.green(`Version bumped to ${newVersion}`));
|
|
2916
2956
|
}
|
|
2917
2957
|
catch (error) {
|
|
2958
|
+
let autoFixed = false;
|
|
2918
2959
|
console.error(colors.red('ERROR: Version bump failed:'), error.message);
|
|
2919
2960
|
// Show additional error details if available
|
|
2920
2961
|
if (error.stderr || error.stdout || error.code) {
|
|
@@ -2933,16 +2974,41 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
2933
2974
|
const stderrLower = (error.stderr || '').toLowerCase();
|
|
2934
2975
|
const stdoutLower = (error.stdout || '').toLowerCase();
|
|
2935
2976
|
const combinedOutput = stderrLower + ' ' + stdoutLower;
|
|
2936
|
-
if (combinedOutput.includes('non-fast-forward') || combinedOutput.includes('rejected') && combinedOutput.includes('behind')) {
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
console.
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2977
|
+
if (combinedOutput.includes('non-fast-forward') || (combinedOutput.includes('rejected') && combinedOutput.includes('behind'))) {
|
|
2978
|
+
// Version bump + tag succeeded locally; only the push failed.
|
|
2979
|
+
// Auto-pull --rebase and retry the push.
|
|
2980
|
+
console.log(colors.yellow('\nLocal branch is behind remote — pulling with rebase...'));
|
|
2981
|
+
const pullResult = runCommand('git', ['pull', '--rebase'], { cwd });
|
|
2982
|
+
if (pullResult.success) {
|
|
2983
|
+
console.log(colors.green(' ✓ Rebased onto remote'));
|
|
2984
|
+
const pushResult = runCommand('git', ['push'], { cwd });
|
|
2985
|
+
if (pushResult.success) {
|
|
2986
|
+
const tagPush = runCommand('git', ['push', '--tags'], { cwd, silent: true });
|
|
2987
|
+
if (tagPush.success) {
|
|
2988
|
+
console.log(colors.green(' ✓ Pushed with tags'));
|
|
2989
|
+
}
|
|
2990
|
+
else {
|
|
2991
|
+
console.log(colors.green(' ✓ Pushed (tags may need manual push)'));
|
|
2992
|
+
}
|
|
2993
|
+
// Re-read version after successful rebase+push
|
|
2994
|
+
const rebased = readPackageJson(cwd);
|
|
2995
|
+
console.log(colors.green(`Version bumped to ${rebased.version}`));
|
|
2996
|
+
autoFixed = true;
|
|
2997
|
+
}
|
|
2998
|
+
else {
|
|
2999
|
+
console.error(colors.red('Push still failed after rebase.'));
|
|
3000
|
+
console.error(' Try: git push --force-with-lease');
|
|
3001
|
+
if (!force) {
|
|
3002
|
+
return false;
|
|
3003
|
+
}
|
|
3004
|
+
}
|
|
3005
|
+
}
|
|
3006
|
+
else {
|
|
3007
|
+
console.error(colors.red('Auto-rebase failed (likely merge conflict).'));
|
|
3008
|
+
console.error(' Resolve conflicts, then: git rebase --continue && git push');
|
|
3009
|
+
if (!force) {
|
|
3010
|
+
return false;
|
|
3011
|
+
}
|
|
2946
3012
|
}
|
|
2947
3013
|
}
|
|
2948
3014
|
else if (stderrLower.includes('tag') && stderrLower.includes('already exists')) {
|
|
@@ -3018,10 +3084,12 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3018
3084
|
console.error(' • Disk space or permissions issues');
|
|
3019
3085
|
console.error(colors.yellow('\nTry running with --verbose or check git status manually'));
|
|
3020
3086
|
}
|
|
3021
|
-
if (!
|
|
3022
|
-
|
|
3087
|
+
if (!autoFixed) {
|
|
3088
|
+
if (!force) {
|
|
3089
|
+
return false;
|
|
3090
|
+
}
|
|
3091
|
+
console.log(colors.yellow('Continuing with --force...'));
|
|
3023
3092
|
}
|
|
3024
|
-
console.log(colors.yellow('Continuing with --force...'));
|
|
3025
3093
|
}
|
|
3026
3094
|
}
|
|
3027
3095
|
else {
|
|
@@ -3302,6 +3370,20 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3302
3370
|
}
|
|
3303
3371
|
}
|
|
3304
3372
|
}
|
|
3373
|
+
// Freeze node_modules: replace symlinks/junctions with real copies
|
|
3374
|
+
if (freeze && !dryRun) {
|
|
3375
|
+
console.log('Freezing node_modules (replacing symlinks with real copies)...');
|
|
3376
|
+
try {
|
|
3377
|
+
freezeDependencies(cwd);
|
|
3378
|
+
console.log(colors.green('✓ node_modules frozen'));
|
|
3379
|
+
}
|
|
3380
|
+
catch (error) {
|
|
3381
|
+
console.error(colors.red(`✗ Freeze failed: ${error.message}`));
|
|
3382
|
+
}
|
|
3383
|
+
}
|
|
3384
|
+
else if (freeze && dryRun) {
|
|
3385
|
+
console.log(' [dry-run] Would freeze node_modules');
|
|
3386
|
+
}
|
|
3305
3387
|
// Finalize - restore file: paths if --files mode (default)
|
|
3306
3388
|
if (files && transformResult.transformed) {
|
|
3307
3389
|
console.log('Restoring file: dependencies (--files mode)...');
|
|
@@ -3350,6 +3432,9 @@ export async function globalize(cwd, options = {}, configOptions = {}) {
|
|
|
3350
3432
|
if (wsl) {
|
|
3351
3433
|
console.log(` Installed in WSL: ${colors.green('✓')}`);
|
|
3352
3434
|
}
|
|
3435
|
+
if (freeze) {
|
|
3436
|
+
console.log(` Frozen node_modules: ${colors.green('✓')}`);
|
|
3437
|
+
}
|
|
3353
3438
|
if (files && transformResult.transformed) {
|
|
3354
3439
|
console.log(` Restored file: deps: ${colors.green('✓')}`);
|
|
3355
3440
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobfrankston/npmglobalize",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.110",
|
|
4
4
|
"description": "Transform file: dependencies to npm versions for publishing",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"url": "https://github.com/BobFrankston/npmglobalize.git"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
+
"@bobfrankston/freezepak": "^0.1.4",
|
|
34
35
|
"@bobfrankston/userconfig": "^1.0.4",
|
|
35
36
|
"@npmcli/package-json": "^7.0.4",
|
|
36
37
|
"json5": "^2.2.3",
|
|
@@ -43,6 +44,7 @@
|
|
|
43
44
|
"access": "public"
|
|
44
45
|
},
|
|
45
46
|
".dependencies": {
|
|
47
|
+
"@bobfrankston/freezepak": "file:../freezepak",
|
|
46
48
|
"@bobfrankston/userconfig": "file:../userconfig",
|
|
47
49
|
"@npmcli/package-json": "^7.0.4",
|
|
48
50
|
"json5": "^2.2.3",
|