@udondan/avanti 0.12.1 → 0.13.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/README.md +54 -9
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +7 -0
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/lock.d.ts +3 -0
- package/dist/commands/lock.d.ts.map +1 -0
- package/dist/commands/lock.js +103 -0
- package/dist/commands/lock.js.map +1 -0
- package/dist/commands/log.js +30 -0
- package/dist/commands/log.js.map +1 -1
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +126 -15
- package/dist/commands/pull.js.map +1 -1
- package/dist/config-writeback.d.ts +12 -0
- package/dist/config-writeback.d.ts.map +1 -0
- package/dist/config-writeback.js +183 -0
- package/dist/config-writeback.js.map +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +44 -4
- package/dist/config.js.map +1 -1
- package/dist/history.d.ts +8 -1
- package/dist/history.d.ts.map +1 -1
- package/dist/history.js +5 -3
- package/dist/history.js.map +1 -1
- package/dist/sha.d.ts +2 -0
- package/dist/sha.d.ts.map +1 -0
- package/dist/sha.js +32 -0
- package/dist/sha.js.map +1 -0
- package/dist/sources/index.d.ts +7 -0
- package/dist/sources/index.d.ts.map +1 -1
- package/dist/sources/index.js +156 -31
- package/dist/sources/index.js.map +1 -1
- package/dist/types.d.ts +13 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Avanti!
|
|
2
2
|
|
|
3
3
|
A stateful package manager for arbitrary text files. Declare what you need and where to get it; avanti fetches, diffs, and writes with full version history, atomic rollbacks, and diff-before-apply safety.
|
|
4
4
|
|
|
@@ -79,15 +79,16 @@ npx @udondan/avanti --help
|
|
|
79
79
|
avanti [options] [command]
|
|
80
80
|
|
|
81
81
|
Options:
|
|
82
|
-
-c, --config <path|url>
|
|
83
|
-
-w, --working-dir <path>
|
|
82
|
+
-c, --config <path|url> path or remote spec for config file (default: auto-detected)
|
|
83
|
+
-w, --working-dir <path> working directory for resolving paths (default: current directory)
|
|
84
84
|
|
|
85
85
|
Commands:
|
|
86
|
-
diff [pullId]
|
|
87
|
-
pull [--yes]
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
86
|
+
diff [pullId] Show diff between remote sources and local files, or vs a past pull
|
|
87
|
+
pull [--yes] [--accept-changes] Pull remote sources and write to local files
|
|
88
|
+
lock [--force] Pin SHA values for all remote sources in the config
|
|
89
|
+
log [file] Show pull history for the current project
|
|
90
|
+
revert [pullId] [--yes] Atomically revert all project files to a past pull state
|
|
91
|
+
reset [--yes] Restore all tracked files to their pre-avanti state
|
|
91
92
|
```
|
|
92
93
|
|
|
93
94
|
### `avanti diff`
|
|
@@ -98,8 +99,35 @@ Shows a colored git-diff-like output of what would change. Exits `0` if no chang
|
|
|
98
99
|
|
|
99
100
|
Fetches all sources, shows the diff, and prompts for confirmation before writing. Use `--yes` to skip the prompt.
|
|
100
101
|
|
|
102
|
+
If any source has a `sha` field and the fetched content's SHA no longer matches, the pull is aborted with a mismatch error. Use `--accept-changes` to review the diff, confirm, and automatically update the SHA values in the config file.
|
|
103
|
+
|
|
101
104
|
When avanti has previously synced a directory from a remote source and a file is no longer present in that source, the file is treated as stale: if avanti created it, it is deleted; if it existed before avanti first touched it, the original content is restored. Stale file changes appear in the diff before you confirm.
|
|
102
105
|
|
|
106
|
+
### `avanti lock`
|
|
107
|
+
|
|
108
|
+
Fetches all remote sources and writes a SHA-256 fingerprint for each one into the config file. Comments and formatting are preserved.
|
|
109
|
+
|
|
110
|
+
```sh
|
|
111
|
+
avanti lock # pin all unpinned remote sources
|
|
112
|
+
avanti lock --force # overwrite existing SHA values with fresh ones
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Once a source is pinned, `avanti pull` will verify the fetched content's SHA before applying any changes. If the upstream changed unexpectedly, avanti aborts with a clear error pointing to the affected source:
|
|
116
|
+
|
|
117
|
+
```text
|
|
118
|
+
SHA mismatch for github:org/standards:company-rules.md
|
|
119
|
+
expected: abc123...
|
|
120
|
+
got: def456...
|
|
121
|
+
|
|
122
|
+
Run `avanti pull --accept-changes` to review the diff and update SHA values.
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
`avanti diff` shows a `⚠ SHA mismatch` warning inline for any source that no longer matches its pinned SHA.
|
|
126
|
+
|
|
127
|
+
SHA is computed over the raw fetched content of each source, before any `replace` or `post` processing. Each file's path and content are fed into the hash in sorted order, separated by null bytes — so renames and additions affect the fingerprint even for single-file sources. Pull history records the observed SHA for every source, so `avanti log` shows a full audit trail of what changed and when.
|
|
128
|
+
|
|
129
|
+
Excluded from SHA pinning: local paths and `raw:` sources (their content is either authored locally or inline in the config, so changes are always visible).
|
|
130
|
+
|
|
103
131
|
## History
|
|
104
132
|
|
|
105
133
|
Every successful `avanti pull` that writes at least one file is recorded in a local history store. This lets you inspect what changed, preview past states, revert the whole project, or fully undo all avanti changes.
|
|
@@ -287,27 +315,34 @@ src: ~/templates/file.txt
|
|
|
287
315
|
src: /absolute/path/file.txt
|
|
288
316
|
```
|
|
289
317
|
|
|
290
|
-
**Map** — for exec, gitlab, github, bitbucket, git, s3, vault, raw:
|
|
318
|
+
**Map** — for exec, gitlab, github, bitbucket, git, s3, vault, http, raw:
|
|
291
319
|
|
|
292
320
|
```yaml
|
|
293
321
|
src:
|
|
294
322
|
exec: <shell command> # stdout becomes file content; target required
|
|
323
|
+
sha: abc123... # optional SHA-256 to verify stdout (see below)
|
|
295
324
|
|
|
296
325
|
src:
|
|
297
326
|
raw: | # inline content; target required
|
|
298
327
|
your content here
|
|
299
328
|
|
|
329
|
+
src:
|
|
330
|
+
http: https://example.com/file.txt # explicit http/https URL with optional SHA
|
|
331
|
+
sha: abc123...
|
|
332
|
+
|
|
300
333
|
src:
|
|
301
334
|
gitlab:
|
|
302
335
|
project: group/repo # GitLab project path
|
|
303
336
|
file: path/to/file.txt # file or directory in repo
|
|
304
337
|
ref: main # branch, tag, or $latest (optional)
|
|
338
|
+
sha: abc123... # optional SHA-256 fingerprint
|
|
305
339
|
|
|
306
340
|
src:
|
|
307
341
|
github:
|
|
308
342
|
repo: owner/repo # GitHub owner/repo
|
|
309
343
|
file: path/to/file.txt # file or directory in repo
|
|
310
344
|
ref: main # branch, tag, or $latest (optional)
|
|
345
|
+
sha: abc123... # optional SHA-256 fingerprint
|
|
311
346
|
|
|
312
347
|
src:
|
|
313
348
|
bitbucket:
|
|
@@ -315,22 +350,32 @@ src:
|
|
|
315
350
|
repo: my-repo # repository slug
|
|
316
351
|
file: path/to/file.txt # file or directory in repo
|
|
317
352
|
ref: main # branch, tag, or $latest (optional)
|
|
353
|
+
sha: abc123... # optional SHA-256 fingerprint
|
|
318
354
|
|
|
319
355
|
src:
|
|
320
356
|
git:
|
|
321
357
|
repo: https://github.com/org/repo.git # any git remote (HTTPS or SSH)
|
|
322
358
|
file: path/to/file.txt # file or directory in repo
|
|
323
359
|
ref: main # branch, tag, or commit hash (optional)
|
|
360
|
+
sha: abc123... # optional SHA-256 fingerprint
|
|
324
361
|
|
|
325
362
|
src:
|
|
326
363
|
s3: s3://my-bucket/path/to/file.txt # S3 URI; end with / for a prefix sync
|
|
364
|
+
sha: abc123... # optional SHA-256 fingerprint
|
|
327
365
|
|
|
328
366
|
src:
|
|
329
367
|
vault:
|
|
330
368
|
path: secret/myapp/config # Vault KV path (mount/subpath)
|
|
331
369
|
field: db_password # specific field to extract (optional; omit for full JSON)
|
|
370
|
+
sha: abc123... # optional SHA-256 fingerprint
|
|
332
371
|
```
|
|
333
372
|
|
|
373
|
+
#### SHA pinning
|
|
374
|
+
|
|
375
|
+
The optional `sha` field pins a source to a specific content fingerprint. When present, avanti verifies the SHA-256 of the raw fetched content matches before writing anything. This makes your config act as a selective lockfile — only sources you care about get pinned, and changes are surfaced explicitly rather than applied silently.
|
|
376
|
+
|
|
377
|
+
Use `avanti lock` to compute and write SHA values automatically. Use `avanti pull --accept-changes` to review a mismatch and update the pinned SHA. Local paths and `raw:` sources do not support `sha` (changes to those are inherently visible).
|
|
378
|
+
|
|
334
379
|
### Directory Sources
|
|
335
380
|
|
|
336
381
|
Any source type that references a path (local, GitLab, GitHub, Bitbucket, git, S3) can point to a directory instead of a single file. End the path with `/` to declare it a directory explicitly; without a trailing slash the tool probes the remote to decide.
|
package/dist/cli.js
CHANGED
|
@@ -5,6 +5,7 @@ const commander_1 = require("commander");
|
|
|
5
5
|
const diff_1 = require("./commands/diff");
|
|
6
6
|
const pull_1 = require("./commands/pull");
|
|
7
7
|
const log_1 = require("./commands/log");
|
|
8
|
+
const lock_1 = require("./commands/lock");
|
|
8
9
|
const revert_1 = require("./commands/revert");
|
|
9
10
|
const reset_1 = require("./commands/reset");
|
|
10
11
|
const package_json_1 = require("../package.json");
|
|
@@ -17,6 +18,7 @@ program
|
|
|
17
18
|
.option('-w, --working-dir <path>', 'working directory for resolving relative paths (default: current directory)');
|
|
18
19
|
program.addCommand((0, diff_1.diffCommand)());
|
|
19
20
|
program.addCommand((0, pull_1.pullCommand)());
|
|
21
|
+
program.addCommand((0, lock_1.lockCommand)());
|
|
20
22
|
program.addCommand((0, log_1.logCommand)());
|
|
21
23
|
program.addCommand((0, revert_1.revertCommand)());
|
|
22
24
|
program.addCommand((0, reset_1.resetCommand)());
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,0CAA8C;AAC9C,0CAA8C;AAC9C,wCAA4C;AAC5C,8CAAkD;AAClD,4CAAgD;AAChD,kDAA0C;AAE1C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CACV,kEAAkE,CACnE;KACA,OAAO,CAAC,sBAAO,CAAC;KAChB,MAAM,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;KACpD,MAAM,CACL,0BAA0B,EAC1B,6EAA6E,CAC9E,CAAC;AAEJ,OAAO,CAAC,UAAU,CAAC,IAAA,kBAAW,GAAE,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,IAAA,kBAAW,GAAE,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,IAAA,gBAAU,GAAE,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,IAAA,sBAAa,GAAE,CAAC,CAAC;AACpC,OAAO,CAAC,UAAU,CAAC,IAAA,oBAAY,GAAE,CAAC,CAAC;AAEnC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,0CAA8C;AAC9C,0CAA8C;AAC9C,wCAA4C;AAC5C,0CAA8C;AAC9C,8CAAkD;AAClD,4CAAgD;AAChD,kDAA0C;AAE1C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CACV,kEAAkE,CACnE;KACA,OAAO,CAAC,sBAAO,CAAC;KAChB,MAAM,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;KACpD,MAAM,CACL,0BAA0B,EAC1B,6EAA6E,CAC9E,CAAC;AAEJ,OAAO,CAAC,UAAU,CAAC,IAAA,kBAAW,GAAE,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,IAAA,kBAAW,GAAE,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,IAAA,kBAAW,GAAE,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,IAAA,gBAAU,GAAE,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,IAAA,sBAAa,GAAE,CAAC,CAAC;AACpC,OAAO,CAAC,UAAU,CAAC,IAAA,oBAAY,GAAE,CAAC,CAAC;AAEnC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,wBAAgB,WAAW,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,wBAAgB,WAAW,IAAI,OAAO,CAkFrC"}
|
package/dist/commands/diff.js
CHANGED
|
@@ -60,6 +60,13 @@ function diffCommand() {
|
|
|
60
60
|
for (const entry of config.files) {
|
|
61
61
|
try {
|
|
62
62
|
const result = await (0, sources_1.fetchSource)(entry, workingDir, vars);
|
|
63
|
+
for (const rec of result.sourceRecords) {
|
|
64
|
+
if (!rec.matched) {
|
|
65
|
+
console.error(`⚠ SHA mismatch for ${rec.sourceLabel}\n` +
|
|
66
|
+
` expected: ${rec.expectedSha}\n` +
|
|
67
|
+
` got: ${rec.observedSha}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
63
70
|
for (const [relPath, rawContent] of result.files) {
|
|
64
71
|
let content = rawContent;
|
|
65
72
|
if (entry.replace?.length)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/commands/lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,WAAW,IAAI,OAAO,CAkFrC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.lockCommand = void 0;
|
|
27
|
+
const commander_1 = require("commander");
|
|
28
|
+
const path = __importStar(require("path"));
|
|
29
|
+
const config_1 = require("../config");
|
|
30
|
+
const sources_1 = require("../sources");
|
|
31
|
+
const config_writeback_1 = require("../config-writeback");
|
|
32
|
+
function lockCommand() {
|
|
33
|
+
return new commander_1.Command('lock')
|
|
34
|
+
.description('Compute and pin SHA values for all remote sources in the config')
|
|
35
|
+
.option('--force', 'overwrite existing SHA values')
|
|
36
|
+
.action(async (options, cmd) => {
|
|
37
|
+
const opts = options;
|
|
38
|
+
const configPath = (0, config_1.resolveConfigPath)(cmd.parent?.opts().config);
|
|
39
|
+
const rawWorkingDir = cmd.parent?.opts().workingDir;
|
|
40
|
+
const workingDir = rawWorkingDir
|
|
41
|
+
? path.resolve(rawWorkingDir)
|
|
42
|
+
: process.cwd();
|
|
43
|
+
if ((0, config_1.isRemoteConfigSpec)(configPath)) {
|
|
44
|
+
console.error('avanti lock requires a local config file.');
|
|
45
|
+
process.exit(2);
|
|
46
|
+
}
|
|
47
|
+
let config;
|
|
48
|
+
try {
|
|
49
|
+
config = await (0, config_1.loadConfig)(configPath);
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
console.error(err.message);
|
|
53
|
+
process.exit(2);
|
|
54
|
+
}
|
|
55
|
+
const vars = config.variables ?? {};
|
|
56
|
+
const toPin = new Map(); // label → sha
|
|
57
|
+
let hasError = false;
|
|
58
|
+
let remoteSourceCount = 0;
|
|
59
|
+
for (const entry of config.files) {
|
|
60
|
+
try {
|
|
61
|
+
const result = await (0, sources_1.fetchSource)(entry, workingDir, vars);
|
|
62
|
+
remoteSourceCount += result.sourceRecords.length;
|
|
63
|
+
for (const rec of result.sourceRecords) {
|
|
64
|
+
if (!opts.force && rec.expectedSha !== undefined)
|
|
65
|
+
continue;
|
|
66
|
+
toPin.set(rec.sourceLabel, rec.observedSha);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
console.error(`Error processing ${JSON.stringify(entry.src)}: ${err.message}`);
|
|
71
|
+
hasError = true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (toPin.size === 0) {
|
|
75
|
+
if (hasError)
|
|
76
|
+
process.exit(2);
|
|
77
|
+
if (remoteSourceCount === 0) {
|
|
78
|
+
console.log('No SHA-pinnable remote sources found in config.');
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
console.log('All remote sources already have SHA values pinned. Use --force to overwrite.');
|
|
82
|
+
}
|
|
83
|
+
process.exit(0);
|
|
84
|
+
}
|
|
85
|
+
if (hasError) {
|
|
86
|
+
console.error('Aborting: one or more sources failed to fetch. No changes written.');
|
|
87
|
+
process.exit(2);
|
|
88
|
+
}
|
|
89
|
+
const pinned = (0, config_writeback_1.writeUpdatedShas)(configPath, toPin);
|
|
90
|
+
if (pinned) {
|
|
91
|
+
for (const [label, sha] of toPin) {
|
|
92
|
+
console.log(` pinned ${label} ${sha.slice(0, 16)}`);
|
|
93
|
+
}
|
|
94
|
+
console.log(`\nPinned ${toPin.size} source(s).`);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
console.log('All SHA values are already up to date.');
|
|
98
|
+
}
|
|
99
|
+
process.exit(0);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
exports.lockCommand = lockCommand;
|
|
103
|
+
//# sourceMappingURL=lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/commands/lock.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/log.js
CHANGED
|
@@ -62,6 +62,18 @@ function showPullHistory(history) {
|
|
|
62
62
|
for (const ref of pull.files) {
|
|
63
63
|
const label = ref.wasNew ? '(new file)' : '(modified)';
|
|
64
64
|
console.log(` ${ref.absolutePath} → v${ref.version} ${label}`);
|
|
65
|
+
if (ref.sources && ref.sources.length > 0) {
|
|
66
|
+
for (const s of ref.sources) {
|
|
67
|
+
const shaShort = s.observedSha.slice(0, 16);
|
|
68
|
+
if (s.accepted && s.expectedSha) {
|
|
69
|
+
const prevShort = s.expectedSha.slice(0, 16);
|
|
70
|
+
console.log(` ${s.label} sha:${shaShort} ⚠ accepted (was: ${prevShort})`);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
console.log(` ${s.label} sha:${shaShort}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
65
77
|
}
|
|
66
78
|
console.log('');
|
|
67
79
|
}
|
|
@@ -76,6 +88,8 @@ function showFileHistory(history, filePath, workingDir) {
|
|
|
76
88
|
return;
|
|
77
89
|
}
|
|
78
90
|
console.log(`${absolutePath}\n`);
|
|
91
|
+
const pulls = history.listPulls();
|
|
92
|
+
const pullsById = new Map(pulls.map((p) => [p.pullId, p]));
|
|
79
93
|
const versions = [...fileHistory.versions].reverse();
|
|
80
94
|
for (const v of versions) {
|
|
81
95
|
const vLabel = `v${v.version}`;
|
|
@@ -89,6 +103,22 @@ function showFileHistory(history, filePath, workingDir) {
|
|
|
89
103
|
if (v.isOriginal)
|
|
90
104
|
suffix = ' (original, before avanti)';
|
|
91
105
|
console.log(` ${vLabel.padEnd(4)} ${ts} ${pullRef}${suffix}`);
|
|
106
|
+
if (v.pullId) {
|
|
107
|
+
const pullEntry = pullsById.get(v.pullId);
|
|
108
|
+
const fileRef = pullEntry?.files.find((f) => f.absolutePath === absolutePath && f.version === v.version);
|
|
109
|
+
if (fileRef?.sources && fileRef.sources.length > 0) {
|
|
110
|
+
for (const s of fileRef.sources) {
|
|
111
|
+
const shaShort = s.observedSha.slice(0, 16);
|
|
112
|
+
if (s.accepted && s.expectedSha) {
|
|
113
|
+
const prevShort = s.expectedSha.slice(0, 16);
|
|
114
|
+
console.log(` ${s.label} sha:${shaShort} ⚠ accepted (was: ${prevShort})`);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
console.log(` ${s.label} sha:${shaShort}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
92
122
|
}
|
|
93
123
|
}
|
|
94
124
|
function formatTimestamp(iso) {
|
package/dist/commands/log.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/commands/log.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yCAAoC;AACpC,2CAA6B;AAC7B,sCAAkE;AAClE,
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/commands/log.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmGpC,wBAAgB,WAAW,IAAI,OAAO,CAoSrC"}
|
package/dist/commands/pull.js
CHANGED
|
@@ -34,14 +34,28 @@ const diff_1 = require("../diff");
|
|
|
34
34
|
const writer_1 = require("../writer");
|
|
35
35
|
const history_1 = require("../history");
|
|
36
36
|
const prompt_1 = require("../prompt");
|
|
37
|
+
const config_writeback_1 = require("../config-writeback");
|
|
37
38
|
async function runFetchLoop(config, workingDir) {
|
|
38
39
|
const vars = config.variables ?? {};
|
|
39
40
|
const writeTargets = [];
|
|
40
41
|
const allDiffs = [];
|
|
42
|
+
const shaErrors = [];
|
|
43
|
+
const seenShaErrorLabels = new Set();
|
|
44
|
+
const sourceRecordsByTarget = new Map();
|
|
41
45
|
let hasError = false;
|
|
42
46
|
for (const entry of config.files) {
|
|
43
47
|
try {
|
|
44
48
|
const result = await (0, sources_1.fetchSource)(entry, workingDir, vars);
|
|
49
|
+
for (const rec of result.sourceRecords) {
|
|
50
|
+
if (!rec.matched && !seenShaErrorLabels.has(rec.sourceLabel)) {
|
|
51
|
+
seenShaErrorLabels.add(rec.sourceLabel);
|
|
52
|
+
shaErrors.push({
|
|
53
|
+
sourceLabel: rec.sourceLabel,
|
|
54
|
+
expectedSha: rec.expectedSha,
|
|
55
|
+
observedSha: rec.observedSha,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
45
59
|
for (const [relPath, rawContent] of result.files) {
|
|
46
60
|
let content = rawContent;
|
|
47
61
|
if (entry.replace?.length)
|
|
@@ -51,6 +65,9 @@ async function runFetchLoop(config, workingDir) {
|
|
|
51
65
|
const targetPath = (0, diff_1.resolveTargetPath)(entry, relPath, workingDir, vars);
|
|
52
66
|
allDiffs.push((0, diff_1.computeDiff)(targetPath, content));
|
|
53
67
|
writeTargets.push({ targetPath, content, mode: entry.mode });
|
|
68
|
+
if (result.sourceRecords.length > 0) {
|
|
69
|
+
sourceRecordsByTarget.set(targetPath, result.sourceRecords);
|
|
70
|
+
}
|
|
54
71
|
}
|
|
55
72
|
}
|
|
56
73
|
catch (err) {
|
|
@@ -58,13 +75,22 @@ async function runFetchLoop(config, workingDir) {
|
|
|
58
75
|
hasError = true;
|
|
59
76
|
}
|
|
60
77
|
}
|
|
61
|
-
return { writeTargets, allDiffs, hasError };
|
|
78
|
+
return { writeTargets, allDiffs, hasError, shaErrors, sourceRecordsByTarget };
|
|
79
|
+
}
|
|
80
|
+
function printShaErrors(errors) {
|
|
81
|
+
for (const e of errors) {
|
|
82
|
+
console.error(`SHA mismatch for ${e.sourceLabel}\n` +
|
|
83
|
+
` expected: ${e.expectedSha}\n` +
|
|
84
|
+
` got: ${e.observedSha}`);
|
|
85
|
+
}
|
|
62
86
|
}
|
|
63
87
|
function pullCommand() {
|
|
64
88
|
return new commander_1.Command('pull')
|
|
65
89
|
.description('Pull remote sources and write to local files')
|
|
66
90
|
.option('-y, --yes', 'skip confirmation prompt')
|
|
91
|
+
.option('--accept-changes', 'accept SHA mismatches, update SHA values in config, and apply changes')
|
|
67
92
|
.action(async (options, cmd) => {
|
|
93
|
+
const opts = options;
|
|
68
94
|
const configPath = (0, config_1.resolveConfigPath)(cmd.parent?.opts().config);
|
|
69
95
|
const rawWorkingDir = cmd.parent?.opts().workingDir;
|
|
70
96
|
const workingDir = rawWorkingDir
|
|
@@ -82,11 +108,17 @@ function pullCommand() {
|
|
|
82
108
|
const historyAvailable = history.ensureStorageDir();
|
|
83
109
|
const pullId = historyAvailable ? history.openPullSession() : null;
|
|
84
110
|
const firstPass = await runFetchLoop(config, workingDir);
|
|
85
|
-
let { writeTargets, allDiffs } = firstPass;
|
|
111
|
+
let { writeTargets, allDiffs, sourceRecordsByTarget } = firstPass;
|
|
86
112
|
if (firstPass.hasError) {
|
|
87
113
|
console.error('Aborting due to errors.');
|
|
88
114
|
process.exit(2);
|
|
89
115
|
}
|
|
116
|
+
// SHA validation — abort unless --accept-changes
|
|
117
|
+
if (firstPass.shaErrors.length > 0 && !opts.acceptChanges) {
|
|
118
|
+
printShaErrors(firstPass.shaErrors);
|
|
119
|
+
console.error('\nRun `avanti pull --accept-changes` to review the diff and update SHA values.');
|
|
120
|
+
process.exit(2);
|
|
121
|
+
}
|
|
90
122
|
// Detect self-config update: only applies to local config files
|
|
91
123
|
if (!(0, config_1.isRemoteConfigSpec)(configPath)) {
|
|
92
124
|
const configIdx = writeTargets.findIndex((t) => t.targetPath === configPath);
|
|
@@ -100,16 +132,28 @@ function pullCommand() {
|
|
|
100
132
|
console.error('Aborting due to errors in re-evaluated config.');
|
|
101
133
|
process.exit(2);
|
|
102
134
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
135
|
+
if (second.shaErrors.length > 0 && !opts.acceptChanges) {
|
|
136
|
+
printShaErrors(second.shaErrors);
|
|
137
|
+
console.error('\nRun `avanti pull --accept-changes` to review the diff and update SHA values.');
|
|
138
|
+
process.exit(2);
|
|
139
|
+
}
|
|
106
140
|
const configInSecond = second.writeTargets.findIndex((t) => t.targetPath === configPath);
|
|
107
141
|
if (configInSecond === -1) {
|
|
108
142
|
second.writeTargets.push(writeTargets[configIdx]);
|
|
109
143
|
second.allDiffs.push(allDiffs[configIdx]);
|
|
144
|
+
const firstPassRecords = sourceRecordsByTarget.get(configPath);
|
|
145
|
+
if (firstPassRecords) {
|
|
146
|
+
second.sourceRecordsByTarget.set(configPath, firstPassRecords);
|
|
147
|
+
}
|
|
110
148
|
}
|
|
111
149
|
writeTargets = second.writeTargets;
|
|
112
150
|
allDiffs = second.allDiffs;
|
|
151
|
+
sourceRecordsByTarget = second.sourceRecordsByTarget;
|
|
152
|
+
const existingLabels = new Set(firstPass.shaErrors.map((e) => e.sourceLabel));
|
|
153
|
+
for (const e of second.shaErrors) {
|
|
154
|
+
if (!existingLabels.has(e.sourceLabel))
|
|
155
|
+
firstPass.shaErrors.push(e);
|
|
156
|
+
}
|
|
113
157
|
}
|
|
114
158
|
catch (err) {
|
|
115
159
|
console.warn(`Warning: updated config is invalid, skipping re-evaluation: ${err.message}`);
|
|
@@ -148,26 +192,81 @@ function pullCommand() {
|
|
|
148
192
|
const hasChanges = allDiffs.some((d) => d.hasChanges) ||
|
|
149
193
|
staleDiffs.some((d) => d.hasChanges);
|
|
150
194
|
(0, diff_1.printDiffs)([...allDiffs, ...staleDiffs]);
|
|
151
|
-
|
|
195
|
+
// Show SHA mismatch summary when using --accept-changes
|
|
196
|
+
if (opts.acceptChanges && firstPass.shaErrors.length > 0) {
|
|
197
|
+
console.error('');
|
|
198
|
+
printShaErrors(firstPass.shaErrors);
|
|
199
|
+
}
|
|
200
|
+
if (!hasChanges && firstPass.shaErrors.length === 0) {
|
|
152
201
|
console.log('Nothing to do.');
|
|
153
202
|
process.exit(0);
|
|
154
203
|
}
|
|
155
|
-
const yes =
|
|
204
|
+
const yes = opts.yes ?? false;
|
|
156
205
|
if (!yes) {
|
|
157
|
-
const
|
|
206
|
+
const promptMsg = opts.acceptChanges && firstPass.shaErrors.length > 0
|
|
207
|
+
? 'Accept new SHA values and apply changes? [y/N] '
|
|
208
|
+
: 'Apply changes? [y/N] ';
|
|
209
|
+
const ok = await (0, prompt_1.confirm)(promptMsg);
|
|
158
210
|
if (!ok) {
|
|
159
211
|
console.log('Aborted.');
|
|
160
212
|
process.exit(0);
|
|
161
213
|
}
|
|
162
214
|
}
|
|
215
|
+
// Warn when --accept-changes is used with a remote config: SHA values
|
|
216
|
+
// cannot be written back, so the mismatch will recur on the next pull.
|
|
217
|
+
if (opts.acceptChanges &&
|
|
218
|
+
firstPass.shaErrors.length > 0 &&
|
|
219
|
+
(0, config_1.isRemoteConfigSpec)(configPath)) {
|
|
220
|
+
console.warn('Warning: config is remote; SHA values cannot be written back. ' +
|
|
221
|
+
'Mismatches accepted for this session only.');
|
|
222
|
+
}
|
|
223
|
+
// Pre-apply SHA updates to the config write target in-memory so that both
|
|
224
|
+
// history and the on-disk file reflect the final pinned state in one pass.
|
|
225
|
+
const shaUpdates = opts.acceptChanges &&
|
|
226
|
+
firstPass.shaErrors.length > 0 &&
|
|
227
|
+
!(0, config_1.isRemoteConfigSpec)(configPath)
|
|
228
|
+
? new Map(firstPass.shaErrors.map((e) => [e.sourceLabel, e.observedSha]))
|
|
229
|
+
: null;
|
|
230
|
+
let configShaPreApplied = false;
|
|
231
|
+
if (shaUpdates !== null) {
|
|
232
|
+
const configTargetIdx = writeTargets.findIndex((t) => t.targetPath === configPath);
|
|
233
|
+
if (configTargetIdx !== -1) {
|
|
234
|
+
const patched = (0, config_writeback_1.applyUpdatedShas)(writeTargets[configTargetIdx].content, shaUpdates);
|
|
235
|
+
if (patched !== null) {
|
|
236
|
+
writeTargets[configTargetIdx] = {
|
|
237
|
+
...writeTargets[configTargetIdx],
|
|
238
|
+
content: patched,
|
|
239
|
+
};
|
|
240
|
+
// Recompute diff so staging and atomicWrite both see SHA-patched content,
|
|
241
|
+
// even when the original content diff was empty.
|
|
242
|
+
allDiffs[configTargetIdx] = (0, diff_1.computeDiff)(writeTargets[configTargetIdx].targetPath, patched);
|
|
243
|
+
configShaPreApplied = true;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
163
247
|
// Stage history versions before atomicWrite so v0 is captured before overwrite
|
|
164
248
|
const stagedFileRefs = [];
|
|
165
249
|
if (pullId) {
|
|
250
|
+
const acceptedShaLabels = new Set(firstPass.shaErrors.map((e) => e.sourceLabel));
|
|
166
251
|
for (let i = 0; i < writeTargets.length; i++) {
|
|
167
|
-
|
|
252
|
+
const targetPath = writeTargets[i].targetPath;
|
|
253
|
+
const records = sourceRecordsByTarget.get(targetPath);
|
|
254
|
+
const hasAcceptedSha = opts.acceptChanges &&
|
|
255
|
+
records?.some((r) => !r.matched && acceptedShaLabels.has(r.sourceLabel));
|
|
256
|
+
if (!allDiffs[i].hasChanges && !hasAcceptedSha)
|
|
168
257
|
continue;
|
|
169
258
|
try {
|
|
170
|
-
const
|
|
259
|
+
const sourceShaRecords = records !== undefined
|
|
260
|
+
? records.map((r) => ({
|
|
261
|
+
label: r.sourceLabel,
|
|
262
|
+
observedSha: r.observedSha,
|
|
263
|
+
expectedSha: r.expectedSha,
|
|
264
|
+
accepted: !r.matched &&
|
|
265
|
+
(opts.acceptChanges ?? false) &&
|
|
266
|
+
acceptedShaLabels.has(r.sourceLabel),
|
|
267
|
+
}))
|
|
268
|
+
: undefined;
|
|
269
|
+
const { fileRef } = history.stageFileVersion(pullId, targetPath, writeTargets[i].content, allDiffs[i].isNew, sourceShaRecords);
|
|
171
270
|
stagedFileRefs.push(fileRef);
|
|
172
271
|
}
|
|
173
272
|
catch {
|
|
@@ -176,17 +275,29 @@ function pullCommand() {
|
|
|
176
275
|
}
|
|
177
276
|
}
|
|
178
277
|
try {
|
|
179
|
-
(
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
staleToDelete.length;
|
|
278
|
+
const changedTargets = writeTargets.filter((_, i) => allDiffs[i].hasChanges);
|
|
279
|
+
(0, writer_1.atomicWrite)([...changedTargets, ...staleToRestore], staleToDelete);
|
|
280
|
+
const written = changedTargets.length + staleToRestore.length + staleToDelete.length;
|
|
183
281
|
console.log(`Wrote ${written} file(s).`);
|
|
184
282
|
}
|
|
185
283
|
catch (err) {
|
|
186
284
|
console.error(`Write failed: ${err.message}`);
|
|
187
285
|
process.exit(2);
|
|
188
286
|
}
|
|
189
|
-
//
|
|
287
|
+
// SHA writeback: write updated sha values into config file after all writes complete.
|
|
288
|
+
// Skipped when config was a write target and already patched in-memory above.
|
|
289
|
+
if (shaUpdates !== null && !configShaPreApplied) {
|
|
290
|
+
try {
|
|
291
|
+
const pinned = (0, config_writeback_1.writeUpdatedShas)(configPath, shaUpdates);
|
|
292
|
+
if (pinned)
|
|
293
|
+
console.log(`Updated ${shaUpdates.size} SHA pin(s) in config.`);
|
|
294
|
+
}
|
|
295
|
+
catch (err) {
|
|
296
|
+
console.warn(`Warning: could not update SHA values in config: ${err.message}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// Only record to pulls.jsonl if at least one file was staged (written or
|
|
300
|
+
// SHA-accepted via --accept-changes with no content diff)
|
|
190
301
|
if (pullId && stagedFileRefs.length > 0) {
|
|
191
302
|
try {
|
|
192
303
|
history.closePullSession(pullId, (0, config_1.normalizeConfigKey)(configPath), stagedFileRefs);
|