@vltpkg/cli-sdk 1.5.0 → 1.6.1
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/dist/commands/build.d.ts +8 -3
- package/dist/commands/build.js +31 -3
- package/dist/commands/ci.d.ts +1 -1
- package/dist/commands/create.d.ts +2 -1
- package/dist/commands/create.js +2 -3
- package/dist/commands/exec.d.ts +2 -1
- package/dist/commands/exec.js +2 -3
- package/dist/commands/init.js +5 -2
- package/dist/commands/install/reporter.d.ts +1 -1
- package/dist/commands/install/reporter.js +45 -5
- package/dist/commands/install.d.ts +21 -3
- package/dist/commands/install.js +84 -30
- package/dist/commands/list.js +5 -1
- package/dist/commands/query.js +5 -1
- package/dist/commands/setup.d.ts +28 -2
- package/dist/commands/setup.js +185 -3
- package/dist/commands/skills.js +2 -3
- package/dist/commands/token.js +1 -1
- package/dist/commands/uninstall.d.ts +10 -3
- package/dist/commands/uninstall.js +28 -2
- package/dist/commands/update.d.ts +1 -1
- package/dist/config/definition.d.ts +32 -0
- package/dist/config/definition.js +60 -0
- package/dist/config/index.d.ts +26 -3
- package/dist/config/index.js +149 -7
- package/dist/global-bin-dir.d.ts +37 -0
- package/dist/global-bin-dir.js +138 -0
- package/dist/global-project.d.ts +18 -0
- package/dist/global-project.js +67 -0
- package/dist/global-state.d.ts +24 -0
- package/dist/global-state.js +94 -0
- package/dist/global.d.ts +78 -0
- package/dist/global.js +409 -0
- package/dist/index.js +7 -2
- package/dist/install-receipt.d.ts +40 -0
- package/dist/install-receipt.js +69 -0
- package/dist/output.js +13 -0
- package/dist/pack-tarball.d.ts +3 -1
- package/dist/pack-tarball.js +29 -19
- package/dist/parse-add-remove-args.js +2 -14
- package/dist/query-auth.d.ts +3 -2
- package/dist/query-auth.js +6 -4
- package/dist/reload-config.js +2 -1
- package/dist/require-registry.d.ts +7 -0
- package/dist/require-registry.js +13 -1
- package/dist/self-update.d.ts +74 -0
- package/dist/self-update.js +401 -0
- package/dist/shell-setup/env.d.ts +9 -0
- package/dist/shell-setup/env.js +25 -0
- package/dist/shell-setup/index.d.ts +69 -0
- package/dist/shell-setup/index.js +213 -0
- package/dist/shell-setup/posix.d.ts +36 -0
- package/dist/shell-setup/posix.js +158 -0
- package/dist/shell-setup/windows.d.ts +39 -0
- package/dist/shell-setup/windows.js +151 -0
- package/dist/shell.d.ts +18 -0
- package/dist/shell.js +110 -0
- package/dist/telemetry.js +8 -1
- package/package.json +30 -28
package/dist/commands/build.d.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import type { BuildResult } from '@vltpkg/graph';
|
|
2
|
+
import type { GlobalBins } from '../global.ts';
|
|
2
3
|
import type { CommandFn, CommandUsage } from '../index.ts';
|
|
4
|
+
export type BuildCommandResult = BuildResult & {
|
|
5
|
+
global?: GlobalBins;
|
|
6
|
+
};
|
|
3
7
|
export declare const views: {
|
|
4
|
-
readonly human: (result:
|
|
5
|
-
readonly json: (result:
|
|
8
|
+
readonly human: (result: BuildCommandResult) => string;
|
|
9
|
+
readonly json: (result: BuildCommandResult) => {
|
|
10
|
+
global?: GlobalBins | undefined;
|
|
6
11
|
message: string;
|
|
7
12
|
skipped?: {
|
|
8
13
|
id: import("@vltpkg/dep-id").DepID;
|
|
@@ -28,4 +33,4 @@ export declare const usage: CommandUsage;
|
|
|
28
33
|
* Build command implementation. Runs any required "postinstall"
|
|
29
34
|
* lifecycle scripts and binary linking.
|
|
30
35
|
*/
|
|
31
|
-
export declare const command: CommandFn<
|
|
36
|
+
export declare const command: CommandFn<BuildCommandResult>;
|
package/dist/commands/build.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { build } from '@vltpkg/graph';
|
|
1
|
+
import { actual, build } from '@vltpkg/graph';
|
|
2
2
|
import { error } from '@vltpkg/error-cause';
|
|
3
3
|
import { commandUsage } from "../config/usage.js";
|
|
4
|
+
import { globalBinsLines, linkGlobalBins } from "../global.js";
|
|
5
|
+
import { resolveGlobalBinDir } from "../global-bin-dir.js";
|
|
4
6
|
import { isErrorWithCause } from '@vltpkg/types';
|
|
5
7
|
const skippedMessage = (count, reason) => `${count} package${count === 1 ? '' : 's'} not built, ${reason === 'unscanned' ?
|
|
6
8
|
'Socket has not scanned them yet'
|
|
@@ -23,6 +25,8 @@ export const views = {
|
|
|
23
25
|
if (skippedCount > 0) {
|
|
24
26
|
messages.push(`⏳ ${skippedMessage(skippedCount, result.skippedReason)}`);
|
|
25
27
|
}
|
|
28
|
+
if (result.global)
|
|
29
|
+
messages.push(...globalBinsLines(result.global));
|
|
26
30
|
return messages.join('\n');
|
|
27
31
|
},
|
|
28
32
|
json: (result) => {
|
|
@@ -45,6 +49,7 @@ export const views = {
|
|
|
45
49
|
: skippedList.length ?
|
|
46
50
|
skippedMessage(skippedList.length, result.skippedReason)
|
|
47
51
|
: 'No packages needed building.',
|
|
52
|
+
...(result.global ? { global: result.global } : null),
|
|
48
53
|
};
|
|
49
54
|
},
|
|
50
55
|
};
|
|
@@ -68,6 +73,9 @@ export const usage = () => commandUsage({
|
|
|
68
73
|
value: '<query>',
|
|
69
74
|
description: 'Query selector to filter packages using DSS syntax.',
|
|
70
75
|
},
|
|
76
|
+
global: {
|
|
77
|
+
description: 'Build packages installed in the global project.',
|
|
78
|
+
},
|
|
71
79
|
},
|
|
72
80
|
});
|
|
73
81
|
const isGraphRunError = (error) => typeof error === 'object' &&
|
|
@@ -81,6 +89,8 @@ const isGraphRunError = (error) => typeof error === 'object' &&
|
|
|
81
89
|
*/
|
|
82
90
|
export const command = async (conf) => {
|
|
83
91
|
const { options, projectRoot } = conf;
|
|
92
|
+
const binDir = conf.globalRoot ? await resolveGlobalBinDir(conf) : undefined;
|
|
93
|
+
let result;
|
|
84
94
|
try {
|
|
85
95
|
// Get target from option or first positional, default to all scripts
|
|
86
96
|
const targetOption = conf.get('target');
|
|
@@ -89,7 +99,7 @@ export const command = async (conf) => {
|
|
|
89
99
|
targetPositional ||
|
|
90
100
|
':scripts:not(:built):not(:malware)';
|
|
91
101
|
// Run the build process using the graph build function
|
|
92
|
-
|
|
102
|
+
result = await build({
|
|
93
103
|
...options,
|
|
94
104
|
projectRoot,
|
|
95
105
|
packageJson: options.packageJson,
|
|
@@ -97,7 +107,6 @@ export const command = async (conf) => {
|
|
|
97
107
|
scurry: options.scurry,
|
|
98
108
|
target,
|
|
99
109
|
});
|
|
100
|
-
return result;
|
|
101
110
|
}
|
|
102
111
|
catch (cause) {
|
|
103
112
|
const graphRunError = isErrorWithCause(cause) && isGraphRunError(cause.cause) ?
|
|
@@ -109,4 +118,23 @@ export const command = async (conf) => {
|
|
|
109
118
|
}
|
|
110
119
|
throw error('Build failed', { cause });
|
|
111
120
|
}
|
|
121
|
+
if (!binDir)
|
|
122
|
+
return result;
|
|
123
|
+
// relink global bins, targets may be new
|
|
124
|
+
const graph = actual.load({
|
|
125
|
+
...options,
|
|
126
|
+
projectRoot,
|
|
127
|
+
mainManifest: options.packageJson.read(projectRoot),
|
|
128
|
+
monorepo: options.monorepo,
|
|
129
|
+
scurry: options.scurry,
|
|
130
|
+
loadManifests: true,
|
|
131
|
+
});
|
|
132
|
+
const global = await linkGlobalBins(graph, {
|
|
133
|
+
projectRoot,
|
|
134
|
+
scurry: options.scurry,
|
|
135
|
+
force: options.force,
|
|
136
|
+
binDir,
|
|
137
|
+
fallback: () => resolveGlobalBinDir(conf, { selfUnwritable: true }),
|
|
138
|
+
});
|
|
139
|
+
return { ...result, global };
|
|
112
140
|
};
|
package/dist/commands/ci.d.ts
CHANGED
|
@@ -6,6 +6,6 @@ export declare const needsNpmRegistry = true;
|
|
|
6
6
|
export declare const usage: CommandUsage;
|
|
7
7
|
export declare const views: {
|
|
8
8
|
readonly json: (i: CIResult) => import("@vltpkg/graph").LockfileData;
|
|
9
|
-
readonly human: import("../view.ts").LazyView<InstallResult
|
|
9
|
+
readonly human: import("../view.ts").LazyView<Partial<InstallResult>>;
|
|
10
10
|
};
|
|
11
11
|
export declare const command: CommandFn<CIResult>;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { PromptFn } from '@vltpkg/vlx';
|
|
2
2
|
import type { ExecResult } from '../exec-command.ts';
|
|
3
3
|
import type { CommandFn, CommandUsage } from '../index.ts';
|
|
4
|
+
import { prettyPath } from '../shell.ts';
|
|
4
5
|
export { views } from '../exec-command.ts';
|
|
5
6
|
export declare const needsRegistry = true;
|
|
6
7
|
export declare const usage: CommandUsage;
|
|
7
|
-
export
|
|
8
|
+
export { prettyPath };
|
|
8
9
|
export declare const promptFn: PromptFn;
|
|
9
10
|
export declare const command: CommandFn<ExecResult>;
|
package/dist/commands/create.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { exec, execFG } from '@vltpkg/run';
|
|
2
2
|
import * as vlx from '@vltpkg/vlx';
|
|
3
|
-
import { homedir } from 'node:os';
|
|
4
3
|
import { createInterface } from 'node:readline/promises';
|
|
5
4
|
import { commandUsage } from "../config/usage.js";
|
|
6
5
|
import { ExecCommand } from "../exec-command.js";
|
|
7
6
|
import { styleTextStdout } from "../output.js";
|
|
7
|
+
import { prettyPath } from "../shell.js";
|
|
8
8
|
export { views } from "../exec-command.js";
|
|
9
9
|
export const needsRegistry = true;
|
|
10
10
|
export const usage = () => commandUsage({
|
|
@@ -47,8 +47,7 @@ export const usage = () => commandUsage({
|
|
|
47
47
|
},
|
|
48
48
|
},
|
|
49
49
|
});
|
|
50
|
-
|
|
51
|
-
export const prettyPath = (path) => path.startsWith(HOME) ? `~${path.substring(HOME.length)}` : path;
|
|
50
|
+
export { prettyPath };
|
|
52
51
|
export const promptFn = async (pkgSpec, path, resolution) => {
|
|
53
52
|
const response = await createInterface(process.stdin, process.stdout).question(`About to install: ${styleTextStdout(['bgWhiteBright', 'black', 'bold'], String(pkgSpec))}
|
|
54
53
|
from: ${styleTextStdout(['bgWhiteBright', 'black', 'bold'], resolution)}
|
package/dist/commands/exec.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { PromptFn } from '@vltpkg/vlx';
|
|
2
2
|
import type { ExecResult } from '../exec-command.ts';
|
|
3
3
|
import type { CommandFn, CommandUsage } from '../index.ts';
|
|
4
|
+
import { prettyPath } from '../shell.ts';
|
|
4
5
|
export { views } from '../exec-command.ts';
|
|
5
6
|
export declare const needsRegistry = true;
|
|
6
7
|
export declare const needsNpmRegistry = true;
|
|
7
8
|
export declare const usage: CommandUsage;
|
|
8
|
-
export
|
|
9
|
+
export { prettyPath };
|
|
9
10
|
export declare const promptFn: PromptFn;
|
|
10
11
|
export declare const command: CommandFn<ExecResult>;
|
package/dist/commands/exec.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { exec, execFG } from '@vltpkg/run';
|
|
2
2
|
import * as vlx from '@vltpkg/vlx';
|
|
3
|
-
import { homedir } from 'node:os';
|
|
4
3
|
import { env, platform } from 'node:process';
|
|
5
4
|
import { createInterface } from 'node:readline/promises';
|
|
6
5
|
import { commandUsage } from "../config/usage.js";
|
|
7
6
|
import { ExecCommand } from "../exec-command.js";
|
|
8
7
|
import { styleTextStdout } from "../output.js";
|
|
8
|
+
import { prettyPath } from "../shell.js";
|
|
9
9
|
export { views } from "../exec-command.js";
|
|
10
10
|
export const needsRegistry = true;
|
|
11
11
|
export const needsNpmRegistry = true;
|
|
@@ -113,8 +113,7 @@ export const usage = () => commandUsage({
|
|
|
113
113
|
},
|
|
114
114
|
},
|
|
115
115
|
});
|
|
116
|
-
|
|
117
|
-
export const prettyPath = (path) => path.startsWith(HOME) ? `~${path.substring(HOME.length)}` : path;
|
|
116
|
+
export { prettyPath };
|
|
118
117
|
export const promptFn = async (pkgSpec, path, resolution) => {
|
|
119
118
|
const response = await createInterface(process.stdin, process.stdout).question(`About to install: ${styleTextStdout(['bgWhiteBright', 'black', 'bold'], String(pkgSpec))}
|
|
120
119
|
from: ${styleTextStdout(['bgWhiteBright', 'black', 'bold'], resolution)}
|
package/dist/commands/init.js
CHANGED
|
@@ -76,7 +76,7 @@ export const command = async (conf) => {
|
|
|
76
76
|
// create the folder in case it's missing
|
|
77
77
|
mkdirSync(cwd, { recursive: true });
|
|
78
78
|
// run the initialization script and collect results
|
|
79
|
-
results.push(await init({ cwd }));
|
|
79
|
+
results.push(await init({ cwd, packageJson: conf.options.packageJson }));
|
|
80
80
|
// Check if this workspace path is covered by existing workspace patterns
|
|
81
81
|
const isMatched = Object.values(parsedWSConfig).some((group) => {
|
|
82
82
|
const { patterns, ignore } = splitNegatedPatterns(group);
|
|
@@ -136,7 +136,10 @@ export const command = async (conf) => {
|
|
|
136
136
|
await install({ ...conf.options, allowScripts });
|
|
137
137
|
return results;
|
|
138
138
|
}
|
|
139
|
-
const result = await init({
|
|
139
|
+
const result = await init({
|
|
140
|
+
cwd: process.cwd(),
|
|
141
|
+
packageJson: conf.options.packageJson,
|
|
142
|
+
});
|
|
140
143
|
// run install to set up node_modules and vlt-lock.json
|
|
141
144
|
await install({ ...conf.options, allowScripts });
|
|
142
145
|
return result;
|
|
@@ -3,7 +3,7 @@ import type { InstallResult } from '../install.ts';
|
|
|
3
3
|
export declare class InstallReporter extends ViewClass {
|
|
4
4
|
#private;
|
|
5
5
|
start(): void;
|
|
6
|
-
done(_result: InstallResult
|
|
6
|
+
done(_result: Partial<InstallResult>, { time }: {
|
|
7
7
|
time: number;
|
|
8
8
|
}): Promise<undefined>;
|
|
9
9
|
error(err: unknown): void;
|
|
@@ -4,8 +4,11 @@ import Spinner from 'ink-spinner';
|
|
|
4
4
|
import { createElement as $, Fragment, useEffect, useState, } from 'react';
|
|
5
5
|
import { ViewClass } from "../../view.js";
|
|
6
6
|
import { asError } from '@vltpkg/types';
|
|
7
|
+
import { isSelfUpdateArgs, selfUpdateLines, } from "../../self-update.js";
|
|
7
8
|
import { persistedEntries } from "../../persist-spec-config.js";
|
|
8
9
|
import { keptLine, savedLine, unmatchedLines, unscannedLines, } from "../../allow-skills.js";
|
|
10
|
+
import { globalBinsLines } from "../../global.js";
|
|
11
|
+
import { offerPathSetup } from "../../shell-setup/index.js";
|
|
9
12
|
const labels = {
|
|
10
13
|
build: 'resolving dependencies',
|
|
11
14
|
actual: '',
|
|
@@ -75,6 +78,7 @@ const App = ({ trailer }) => {
|
|
|
75
78
|
};
|
|
76
79
|
export class InstallReporter extends ViewClass {
|
|
77
80
|
#instance = null;
|
|
81
|
+
#plain = false;
|
|
78
82
|
start() {
|
|
79
83
|
// Ink measures the terminal on every render, and when stdout has no
|
|
80
84
|
// width (a pipe, a CI log) it does so by spawning `tput cols` and
|
|
@@ -87,17 +91,35 @@ export class InstallReporter extends ViewClass {
|
|
|
87
91
|
process.stdout.columns ||=
|
|
88
92
|
Number.isInteger(cols) && cols > 0 ? cols : 80;
|
|
89
93
|
}
|
|
94
|
+
// npm may write to the terminal: no live view
|
|
95
|
+
if (isSelfUpdateArgs(this.config)) {
|
|
96
|
+
this.#plain = true;
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
90
99
|
this.#instance = render($(App));
|
|
91
100
|
}
|
|
92
101
|
async done(_result, { time }) {
|
|
93
|
-
|
|
102
|
+
const { self } = _result;
|
|
103
|
+
let out = self && !_result.graph ? '' : `Done in ${time}ms`;
|
|
94
104
|
// prints a very complete message explaining users the next steps
|
|
95
105
|
// in case there are packages to be built
|
|
106
|
+
const g = _result.global ? ' -g' : '';
|
|
96
107
|
if (_result.buildQueue?.length) {
|
|
97
108
|
out += `\n\n📦 ${_result.buildQueue.length} packages have install scripts defined & were not fully built\n`;
|
|
98
|
-
out +=
|
|
99
|
-
out +=
|
|
100
|
-
|
|
109
|
+
out += `🔎 Run \`vlt query${g} :scripts\` to list them\n`;
|
|
110
|
+
out += `🔨 Run \`vlt build${g}\` to run all required scripts to build installed packages.\n`;
|
|
111
|
+
}
|
|
112
|
+
if (self) {
|
|
113
|
+
for (const l of selfUpdateLines(self))
|
|
114
|
+
out += out ? `\n${l}` : l;
|
|
115
|
+
}
|
|
116
|
+
if (_result.global) {
|
|
117
|
+
// the self-update line says why
|
|
118
|
+
const bins = self?.status === 'updated' && self.case === 'bootstrap' ?
|
|
119
|
+
{ ..._result.global, notWritable: undefined }
|
|
120
|
+
: _result.global;
|
|
121
|
+
for (const l of globalBinsLines(bins))
|
|
122
|
+
out += `\n${l}`;
|
|
101
123
|
}
|
|
102
124
|
const { linked = [], removed = [], conflicts = [], skipped = [], gitignore = [], unmatched = [], } = _result.skills ?? {};
|
|
103
125
|
const s = (n) => (n === 1 ? '' : 's');
|
|
@@ -139,7 +161,25 @@ export class InstallReporter extends ViewClass {
|
|
|
139
161
|
out += `\n${keptLine(a.stored)}`;
|
|
140
162
|
else if (a)
|
|
141
163
|
out += `\n${savedLine(a.query, 'project')}`;
|
|
142
|
-
|
|
164
|
+
// failed: npm already said why
|
|
165
|
+
if (!out)
|
|
166
|
+
return undefined;
|
|
167
|
+
if (this.#plain)
|
|
168
|
+
this.#instance = render($(Text, null, out));
|
|
169
|
+
else
|
|
170
|
+
this.#instance?.rerender($(App, { trailer: out }));
|
|
171
|
+
if (_result.global) {
|
|
172
|
+
await offerPathSetup(_result.global, {
|
|
173
|
+
globalDir: this.config.projectRoot,
|
|
174
|
+
yes: !!this.config.get('yes'),
|
|
175
|
+
noModifyPath: !!this.config.get('no-modify-path'),
|
|
176
|
+
// ink owns the terminal until unmounted
|
|
177
|
+
beforeOutput: () => {
|
|
178
|
+
this.#instance?.unmount();
|
|
179
|
+
this.#instance = null;
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
}
|
|
143
183
|
return undefined;
|
|
144
184
|
}
|
|
145
185
|
error(err) {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { AllowSkillsSave } from '../allow-skills.ts';
|
|
2
|
+
import type { GlobalBins } from '../global.ts';
|
|
3
|
+
import type { SelfUpdate } from '../self-update.ts';
|
|
2
4
|
import type { MigratedWorkspaces } from '../migrate-workspaces.ts';
|
|
3
5
|
import type { SpecConfigPersistPlan } from '../persist-spec-config.ts';
|
|
4
6
|
import type { DepID } from '@vltpkg/dep-id';
|
|
@@ -37,12 +39,28 @@ export type InstallResult = {
|
|
|
37
39
|
* is stored.
|
|
38
40
|
*/
|
|
39
41
|
allowSkills?: AllowSkillsSave;
|
|
42
|
+
/**
|
|
43
|
+
* Bins linked by a `--global` install.
|
|
44
|
+
*/
|
|
45
|
+
global?: GlobalBins;
|
|
46
|
+
/**
|
|
47
|
+
* `vlt install -g vlt`
|
|
48
|
+
*/
|
|
49
|
+
self?: SelfUpdate;
|
|
50
|
+
};
|
|
51
|
+
/** self-update handed off or nothing to do */
|
|
52
|
+
export type InstallCommandResult = InstallResult | {
|
|
53
|
+
self: SelfUpdate;
|
|
40
54
|
};
|
|
41
55
|
export declare const needsRegistry = true;
|
|
42
56
|
export declare const needsNpmRegistry = true;
|
|
43
57
|
export declare const usage: CommandUsage;
|
|
44
58
|
export declare const views: {
|
|
45
|
-
readonly json: (i:
|
|
59
|
+
readonly json: (i: InstallCommandResult) => {
|
|
60
|
+
self: SelfUpdate;
|
|
61
|
+
} | {
|
|
62
|
+
self?: SelfUpdate | undefined;
|
|
63
|
+
global?: GlobalBins | undefined;
|
|
46
64
|
allowSkills?: AllowSkillsSave | undefined;
|
|
47
65
|
skills?: {
|
|
48
66
|
unscanned?: string[];
|
|
@@ -76,6 +94,6 @@ export declare const views: {
|
|
|
76
94
|
}[];
|
|
77
95
|
removed: number;
|
|
78
96
|
};
|
|
79
|
-
readonly human: import("../view.ts").LazyView<InstallResult
|
|
97
|
+
readonly human: import("../view.ts").LazyView<Partial<InstallResult>>;
|
|
80
98
|
};
|
|
81
|
-
export declare const command: CommandFn<
|
|
99
|
+
export declare const command: CommandFn<InstallCommandResult>;
|
package/dist/commands/install.js
CHANGED
|
@@ -2,6 +2,9 @@ import { commandUsage } from "../config/usage.js";
|
|
|
2
2
|
import { install } from '@vltpkg/graph';
|
|
3
3
|
import { saveAllowSkills } from "../allow-skills.js";
|
|
4
4
|
import { parseAddArgs } from "../parse-add-remove-args.js";
|
|
5
|
+
import { assertGlobalOptions, linkGlobalBins, parseGlobalAddArgs, removeGlobalWorkspaces, } from "../global.js";
|
|
6
|
+
import { resolveGlobalBinDir } from "../global-bin-dir.js";
|
|
7
|
+
import { deferSelfRemove, runningStoreDep, selfUpdate, } from "../self-update.js";
|
|
5
8
|
import { planSpecConfigPersist } from "../persist-spec-config.js";
|
|
6
9
|
import { asUnknownSpecPrefix } from "../require-registry.js";
|
|
7
10
|
import { addTypesDeps } from "../save-types.js";
|
|
@@ -69,6 +72,9 @@ export const usage = () => commandUsage({
|
|
|
69
72
|
value: '<query>',
|
|
70
73
|
description: "Link agent skills of packages matching this DSS query into the project's agent skill dirs. Saved to vlt.json.",
|
|
71
74
|
},
|
|
75
|
+
global: {
|
|
76
|
+
description: 'Install packages globally, each in its own workspace of the global project, linking their bins. `vlt install -g vlt` updates vlt itself.',
|
|
77
|
+
},
|
|
72
78
|
},
|
|
73
79
|
});
|
|
74
80
|
// link mounts; `unchanged` left out
|
|
@@ -78,6 +84,8 @@ const skillsJson = ({ linked, unchanged: _, ...rest }) => ({
|
|
|
78
84
|
});
|
|
79
85
|
export const views = {
|
|
80
86
|
json: i => {
|
|
87
|
+
if (!('graph' in i))
|
|
88
|
+
return { self: i.self };
|
|
81
89
|
const added = i.diff?.nodes.add ?? new Set();
|
|
82
90
|
const deleted = i.diff?.nodes.delete ?? new Set();
|
|
83
91
|
// The actual (from) graph represents what was on disk before the install.
|
|
@@ -131,7 +139,7 @@ export const views = {
|
|
|
131
139
|
...(i.buildQueue?.length ?
|
|
132
140
|
{
|
|
133
141
|
buildQueue: i.buildQueue,
|
|
134
|
-
message: `${i.buildQueue.length} packages that will need to be built, run "vlt build" to complete the install.`,
|
|
142
|
+
message: `${i.buildQueue.length} packages that will need to be built, run "vlt build${i.global ? ' -g' : ''}" to complete the install.`,
|
|
135
143
|
}
|
|
136
144
|
: null),
|
|
137
145
|
...(i.persistedConfig ?
|
|
@@ -142,6 +150,8 @@ export const views = {
|
|
|
142
150
|
: null),
|
|
143
151
|
...(i.skills ? { skills: skillsJson(i.skills) } : null),
|
|
144
152
|
...(i.allowSkills ? { allowSkills: i.allowSkills } : null),
|
|
153
|
+
...(i.global ? { global: i.global } : null),
|
|
154
|
+
...(i.self ? { self: i.self } : null),
|
|
145
155
|
};
|
|
146
156
|
},
|
|
147
157
|
human: lazyView(async () => (await import('./install/reporter.ts')).InstallReporter),
|
|
@@ -149,42 +159,52 @@ export const views = {
|
|
|
149
159
|
export const command = async (conf) => {
|
|
150
160
|
// TODO: we should probably throw an error if the user
|
|
151
161
|
// tries to install using view=mermaid
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
162
|
+
if (conf.globalRoot)
|
|
163
|
+
assertGlobalOptions(conf);
|
|
164
|
+
// throws before any global ws dir is created
|
|
155
165
|
const persist = planSpecConfigPersist(conf);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
const
|
|
166
|
+
// vlt i -g vlt: before any global ws or bin dir is created
|
|
167
|
+
const selfPlan = await selfUpdate(conf);
|
|
168
|
+
if (selfPlan && 'done' in selfPlan)
|
|
169
|
+
return { self: selfPlan.done };
|
|
170
|
+
const binDir = conf.globalRoot ?
|
|
171
|
+
await resolveGlobalBinDir(conf, {
|
|
172
|
+
selfUnwritable: !!selfPlan?.selfUnwritable,
|
|
173
|
+
})
|
|
174
|
+
: undefined;
|
|
175
|
+
// before reading options, it may reset them
|
|
176
|
+
const globalAdd = conf.globalRoot ? await parseGlobalAddArgs(conf) : undefined;
|
|
177
|
+
// never removed from under itself
|
|
178
|
+
const keep = conf.globalRoot ?
|
|
179
|
+
await runningStoreDep(conf.globalRoot)
|
|
180
|
+
: undefined;
|
|
169
181
|
const installStart = Date.now();
|
|
170
|
-
const { buildQueue, graph, diff, skills } = await
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
expectLockfile,
|
|
174
|
-
allowScripts,
|
|
175
|
-
allowSkills,
|
|
176
|
-
skillsDirs: conf.get('skills-dir'),
|
|
177
|
-
lockfileOnly,
|
|
178
|
-
saveExact,
|
|
179
|
-
savePrefix,
|
|
180
|
-
}, add).catch((er) => {
|
|
182
|
+
const { buildQueue, graph, diff, skills } = await runInstall(conf, globalAdd?.add, keep).catch(async (er) => {
|
|
183
|
+
if (globalAdd)
|
|
184
|
+
await removeGlobalWorkspaces(globalAdd.created);
|
|
181
185
|
throw asUnknownSpecPrefix(er);
|
|
182
186
|
});
|
|
183
|
-
const migrated =
|
|
187
|
+
const migrated = (conf.options['frozen-lockfile'] ||
|
|
188
|
+
conf.options['expect-lockfile']) ?
|
|
189
|
+
undefined
|
|
190
|
+
: migrateWorkspaces(conf);
|
|
191
|
+
if (conf.globalRoot)
|
|
192
|
+
await deferSelfRemove(conf.globalRoot, graph, keep);
|
|
193
|
+
const global = globalAdd &&
|
|
194
|
+
binDir &&
|
|
195
|
+
(await linkGlobalBins(graph, {
|
|
196
|
+
projectRoot: conf.options.projectRoot,
|
|
197
|
+
scurry: conf.options.scurry,
|
|
198
|
+
force: conf.options.force,
|
|
199
|
+
binDir,
|
|
200
|
+
fallback: () => resolveGlobalBinDir(conf, { selfUnwritable: true }),
|
|
201
|
+
}, globalAdd.importers));
|
|
184
202
|
if (persist)
|
|
185
203
|
await conf.addConfigToFile(persist.which, persist.values);
|
|
186
204
|
// nothing linked on --lockfile-only
|
|
187
|
-
const allowSkillsSave =
|
|
205
|
+
const allowSkillsSave = conf.options['lockfile-only'] ?
|
|
206
|
+
undefined
|
|
207
|
+
: await saveAllowSkills(conf);
|
|
188
208
|
/* c8 ignore next 9 - telemetry is best-effort */
|
|
189
209
|
try {
|
|
190
210
|
trackInstall({
|
|
@@ -201,5 +221,39 @@ export const command = async (conf) => {
|
|
|
201
221
|
...(migrated ? { migratedWorkspaces: migrated } : null),
|
|
202
222
|
...(skills ? { skills } : null),
|
|
203
223
|
...(allowSkillsSave ? { allowSkills: allowSkillsSave } : null),
|
|
224
|
+
...(global ? { global } : null),
|
|
225
|
+
...(selfPlan ? { self: await selfPlan.finish(global) } : null),
|
|
204
226
|
};
|
|
205
227
|
};
|
|
228
|
+
// async, so any throw rolls back global ws dirs
|
|
229
|
+
const runInstall = async (conf, globalAdd, keep) => {
|
|
230
|
+
const monorepo = conf.options.monorepo;
|
|
231
|
+
const scurry = conf.options.scurry;
|
|
232
|
+
const add = globalAdd ?? parseAddArgs(conf, scurry, monorepo).add;
|
|
233
|
+
// global ws has only the package as dep
|
|
234
|
+
if (conf.values['save-types'] && !globalAdd)
|
|
235
|
+
await addTypesDeps(conf, add);
|
|
236
|
+
const frozenLockfile = conf.options['frozen-lockfile'];
|
|
237
|
+
const expectLockfile = conf.options['expect-lockfile'];
|
|
238
|
+
const lockfileOnly = conf.options['lockfile-only'];
|
|
239
|
+
const saveExact = conf.values['save-exact'];
|
|
240
|
+
const savePrefix = conf.values['save-prefix'];
|
|
241
|
+
/* c8 ignore start */
|
|
242
|
+
const allowScripts = conf.get('allow-scripts') ?
|
|
243
|
+
String(conf.get('allow-scripts'))
|
|
244
|
+
: ':not(*)';
|
|
245
|
+
/* c8 ignore stop */
|
|
246
|
+
const allowSkills = conf.get('allow-skills');
|
|
247
|
+
return install({
|
|
248
|
+
...conf.options,
|
|
249
|
+
frozenLockfile,
|
|
250
|
+
expectLockfile,
|
|
251
|
+
allowScripts,
|
|
252
|
+
allowSkills,
|
|
253
|
+
skillsDirs: conf.get('skills-dir'),
|
|
254
|
+
lockfileOnly,
|
|
255
|
+
saveExact,
|
|
256
|
+
savePrefix,
|
|
257
|
+
...(keep ? { keepNodes: new Set([keep]) } : null),
|
|
258
|
+
}, add);
|
|
259
|
+
};
|
package/dist/commands/list.js
CHANGED
|
@@ -63,6 +63,9 @@ export const usage = () => commandUsage({
|
|
|
63
63
|
value: '[human | json | mermaid | svg | png | count]',
|
|
64
64
|
description: 'Output format. Defaults to human-readable or json if no tty. Use svg or png to render the dependency graph as an image and open it. Count outputs the number of dependency relationships in the result.',
|
|
65
65
|
},
|
|
66
|
+
global: {
|
|
67
|
+
description: 'List globally installed packages.',
|
|
68
|
+
},
|
|
66
69
|
},
|
|
67
70
|
});
|
|
68
71
|
export const views = {
|
|
@@ -101,7 +104,8 @@ export const command = async (conf) => {
|
|
|
101
104
|
const usesHostContext = [queryString, scopeQueryString].some(q => q?.includes(':host('));
|
|
102
105
|
// optionally load the cwd graph if we found a package.json file
|
|
103
106
|
if (mainManifest) {
|
|
104
|
-
|
|
107
|
+
// the global project is always vlt managed
|
|
108
|
+
if (!usesHostContext && !conf.globalRoot) {
|
|
105
109
|
assertVltInstalled(conf.options.projectRoot, 'ls');
|
|
106
110
|
}
|
|
107
111
|
graph = actual.load({
|
package/dist/commands/query.js
CHANGED
|
@@ -80,6 +80,9 @@ export const usage = () => commandUsage({
|
|
|
80
80
|
value: '[human | json | mermaid | svg | png | count]',
|
|
81
81
|
description: 'Output format. Defaults to human-readable or json if no tty. Use svg or png to render the dependency graph as an image and open it. Count outputs the number of dependency relationships in the result.',
|
|
82
82
|
},
|
|
83
|
+
global: {
|
|
84
|
+
description: 'Query the global project.',
|
|
85
|
+
},
|
|
83
86
|
},
|
|
84
87
|
});
|
|
85
88
|
const validateExpectedResult = (conf, edges) => {
|
|
@@ -128,7 +131,8 @@ export const command = async (conf) => {
|
|
|
128
131
|
const usesHostContext = [queryString, scopeQueryString].some(q => q?.includes(':host('));
|
|
129
132
|
// optionally load the cwd graph if we found a package.json file
|
|
130
133
|
if (mainManifest) {
|
|
131
|
-
|
|
134
|
+
// the global project is always vlt managed
|
|
135
|
+
if (!usesHostContext && !conf.globalRoot) {
|
|
132
136
|
assertVltInstalled(conf.options.projectRoot, 'query');
|
|
133
137
|
}
|
|
134
138
|
graph = actual.load({
|
package/dist/commands/setup.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { Shell } from '../shell.ts';
|
|
2
|
+
import type { PathSetupFile } from '../shell-setup/index.ts';
|
|
1
3
|
import type { CommandFn, CommandUsage } from '../index.ts';
|
|
2
4
|
/** Where users sign up for / log into a vlt.io account. */
|
|
3
5
|
export declare const VLT_SIGNUP_URL = "https://www.vlt.io";
|
|
@@ -29,9 +31,33 @@ export type SetupResult = {
|
|
|
29
31
|
* the project's `vlt.json`, so the result won't take effect here.
|
|
30
32
|
*/
|
|
31
33
|
shadowedByProject?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* PATH step outcome; absent when skipped (--yes, no terminal,
|
|
36
|
+
* no-modify-path)
|
|
37
|
+
*/
|
|
38
|
+
path?: SetupPathResult['path'] | SetupPathFailed;
|
|
39
|
+
};
|
|
40
|
+
export type SetupPathFailed = {
|
|
41
|
+
status: 'failed';
|
|
42
|
+
/** why; may hold the manual line */
|
|
43
|
+
message: string;
|
|
44
|
+
};
|
|
45
|
+
export type SetupPathResult = {
|
|
46
|
+
path: {
|
|
47
|
+
status: 'added' | 'unchanged' | 'in-path' | 'disabled' | 'cancelled';
|
|
48
|
+
/** canonical dir added to the PATH */
|
|
49
|
+
dir: string;
|
|
50
|
+
shell: Shell;
|
|
51
|
+
files: PathSetupFile[];
|
|
52
|
+
backups: string[];
|
|
53
|
+
/** manual line for the shell */
|
|
54
|
+
command: string;
|
|
55
|
+
/** loads it in the current shell */
|
|
56
|
+
source: string;
|
|
57
|
+
};
|
|
32
58
|
};
|
|
33
59
|
export declare const views: {
|
|
34
|
-
readonly human: (result: SetupResult) => string;
|
|
60
|
+
readonly human: (result: SetupResult | SetupPathResult) => string;
|
|
35
61
|
};
|
|
36
62
|
export declare const usage: CommandUsage;
|
|
37
|
-
export declare const command: CommandFn<SetupResult>;
|
|
63
|
+
export declare const command: CommandFn<SetupResult | SetupPathResult>;
|