@detergent-software/atk 8.9.0-dev.9 → 8.9.1-dev.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/CHANGELOG.md +262 -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 +14 -14
- 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/lib/adapter.d.ts +10 -1
- package/build/lib/adapter.d.ts.map +1 -1
- package/build/lib/adapter.js +23 -0
- 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/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 +10 -0
- package/build/lib/checksum.d.ts.map +1 -1
- package/build/lib/checksum.js +17 -0
- 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 +6 -4
- package/build/lib/installer.d.ts.map +1 -1
- package/build/lib/installer.js +53 -23
- 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 +2 -2
- package/build/lib/lockfile.d.ts.map +1 -1
- package/build/lib/lockfile.js +28 -19
- 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 +3 -2
- package/build/lib/owned-paths.d.ts.map +1 -1
- package/build/lib/owned-paths.js +4 -2
- 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 +11 -0
- package/build/lib/process-alive.d.ts.map +1 -0
- package/build/lib/process-alive.js +22 -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 +3 -6
- package/build/lib/publish-flow.d.ts.map +1 -1
- package/build/lib/publish-flow.js +199 -246
- package/build/lib/publish-flow.js.map +1 -1
- package/build/lib/publish-run.d.ts +2 -2
- package/build/lib/publish-run.js +11 -6
- package/build/lib/publish-run.js.map +1 -1
- 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/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/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 +31 -7
- package/build/lib/sync.js.map +1 -1
- package/build/lib/uninstaller.d.ts.map +1 -1
- package/build/lib/uninstaller.js +6 -3
- 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.map +1 -1
- package/build/lib/write-file.js +63 -11
- package/build/lib/write-file.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { writeFile } from 'node:fs/promises';
|
|
2
2
|
import { join, resolve } from 'node:path';
|
|
3
|
+
import { compare as semverCompare, valid as semverValid } from 'semver';
|
|
3
4
|
import { loadAllAdapters, resolveInstalledPaths } from './adapter.js';
|
|
4
5
|
import { isApiError } from './api-client.js';
|
|
5
6
|
import { getCredential } from './auth.js';
|
|
6
|
-
import { hashFile } from './checksum.js';
|
|
7
7
|
import { errorGuidance, errorMessage } from './errors.js';
|
|
8
|
-
import { detectCompatibleTools, getSignedInUserName } from './init.js';
|
|
9
|
-
import {
|
|
8
|
+
import { detectCompatibleTools, getEntrypointName, getSignedInUserName } from './init.js';
|
|
9
|
+
import { findInstalledAsset, readLockfile } from './lockfile.js';
|
|
10
10
|
import { diffManifests, fetchExistingManifest } from './manifest-diff.js';
|
|
11
11
|
import { parseOrgFromName } from './org.js';
|
|
12
12
|
import { findProjectRoot } from './paths.js';
|
|
13
|
-
import { buildPublishPlan, buildStagingArea, bumpVersion, checkRegistryVersion, detectAssetFromPath, detectPublishType, executePublish, findSiblingDependencies, isOrgScopedTarget, loadPublishBatch, loadPublishEntries, mapPublishError, missingDependencies, resolvePlanDependencies, unknownToolsError, updateManifestField, updateManifestVersion, validatePublishTarget, } from './publisher.js';
|
|
14
|
-
import { clearCache,
|
|
13
|
+
import { buildPublishPlan, buildStagingArea, bumpVersion, checkRegistryVersion, detectAssetFromPath, detectPublishType, executePublish, filledManifestFields, findSiblingDependencies, isOrgScopedTarget, loadPublishBatch, loadPublishEntries, mapPublishError, missingDependencies, readManifestFile, resolvePlanDependencies, unknownToolsError, updateManifestField, updateManifestVersion, validatePublishTarget, } from './publisher.js';
|
|
14
|
+
import { clearCache, fetchAssetFileBytes, fetchAssetReadme, fetchRegistry, findAsset } from './registry.js';
|
|
15
15
|
import { parseReviewersInput, validateGithubUsername } from './reviewers.js';
|
|
16
16
|
import { stageInstalledFiles } from './staging.js';
|
|
17
17
|
import { resolveTools } from './tool-resolver.js';
|
|
@@ -162,6 +162,64 @@ async function firstFailure(edits) {
|
|
|
162
162
|
}
|
|
163
163
|
return undefined;
|
|
164
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* The metadata step of a raw publish, for a raw folder or an installed asset, whose `source`
|
|
167
|
+
* gives its org and any description of its own: the signed-in author, the description from
|
|
168
|
+
* --description or the source, the tags from --tags, and the tools from --tools or detection.
|
|
169
|
+
* An interactive run goes on to ask for what is missing; a non-interactive one stages the
|
|
170
|
+
* manifest now, or fails without a description or tools.
|
|
171
|
+
*/
|
|
172
|
+
async function gatherRawMetadata(state, ctx, detection, source) {
|
|
173
|
+
const [signedIn, tools] = await Promise.all([
|
|
174
|
+
getSignedInUserName(),
|
|
175
|
+
state.flags.toolsFlag ? splitList(state.flags.toolsFlag) : detectCompatibleTools(detection.assetType),
|
|
176
|
+
]);
|
|
177
|
+
if (ctx.cancelled())
|
|
178
|
+
return;
|
|
179
|
+
const author = signedIn ?? '';
|
|
180
|
+
const description = state.flags.descriptionFlag?.trim() || source.description;
|
|
181
|
+
if (!state.nonInteractive) {
|
|
182
|
+
ctx.dispatch({
|
|
183
|
+
authorValue: author,
|
|
184
|
+
...(description ? { description } : {}),
|
|
185
|
+
orgValue: source.org ?? '',
|
|
186
|
+
rawDetection: detection,
|
|
187
|
+
toolsDetected: tools,
|
|
188
|
+
type: 'RAW_DETECT_DONE',
|
|
189
|
+
});
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (!description) {
|
|
193
|
+
ctx.dispatch({
|
|
194
|
+
message: state.flags.fromInstalled
|
|
195
|
+
? `description required: provide --description (the lockfile has none for '${detection.name}')`
|
|
196
|
+
: 'description required: provide --description or include in manifest.json',
|
|
197
|
+
type: 'ERROR',
|
|
198
|
+
});
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (tools.length === 0) {
|
|
202
|
+
ctx.dispatch({
|
|
203
|
+
message: `--tools <comma-separated> required: no tools detected for type ${detection.assetType}`,
|
|
204
|
+
type: 'ERROR',
|
|
205
|
+
});
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const stagingDir = await buildStagingArea(detection, {
|
|
209
|
+
author,
|
|
210
|
+
description,
|
|
211
|
+
...(source.org ? { org: source.org } : {}),
|
|
212
|
+
tags: splitList(state.flags.tagsFlag),
|
|
213
|
+
tools,
|
|
214
|
+
});
|
|
215
|
+
ctx.stage(stagingDir);
|
|
216
|
+
if (ctx.cancelled())
|
|
217
|
+
return;
|
|
218
|
+
const detected = await detectPublishType(stagingDir);
|
|
219
|
+
if (ctx.cancelled())
|
|
220
|
+
return;
|
|
221
|
+
ctx.dispatch({ rawDetection: detection, target: detected, type: 'RAW_DETECT_DONE_NON_INTERACTIVE' });
|
|
222
|
+
}
|
|
165
223
|
function stepFor(state) {
|
|
166
224
|
switch (state.phase) {
|
|
167
225
|
case 'building-plan':
|
|
@@ -174,8 +232,6 @@ function stepFor(state) {
|
|
|
174
232
|
return detecting;
|
|
175
233
|
case 'gathering-metadata':
|
|
176
234
|
return state.metadataSubPhase === 'building-staging' ? buildingStaging : undefined;
|
|
177
|
-
case 'installing':
|
|
178
|
-
return installing;
|
|
179
235
|
case 'loading-tools':
|
|
180
236
|
return loadingTools;
|
|
181
237
|
case 'publishing':
|
|
@@ -228,10 +284,10 @@ function toErrorAction(err, override) {
|
|
|
228
284
|
}
|
|
229
285
|
/**
|
|
230
286
|
* Write what the run changed in memory to the manifests on disk: the root's bump and each
|
|
231
|
-
* entry's, and the tags and tools the
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
* other files are still written.
|
|
287
|
+
* entry's, and the tags and tools the publish sent on top of the root's manifest (from flags,
|
|
288
|
+
* prompts or detection). Only once the publish has opened its PR, so a cancelled or failed one
|
|
289
|
+
* leaves every manifest as it was. A file whose write fails takes none of its later edits and
|
|
290
|
+
* comes back as one warning naming the fields it lacks; the other files are still written.
|
|
235
291
|
*/
|
|
236
292
|
async function writeManifestEdits(state) {
|
|
237
293
|
const target = state.target;
|
|
@@ -243,19 +299,14 @@ async function writeManifestEdits(state) {
|
|
|
243
299
|
files.set(path, [...(files.get(path) ?? []), { field, value, write }]);
|
|
244
300
|
};
|
|
245
301
|
const version = (dir, file, value) => edit(dir, file, 'version', value, () => updateManifestVersion(dir, file, value));
|
|
246
|
-
const
|
|
302
|
+
const manifestFile = target.type === 'asset' ? 'manifest.json' : 'bundle.json';
|
|
247
303
|
if (state.versionCheck?.status === 'needs-bump' && state.resolvedVersion) {
|
|
248
|
-
version(target.sourceDir,
|
|
304
|
+
version(target.sourceDir, manifestFile, state.resolvedVersion);
|
|
249
305
|
}
|
|
250
|
-
//
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
field('tags', tags);
|
|
255
|
-
}
|
|
256
|
-
if (state.selectedPromptTools.length > 0) {
|
|
257
|
-
field('tools', tools);
|
|
258
|
-
}
|
|
306
|
+
// A manifest that can't be read now takes no field edits; its version edit, if any, warns.
|
|
307
|
+
const written = await readManifestFile(target).catch(() => undefined);
|
|
308
|
+
for (const [name, value] of Object.entries(written ? filledManifestFields(written, target) : {})) {
|
|
309
|
+
edit(target.sourceDir, manifestFile, name, value, () => updateManifestField(target.sourceDir, manifestFile, name, value));
|
|
259
310
|
}
|
|
260
311
|
for (const entry of state.entries) {
|
|
261
312
|
if (entry.versionCheck?.status === 'needs-bump' && entry.resolvedVersion) {
|
|
@@ -268,7 +319,7 @@ async function writeManifestEdits(state) {
|
|
|
268
319
|
if (!failed)
|
|
269
320
|
continue;
|
|
270
321
|
const missing = edits.slice(failed.index);
|
|
271
|
-
// Only the version matters to the next publish: it
|
|
322
|
+
// Only the version matters to the next publish: it fills missing tags and tools again.
|
|
272
323
|
const again = missing.some((e) => e.field === 'version') ? ' before you publish it again' : '';
|
|
273
324
|
unwritten.push(`The PR is open, but ${path} wasn't updated (${errorMessage(failed.error)}): set ${missing.map((e) => `"${e.field}" to ${JSON.stringify(e.value)}`).join(', ')}${again}.`);
|
|
274
325
|
}
|
|
@@ -277,29 +328,45 @@ async function writeManifestEdits(state) {
|
|
|
277
328
|
// ---------------------------------------------------------------------------
|
|
278
329
|
// Steps, one per phase that waits on work
|
|
279
330
|
// ---------------------------------------------------------------------------
|
|
331
|
+
/**
|
|
332
|
+
* The installed asset's files, at their source paths, through a raw publish's metadata step,
|
|
333
|
+
* with the version, entrypoint, dependencies, org and description its lockfile entry records.
|
|
334
|
+
*/
|
|
280
335
|
const resolvingInstalled = {
|
|
281
336
|
async run(state, ctx) {
|
|
282
337
|
const source = await findInstalledSource(state, ctx);
|
|
283
338
|
if (!source)
|
|
284
339
|
return;
|
|
285
340
|
const { adapter, installed, projectRoot } = source;
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
341
|
+
const { files } = resolveInstalledPaths(installed, adapter, projectRoot);
|
|
342
|
+
// An older lockfile entry has no entrypoint: the type's usual one when it was installed, else its first file.
|
|
343
|
+
const usual = getEntrypointName(installed.type, installed.name);
|
|
344
|
+
const entrypoint = installed.entrypoint ?? (files.some((file) => file.sourcePath === usual) ? usual : files[0]?.sourcePath);
|
|
345
|
+
const dependencies = (installed.dependencies ?? []).map(({ name, type, version }) => ({
|
|
346
|
+
name,
|
|
347
|
+
type,
|
|
348
|
+
...(version ? { version } : {}),
|
|
349
|
+
}));
|
|
350
|
+
const detection = {
|
|
351
|
+
assetType: installed.type,
|
|
352
|
+
...(dependencies.length > 0 ? { dependencies } : {}),
|
|
353
|
+
...(entrypoint ? { entrypoint } : {}),
|
|
354
|
+
files: files.map((file) => ({
|
|
355
|
+
absolutePath: join(projectRoot, file.installedPath),
|
|
356
|
+
relativePath: file.sourcePath,
|
|
357
|
+
})),
|
|
296
358
|
name: installed.name,
|
|
297
|
-
|
|
298
|
-
type: installed.type,
|
|
359
|
+
sourceDir: projectRoot,
|
|
299
360
|
version: installed.version,
|
|
300
361
|
};
|
|
301
|
-
|
|
302
|
-
|
|
362
|
+
// A --with folder that is missing, a bundle or a repeat fails here, before any prompt, as in detecting.
|
|
363
|
+
if (state.flags.withPaths?.length) {
|
|
364
|
+
const entries = await loadPublishEntries(state.flags.withPaths, projectRoot);
|
|
365
|
+
if (ctx.cancelled())
|
|
366
|
+
return;
|
|
367
|
+
ctx.dispatch({ entries, type: 'ENTRIES_LOADED' });
|
|
368
|
+
}
|
|
369
|
+
await gatherRawMetadata(state, ctx, detection, { description: installed.description, org: installed.org });
|
|
303
370
|
},
|
|
304
371
|
};
|
|
305
372
|
const resolvingUpdate = {
|
|
@@ -309,21 +376,35 @@ const resolvingUpdate = {
|
|
|
309
376
|
return;
|
|
310
377
|
const { adapter, installed, org, projectRoot } = source;
|
|
311
378
|
const assetName = state.flags.rawPath;
|
|
312
|
-
// Fetch the registry to find the latest version
|
|
379
|
+
// Fetch the registry to find the latest version. An installed entry is always an asset.
|
|
313
380
|
const registry = await fetchRegistry({ force: state.flags.refresh });
|
|
314
381
|
if (ctx.cancelled())
|
|
315
382
|
return;
|
|
316
|
-
// Look up the asset in the registry: try findAsset first, then findBundle
|
|
317
383
|
const resolvedAsset = findAsset(registry, installed.name, installed.type, undefined, installed.org ?? org);
|
|
318
|
-
|
|
319
|
-
if (!resolvedAsset && !resolvedBundle) {
|
|
384
|
+
if (!resolvedAsset) {
|
|
320
385
|
ctx.dispatch({ message: `Asset '${assetName}' not found in the registry.`, type: 'ERROR' });
|
|
321
386
|
return;
|
|
322
387
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
388
|
+
// The installed files go out on top of the latest's manifest, so they must not be older
|
|
389
|
+
// than it: they would publish the next version without the changes made since.
|
|
390
|
+
const latestVersion = resolvedAsset.version;
|
|
391
|
+
if (!semverValid(installed.version) || semverCompare(installed.version, latestVersion) < 0) {
|
|
392
|
+
ctx.dispatch({
|
|
393
|
+
command: `atk diff ${assetName}`,
|
|
394
|
+
hint: `See what changed since v${installed.version} with \`atk diff ${assetName}\`, get the latest into a folder with \`atk checkout ${assetName}\`, carry your edits into it, and publish that folder.`,
|
|
395
|
+
message: `'${assetName}' is installed at v${installed.version}, but the registry's latest is v${latestVersion}. --update would publish your copy, built on v${installed.version}, as the next version and undo the changes made since.`,
|
|
396
|
+
type: 'ERROR',
|
|
397
|
+
});
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
// The latest's manifest as the registry has it, byte for byte, so a field this CLI's schema
|
|
401
|
+
// doesn't know (from a newer publisher) is published again; and its README, if any.
|
|
402
|
+
const { org: assetOrg, type } = resolvedAsset.asset;
|
|
403
|
+
const ref = { name: installed.name, ...(assetOrg ? { org: assetOrg } : {}), type };
|
|
404
|
+
const [manifest, readme] = await Promise.all([
|
|
405
|
+
fetchAssetFileBytes(ref, latestVersion, 'manifest.json'),
|
|
406
|
+
fetchAssetReadme(ref, latestVersion),
|
|
407
|
+
]);
|
|
327
408
|
if (ctx.cancelled())
|
|
328
409
|
return;
|
|
329
410
|
// Copy the user's locally modified files into a temp staging directory
|
|
@@ -331,13 +412,9 @@ const resolvingUpdate = {
|
|
|
331
412
|
ctx.stage(tempDir);
|
|
332
413
|
if (ctx.cancelled())
|
|
333
414
|
return;
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
await writeFile(join(tempDir, fetched.manifestFileName), fetched.manifestContent, 'utf-8');
|
|
338
|
-
// Write README if present
|
|
339
|
-
if (fetched.readmeContent) {
|
|
340
|
-
await writeFile(join(tempDir, 'README.md'), fetched.readmeContent, 'utf-8');
|
|
415
|
+
await writeFile(join(tempDir, 'manifest.json'), manifest);
|
|
416
|
+
if (readme) {
|
|
417
|
+
await writeFile(join(tempDir, 'README.md'), readme, 'utf-8');
|
|
341
418
|
}
|
|
342
419
|
ctx.dispatch({ resolvedPath: tempDir, type: 'RESOLVED_UPDATE' });
|
|
343
420
|
},
|
|
@@ -388,66 +465,11 @@ const detecting = {
|
|
|
388
465
|
const detection = await detectAssetFromPath(state.resolvedPath, adapter, projectRoot);
|
|
389
466
|
if (ctx.cancelled())
|
|
390
467
|
return;
|
|
391
|
-
//
|
|
392
|
-
const author = (await getSignedInUserName()) ?? '';
|
|
393
|
-
if (ctx.cancelled())
|
|
394
|
-
return;
|
|
468
|
+
// No manifest exists yet, so the project's org and the flags and prompts give the metadata.
|
|
395
469
|
const lockfile = await readLockfile(projectRoot);
|
|
396
470
|
if (ctx.cancelled())
|
|
397
471
|
return;
|
|
398
|
-
|
|
399
|
-
if (ctx.cancelled())
|
|
400
|
-
return;
|
|
401
|
-
// Non-interactive mode (raw publish — no manifest exists yet, so the only
|
|
402
|
-
// sources for description are --description flag or exit-1; tags come from
|
|
403
|
-
// --tags or default to empty). Tool detection runs for both modes above.
|
|
404
|
-
if (!state.nonInteractive) {
|
|
405
|
-
// Interactive mode — gather metadata from the user
|
|
406
|
-
ctx.dispatch({
|
|
407
|
-
authorValue: author,
|
|
408
|
-
orgValue: lockfile.org ?? '',
|
|
409
|
-
rawDetection: detection,
|
|
410
|
-
toolsDetected: tools,
|
|
411
|
-
type: 'RAW_DETECT_DONE',
|
|
412
|
-
});
|
|
413
|
-
return;
|
|
414
|
-
}
|
|
415
|
-
if (!state.flags.descriptionFlag) {
|
|
416
|
-
ctx.dispatch({
|
|
417
|
-
message: 'description required: provide --description or include in manifest.json',
|
|
418
|
-
type: 'ERROR',
|
|
419
|
-
});
|
|
420
|
-
return;
|
|
421
|
-
}
|
|
422
|
-
// Tools resolution: --tools flag -> detected (already populated above)
|
|
423
|
-
let toolsList;
|
|
424
|
-
if (state.flags.toolsFlag) {
|
|
425
|
-
toolsList = splitList(state.flags.toolsFlag);
|
|
426
|
-
}
|
|
427
|
-
else if (tools.length > 0) {
|
|
428
|
-
toolsList = tools;
|
|
429
|
-
}
|
|
430
|
-
else {
|
|
431
|
-
ctx.dispatch({
|
|
432
|
-
message: `--tools <comma-separated> required: no tools detected for type ${detection.assetType}`,
|
|
433
|
-
type: 'ERROR',
|
|
434
|
-
});
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
const stagingDir = await buildStagingArea(detection, {
|
|
438
|
-
author,
|
|
439
|
-
description: state.flags.descriptionFlag,
|
|
440
|
-
...(lockfile.org ? { org: lockfile.org } : {}),
|
|
441
|
-
tags: splitList(state.flags.tagsFlag),
|
|
442
|
-
tools: toolsList,
|
|
443
|
-
});
|
|
444
|
-
ctx.stage(stagingDir);
|
|
445
|
-
if (ctx.cancelled())
|
|
446
|
-
return;
|
|
447
|
-
const detected = await detectPublishType(stagingDir);
|
|
448
|
-
if (ctx.cancelled())
|
|
449
|
-
return;
|
|
450
|
-
ctx.dispatch({ rawDetection: detection, target: detected, type: 'RAW_DETECT_DONE_NON_INTERACTIVE' });
|
|
472
|
+
await gatherRawMetadata(state, ctx, detection, { org: lockfile.org });
|
|
451
473
|
},
|
|
452
474
|
};
|
|
453
475
|
/** The `building-staging` sub-phase of `gathering-metadata`: the manifest from the prompts' answers. */
|
|
@@ -528,14 +550,13 @@ const validating = {
|
|
|
528
550
|
},
|
|
529
551
|
};
|
|
530
552
|
/**
|
|
531
|
-
* In interactive mode, loads adapters for the multi-select prompt.
|
|
532
|
-
*
|
|
533
|
-
*
|
|
534
|
-
* checking-registry.
|
|
553
|
+
* In interactive mode without --tools, loads adapters for the multi-select prompt. Otherwise
|
|
554
|
+
* resolves tools via manifest -> --tools flag -> detectCompatibleTools(assetType) -> exit 1,
|
|
555
|
+
* then dispatches RESOLVE_TOOLS_NONINTERACTIVE to advance past the prompt.
|
|
535
556
|
*/
|
|
536
557
|
const loadingTools = {
|
|
537
558
|
async run(state, ctx) {
|
|
538
|
-
if (!state.nonInteractive) {
|
|
559
|
+
if (!state.nonInteractive && !state.flags.toolsFlag) {
|
|
539
560
|
const adapters = await loadAllAdapters();
|
|
540
561
|
if (ctx.cancelled())
|
|
541
562
|
return;
|
|
@@ -689,8 +710,8 @@ const buildingPlan = {
|
|
|
689
710
|
const localPlan = await buildPublishPlan(currentTarget, currentVersion, state.isUpdate, state.flags.message, reviewers, entries, ...(isBatch(state.flags) ? [state.flags.rawPath] : []));
|
|
690
711
|
if (ctx.cancelled())
|
|
691
712
|
return;
|
|
692
|
-
//
|
|
693
|
-
//
|
|
713
|
+
// Ask the API for its plan now, so the preview and --dry-run show its dependencies
|
|
714
|
+
// and reviewers, and anything it rejects stops before the confirm prompt.
|
|
694
715
|
const publishPlan = await resolvePlanDependencies(localPlan);
|
|
695
716
|
if (ctx.cancelled())
|
|
696
717
|
return;
|
|
@@ -727,77 +748,14 @@ const publishing = {
|
|
|
727
748
|
catch {
|
|
728
749
|
// Best-effort — don't fail publish over cache
|
|
729
750
|
}
|
|
730
|
-
//
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
const projectRoot = findProjectRoot(state.flags.projectRoot);
|
|
734
|
-
const pubTools = await resolveTools(state.flags.tool);
|
|
735
|
-
const pubAdapter = pubTools[0].adapter;
|
|
736
|
-
await withLockfileLock(projectRoot, async () => {
|
|
737
|
-
const lockfile = await readLockfile(projectRoot);
|
|
738
|
-
const { name, org } = parseOrgFromName(state.flags.rawPath);
|
|
739
|
-
const installed = findInstalledAsset(lockfile, name, undefined, org);
|
|
740
|
-
if (installed) {
|
|
741
|
-
const resolved = resolveInstalledPaths(installed, pubAdapter, projectRoot);
|
|
742
|
-
const updatedFiles = await Promise.all(resolved.files.map(async (file) => ({
|
|
743
|
-
checksum: await hashFile(join(projectRoot, file.installedPath)),
|
|
744
|
-
sourcePath: file.sourcePath,
|
|
745
|
-
})));
|
|
746
|
-
const updatedLockfile = addAssetToLockfile(lockfile, {
|
|
747
|
-
...installed,
|
|
748
|
-
files: updatedFiles,
|
|
749
|
-
version: state.resolvedVersion,
|
|
750
|
-
});
|
|
751
|
-
await writeLockfile(projectRoot, updatedLockfile);
|
|
752
|
-
}
|
|
753
|
-
});
|
|
754
|
-
}
|
|
755
|
-
catch {
|
|
756
|
-
// Best-effort — don't fail publish over lockfile update
|
|
757
|
-
}
|
|
758
|
-
}
|
|
751
|
+
// The lockfile is left as it was, even for an installed asset or a raw folder: the registry
|
|
752
|
+
// has the new version only once the PR merges, and a fresh clone installs the version the
|
|
753
|
+
// lockfile names (ATK-592). `atk update` (or `atk install`) records it after the merge.
|
|
759
754
|
if (ctx.cancelled())
|
|
760
755
|
return;
|
|
761
756
|
ctx.dispatch({ result, type: 'PUBLISH_DONE' });
|
|
762
757
|
},
|
|
763
758
|
};
|
|
764
|
-
/** A raw publish records the asset it published in the lockfile, as installed from the project's own files. */
|
|
765
|
-
const installing = {
|
|
766
|
-
async run(state, ctx) {
|
|
767
|
-
try {
|
|
768
|
-
const projectRoot = findProjectRoot(state.flags.projectRoot);
|
|
769
|
-
await withLockfileLock(projectRoot, async () => {
|
|
770
|
-
// Read current lockfile
|
|
771
|
-
const lockfile = await readLockfile(projectRoot);
|
|
772
|
-
// Compute checksums from actual project files (not staging copies)
|
|
773
|
-
const files = [];
|
|
774
|
-
for (const file of state.rawDetection.files) {
|
|
775
|
-
const checksum = await hashFile(file.absolutePath);
|
|
776
|
-
files.push({
|
|
777
|
-
checksum,
|
|
778
|
-
sourcePath: file.relativePath,
|
|
779
|
-
});
|
|
780
|
-
}
|
|
781
|
-
// Build InstalledAsset entry
|
|
782
|
-
const installedAsset = {
|
|
783
|
-
files,
|
|
784
|
-
installReason: 'direct',
|
|
785
|
-
name: state.rawDetection.name,
|
|
786
|
-
org: state.orgValue || undefined,
|
|
787
|
-
type: state.rawDetection.assetType,
|
|
788
|
-
version: state.resolvedVersion || state.target?.data.version || '1.0.0',
|
|
789
|
-
};
|
|
790
|
-
// Add to lockfile and write
|
|
791
|
-
const updatedLockfile = addAssetToLockfile(lockfile, installedAsset);
|
|
792
|
-
await writeLockfile(projectRoot, updatedLockfile);
|
|
793
|
-
});
|
|
794
|
-
}
|
|
795
|
-
catch {
|
|
796
|
-
// Publish already succeeded, so just warn and move to done
|
|
797
|
-
}
|
|
798
|
-
ctx.dispatch({ type: 'INSTALL_DONE' });
|
|
799
|
-
},
|
|
800
|
-
};
|
|
801
759
|
// ---------------------------------------------------------------------------
|
|
802
760
|
// Reducer
|
|
803
761
|
// ---------------------------------------------------------------------------
|
|
@@ -855,8 +813,6 @@ export function publishReducer(state, action) {
|
|
|
855
813
|
errorMessage: action.message,
|
|
856
814
|
phase: 'error',
|
|
857
815
|
};
|
|
858
|
-
case 'INSTALL_DONE':
|
|
859
|
-
return { ...state, phase: 'done' };
|
|
860
816
|
case 'PLAN_DONE': {
|
|
861
817
|
// dry-run always shows the dry-run result; --yes / non-TTY skip the confirm prompt
|
|
862
818
|
// and proceed directly to publishing.
|
|
@@ -877,30 +833,28 @@ export function publishReducer(state, action) {
|
|
|
877
833
|
plan: action.plan,
|
|
878
834
|
};
|
|
879
835
|
}
|
|
880
|
-
case 'PUBLISH_DONE':
|
|
881
|
-
|
|
882
|
-
return {
|
|
883
|
-
...state,
|
|
884
|
-
phase: nextPhase,
|
|
885
|
-
publishResult: action.result,
|
|
886
|
-
};
|
|
887
|
-
}
|
|
836
|
+
case 'PUBLISH_DONE':
|
|
837
|
+
return { ...state, phase: 'done', publishResult: action.result };
|
|
888
838
|
case 'PUBLISH_PROGRESS':
|
|
889
839
|
return { ...state, progressMessage: action.message };
|
|
890
840
|
case 'RAW_DETECT_DONE':
|
|
841
|
+
// Ask only for what neither a flag nor the installed asset gave.
|
|
891
842
|
return {
|
|
892
843
|
...state,
|
|
893
844
|
authorValue: action.authorValue,
|
|
894
|
-
|
|
845
|
+
descriptionValue: action.description ?? '',
|
|
846
|
+
isRawPublish: !state.flags.fromInstalled,
|
|
847
|
+
metadataSubPhase: action.description === undefined ? 'description' : metadataAfterDescription(state),
|
|
895
848
|
orgValue: action.orgValue,
|
|
896
849
|
phase: 'gathering-metadata',
|
|
897
850
|
rawDetection: action.rawDetection,
|
|
851
|
+
tagsValue: state.flags.tagsFlag ?? '',
|
|
898
852
|
toolsDetected: action.toolsDetected,
|
|
899
853
|
};
|
|
900
854
|
case 'RAW_DETECT_DONE_NON_INTERACTIVE':
|
|
901
855
|
return {
|
|
902
856
|
...state,
|
|
903
|
-
isRawPublish:
|
|
857
|
+
isRawPublish: !state.flags.fromInstalled,
|
|
904
858
|
phase: 'validating',
|
|
905
859
|
rawDetection: action.rawDetection,
|
|
906
860
|
target: action.target,
|
|
@@ -920,34 +874,32 @@ export function publishReducer(state, action) {
|
|
|
920
874
|
}
|
|
921
875
|
else {
|
|
922
876
|
// needs-bump
|
|
923
|
-
if (state.
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
};
|
|
932
|
-
nextPhase = 'building-plan';
|
|
933
|
-
}
|
|
934
|
-
catch {
|
|
935
|
-
errorMessage = 'Failed to compute bumped version.';
|
|
936
|
-
nextPhase = 'error';
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
else if (isBatch(state.flags)) {
|
|
940
|
-
// advanceToPlan lists every asset of the batch that needs --bump, once the entries are checked.
|
|
877
|
+
if (state.flags.bump && state.target) {
|
|
878
|
+
// --bump applies in any run; a successful publish writes it to the manifest
|
|
879
|
+
try {
|
|
880
|
+
bumpedVersion = bumpVersion(versionCheck.latestVersion, state.flags.bump);
|
|
881
|
+
bumpedTarget = {
|
|
882
|
+
...state.target,
|
|
883
|
+
data: { ...state.target.data, version: bumpedVersion },
|
|
884
|
+
};
|
|
941
885
|
nextPhase = 'building-plan';
|
|
942
886
|
}
|
|
943
|
-
|
|
944
|
-
errorMessage =
|
|
887
|
+
catch {
|
|
888
|
+
errorMessage = 'Failed to compute bumped version.';
|
|
945
889
|
nextPhase = 'error';
|
|
946
890
|
}
|
|
947
891
|
}
|
|
948
|
-
else {
|
|
892
|
+
else if (!state.nonInteractive) {
|
|
949
893
|
nextPhase = 'bump-prompt';
|
|
950
894
|
}
|
|
895
|
+
else if (isBatch(state.flags)) {
|
|
896
|
+
// advanceToPlan lists every asset of the batch that needs --bump, once the entries are checked.
|
|
897
|
+
nextPhase = 'building-plan';
|
|
898
|
+
}
|
|
899
|
+
else {
|
|
900
|
+
errorMessage = `--bump <patch|minor|major> required: registry has v${versionCheck.latestVersion} but manifest is not newer`;
|
|
901
|
+
nextPhase = 'error';
|
|
902
|
+
}
|
|
951
903
|
}
|
|
952
904
|
const checked = {
|
|
953
905
|
...state,
|
|
@@ -970,16 +922,11 @@ export function publishReducer(state, action) {
|
|
|
970
922
|
: undefined;
|
|
971
923
|
return {
|
|
972
924
|
...state,
|
|
973
|
-
|
|
925
|
+
// An interactive run's --tools stood in for the tools prompt; the reviewer prompt may still follow.
|
|
926
|
+
phase: state.nonInteractive ? 'checking-registry' : phaseAfterMetadata(updatedTarget),
|
|
974
927
|
target: updatedTarget,
|
|
975
928
|
};
|
|
976
929
|
}
|
|
977
|
-
case 'RESOLVED_INSTALLED':
|
|
978
|
-
return {
|
|
979
|
-
...state,
|
|
980
|
-
phase: 'detecting',
|
|
981
|
-
resolvedPath: action.resolvedPath,
|
|
982
|
-
};
|
|
983
930
|
case 'RESOLVED_UPDATE':
|
|
984
931
|
return {
|
|
985
932
|
...state,
|
|
@@ -1062,7 +1009,7 @@ export function publishReducer(state, action) {
|
|
|
1062
1009
|
return {
|
|
1063
1010
|
...state,
|
|
1064
1011
|
descriptionValue: trimmed,
|
|
1065
|
-
metadataSubPhase:
|
|
1012
|
+
metadataSubPhase: metadataAfterDescription(state),
|
|
1066
1013
|
};
|
|
1067
1014
|
}
|
|
1068
1015
|
case 'SUBMIT_PROMPT_TAGS': {
|
|
@@ -1170,19 +1117,21 @@ export function publishReducer(state, action) {
|
|
|
1170
1117
|
validation: action.validation,
|
|
1171
1118
|
};
|
|
1172
1119
|
}
|
|
1173
|
-
//
|
|
1174
|
-
//
|
|
1175
|
-
|
|
1176
|
-
|
|
1120
|
+
// A manifest without tags takes them from --tags right here, in any run: a non-interactive
|
|
1121
|
+
// one without the flag publishes none, an interactive one asks. Manifest tags always win.
|
|
1122
|
+
const tagsFromFlag = !hasTags && (state.nonInteractive || state.flags.tagsFlag !== undefined);
|
|
1123
|
+
let nextTarget = state.target;
|
|
1124
|
+
if (tagsFromFlag && nextTarget) {
|
|
1125
|
+
const flagTags = splitList(state.flags.tagsFlag);
|
|
1126
|
+
nextTarget = {
|
|
1127
|
+
...nextTarget,
|
|
1128
|
+
data: { ...nextTarget.data, tags: flagTags.length > 0 ? flagTags : undefined },
|
|
1129
|
+
};
|
|
1130
|
+
}
|
|
1131
|
+
// Non-interactive path: either route to loading-tools (effect resolves tools async) or
|
|
1132
|
+
// directly to checking-registry. The reviewer prompt never applies here — non-interactive
|
|
1133
|
+
// mode always skips it.
|
|
1177
1134
|
if (state.nonInteractive) {
|
|
1178
|
-
let nextTarget = state.target;
|
|
1179
|
-
if (!hasTags && nextTarget) {
|
|
1180
|
-
const flagTags = splitList(state.flags.tagsFlag);
|
|
1181
|
-
nextTarget = {
|
|
1182
|
-
...nextTarget,
|
|
1183
|
-
data: { ...nextTarget.data, tags: flagTags.length > 0 ? flagTags : undefined },
|
|
1184
|
-
};
|
|
1185
|
-
}
|
|
1186
1135
|
let nextPhase;
|
|
1187
1136
|
if (!hasTools) {
|
|
1188
1137
|
// The loading-tools effect detects whether we're non-interactive and
|
|
@@ -1201,7 +1150,7 @@ export function publishReducer(state, action) {
|
|
|
1201
1150
|
};
|
|
1202
1151
|
}
|
|
1203
1152
|
let nextPhase;
|
|
1204
|
-
if (!hasTags) {
|
|
1153
|
+
if (!hasTags && !tagsFromFlag) {
|
|
1205
1154
|
nextPhase = 'prompting-tags';
|
|
1206
1155
|
}
|
|
1207
1156
|
else if (!hasTools) {
|
|
@@ -1214,6 +1163,7 @@ export function publishReducer(state, action) {
|
|
|
1214
1163
|
...state,
|
|
1215
1164
|
phase: nextPhase,
|
|
1216
1165
|
reviewerValue,
|
|
1166
|
+
target: nextTarget,
|
|
1217
1167
|
validation: action.validation,
|
|
1218
1168
|
};
|
|
1219
1169
|
}
|
|
@@ -1224,7 +1174,7 @@ export function publishReducer(state, action) {
|
|
|
1224
1174
|
/**
|
|
1225
1175
|
* The step before `building-plan`, once the root asset's own checks are done:
|
|
1226
1176
|
* check the entries not yet checked, then settle each entry that needs a bump
|
|
1227
|
-
* (the bump prompt
|
|
1177
|
+
* (`--bump`; without it, the bump prompt, or an error when non-interactive), then plan.
|
|
1228
1178
|
*/
|
|
1229
1179
|
function advanceToPlan(state) {
|
|
1230
1180
|
if (state.entries.some((entry) => !entry.versionCheck)) {
|
|
@@ -1254,18 +1204,17 @@ function advanceToPlan(state) {
|
|
|
1254
1204
|
if (entry?.versionCheck?.status !== 'needs-bump') {
|
|
1255
1205
|
return { ...state, bumpEntry: undefined, phase: 'building-plan' };
|
|
1256
1206
|
}
|
|
1207
|
+
if (state.flags.bump) {
|
|
1208
|
+
return bumpEntryAt(state, index, state.flags.bump);
|
|
1209
|
+
}
|
|
1257
1210
|
if (!state.nonInteractive) {
|
|
1258
1211
|
return { ...state, bumpEntry: index, bumpSelection: '', phase: 'bump-prompt' };
|
|
1259
1212
|
}
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
phase: 'error',
|
|
1266
|
-
};
|
|
1267
|
-
}
|
|
1268
|
-
return bumpEntryAt(state, index, state.flags.bump);
|
|
1213
|
+
return {
|
|
1214
|
+
...state,
|
|
1215
|
+
errorMessage: `--bump <patch|minor|major> required: registry has v${entry.versionCheck.latestVersion} of ${entry.target.assetType}:${entry.target.data.name} (from ${entry.label}) but its manifest is not newer`,
|
|
1216
|
+
phase: 'error',
|
|
1217
|
+
};
|
|
1269
1218
|
}
|
|
1270
1219
|
/**
|
|
1271
1220
|
* Bump the entry at `index` from its registry version, then go on toward the
|
|
@@ -1284,6 +1233,10 @@ function bumpEntryAt(state, index, bump) {
|
|
|
1284
1233
|
}
|
|
1285
1234
|
return advanceToPlan({ ...state, entries: replaceEntry(state.entries, index, withVersion(entry, version)) });
|
|
1286
1235
|
}
|
|
1236
|
+
/** A raw publish's step after its description: the tags prompt, unless --tags answered it. */
|
|
1237
|
+
function metadataAfterDescription(state) {
|
|
1238
|
+
return state.flags.tagsFlag === undefined ? 'tags' : 'building-staging';
|
|
1239
|
+
}
|
|
1287
1240
|
/**
|
|
1288
1241
|
* Phase to enter once the tags/tools metadata prompts are resolved: org-scoped
|
|
1289
1242
|
* targets get the reviewer prompt, everything else proceeds to the registry check.
|