agmsg-cloud 0.1.0 → 0.1.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.
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// The `--version` contract, parsed as records rather than searched for.
|
|
2
|
+
//
|
|
3
|
+
// The command answers with TWO facts now (#341) — which build, and which copy
|
|
4
|
+
// of it answered — and a check that takes the first line matching each shape
|
|
5
|
+
// cannot tell one answer from two disagreeing ones. A binary printing two
|
|
6
|
+
// identity lines is broken in a way that matters precisely when several
|
|
7
|
+
// installs are in play, which is the situation the second line was added for;
|
|
8
|
+
// `find` would report the first and call it a pass.
|
|
9
|
+
//
|
|
10
|
+
// So: exactly one of each, nothing else, and the version read from the identity
|
|
11
|
+
// line alone. That last part is not tidiness. A directory carries
|
|
12
|
+
// version-shaped fragments of its own — a node prefix, a store entry, an npx
|
|
13
|
+
// cache path — and scanning the whole output for "every version here is the one
|
|
14
|
+
// asked for" fails a CORRECT package the moment it is installed under such a
|
|
15
|
+
// path. A verification that fails good releases is worse than none: the next
|
|
16
|
+
// real failure gets waved through as another false alarm.
|
|
17
|
+
export const IDENTITY_PREFIX = 'agmsg-cloud/';
|
|
18
|
+
export const FROM_PREFIX = 'running from ';
|
|
19
|
+
const VERSION_SHAPED = /\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/g;
|
|
20
|
+
/** Distinct version-shaped tokens in one string, in order of first appearance. */
|
|
21
|
+
export function versionsIn(text) {
|
|
22
|
+
return [...new Set(text.match(VERSION_SHAPED) ?? [])];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Read `--version` output as the pair of records it is.
|
|
26
|
+
*
|
|
27
|
+
* Every rejection names what was seen, because this runs against a published
|
|
28
|
+
* artifact where the next question is always "then what DID it print".
|
|
29
|
+
*/
|
|
30
|
+
export function parseVersionOutput(output) {
|
|
31
|
+
const lines = output
|
|
32
|
+
.split('\n')
|
|
33
|
+
.map((line) => line.trim())
|
|
34
|
+
.filter((line) => line !== '');
|
|
35
|
+
const identity = lines.filter((line) => line.startsWith(IDENTITY_PREFIX));
|
|
36
|
+
const from = lines.filter((line) => line.startsWith(FROM_PREFIX));
|
|
37
|
+
const other = lines.filter((line) => !line.startsWith(IDENTITY_PREFIX) && !line.startsWith(FROM_PREFIX));
|
|
38
|
+
if (identity.length === 0)
|
|
39
|
+
return { ok: false, reason: `no \`${IDENTITY_PREFIX}<version>\` line` };
|
|
40
|
+
if (identity.length > 1) {
|
|
41
|
+
return { ok: false, reason: `${identity.length} identity lines: ${identity.join(' | ')}` };
|
|
42
|
+
}
|
|
43
|
+
if (from.length === 0)
|
|
44
|
+
return { ok: false, reason: `no \`${FROM_PREFIX}<directory>\` line` };
|
|
45
|
+
if (from.length > 1) {
|
|
46
|
+
return { ok: false, reason: `${from.length} \`${FROM_PREFIX.trim()}\` lines: ${from.join(' | ')}` };
|
|
47
|
+
}
|
|
48
|
+
// Anything else is unexplained output, and this command's whole purpose is to
|
|
49
|
+
// be readable when something else has already gone wrong.
|
|
50
|
+
if (other.length > 0)
|
|
51
|
+
return { ok: false, reason: `unexpected output: ${other.join(' | ')}` };
|
|
52
|
+
const version = identity[0].slice(IDENTITY_PREFIX.length).trim();
|
|
53
|
+
if (version === '')
|
|
54
|
+
return { ok: false, reason: `identity line names no version: ${identity[0]}` };
|
|
55
|
+
// The identity line must carry ONE version and it must be the one it names —
|
|
56
|
+
// `agmsg-cloud/1.2.3 (from 4.5.6)` is two claims wearing one line.
|
|
57
|
+
const onLine = versionsIn(identity[0]);
|
|
58
|
+
if (onLine.length !== 1 || onLine[0] !== version) {
|
|
59
|
+
return { ok: false, reason: `identity line is not a single version: ${identity[0]}` };
|
|
60
|
+
}
|
|
61
|
+
const directory = from[0].slice(FROM_PREFIX.length).trim();
|
|
62
|
+
if (directory === '')
|
|
63
|
+
return { ok: false, reason: `no directory named: ${from[0]}` };
|
|
64
|
+
return { ok: true, version, directory };
|
|
65
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agmsg-cloud",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Companion CLI for the agmsg cloud service: connect a team, join from another machine, and back up its keys.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
14
|
"dist/src",
|
|
15
|
-
"
|
|
15
|
+
"dist/scripts",
|
|
16
|
+
"!dist/**/*.map"
|
|
16
17
|
],
|
|
17
18
|
"repository": {
|
|
18
19
|
"type": "git",
|