@detergent-software/atk 8.9.0-dev.3 → 8.9.0-dev.31
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/CHANGELOG.md +211 -0
- package/README.md +22 -12
- package/build/cli.js +18 -6
- package/build/cli.js.map +1 -1
- package/build/command-manifest.json +1507 -0
- package/build/commands/_app.d.ts.map +1 -1
- package/build/commands/_app.js +8 -4
- package/build/commands/_app.js.map +1 -1
- package/build/commands/audit.d.ts.map +1 -1
- package/build/commands/audit.js +1 -1
- package/build/commands/audit.js.map +1 -1
- package/build/commands/browse.js +2 -2
- package/build/commands/browse.js.map +1 -1
- package/build/commands/cache.d.ts +1 -1
- package/build/commands/cache.d.ts.map +1 -1
- package/build/commands/cache.js +1 -16
- package/build/commands/cache.js.map +1 -1
- package/build/commands/config.d.ts.map +1 -1
- package/build/commands/config.js +1 -1
- package/build/commands/config.js.map +1 -1
- package/build/commands/diff.d.ts.map +1 -1
- package/build/commands/diff.js +4 -0
- package/build/commands/diff.js.map +1 -1
- package/build/commands/drift.d.ts.map +1 -1
- package/build/commands/drift.js +4 -0
- package/build/commands/drift.js.map +1 -1
- package/build/commands/index.d.ts.map +1 -1
- package/build/commands/index.js +5 -40
- package/build/commands/index.js.map +1 -1
- package/build/commands/info.d.ts.map +1 -1
- package/build/commands/info.js +50 -33
- package/build/commands/info.js.map +1 -1
- package/build/commands/init.d.ts.map +1 -1
- package/build/commands/init.js +4 -2
- package/build/commands/init.js.map +1 -1
- package/build/commands/install.d.ts.map +1 -1
- package/build/commands/install.js +28 -7
- package/build/commands/install.js.map +1 -1
- package/build/commands/list.js +2 -2
- package/build/commands/list.js.map +1 -1
- package/build/commands/login.d.ts.map +1 -1
- package/build/commands/login.js +12 -2
- package/build/commands/login.js.map +1 -1
- package/build/commands/logout.d.ts.map +1 -1
- package/build/commands/logout.js +9 -1
- package/build/commands/logout.js.map +1 -1
- package/build/commands/outdated.js +1 -1
- package/build/commands/outdated.js.map +1 -1
- package/build/commands/prune.d.ts.map +1 -1
- package/build/commands/prune.js +4 -2
- package/build/commands/prune.js.map +1 -1
- package/build/commands/publish.d.ts +1 -1
- package/build/commands/publish.d.ts.map +1 -1
- package/build/commands/publish.js +31 -36
- package/build/commands/publish.js.map +1 -1
- package/build/commands/release-notes.d.ts.map +1 -1
- package/build/commands/release-notes.js +4 -0
- package/build/commands/release-notes.js.map +1 -1
- package/build/commands/schema.d.ts +3 -3
- package/build/commands/search.js +1 -1
- package/build/commands/search.js.map +1 -1
- package/build/commands/sync.d.ts +1 -1
- package/build/commands/sync.d.ts.map +1 -1
- package/build/commands/sync.js +27 -12
- package/build/commands/sync.js.map +1 -1
- package/build/commands/update.d.ts.map +1 -1
- package/build/commands/update.js +58 -9
- package/build/commands/update.js.map +1 -1
- package/build/commands/whoami.d.ts.map +1 -1
- package/build/commands/whoami.js +16 -4
- package/build/commands/whoami.js.map +1 -1
- package/build/commands/why.js +3 -4
- package/build/commands/why.js.map +1 -1
- package/build/components/Header.d.ts +2 -3
- package/build/components/Header.d.ts.map +1 -1
- package/build/components/Header.js +2 -9
- package/build/components/Header.js.map +1 -1
- package/build/components/LocalEditsHint.d.ts +16 -0
- package/build/components/LocalEditsHint.d.ts.map +1 -0
- package/build/components/LocalEditsHint.js +18 -0
- package/build/components/LocalEditsHint.js.map +1 -0
- package/build/components/SyncAllInSync.d.ts +5 -1
- package/build/components/SyncAllInSync.d.ts.map +1 -1
- package/build/components/SyncAllInSync.js +2 -2
- package/build/components/SyncAllInSync.js.map +1 -1
- package/build/components/header-art.d.ts +7 -0
- package/build/components/header-art.d.ts.map +1 -0
- package/build/components/header-art.js +14 -0
- package/build/components/header-art.js.map +1 -0
- package/build/components/index.d.ts +1 -0
- package/build/components/index.d.ts.map +1 -1
- package/build/components/index.js +1 -0
- package/build/components/index.js.map +1 -1
- package/build/hooks/useListActions.d.ts.map +1 -1
- package/build/hooks/useListActions.js +4 -0
- package/build/hooks/useListActions.js.map +1 -1
- package/build/hooks/usePruneState.d.ts +1 -7
- package/build/hooks/usePruneState.d.ts.map +1 -1
- package/build/hooks/usePruneState.js +18 -62
- package/build/hooks/usePruneState.js.map +1 -1
- package/build/hooks/usePublishState.d.ts +43 -8
- package/build/hooks/usePublishState.d.ts.map +1 -1
- package/build/hooks/usePublishState.js +82 -565
- package/build/hooks/usePublishState.js.map +1 -1
- package/build/lib/adapter.d.ts +10 -1
- package/build/lib/adapter.d.ts.map +1 -1
- package/build/lib/adapter.js +46 -3
- package/build/lib/adapter.js.map +1 -1
- package/build/lib/api-client.d.ts +9 -5
- package/build/lib/api-client.d.ts.map +1 -1
- package/build/lib/api-client.js +35 -8
- package/build/lib/api-client.js.map +1 -1
- package/build/lib/atk-api/generated/types.gen.d.ts +4 -4
- package/build/lib/auth.d.ts +12 -2
- package/build/lib/auth.d.ts.map +1 -1
- package/build/lib/auth.js +38 -3
- package/build/lib/auth.js.map +1 -1
- package/build/lib/checksum.d.ts +40 -14
- package/build/lib/checksum.d.ts.map +1 -1
- package/build/lib/checksum.js +110 -57
- package/build/lib/checksum.js.map +1 -1
- package/build/lib/config.d.ts +4 -4
- package/build/lib/config.d.ts.map +1 -1
- package/build/lib/config.js +31 -8
- package/build/lib/config.js.map +1 -1
- package/build/lib/diagnostics.d.ts.map +1 -1
- package/build/lib/diagnostics.js +10 -7
- package/build/lib/diagnostics.js.map +1 -1
- package/build/lib/diff-command.js +1 -1
- package/build/lib/diff-command.js.map +1 -1
- package/build/lib/errors.d.ts +4 -1
- package/build/lib/errors.d.ts.map +1 -1
- package/build/lib/errors.js.map +1 -1
- package/build/lib/format-age.d.ts +3 -0
- package/build/lib/format-age.d.ts.map +1 -0
- package/build/lib/format-age.js +18 -0
- package/build/lib/format-age.js.map +1 -0
- package/build/lib/installer.d.ts +8 -11
- package/build/lib/installer.d.ts.map +1 -1
- package/build/lib/installer.js +83 -28
- package/build/lib/installer.js.map +1 -1
- package/build/lib/local-edits.d.ts +72 -0
- package/build/lib/local-edits.d.ts.map +1 -0
- package/build/lib/local-edits.js +145 -0
- package/build/lib/local-edits.js.map +1 -0
- package/build/lib/lockfile.d.ts +12 -8
- package/build/lib/lockfile.d.ts.map +1 -1
- package/build/lib/lockfile.js +209 -59
- package/build/lib/lockfile.js.map +1 -1
- package/build/lib/mover.d.ts.map +1 -1
- package/build/lib/mover.js +11 -12
- package/build/lib/mover.js.map +1 -1
- package/build/lib/multi-tool-install.d.ts +4 -2
- package/build/lib/multi-tool-install.d.ts.map +1 -1
- package/build/lib/multi-tool-install.js +12 -2
- package/build/lib/multi-tool-install.js.map +1 -1
- package/build/lib/offline.d.ts +19 -0
- package/build/lib/offline.d.ts.map +1 -0
- package/build/lib/offline.js +26 -0
- package/build/lib/offline.js.map +1 -0
- package/build/lib/owned-paths.d.ts +7 -4
- package/build/lib/owned-paths.d.ts.map +1 -1
- package/build/lib/owned-paths.js +23 -8
- package/build/lib/owned-paths.js.map +1 -1
- package/build/lib/parse-json.d.ts +12 -0
- package/build/lib/parse-json.d.ts.map +1 -1
- package/build/lib/parse-json.js +15 -2
- package/build/lib/parse-json.js.map +1 -1
- package/build/lib/pastel/commander-specs.d.ts +7 -0
- package/build/lib/pastel/commander-specs.d.ts.map +1 -0
- package/build/lib/pastel/commander-specs.js +50 -0
- package/build/lib/pastel/commander-specs.js.map +1 -0
- package/build/lib/pastel/generate-arguments.d.ts +3 -3
- package/build/lib/pastel/generate-arguments.d.ts.map +1 -1
- package/build/lib/pastel/generate-arguments.js +25 -22
- package/build/lib/pastel/generate-arguments.js.map +1 -1
- package/build/lib/pastel/generate-command.d.ts +7 -5
- package/build/lib/pastel/generate-command.d.ts.map +1 -1
- package/build/lib/pastel/generate-command.js +32 -67
- package/build/lib/pastel/generate-command.js.map +1 -1
- package/build/lib/pastel/generate-commands.d.ts +3 -5
- package/build/lib/pastel/generate-commands.d.ts.map +1 -1
- package/build/lib/pastel/generate-commands.js +6 -10
- package/build/lib/pastel/generate-commands.js.map +1 -1
- package/build/lib/pastel/generate-options.d.ts +3 -3
- package/build/lib/pastel/generate-options.d.ts.map +1 -1
- package/build/lib/pastel/generate-options.js +16 -13
- package/build/lib/pastel/generate-options.js.map +1 -1
- package/build/lib/pastel/index.d.ts +26 -4
- package/build/lib/pastel/index.d.ts.map +1 -1
- package/build/lib/pastel/index.js +104 -18
- package/build/lib/pastel/index.js.map +1 -1
- package/build/lib/pastel/internal-types.d.ts +39 -8
- package/build/lib/pastel/internal-types.d.ts.map +1 -1
- package/build/lib/pastel/manifest.d.ts +8 -0
- package/build/lib/pastel/manifest.d.ts.map +1 -0
- package/build/lib/pastel/manifest.js +7 -0
- package/build/lib/pastel/manifest.js.map +1 -0
- package/build/lib/pastel/read-commands.d.ts +7 -2
- package/build/lib/pastel/read-commands.d.ts.map +1 -1
- package/build/lib/pastel/read-commands.js +51 -30
- package/build/lib/pastel/read-commands.js.map +1 -1
- package/build/lib/pastel/render-command.d.ts +13 -0
- package/build/lib/pastel/render-command.d.ts.map +1 -0
- package/build/lib/pastel/render-command.js +56 -0
- package/build/lib/pastel/render-command.js.map +1 -0
- package/build/lib/process-alive.d.ts +8 -0
- package/build/lib/process-alive.d.ts.map +1 -0
- package/build/lib/process-alive.js +16 -0
- package/build/lib/process-alive.js.map +1 -0
- package/build/lib/pruner.d.ts +26 -0
- package/build/lib/pruner.d.ts.map +1 -0
- package/build/lib/pruner.js +42 -0
- package/build/lib/pruner.js.map +1 -0
- package/build/lib/publish-flow.d.ts +7 -15
- package/build/lib/publish-flow.d.ts.map +1 -1
- package/build/lib/publish-flow.js +634 -178
- package/build/lib/publish-flow.js.map +1 -1
- package/build/lib/publish-run.d.ts +55 -0
- package/build/lib/publish-run.d.ts.map +1 -0
- package/build/lib/publish-run.js +169 -0
- package/build/lib/publish-run.js.map +1 -0
- package/build/lib/publisher.d.ts +23 -16
- package/build/lib/publisher.d.ts.map +1 -1
- package/build/lib/publisher.js +34 -35
- package/build/lib/publisher.js.map +1 -1
- package/build/lib/registrar.d.ts.map +1 -1
- package/build/lib/registrar.js +2 -2
- package/build/lib/registrar.js.map +1 -1
- package/build/lib/registry.d.ts +18 -7
- package/build/lib/registry.d.ts.map +1 -1
- package/build/lib/registry.js +113 -32
- package/build/lib/registry.js.map +1 -1
- package/build/lib/root-path.d.ts +11 -0
- package/build/lib/root-path.d.ts.map +1 -1
- package/build/lib/root-path.js +15 -1
- package/build/lib/root-path.js.map +1 -1
- package/build/lib/schemas/config.d.ts +3 -1
- package/build/lib/schemas/config.d.ts.map +1 -1
- package/build/lib/schemas/config.js +1 -1
- package/build/lib/schemas/config.js.map +1 -1
- package/build/lib/schemas/lockfile.d.ts +156 -23
- package/build/lib/schemas/lockfile.d.ts.map +1 -1
- package/build/lib/schemas/lockfile.js +100 -79
- package/build/lib/schemas/lockfile.js.map +1 -1
- package/build/lib/setup.d.ts.map +1 -1
- package/build/lib/setup.js +53 -48
- package/build/lib/setup.js.map +1 -1
- package/build/lib/sync.d.ts +22 -6
- package/build/lib/sync.d.ts.map +1 -1
- package/build/lib/sync.js +59 -7
- package/build/lib/sync.js.map +1 -1
- package/build/lib/uninstaller.d.ts.map +1 -1
- package/build/lib/uninstaller.js +8 -5
- package/build/lib/uninstaller.js.map +1 -1
- package/build/lib/update-check.d.ts +4 -0
- package/build/lib/update-check.d.ts.map +1 -1
- package/build/lib/update-check.js +55 -56
- package/build/lib/update-check.js.map +1 -1
- package/build/lib/updater.d.ts +31 -1
- package/build/lib/updater.d.ts.map +1 -1
- package/build/lib/updater.js +143 -4
- package/build/lib/updater.js.map +1 -1
- package/build/lib/usage-error.d.ts +20 -0
- package/build/lib/usage-error.d.ts.map +1 -0
- package/build/lib/usage-error.js +41 -0
- package/build/lib/usage-error.js.map +1 -0
- package/build/lib/user-setup.d.ts.map +1 -1
- package/build/lib/user-setup.js +62 -59
- package/build/lib/user-setup.js.map +1 -1
- package/build/lib/write-file.d.ts +5 -0
- package/build/lib/write-file.d.ts.map +1 -1
- package/build/lib/write-file.js +68 -13
- package/build/lib/write-file.js.map +1 -1
- package/package.json +81 -81
|
@@ -5,10 +5,13 @@ import { gt as semverGt, valid as semverValid } from 'semver';
|
|
|
5
5
|
import { getCacheDir, loadConfig } from './config.js';
|
|
6
6
|
import { fetchWithRetry } from './fetch-retry.js';
|
|
7
7
|
import { addNotice } from './notices.js';
|
|
8
|
+
import { isOffline } from './offline.js';
|
|
8
9
|
import { CLI_VERSION, isPreRelease, upgradeCommand } from './version.js';
|
|
9
|
-
|
|
10
|
+
/** The package's dist-tags alone (about 40 bytes), not its packument (over 1 MB). */
|
|
11
|
+
export const NPM_DIST_TAGS_URL = 'https://registry.npmjs.org/-/package/@detergent-software%2fatk/dist-tags';
|
|
10
12
|
const NPM_CACHE_FILE = 'npm-version.json';
|
|
11
|
-
|
|
13
|
+
/** How long the cached dist-tags stand before the check asks npm again; not the registry's `cacheTtlMinutes`. */
|
|
14
|
+
export const UPDATE_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
12
15
|
/** The JSON-mode refresh makes one attempt and gives up after this long, so it barely delays exit. */
|
|
13
16
|
export const BACKGROUND_REFRESH_TIMEOUT_MS = 1_500;
|
|
14
17
|
/**
|
|
@@ -28,17 +31,17 @@ export async function getUpdateInfo() {
|
|
|
28
31
|
const channel = isPreRelease() ? 'dev' : 'latest';
|
|
29
32
|
const cacheDir = getCacheDir(config);
|
|
30
33
|
const cachePath = join(cacheDir, NPM_CACHE_FILE);
|
|
31
|
-
const
|
|
32
|
-
let
|
|
33
|
-
if (!
|
|
34
|
-
|
|
35
|
-
if (!
|
|
34
|
+
const cached = await readNpmCache(cachePath);
|
|
35
|
+
let tags = cached && cached.ageMs <= UPDATE_CHECK_INTERVAL_MS ? cached.tags : null;
|
|
36
|
+
if (!tags) {
|
|
37
|
+
tags = await fetchDistTags();
|
|
38
|
+
if (!tags) {
|
|
36
39
|
return null;
|
|
37
40
|
}
|
|
38
|
-
|
|
39
|
-
await writeNpmCache(cachePath, cacheDir, channel, fetched);
|
|
41
|
+
await writeNpmCache(cachePath, cacheDir, tags);
|
|
40
42
|
}
|
|
41
|
-
|
|
43
|
+
const latestVersion = tags[channel];
|
|
44
|
+
if (!latestVersion || !semverValid(CLI_VERSION) || !semverValid(latestVersion)) {
|
|
42
45
|
return null;
|
|
43
46
|
}
|
|
44
47
|
if (!semverGt(latestVersion, CLI_VERSION)) {
|
|
@@ -73,20 +76,20 @@ export async function noteCachedUpdate() {
|
|
|
73
76
|
const channel = isPreRelease() ? 'dev' : 'latest';
|
|
74
77
|
const cacheDir = getCacheDir(config);
|
|
75
78
|
const cachePath = join(cacheDir, NPM_CACHE_FILE);
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
if (
|
|
79
|
+
const cached = await readNpmCache(cachePath);
|
|
80
|
+
const version = cached?.tags[channel];
|
|
81
|
+
if (version && semverValid(CLI_VERSION) && semverValid(version) && semverGt(version, CLI_VERSION)) {
|
|
79
82
|
const command = upgradeCommand(channel);
|
|
80
83
|
addNotice({
|
|
81
84
|
command,
|
|
82
85
|
kind: 'update-available',
|
|
83
|
-
text: `ATK ${
|
|
86
|
+
text: `ATK ${version} is available (this is ${CLI_VERSION}). Run \`${command}\` to update.`,
|
|
84
87
|
});
|
|
85
88
|
}
|
|
86
|
-
if (!cached || cached.ageMs >
|
|
87
|
-
void
|
|
88
|
-
if (
|
|
89
|
-
await writeNpmCache(cachePath, cacheDir,
|
|
89
|
+
if (!cached || cached.ageMs > UPDATE_CHECK_INTERVAL_MS) {
|
|
90
|
+
void fetchDistTags('once').then(async (tags) => {
|
|
91
|
+
if (tags) {
|
|
92
|
+
await writeNpmCache(cachePath, cacheDir, tags);
|
|
90
93
|
}
|
|
91
94
|
});
|
|
92
95
|
}
|
|
@@ -96,71 +99,67 @@ export async function noteCachedUpdate() {
|
|
|
96
99
|
}
|
|
97
100
|
}
|
|
98
101
|
/**
|
|
99
|
-
* The
|
|
100
|
-
* shared retry policy; `'once'` makes a single attempt that is
|
|
101
|
-
* {@link BACKGROUND_REFRESH_TIMEOUT_MS}.
|
|
102
|
+
* The `dev` and `latest` dist-tags from npm (either may be missing), or null on any failure
|
|
103
|
+
* or offline. `'retry'` uses the shared retry policy; `'once'` makes a single attempt that is
|
|
104
|
+
* aborted after {@link BACKGROUND_REFRESH_TIMEOUT_MS}.
|
|
102
105
|
*/
|
|
103
|
-
async function
|
|
106
|
+
async function fetchDistTags(attempts = 'retry') {
|
|
107
|
+
if (isOffline()) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
104
110
|
try {
|
|
105
111
|
const init = { headers: { accept: 'application/json' } };
|
|
106
112
|
const response = attempts === 'retry'
|
|
107
|
-
? await fetchWithRetry(
|
|
108
|
-
: await globalThis.fetch(
|
|
113
|
+
? await fetchWithRetry(NPM_DIST_TAGS_URL, init)
|
|
114
|
+
: await globalThis.fetch(NPM_DIST_TAGS_URL, {
|
|
109
115
|
...init,
|
|
110
116
|
signal: AbortSignal.timeout(BACKGROUND_REFRESH_TIMEOUT_MS),
|
|
111
117
|
});
|
|
112
118
|
if (!response.ok) {
|
|
113
119
|
return null;
|
|
114
120
|
}
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
const distTags = body['dist-tags'];
|
|
118
|
-
if (!distTags || typeof distTags !== 'object') {
|
|
119
|
-
return null;
|
|
120
|
-
}
|
|
121
|
-
const value = distTags[channel];
|
|
122
|
-
return typeof value === 'string' ? value : null;
|
|
121
|
+
const tags = pickDistTags(JSON.parse(await response.text()));
|
|
122
|
+
return tags.dev || tags.latest ? tags : null;
|
|
123
123
|
}
|
|
124
124
|
catch {
|
|
125
125
|
return null;
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
/** The string `dev` and `latest` entries of a dist-tags object; anything else is dropped. */
|
|
129
|
+
function pickDistTags(body) {
|
|
130
|
+
const tags = {};
|
|
131
|
+
if (body && typeof body === 'object') {
|
|
132
|
+
for (const channel of ['dev', 'latest']) {
|
|
133
|
+
const value = Reflect.get(body, channel);
|
|
134
|
+
if (typeof value === 'string') {
|
|
135
|
+
tags[channel] = value;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return tags;
|
|
131
140
|
}
|
|
132
|
-
/**
|
|
133
|
-
|
|
141
|
+
/**
|
|
142
|
+
* The cached dist-tags and the cache file's age, or null when there is no readable cache.
|
|
143
|
+
* One fetch writes every tag, so the file's age holds for each of them, present or not.
|
|
144
|
+
*/
|
|
145
|
+
async function readNpmCache(cachePath) {
|
|
134
146
|
try {
|
|
135
147
|
const fileStat = await stat(cachePath);
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
const value = parsed[channel];
|
|
139
|
-
return typeof value === 'string' ? { ageMs: Date.now() - fileStat.mtimeMs, version: value } : null;
|
|
148
|
+
const tags = pickDistTags(JSON.parse(await readFile(cachePath, 'utf-8')));
|
|
149
|
+
return { ageMs: Date.now() - fileStat.mtimeMs, tags };
|
|
140
150
|
}
|
|
141
151
|
catch {
|
|
142
152
|
return null;
|
|
143
153
|
}
|
|
144
154
|
}
|
|
145
|
-
|
|
155
|
+
/** Replaces the cache with npm's latest answer, so a tag npm no longer has goes too. */
|
|
156
|
+
async function writeNpmCache(cachePath, cacheDir, tags) {
|
|
146
157
|
try {
|
|
147
|
-
|
|
148
|
-
try {
|
|
149
|
-
const raw = await readFile(cachePath, 'utf-8');
|
|
150
|
-
existing = JSON.parse(raw);
|
|
151
|
-
}
|
|
152
|
-
catch {
|
|
153
|
-
existing = {};
|
|
154
|
-
}
|
|
155
|
-
const merged = {
|
|
156
|
-
...existing,
|
|
157
|
-
[channel]: version,
|
|
158
|
-
fetchedAt: Date.now(),
|
|
159
|
-
};
|
|
158
|
+
const file = { ...tags, fetchedAt: Date.now() };
|
|
160
159
|
if (!existsSync(cacheDir)) {
|
|
161
160
|
await mkdir(cacheDir, { recursive: true });
|
|
162
161
|
}
|
|
163
|
-
await writeFile(cachePath, JSON.stringify(
|
|
162
|
+
await writeFile(cachePath, JSON.stringify(file), 'utf-8');
|
|
164
163
|
}
|
|
165
164
|
catch {
|
|
166
165
|
// Non-fatal — banner can still render without a write.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../src/lib/update-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,EAAE,IAAI,QAAQ,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,QAAQ,CAAC;AAE9D,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEzE,MAAM,
|
|
1
|
+
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../src/lib/update-check.ts"],"names":[],"mappings":"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"}
|
package/build/lib/updater.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { Registry } from './schemas/index.js';
|
|
|
4
4
|
import type { InstalledAsset, Lockfile } from './schemas/lockfile.js';
|
|
5
5
|
import { ApiCodeError, type ErrorGuidance } from './errors.js';
|
|
6
6
|
import { type InstallResult } from './installer.js';
|
|
7
|
+
import { type LocalEdits } from './local-edits.js';
|
|
7
8
|
import { type Scope } from './scope.js';
|
|
8
9
|
export interface OutdatedAsset {
|
|
9
10
|
/** Whether the asset is frozen. */
|
|
@@ -40,6 +41,11 @@ export interface UndeclaredRemoval {
|
|
|
40
41
|
}>;
|
|
41
42
|
}
|
|
42
43
|
export interface UpdateAssetsResult {
|
|
44
|
+
/**
|
|
45
|
+
* Assets skipped during bulk update because files they placed were edited (`localEdits`), with
|
|
46
|
+
* those files. `force` updates them.
|
|
47
|
+
*/
|
|
48
|
+
editedSkipped?: Array<OutdatedAsset & Pick<LocalEdits, 'dependencies' | 'files' | 'unchecked'>>;
|
|
43
49
|
/** Assets skipped because they were uninstalled for this tool (`excludedTools`). */
|
|
44
50
|
excludedSkipped?: Array<{
|
|
45
51
|
name: string;
|
|
@@ -105,10 +111,17 @@ export interface UpdateOptions {
|
|
|
105
111
|
* every tool and the lockfile stay on the version they had.
|
|
106
112
|
*/
|
|
107
113
|
failedFor?: Map<string, string>;
|
|
108
|
-
/** Force update even if the asset is pinned. */
|
|
114
|
+
/** Force update even if the asset is pinned, and overwrite local edits. */
|
|
109
115
|
force?: boolean;
|
|
110
116
|
/** Set of frozen asset composite keys in format `${type}:${org ?? ''}:${name}`. */
|
|
111
117
|
frozenAssets?: Set<string>;
|
|
118
|
+
/**
|
|
119
|
+
* The installed assets with local edits (`findLocalEdits`), keyed like `frozenAssets`: an update
|
|
120
|
+
* would overwrite them, so without `force` a bulk update skips them and a named one, or one whose
|
|
121
|
+
* plan replaces an edited dependency, is refused. Found once before a multi-tool run, so every
|
|
122
|
+
* tool skips the same assets and the lockfile keeps one version for them.
|
|
123
|
+
*/
|
|
124
|
+
localEdits?: Map<string, LocalEdits>;
|
|
112
125
|
/** Callback for progress updates. */
|
|
113
126
|
onProgress?: (message: string) => void;
|
|
114
127
|
/** Project root directory. */
|
|
@@ -146,6 +159,7 @@ export interface UpdateWarning {
|
|
|
146
159
|
command: string;
|
|
147
160
|
message: string;
|
|
148
161
|
}
|
|
162
|
+
type AssetIdentity = Pick<InstalledAsset, 'name' | 'org' | 'type'>;
|
|
149
163
|
export declare class UpdaterError extends ApiCodeError {
|
|
150
164
|
name: string;
|
|
151
165
|
}
|
|
@@ -215,4 +229,20 @@ export declare function updateAsset(assetName: string, installed: InstalledAsset
|
|
|
215
229
|
* bypasses the outdated check and updates directly to the specified version.
|
|
216
230
|
*/
|
|
217
231
|
export declare function updateAssets(assetNames: string[] | undefined, lockfile: Lockfile, registry: Registry, options: UpdateOptions): Promise<UpdateAssetsResult>;
|
|
232
|
+
/**
|
|
233
|
+
* `localEdits` plus, for each of `outdated` without edits of its own, the edits of the installed
|
|
234
|
+
* dependencies its update to `targetVersion` (else its `latestVersion`) would replace or remove for
|
|
235
|
+
* any of `adapters`, under the asset's key with those dependencies named. An update skips or
|
|
236
|
+
* refuses such an asset as it does one with its own edits. Found once, before a multi-tool run
|
|
237
|
+
* changes any files, and for the dry run the same way, so both list the same assets.
|
|
238
|
+
*/
|
|
239
|
+
export declare function withDependencyEdits(outdated: Array<AssetIdentity & {
|
|
240
|
+
latestVersion: string;
|
|
241
|
+
}>, lockfile: Lockfile, registry: Registry, localEdits: Map<string, LocalEdits>, { adapters, projectDir, scope, targetVersion, }: {
|
|
242
|
+
adapters: Adapter[];
|
|
243
|
+
projectDir: string;
|
|
244
|
+
scope?: Scope;
|
|
245
|
+
targetVersion?: string;
|
|
246
|
+
}): Map<string, LocalEdits>;
|
|
247
|
+
export {};
|
|
218
248
|
//# sourceMappingURL=updater.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updater.d.ts","sourceRoot":"","sources":["../../src/lib/updater.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAatE,OAAO,EACL,YAAY,EAGZ,KAAK,aAAa,EAGnB,MAAM,aAAa,CAAC;AAErB,OAAO,EAOL,KAAK,aAAa,EAEnB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"updater.d.ts","sourceRoot":"","sources":["../../src/lib/updater.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAatE,OAAO,EACL,YAAY,EAGZ,KAAK,aAAa,EAGnB,MAAM,aAAa,CAAC;AAErB,OAAO,EAOL,KAAK,aAAa,EAEnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAgBnD,OAAO,EAAE,KAAK,KAAK,EAA6B,MAAM,YAAY,CAAC;AAGnE,MAAM,WAAW,aAAa;IAC5B,mCAAmC;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,0FAA0F;AAC1F,MAAM,WAAW,WAAW;IAC1B,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,iEAAiE;AACjE,MAAM,WAAW,iBAAiB;IAChC,6FAA6F;IAC7F,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,iDAAiD;IACjD,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;CACjE;AAED,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC;IAChG,oFAAoF;IACpF,eAAe,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IACzE;;;OAGG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC;QACpB,UAAU,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,SAAS,CAAA;SAAE,CAAC;QAC7D,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,SAAS,CAAC;KACjB,CAAC,CAAC;IACH,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,2EAA2E;IAC3E,aAAa,CAAC,EAAE,aAAa,EAAE,CAAC;IAChC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B;;;OAGG;IACH,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,EAAE,CAAC;IAC/B;;;;OAIG;IACH,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,2EAA2E;IAC3E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,mFAAmF;IACnF,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACrC,qCAAqC;IACrC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,wDAAwD;IACxD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,QAAQ,CAAC;IACxB,gFAAgF;IAChF,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,aAAa,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,KAAK,aAAa,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC,CAAC;AAEnE,qBAAa,YAAa,SAAQ,YAAY;IACnC,IAAI,SAAkB;CAChC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,aAAa,EAAE,CA2BhH;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,WAAW,EAAE,CAenF;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,EACtD,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,OAAO,GACf,OAAO,CAKT;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,OAAO,GACf,OAAO,CAKT;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IAAC,IAAI,CAAC,EAAE,SAAS,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACxG,cAAc,CA+BhB;AAED;;;;;;;GAOG;AACH,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,cAAc,EAAE,EAC5B,QAAQ,EAAE,QAAQ,EAClB,EACE,OAAO,EACP,UAAU,EACV,UAAU,EACV,YAAY,GACb,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,YAAY,GAAG,YAAY,CAAC,GAAG;IAAE,YAAY,EAAE,QAAQ,CAAA;CAAE,GAC3F,OAAO,CAAC,iBAAiB,CAAC,CA4B5B;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,cAAc,EACzB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,YAAY,CAAC,CAEvB;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAAE,GAAG,SAAS,EAChC,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,kBAAkB,CAAC,CA6P7B;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,KAAK,CAAC,aAAa,GAAG;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,EAC1D,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EACnC,EACE,QAAQ,EACR,UAAU,EACV,KAAK,EACL,aAAa,GACd,EAAE;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GACpF,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAoCzB"}
|
package/build/lib/updater.js
CHANGED
|
@@ -6,14 +6,15 @@ import { getConfigEntriesForTool } from './config-entries.js';
|
|
|
6
6
|
import { ApiCodeError, asSentence, errorGuidance, errorMessage, isRunWideFailure, } from './errors.js';
|
|
7
7
|
import { restoreFiles, snapshotFiles } from './file-snapshot.js';
|
|
8
8
|
import { executeInstallPlan, fetchPlanFiles, FileConflictError, InstallerError, installFailureMessage, InstallPlanError, } from './installer.js';
|
|
9
|
-
import {
|
|
9
|
+
import {} from './local-edits.js';
|
|
10
|
+
import { addAssetToLockfile, findDependencyAsset, findDependents, findInstalledAsset, getLockfilePath, identityKey, readLockfile, writeLockfile, } from './lockfile.js';
|
|
10
11
|
import { withoutKeptDependencies } from './multi-tool-install.js';
|
|
11
12
|
import { formatOrgName, parseOrgFromName, scopeSwitchGuidance } from './org.js';
|
|
12
13
|
import { findAsset } from './registry.js';
|
|
13
14
|
import { resolveInstallPlan } from './resolver.js';
|
|
14
15
|
import { fromRoot } from './root-path.js';
|
|
15
16
|
import { scopedCommand, scopeLabel } from './scope.js';
|
|
16
|
-
import { removeUndeclaredCopy, uninstallAsset } from './uninstaller.js';
|
|
17
|
+
import { planUninstall, removeUndeclaredCopy, uninstallAsset } from './uninstaller.js';
|
|
17
18
|
export class UpdaterError extends ApiCodeError {
|
|
18
19
|
name = 'UpdaterError';
|
|
19
20
|
}
|
|
@@ -198,6 +199,9 @@ export async function updateAssets(assetNames, lockfile, registry, options) {
|
|
|
198
199
|
if (installed.pinnedVersion && !options.force) {
|
|
199
200
|
throw pinnedError(`Asset "${name}" is pinned to version "${installed.pinnedVersion}".`, spec, options.scope);
|
|
200
201
|
}
|
|
202
|
+
const edits = options.force ? undefined : options.localEdits?.get(compositeKey);
|
|
203
|
+
if (edits)
|
|
204
|
+
throw localEditsError(name, [edits], spec, options.scope);
|
|
201
205
|
// Uninstalled for this tool: leave it alone (updating would reinstall it here). The
|
|
202
206
|
// other tools in a multi-tool update still get the new version.
|
|
203
207
|
if (excludedAtVersion(registry, installed, options.targetVersion, options.adapter)) {
|
|
@@ -238,6 +242,7 @@ export async function updateAssets(assetNames, lockfile, registry, options) {
|
|
|
238
242
|
}
|
|
239
243
|
const outdated = checkOutdated(lockfile, registry, options.frozenAssets);
|
|
240
244
|
let toUpdate;
|
|
245
|
+
const editedSkipped = [];
|
|
241
246
|
const frozenSkipped = [];
|
|
242
247
|
const skipped = [];
|
|
243
248
|
if (assetNames && assetNames.length > 0) {
|
|
@@ -265,11 +270,17 @@ export async function updateAssets(assetNames, lockfile, registry, options) {
|
|
|
265
270
|
throw pinnedError(`Asset "${asset.name}" is pinned.`, assetSpec(asset, options.type), options.scope);
|
|
266
271
|
}
|
|
267
272
|
}
|
|
273
|
+
for (const asset of toUpdate) {
|
|
274
|
+
const edits = options.force ? undefined : options.localEdits?.get(identityKey(asset));
|
|
275
|
+
if (edits)
|
|
276
|
+
throw localEditsError(asset.name, [edits], assetSpec(asset, options.type), options.scope);
|
|
277
|
+
}
|
|
268
278
|
}
|
|
269
279
|
else {
|
|
270
|
-
// Bulk update: skip pinned and
|
|
280
|
+
// Bulk update: skip pinned, frozen and edited assets without error
|
|
271
281
|
toUpdate = [];
|
|
272
282
|
for (const asset of outdated) {
|
|
283
|
+
const edits = options.force ? undefined : options.localEdits?.get(identityKey(asset));
|
|
273
284
|
if (asset.frozen) {
|
|
274
285
|
frozenSkipped.push(asset);
|
|
275
286
|
const thaw = scopedCommand(`atk thaw ${asset.name}`, options.scope);
|
|
@@ -280,6 +291,17 @@ export async function updateAssets(assetNames, lockfile, registry, options) {
|
|
|
280
291
|
const force = scopedCommand(`atk update ${asset.name} --force`, options.scope);
|
|
281
292
|
options.onProgress?.(`Skipping pinned asset ${asset.name} (pinned, use "${force}" to override)`);
|
|
282
293
|
}
|
|
294
|
+
else if (edits) {
|
|
295
|
+
const { dependencies, files, unchecked } = edits;
|
|
296
|
+
editedSkipped.push({
|
|
297
|
+
...asset,
|
|
298
|
+
...(dependencies ? { dependencies } : {}),
|
|
299
|
+
files,
|
|
300
|
+
...(unchecked ? { unchecked } : {}),
|
|
301
|
+
});
|
|
302
|
+
const force = scopedCommand(`atk update ${assetSpec(asset, options.type)} --force`, options.scope);
|
|
303
|
+
options.onProgress?.(`Skipping ${asset.name}: it has local edits (use "${force}" to overwrite them)`);
|
|
304
|
+
}
|
|
283
305
|
else {
|
|
284
306
|
toUpdate.push(asset);
|
|
285
307
|
}
|
|
@@ -320,6 +342,7 @@ export async function updateAssets(assetNames, lockfile, registry, options) {
|
|
|
320
342
|
});
|
|
321
343
|
if (toUpdate.length === 0) {
|
|
322
344
|
return {
|
|
345
|
+
...(editedSkipped.length > 0 ? { editedSkipped } : {}),
|
|
323
346
|
...(excludedSkipped.length > 0 ? { excludedSkipped } : {}),
|
|
324
347
|
...(failedSkipped.length > 0 ? { failedSkipped } : {}),
|
|
325
348
|
failures: [],
|
|
@@ -382,6 +405,7 @@ export async function updateAssets(assetNames, lockfile, registry, options) {
|
|
|
382
405
|
toolLockfile = await withInstalledEntries(toolLockfile, updated.plan, options).catch(() => toolLockfile);
|
|
383
406
|
}
|
|
384
407
|
return {
|
|
408
|
+
...(editedSkipped.length > 0 ? { editedSkipped } : {}),
|
|
385
409
|
...(excludedSkipped.length > 0 ? { excludedSkipped } : {}),
|
|
386
410
|
...(failedSkipped.length > 0 ? { failedSkipped } : {}),
|
|
387
411
|
failures,
|
|
@@ -392,10 +416,95 @@ export async function updateAssets(assetNames, lockfile, registry, options) {
|
|
|
392
416
|
...(undeclared.length > 0 ? { undeclared } : {}),
|
|
393
417
|
};
|
|
394
418
|
}
|
|
419
|
+
/**
|
|
420
|
+
* `localEdits` plus, for each of `outdated` without edits of its own, the edits of the installed
|
|
421
|
+
* dependencies its update to `targetVersion` (else its `latestVersion`) would replace or remove for
|
|
422
|
+
* any of `adapters`, under the asset's key with those dependencies named. An update skips or
|
|
423
|
+
* refuses such an asset as it does one with its own edits. Found once, before a multi-tool run
|
|
424
|
+
* changes any files, and for the dry run the same way, so both list the same assets.
|
|
425
|
+
*/
|
|
426
|
+
export function withDependencyEdits(outdated, lockfile, registry, localEdits, { adapters, projectDir, scope, targetVersion, }) {
|
|
427
|
+
const withDependencies = new Map(localEdits);
|
|
428
|
+
if (localEdits.size === 0)
|
|
429
|
+
return withDependencies;
|
|
430
|
+
for (const asset of outdated) {
|
|
431
|
+
const installed = lockfileEntryFor(lockfile, asset);
|
|
432
|
+
if (!installed || localEdits.has(identityKey(installed)))
|
|
433
|
+
continue;
|
|
434
|
+
const version = targetVersion ?? asset.latestVersion;
|
|
435
|
+
const resolved = findAsset(registry, installed.name, installed.type, version, installed.org);
|
|
436
|
+
if (!resolved || resolved.asset.org !== installed.org)
|
|
437
|
+
continue;
|
|
438
|
+
const edited = new Map();
|
|
439
|
+
for (const adapter of adapters) {
|
|
440
|
+
if (!supportsType(adapter, installed.type) || isExcludedForTool(installed, adapter.tool))
|
|
441
|
+
continue;
|
|
442
|
+
let plan;
|
|
443
|
+
try {
|
|
444
|
+
plan = planFor(registry, installed, resolved.version, { adapter, lockfile, projectDir, scope });
|
|
445
|
+
}
|
|
446
|
+
catch {
|
|
447
|
+
// The update itself refuses it (a pinned dependency it would move) and says why.
|
|
448
|
+
continue;
|
|
449
|
+
}
|
|
450
|
+
const newDeps = resolved.versionData.dependencies ?? [];
|
|
451
|
+
for (const edits of editsReplacedBy(plan, installed, newDeps, lockfile, adapter, localEdits)) {
|
|
452
|
+
edited.set(identityKey(edits), edits);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
if (edited.size === 0)
|
|
456
|
+
continue;
|
|
457
|
+
const deps = [...edited.values()];
|
|
458
|
+
withDependencies.set(identityKey(installed), {
|
|
459
|
+
dependencies: deps.map(({ name, org, type }) => ({ name, ...(org ? { org } : {}), type })),
|
|
460
|
+
files: deps.flatMap((e) => e.files),
|
|
461
|
+
name: installed.name,
|
|
462
|
+
...(installed.org ? { org: installed.org } : {}),
|
|
463
|
+
type: installed.type,
|
|
464
|
+
...(deps.some((e) => e.unchecked) ? { unchecked: true } : {}),
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
return withDependencies;
|
|
468
|
+
}
|
|
395
469
|
/** How a command names an asset: `@org/name`, with `--type` when the run was given one. */
|
|
396
470
|
function assetSpec(asset, type) {
|
|
397
471
|
return `${formatOrgName(asset.org, asset.name)}${type ? ` --type ${asset.type}` : ''}`;
|
|
398
472
|
}
|
|
473
|
+
/**
|
|
474
|
+
* The installed dependencies of `installed` an update to a version needing `newDeps` removes, as its
|
|
475
|
+
* cleanup does: dependencies it no longer declares, installed as dependencies, that no other asset
|
|
476
|
+
* the adapter's tool has depends on, and the dependencies only they needed.
|
|
477
|
+
*/
|
|
478
|
+
function droppedDependencies(installed, newDeps, lockfile, adapter) {
|
|
479
|
+
const newDepKeys = new Set(newDeps.map((d) => `${d.type}:${d.name}`));
|
|
480
|
+
return (installed.dependencies ?? [])
|
|
481
|
+
.filter((d) => !newDepKeys.has(`${d.type}:${d.name}`))
|
|
482
|
+
.flatMap((d) => {
|
|
483
|
+
const dep = findDependencyAsset(lockfile, d, installed.org);
|
|
484
|
+
if (!dep || (dep.installReason ?? 'direct') !== 'dependency')
|
|
485
|
+
return [];
|
|
486
|
+
const others = findDependents(lockfile, dep.name, dep.type, dep.org).filter((other) => !isSameAsset(other, installed) && !isExcludedForTool(other, adapter.tool));
|
|
487
|
+
// The cleanup uninstalls it with cascade, which also removes the dependencies only it needed.
|
|
488
|
+
return others.length === 0
|
|
489
|
+
? [dep, ...planUninstall(lockfile, dep.name, dep.org, dep.type, [adapter.tool]).orphanedDependencies]
|
|
490
|
+
: [];
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* The local edits of the installed dependencies an update of `installed` with `plan` replaces (the
|
|
495
|
+
* plan's other entries) or removes (see {@link droppedDependencies}). Entries `localEdits` holds for
|
|
496
|
+
* an asset because of its own dependencies (`dependencies` set) don't count.
|
|
497
|
+
*/
|
|
498
|
+
function editsReplacedBy(plan, installed, newDeps, lockfile, adapter, localEdits) {
|
|
499
|
+
const keys = new Set([
|
|
500
|
+
...plan.entries.filter((e) => !isSameAsset(e.asset, installed)).map((e) => identityKey(e.asset)),
|
|
501
|
+
...droppedDependencies(installed, newDeps, lockfile, adapter).map(identityKey),
|
|
502
|
+
]);
|
|
503
|
+
return [...keys].flatMap((key) => {
|
|
504
|
+
const edits = localEdits.get(key);
|
|
505
|
+
return edits && !edits.dependencies ? [edits] : [];
|
|
506
|
+
});
|
|
507
|
+
}
|
|
399
508
|
/**
|
|
400
509
|
* The skip record for an asset whose update would move a dependency whose own update failed for
|
|
401
510
|
* an earlier tool in the run: that tool kept the version the lockfile records, so moving it here
|
|
@@ -499,6 +608,23 @@ function liftFailure(installed, error) {
|
|
|
499
608
|
...errorGuidance(error),
|
|
500
609
|
};
|
|
501
610
|
}
|
|
611
|
+
/**
|
|
612
|
+
* The refusal to update `assetName` over local edits: its own (`edits` is the asset's) or those
|
|
613
|
+
* of a dependency the update replaces. The command forces the update of `spec` in its scope.
|
|
614
|
+
*/
|
|
615
|
+
function localEditsError(assetName, edits, spec, scope) {
|
|
616
|
+
const files = [...new Set(edits.flatMap((e) => e.files))].join(', ');
|
|
617
|
+
const own = edits.some((e) => e.name === assetName && !e.dependencies);
|
|
618
|
+
const dependencies = edits.flatMap((e) => e.dependencies ?? (e.name === assetName ? [] : [e]));
|
|
619
|
+
const names = [...new Set(dependencies.map((d) => `"${formatOrgName(d.org, d.name)}"`))].join(', ');
|
|
620
|
+
const command = scopedCommand(`atk update ${spec} --force`, scope);
|
|
621
|
+
const unchecked = edits.some((e) => e.unchecked)
|
|
622
|
+
? " Some files couldn't be checked against the registry's versions, so they may only be an earlier version's."
|
|
623
|
+
: '';
|
|
624
|
+
return new UpdaterError(own
|
|
625
|
+
? `Asset "${assetName}" has local edits (${files}), which updating it would overwrite. Use --force to overwrite them.`
|
|
626
|
+
: `Updating "${assetName}" would overwrite local edits in ${names} (${files}). Use --force to overwrite them.`, { command, hint: `Copy the edits somewhere else first, or pass --force to overwrite them.${unchecked}` });
|
|
627
|
+
}
|
|
502
628
|
/** The lockfile entry of an outdated asset: same name, type and org. */
|
|
503
629
|
function lockfileEntryFor(lockfile, asset) {
|
|
504
630
|
return (lockfile.assets ?? []).find((a) => isSameAsset(a, asset));
|
|
@@ -591,14 +717,27 @@ async function updateAssetPlanned(assetName, installed, registry, options) {
|
|
|
591
717
|
// Dependencies this tool already has at a version the new one accepts stay as they are, as in
|
|
592
718
|
// `atk install`; moving a pinned one refuses the update before anything changes.
|
|
593
719
|
let plan;
|
|
720
|
+
let kept;
|
|
594
721
|
try {
|
|
595
|
-
|
|
722
|
+
kept = { ...options, lockfile: options.toolLockfile ?? (await readLockfile(projectDir)) };
|
|
596
723
|
plan = planFor(registry, installed, toVersion, kept);
|
|
597
724
|
}
|
|
598
725
|
catch (planError) {
|
|
599
726
|
throw new UpdaterError(`Failed to update "${assetName}" to v${toVersion}: ${failureReason(planError, installed)} ` +
|
|
600
727
|
`v${fromVersion} is still installed.`, errorGuidance(planError));
|
|
601
728
|
}
|
|
729
|
+
// The update replaces the asset and each installed dependency its plan moves, and removes the ones
|
|
730
|
+
// it drops: refuse before the download when one has local edits.
|
|
731
|
+
if (!options.force && options.localEdits) {
|
|
732
|
+
const own = options.localEdits.get(identityKey(installed));
|
|
733
|
+
const newDeps = resolved.versionData.dependencies ?? [];
|
|
734
|
+
const edited = [
|
|
735
|
+
...(own ? [own] : []),
|
|
736
|
+
...editsReplacedBy(plan, installed, newDeps, kept.lockfile, adapter, options.localEdits),
|
|
737
|
+
];
|
|
738
|
+
if (edited.length > 0)
|
|
739
|
+
throw localEditsError(assetName, edited, assetSpec(installed, options.type), scope);
|
|
740
|
+
}
|
|
602
741
|
// Download the target version before removing anything, so a refused download (an outdated
|
|
603
742
|
// CLI, an expired sign-in, the API down) leaves the installed version in place.
|
|
604
743
|
onProgress?.(`Downloading ${assetName}@${toVersion}...`);
|