@erclx/canon 5.1.0 → 5.2.0
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/docs/agents/commands.md
CHANGED
|
@@ -141,3 +141,9 @@ The report carries three states and never changes an exit code. `behind` names
|
|
|
141
141
|
reason the registry could not be reached. Branch on the `skew.state` field in
|
|
142
142
|
the JSON record rather than on the exit, since an offline machine has to read as
|
|
143
143
|
unmeasured rather than as a failing check.
|
|
144
|
+
|
|
145
|
+
`canon upgrade --json` carries one further state, `pending`, that the skew report
|
|
146
|
+
does not. It means the checkout at the working directory holds a release npm does
|
|
147
|
+
not serve yet, so there is nothing to install. The record names that version in
|
|
148
|
+
`checkout` beside `latest`, exits 0, and its `message` starts `CLI stays at`. A
|
|
149
|
+
directory outside any canon checkout never reads `pending`.
|
package/package.json
CHANGED
|
@@ -43,6 +43,6 @@ export function matchInstall(
|
|
|
43
43
|
|
|
44
44
|
export function updatedMessage(before: string, after: string): string {
|
|
45
45
|
return after === before
|
|
46
|
-
? `
|
|
47
|
-
: `
|
|
46
|
+
? `Plugin reinstalled ${after}, unchanged.`
|
|
47
|
+
: `Plugin updated ${before} to ${after}.`
|
|
48
48
|
}
|
package/src/commands/upgrade.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Command } from 'commander'
|
|
2
2
|
import { execa } from 'execa'
|
|
3
|
-
import { PROJECT_ROOT } from '@/project-root'
|
|
3
|
+
import { findCheckoutMismatch, PROJECT_ROOT } from '@/project-root'
|
|
4
4
|
import {
|
|
5
5
|
frameError,
|
|
6
6
|
intro,
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
outro,
|
|
11
11
|
select,
|
|
12
12
|
} from '@/ui'
|
|
13
|
+
import { compareVersions, parseVersion } from '@/version/compare'
|
|
13
14
|
import { readInstalled, UNKNOWN_LABEL } from '@/version/installed'
|
|
14
15
|
import { detectManager, installCommand, type Manager } from '@/version/manager'
|
|
15
16
|
import {
|
|
@@ -30,7 +31,9 @@ interface UpgradeRecord {
|
|
|
30
31
|
readonly before: string
|
|
31
32
|
readonly after?: string
|
|
32
33
|
readonly latest?: string
|
|
33
|
-
|
|
34
|
+
/** The version of the checkout at cwd, present only on `pending`. */
|
|
35
|
+
readonly checkout?: string
|
|
36
|
+
readonly state: 'upgraded' | 'current' | 'pending' | 'cancelled' | 'refused'
|
|
34
37
|
readonly reason?: string
|
|
35
38
|
/**
|
|
36
39
|
* One rendered line for a caller that reports the outcome without parsing
|
|
@@ -117,7 +120,24 @@ async function runUpgrade(opts: UpgradeOptions): Promise<number> {
|
|
|
117
120
|
logStep('Published')
|
|
118
121
|
logInfo(describeSkew(skew))
|
|
119
122
|
|
|
123
|
+
const checkout = readCheckoutVersion()
|
|
124
|
+
const latest = latestOf(skew)
|
|
125
|
+
|
|
120
126
|
if (skew.state === 'current') {
|
|
127
|
+
const note = pendingNote(latest, checkout)
|
|
128
|
+
if (note !== undefined && checkout !== undefined) {
|
|
129
|
+
logWarn(note)
|
|
130
|
+
outro()
|
|
131
|
+
emit(opts, {
|
|
132
|
+
...base(before, manager, command, skew),
|
|
133
|
+
after: before,
|
|
134
|
+
checkout,
|
|
135
|
+
state: 'pending',
|
|
136
|
+
message: `CLI stays at ${before}. ${note}`,
|
|
137
|
+
})
|
|
138
|
+
return 0
|
|
139
|
+
}
|
|
140
|
+
|
|
121
141
|
outro()
|
|
122
142
|
emit(opts, {
|
|
123
143
|
...base(before, manager, command, skew),
|
|
@@ -128,7 +148,7 @@ async function runUpgrade(opts: UpgradeOptions): Promise<number> {
|
|
|
128
148
|
return 0
|
|
129
149
|
}
|
|
130
150
|
|
|
131
|
-
return await applyUpgrade(opts, before, skew, manager, command)
|
|
151
|
+
return await applyUpgrade(opts, before, skew, manager, command, checkout)
|
|
132
152
|
}
|
|
133
153
|
|
|
134
154
|
/**
|
|
@@ -147,6 +167,7 @@ async function applyUpgrade(
|
|
|
147
167
|
skew: SkewReport,
|
|
148
168
|
manager: Manager,
|
|
149
169
|
command: readonly string[],
|
|
170
|
+
checkout: string | undefined,
|
|
150
171
|
): Promise<number> {
|
|
151
172
|
const proceed = await select({
|
|
152
173
|
message: `Run \`${command.join(' ')}\`?`,
|
|
@@ -199,15 +220,50 @@ async function applyUpgrade(
|
|
|
199
220
|
...base(before, manager, command, skew),
|
|
200
221
|
after,
|
|
201
222
|
state: 'upgraded',
|
|
202
|
-
message: upgradedMessage(before, after),
|
|
223
|
+
message: [upgradedMessage(before, after), pendingNote(after, checkout)]
|
|
224
|
+
.filter((part) => part !== undefined)
|
|
225
|
+
.join(' '),
|
|
203
226
|
})
|
|
204
227
|
return 0
|
|
205
228
|
}
|
|
206
229
|
|
|
230
|
+
/**
|
|
231
|
+
* The version of the checkout the caller stands in, read off cwd rather than
|
|
232
|
+
* off `PROJECT_ROOT`, which is the installed package a bare `canon` resolves
|
|
233
|
+
* to. A target project sits in no canon checkout, so this reads nothing there
|
|
234
|
+
* and the verb behaves as it did.
|
|
235
|
+
*/
|
|
236
|
+
function readCheckoutVersion(): string | undefined {
|
|
237
|
+
const dir = findCheckoutMismatch(process.cwd())
|
|
238
|
+
return dir === undefined ? undefined : readInstalled(dir).version
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* The clause a caller appends when the checkout carries a release npm does not
|
|
243
|
+
* serve yet. A pull lands the release commit before the publish job finishes,
|
|
244
|
+
* so for a few minutes the checkout leads the registry, and a release that
|
|
245
|
+
* never publishes keeps it leading. The wording names the served version
|
|
246
|
+
* rather than promising a publish for that reason. `undefined` covers every
|
|
247
|
+
* case with nothing to say, including a version that does not parse.
|
|
248
|
+
*/
|
|
249
|
+
export function pendingNote(
|
|
250
|
+
served: string | undefined,
|
|
251
|
+
checkout: string | undefined,
|
|
252
|
+
): string | undefined {
|
|
253
|
+
if (served === undefined || checkout === undefined) return undefined
|
|
254
|
+
|
|
255
|
+
const local = parseVersion(checkout)
|
|
256
|
+
const published = parseVersion(served)
|
|
257
|
+
if (local === undefined || published === undefined) return undefined
|
|
258
|
+
if (compareVersions(local, published) <= 0) return undefined
|
|
259
|
+
|
|
260
|
+
return `The checkout is at ${checkout} and npm serves ${served}.`
|
|
261
|
+
}
|
|
262
|
+
|
|
207
263
|
export function upgradedMessage(before: string, after: string): string {
|
|
208
264
|
return after === before
|
|
209
|
-
? `
|
|
210
|
-
: `
|
|
265
|
+
? `CLI reinstalled ${after}, unchanged.`
|
|
266
|
+
: `CLI upgraded ${before} to ${after}.`
|
|
211
267
|
}
|
|
212
268
|
|
|
213
269
|
function base(
|