@udondan/avanti 0.20.0 → 0.21.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/README.md +142 -10
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +39 -8
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/lock.d.ts.map +1 -1
- package/dist/commands/lock.js +8 -2
- package/dist/commands/lock.js.map +1 -1
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +115 -9
- package/dist/commands/pull.js.map +1 -1
- package/dist/condition.d.ts +4 -0
- package/dist/condition.d.ts.map +1 -0
- package/dist/condition.js +86 -0
- package/dist/condition.js.map +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +133 -1
- package/dist/config.js.map +1 -1
- package/dist/history.d.ts +9 -0
- package/dist/history.d.ts.map +1 -1
- package/dist/history.js +58 -0
- package/dist/history.js.map +1 -1
- package/dist/processors/insert.d.ts +3 -0
- package/dist/processors/insert.d.ts.map +1 -0
- package/dist/processors/insert.js +285 -0
- package/dist/processors/insert.js.map +1 -0
- package/dist/sources/bitbucket.d.ts.map +1 -1
- package/dist/sources/bitbucket.js +11 -43
- package/dist/sources/bitbucket.js.map +1 -1
- package/dist/sources/index.d.ts +6 -2
- package/dist/sources/index.d.ts.map +1 -1
- package/dist/sources/index.js +24 -6
- package/dist/sources/index.js.map +1 -1
- package/dist/types.d.ts +37 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -15,11 +15,13 @@ atomic rollbacks, and diff-before-apply safety.
|
|
|
15
15
|
- [Usage](#usage)
|
|
16
16
|
- [`avanti diff`](#avanti-diff)
|
|
17
17
|
- [`avanti pull`](#avanti-pull)
|
|
18
|
+
- [`avanti lock`](#avanti-lock)
|
|
18
19
|
- [History](#history)
|
|
19
20
|
- [`avanti log`](#avanti-log)
|
|
20
21
|
- [`avanti diff <pullId>`](#avanti-diff-pullid)
|
|
21
22
|
- [`avanti revert [pullId]`](#avanti-revert-pullid)
|
|
22
23
|
- [`avanti reset`](#avanti-reset)
|
|
24
|
+
- [`--verbose` / `-v`](#--verbose---v)
|
|
23
25
|
- [Working Directory](#working-directory)
|
|
24
26
|
- [Path Constraints](#path-constraints)
|
|
25
27
|
- [Configuration](#configuration)
|
|
@@ -28,6 +30,9 @@ atomic rollbacks, and diff-before-apply safety.
|
|
|
28
30
|
- [Directory Sources](#directory-sources)
|
|
29
31
|
- [JSON Merging](#json-merging)
|
|
30
32
|
- [YAML Merging](#yaml-merging)
|
|
33
|
+
- [TOML Merging](#toml-merging)
|
|
34
|
+
- [Insert Mode](#insert-mode)
|
|
35
|
+
- [Conditions](#conditions)
|
|
31
36
|
- [Variables](#variables)
|
|
32
37
|
- [$self — Self-managing Config](#self--self-managing-config)
|
|
33
38
|
- [Authentication](#authentication)
|
|
@@ -103,6 +108,7 @@ avanti revert # roll back instantly if something breaks
|
|
|
103
108
|
- **Diff preview** — see exactly what will change before applying, or compare against any past pull
|
|
104
109
|
- **Atomic writes** — all files are staged to a temp dir first; targets are only written if everything succeeds
|
|
105
110
|
- **History** — every pull is recorded; inspect what changed, revert the whole project to a past state, or fully undo all avanti changes
|
|
111
|
+
- **Conditions** — use `if` and `ifAny` on file entries or individual sources to conditionally skip based on OS, filesystem path existence, shell command exit code, or whether the target file already exists; supports AND/OR logic and negation with `not: true`
|
|
106
112
|
- **Optional sources** — mark `path:` and `url:` sources `optional: true` to silently skip them when the file is missing or the URL returns 404; lets a central config reference per-user local overrides without erroring on machines that haven't created them
|
|
107
113
|
- **Stale file cleanup** — files dropped from a directory source are automatically deleted or restored to their pre-avanti content
|
|
108
114
|
|
|
@@ -377,14 +383,17 @@ files:
|
|
|
377
383
|
|
|
378
384
|
End the target path with `/` to write a directory source as a mirror; omit the trailing slash to merge all files from the directory into a single output file (YAML/JSON auto-detected by extension, or forced with `yaml:`/`json:`).
|
|
379
385
|
|
|
380
|
-
| Field
|
|
381
|
-
|
|
|
382
|
-
| `src`
|
|
383
|
-
| `
|
|
384
|
-
| `
|
|
385
|
-
| `
|
|
386
|
-
| `
|
|
387
|
-
| `
|
|
386
|
+
| Field | Required | Description |
|
|
387
|
+
| ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
388
|
+
| `src` | Yes | Source (see below). May be a single source or a **list** of sources to concatenate. |
|
|
389
|
+
| `if` | No | Condition object (or list of objects). All must pass for the entry to be processed. See [Conditions](#conditions). |
|
|
390
|
+
| `ifAny` | No | List of condition objects. At least one must pass. See [Conditions](#conditions). |
|
|
391
|
+
| `mode` | No | File permission mode, e.g. `"0755"` |
|
|
392
|
+
| `replace` | No | List of `{from, to}` replacement rules. `from` may be a plain string or `/pattern/flags` regex. |
|
|
393
|
+
| `post` | No | Shell script. Content is piped via stdin; stdout is used as the result. Runs after `replace`. |
|
|
394
|
+
| `json` | No | JSON merge/format options (see below). When omitted, merging is auto-enabled if all sources have a `.json` or `.jsonc` extension. Use `true`/`false` to force on or off regardless of extension. |
|
|
395
|
+
| `yaml` | No | YAML merge/format options (see below). When omitted, merging is auto-enabled if all sources have a `.yaml` or `.yml` extension. Use `true`/`false` to force on or off regardless of extension. Comments are preserved in merged output. |
|
|
396
|
+
| `strategy` | No | Write strategy: `replace` _(default)_ — overwrite the target file entirely; `insert` — merge content into the existing file without clobbering unrelated content. See [Insert Mode](#insert-mode). |
|
|
388
397
|
|
|
389
398
|
### Source Types
|
|
390
399
|
|
|
@@ -788,6 +797,129 @@ files:
|
|
|
788
797
|
src: ./config.toml
|
|
789
798
|
```
|
|
790
799
|
|
|
800
|
+
### Insert Mode
|
|
801
|
+
|
|
802
|
+
By default (`strategy: replace`) avanti overwrites the target file with the fully processed source content. Set `strategy: insert` to **merge** content into an existing file instead of replacing it.
|
|
803
|
+
|
|
804
|
+
```yaml
|
|
805
|
+
files:
|
|
806
|
+
.vscode/settings.json:
|
|
807
|
+
src: ./shared/vscode-settings.json
|
|
808
|
+
json: true
|
|
809
|
+
strategy: insert
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
**How it works:**
|
|
813
|
+
|
|
814
|
+
- **First run** — the fetched content is merged into the existing file (or written as-is if the file does not exist yet).
|
|
815
|
+
- **Subsequent runs (no-op)** — avanti detects that the raw source and the post-processed output (`replace`/`post`) are both unchanged and skips the file entirely.
|
|
816
|
+
- **Subsequent runs (source changed)** — avanti removes the keys/text it previously contributed, then merges the updated content in.
|
|
817
|
+
- **User edits are preserved** — keys or text the user added or modified are left untouched. If a user overrides an avanti-managed key, avanti will not remove it even if the source no longer includes it.
|
|
818
|
+
|
|
819
|
+
**Structured files (JSON / YAML / TOML):**
|
|
820
|
+
|
|
821
|
+
Avanti tracks which keys it contributed in the previous pull. On the next pull it removes only those keys (if they still match) and then merges the new contribution. This means:
|
|
822
|
+
|
|
823
|
+
- Keys removed from the remote source are removed from the local file.
|
|
824
|
+
- Keys the user added or modified independently are preserved.
|
|
825
|
+
- Nested objects and arrays are handled recursively. For arrays, combine with `arrays: concat` so avanti appends items; avanti removes only the items it previously appended, leaving user-owned items intact.
|
|
826
|
+
|
|
827
|
+
```yaml
|
|
828
|
+
files:
|
|
829
|
+
tsconfig.json:
|
|
830
|
+
src: https://example.com/shared-tsconfig.json
|
|
831
|
+
json:
|
|
832
|
+
objects: merge
|
|
833
|
+
arrays: concat
|
|
834
|
+
strategy: insert
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
**Plain text:**
|
|
838
|
+
|
|
839
|
+
On the first insert, the text is appended to the existing file. On subsequent runs, the old block is replaced in-place when the source changes; if it is no longer found (e.g. the user removed it), the new block is appended.
|
|
840
|
+
|
|
841
|
+
### Conditions
|
|
842
|
+
|
|
843
|
+
Use `if` and `ifAny` on a file entry or on an individual source to control when it is processed.
|
|
844
|
+
|
|
845
|
+
**`if`** — a condition object (or list of objects) where **all** checks must pass (AND).
|
|
846
|
+
|
|
847
|
+
**`ifAny`** — a list of condition objects where **at least one** must pass (OR).
|
|
848
|
+
|
|
849
|
+
When both are present, both must pass. Each condition object may also include `not: true` to invert its result.
|
|
850
|
+
|
|
851
|
+
#### Condition fields
|
|
852
|
+
|
|
853
|
+
| Field | Type | Description |
|
|
854
|
+
| --------------- | -------------- | --------------------------------------------------------------------------- |
|
|
855
|
+
| `os` | string or list | Platform must match. Values: `linux`, `mac`, `windows`. List = any matches. |
|
|
856
|
+
| `exists` | string | Path (file or directory) must exist. Variables are resolved. |
|
|
857
|
+
| `exec` | string | Shell command must exit with code `0`. |
|
|
858
|
+
| `target_exists` | `true` | Skip entry if the target path does not already exist (update-only guard). |
|
|
859
|
+
| `not` | boolean | `true` — invert the result of all checks in this condition object. |
|
|
860
|
+
|
|
861
|
+
#### Examples
|
|
862
|
+
|
|
863
|
+
```yaml
|
|
864
|
+
files:
|
|
865
|
+
# Only on Linux
|
|
866
|
+
/etc/app.conf:
|
|
867
|
+
if:
|
|
868
|
+
os: linux
|
|
869
|
+
src: ...
|
|
870
|
+
|
|
871
|
+
# Skip on Windows
|
|
872
|
+
~/.config/app.conf:
|
|
873
|
+
if:
|
|
874
|
+
os: windows
|
|
875
|
+
not: true
|
|
876
|
+
src: ...
|
|
877
|
+
|
|
878
|
+
# Only if Docker is installed
|
|
879
|
+
~/.docker/config.json:
|
|
880
|
+
if:
|
|
881
|
+
exec: which docker
|
|
882
|
+
src: ...
|
|
883
|
+
|
|
884
|
+
# Only update — never create
|
|
885
|
+
~/.ssh/config:
|
|
886
|
+
if:
|
|
887
|
+
target_exists: true
|
|
888
|
+
src: ...
|
|
889
|
+
|
|
890
|
+
# OR: write if on mac OR if app is installed
|
|
891
|
+
app.conf:
|
|
892
|
+
ifAny:
|
|
893
|
+
- os: mac
|
|
894
|
+
- exec: which app
|
|
895
|
+
src: ...
|
|
896
|
+
|
|
897
|
+
# Combined AND + OR
|
|
898
|
+
combined.conf:
|
|
899
|
+
if:
|
|
900
|
+
os: windows
|
|
901
|
+
not: true
|
|
902
|
+
ifAny:
|
|
903
|
+
- exists: /opt/app
|
|
904
|
+
- exec: which app
|
|
905
|
+
src: ...
|
|
906
|
+
```
|
|
907
|
+
|
|
908
|
+
Conditions also apply at the **source level** within a multi-source entry (plain string sources excluded — use `path:` or `url:` wrapper form):
|
|
909
|
+
|
|
910
|
+
```yaml
|
|
911
|
+
files:
|
|
912
|
+
platform.conf:
|
|
913
|
+
src:
|
|
914
|
+
- raw: "# linux config\n"
|
|
915
|
+
if:
|
|
916
|
+
os: linux
|
|
917
|
+
- raw: "# mac config\n"
|
|
918
|
+
if:
|
|
919
|
+
os: mac
|
|
920
|
+
- path: /common/base.conf
|
|
921
|
+
```
|
|
922
|
+
|
|
791
923
|
### Variables
|
|
792
924
|
|
|
793
925
|
Define reusable values at the top level under `variables:`:
|
|
@@ -955,8 +1087,8 @@ Public repositories on github.com and gitlab.com work without any configuration.
|
|
|
955
1087
|
| --------------- | ---------------------------------------------------------------- | ------------------------------------------ |
|
|
956
1088
|
| GitHub | `GITHUB_TOKEN` | `Authorization: Bearer <token>` |
|
|
957
1089
|
| GitLab | `GITLAB_TOKEN` or `GITLAB_PRIVATE_TOKEN` | `PRIVATE-TOKEN: <token>` |
|
|
958
|
-
| Bitbucket | `BITBUCKET_TOKEN`
|
|
959
|
-
| Bitbucket | `
|
|
1090
|
+
| Bitbucket | `BITBUCKET_EMAIL` + `BITBUCKET_TOKEN` | Basic auth (Atlassian API token) |
|
|
1091
|
+
| Bitbucket | `BITBUCKET_TOKEN` | Bearer auth (workspace/repo access token) |
|
|
960
1092
|
| S3 | Standard AWS env vars (`AWS_ACCESS_KEY_ID`, `AWS_PROFILE`, etc.) | AWS SDK credential chain |
|
|
961
1093
|
| Secrets Manager | Standard AWS env vars (`AWS_ACCESS_KEY_ID`, `AWS_PROFILE`, etc.) | AWS SDK credential chain |
|
|
962
1094
|
| SSM | Standard AWS env vars (`AWS_ACCESS_KEY_ID`, `AWS_PROFILE`, etc.) | AWS SDK credential chain |
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmKpC,wBAAgB,WAAW,IAAI,OAAO,CAoJrC"}
|
package/dist/commands/diff.js
CHANGED
|
@@ -35,16 +35,19 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.diffCommand = diffCommand;
|
|
37
37
|
const commander_1 = require("commander");
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
38
39
|
const path = __importStar(require("path"));
|
|
39
40
|
const config_1 = require("../config");
|
|
40
41
|
const sources_1 = require("../sources");
|
|
41
42
|
const replace_1 = require("../processors/replace");
|
|
42
43
|
const post_1 = require("../processors/post");
|
|
44
|
+
const insert_1 = require("../processors/insert");
|
|
43
45
|
const binary_1 = require("../binary");
|
|
44
46
|
const diff_1 = require("../diff");
|
|
45
47
|
const history_1 = require("../history");
|
|
46
48
|
const variables_remote_1 = require("../variables-remote");
|
|
47
|
-
|
|
49
|
+
const condition_1 = require("../condition");
|
|
50
|
+
async function runDiffLoop(config, workingDir, cache, configPath, history) {
|
|
48
51
|
let vars;
|
|
49
52
|
try {
|
|
50
53
|
vars = await (0, variables_remote_1.resolveVariableSpec)(config.variables ?? {}, workingDir, cache);
|
|
@@ -56,13 +59,28 @@ async function runDiffLoop(config, workingDir, cache) {
|
|
|
56
59
|
const allDiffs = [];
|
|
57
60
|
let hasError = false;
|
|
58
61
|
let selfContent;
|
|
59
|
-
|
|
62
|
+
let hasSelf = config_1.SELF_KEY in config.files;
|
|
63
|
+
if (hasSelf) {
|
|
64
|
+
const selfEntry = config.files[config_1.SELF_KEY];
|
|
65
|
+
try {
|
|
66
|
+
hasSelf = (0, condition_1.evaluateConditions)(selfEntry['if'], selfEntry.ifAny, () => configPath !== undefined
|
|
67
|
+
? configPath
|
|
68
|
+
: (0, diff_1.resolveTargetPath)(selfEntry, '', workingDir, vars), workingDir, vars);
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
console.error(`Error processing ${config_1.SELF_KEY}: ${err instanceof Error ? err.message : String(err)}`);
|
|
72
|
+
return { allDiffs: [], hasError: true };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
60
75
|
for (const [key, entry] of Object.entries(config.files)) {
|
|
61
76
|
const isSelf = key === config_1.SELF_KEY;
|
|
62
|
-
if (hasSelf
|
|
77
|
+
if (hasSelf !== isSelf)
|
|
63
78
|
continue;
|
|
64
79
|
try {
|
|
65
|
-
|
|
80
|
+
if (!isSelf &&
|
|
81
|
+
!(0, condition_1.evaluateConditions)(entry['if'], entry.ifAny, () => (0, diff_1.resolveTargetPath)(entry, '', workingDir, vars), workingDir, vars))
|
|
82
|
+
continue;
|
|
83
|
+
const result = await (0, sources_1.fetchSource)(entry, workingDir, vars, cache, isSelf && configPath !== undefined ? () => configPath : undefined);
|
|
66
84
|
for (const rec of result.sourceRecords) {
|
|
67
85
|
if (!rec.matched) {
|
|
68
86
|
console.error(`⚠ SHA mismatch for ${rec.sourceLabel}\n` +
|
|
@@ -76,11 +94,23 @@ async function runDiffLoop(config, workingDir, cache) {
|
|
|
76
94
|
for (const [relPath, rawContent] of result.files) {
|
|
77
95
|
let content = rawContent;
|
|
78
96
|
if (!(0, binary_1.isBinary)(content)) {
|
|
79
|
-
|
|
97
|
+
const rawText = content.toString('utf8');
|
|
98
|
+
let text = rawText;
|
|
80
99
|
if (entry.replace?.length)
|
|
81
100
|
text = (0, replace_1.applyReplace)(text, entry.replace, vars);
|
|
82
101
|
if (entry.post)
|
|
83
102
|
text = (0, post_1.applyPost)(text, entry.post, vars);
|
|
103
|
+
if (entry.strategy === 'insert' && !isSelf) {
|
|
104
|
+
const targetPath = (0, diff_1.resolveTargetPath)(entry, relPath, workingDir, vars);
|
|
105
|
+
const lastInserted = history?.getInsertedFragment(targetPath) ?? null;
|
|
106
|
+
if (lastInserted !== null &&
|
|
107
|
+
rawText === lastInserted.raw &&
|
|
108
|
+
text === lastInserted.processed &&
|
|
109
|
+
fs.existsSync(targetPath)) {
|
|
110
|
+
continue; // source and processed output unchanged — would be a no-op write, skip diff
|
|
111
|
+
}
|
|
112
|
+
text = (0, insert_1.applyInsertMode)(entry, text, lastInserted?.processed ?? null, targetPath);
|
|
113
|
+
}
|
|
84
114
|
content = Buffer.from(text, 'utf8');
|
|
85
115
|
}
|
|
86
116
|
if (isSelf) {
|
|
@@ -122,7 +152,8 @@ function diffCommand() {
|
|
|
122
152
|
process.exit(2);
|
|
123
153
|
}
|
|
124
154
|
const fetchCache = new Map();
|
|
125
|
-
const
|
|
155
|
+
const history = new history_1.HistoryManager((0, config_1.normalizeConfigKey)(configPath), workingDir);
|
|
156
|
+
const firstPass = await runDiffLoop(config, workingDir, fetchCache, configPath, history);
|
|
126
157
|
let { allDiffs, hasError } = firstPass;
|
|
127
158
|
if (hasError)
|
|
128
159
|
process.exit(2);
|
|
@@ -145,7 +176,7 @@ function diffCommand() {
|
|
|
145
176
|
break;
|
|
146
177
|
}
|
|
147
178
|
console.log('$self config resolved; re-evaluating with merged config...');
|
|
148
|
-
const next = await runDiffLoop(currentConfig, workingDir, fetchCache);
|
|
179
|
+
const next = await runDiffLoop(currentConfig, workingDir, fetchCache, configPath, history);
|
|
149
180
|
if (next.hasError) {
|
|
150
181
|
hasError = true;
|
|
151
182
|
break;
|
|
@@ -166,7 +197,7 @@ function diffCommand() {
|
|
|
166
197
|
filesWithoutSelf[k] = v;
|
|
167
198
|
}
|
|
168
199
|
if (Object.keys(filesWithoutSelf).length > 0) {
|
|
169
|
-
const second = await runDiffLoop({ ...stableConfig, files: filesWithoutSelf }, workingDir, fetchCache);
|
|
200
|
+
const second = await runDiffLoop({ ...stableConfig, files: filesWithoutSelf }, workingDir, fetchCache, configPath, history);
|
|
170
201
|
allDiffs = second.allDiffs;
|
|
171
202
|
hasError = second.hasError;
|
|
172
203
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/commands/lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/commands/lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,wBAAgB,WAAW,IAAI,OAAO,CA2GrC"}
|
package/dist/commands/lock.js
CHANGED
|
@@ -37,7 +37,9 @@ exports.lockCommand = lockCommand;
|
|
|
37
37
|
const commander_1 = require("commander");
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
39
|
const config_1 = require("../config");
|
|
40
|
+
const condition_1 = require("../condition");
|
|
40
41
|
const sources_1 = require("../sources");
|
|
42
|
+
const diff_1 = require("../diff");
|
|
41
43
|
const config_writeback_1 = require("../config-writeback");
|
|
42
44
|
const variables_remote_1 = require("../variables-remote");
|
|
43
45
|
function lockCommand() {
|
|
@@ -74,9 +76,13 @@ function lockCommand() {
|
|
|
74
76
|
const toPin = new Map(); // label → sha
|
|
75
77
|
let hasError = false;
|
|
76
78
|
let remoteSourceCount = 0;
|
|
77
|
-
for (const entry of Object.
|
|
79
|
+
for (const [key, entry] of Object.entries(config.files)) {
|
|
78
80
|
try {
|
|
79
|
-
|
|
81
|
+
if (!(0, condition_1.evaluateConditions)(entry['if'], entry.ifAny, () => key === config_1.SELF_KEY
|
|
82
|
+
? configPath
|
|
83
|
+
: (0, diff_1.resolveTargetPath)(entry, '', workingDir, vars), workingDir, vars))
|
|
84
|
+
continue;
|
|
85
|
+
const result = await (0, sources_1.fetchSource)(entry, workingDir, vars, undefined, key === config_1.SELF_KEY ? () => configPath : undefined);
|
|
80
86
|
remoteSourceCount += result.sourceRecords.length;
|
|
81
87
|
for (const rec of result.sourceRecords) {
|
|
82
88
|
if (!opts.force && rec.expectedSha !== undefined)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/commands/lock.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/commands/lock.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;AAuRpC,wBAAgB,WAAW,IAAI,OAAO,CAubrC"}
|
package/dist/commands/pull.js
CHANGED
|
@@ -35,11 +35,14 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.pullCommand = pullCommand;
|
|
37
37
|
const commander_1 = require("commander");
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
38
39
|
const path = __importStar(require("path"));
|
|
39
40
|
const config_1 = require("../config");
|
|
41
|
+
const condition_1 = require("../condition");
|
|
40
42
|
const sources_1 = require("../sources");
|
|
41
43
|
const replace_1 = require("../processors/replace");
|
|
42
44
|
const post_1 = require("../processors/post");
|
|
45
|
+
const insert_1 = require("../processors/insert");
|
|
43
46
|
const binary_1 = require("../binary");
|
|
44
47
|
const diff_1 = require("../diff");
|
|
45
48
|
const writer_1 = require("../writer");
|
|
@@ -47,7 +50,7 @@ const history_1 = require("../history");
|
|
|
47
50
|
const prompt_1 = require("../prompt");
|
|
48
51
|
const config_writeback_1 = require("../config-writeback");
|
|
49
52
|
const variables_remote_1 = require("../variables-remote");
|
|
50
|
-
async function runFetchLoop(config, workingDir, cache) {
|
|
53
|
+
async function runFetchLoop(config, workingDir, cache, configPath, history) {
|
|
51
54
|
let vars;
|
|
52
55
|
try {
|
|
53
56
|
vars = await (0, variables_remote_1.resolveVariableSpec)(config.variables ?? {}, workingDir, cache);
|
|
@@ -60,6 +63,9 @@ async function runFetchLoop(config, workingDir, cache) {
|
|
|
60
63
|
hasError: true,
|
|
61
64
|
shaErrors: [],
|
|
62
65
|
sourceRecordsByTarget: new Map(),
|
|
66
|
+
skippedPaths: new Set(),
|
|
67
|
+
hasUnresolvableSkippedPath: false,
|
|
68
|
+
insertedFragments: new Map(),
|
|
63
69
|
};
|
|
64
70
|
}
|
|
65
71
|
const writeTargets = [];
|
|
@@ -67,17 +73,69 @@ async function runFetchLoop(config, workingDir, cache) {
|
|
|
67
73
|
const shaErrors = [];
|
|
68
74
|
const seenShaErrorLabels = new Set();
|
|
69
75
|
const sourceRecordsByTarget = new Map();
|
|
76
|
+
const skippedPaths = new Set();
|
|
77
|
+
const insertedFragments = new Map();
|
|
78
|
+
let hasUnresolvableSkippedPath = false;
|
|
70
79
|
let hasError = false;
|
|
71
80
|
let selfContent;
|
|
72
81
|
let selfMode;
|
|
73
82
|
let selfSourceRecords;
|
|
74
|
-
|
|
83
|
+
let hasSelf = config_1.SELF_KEY in config.files;
|
|
84
|
+
if (hasSelf) {
|
|
85
|
+
const selfEntry = config.files[config_1.SELF_KEY];
|
|
86
|
+
try {
|
|
87
|
+
hasSelf = (0, condition_1.evaluateConditions)(selfEntry['if'], selfEntry.ifAny, () => configPath !== undefined
|
|
88
|
+
? configPath
|
|
89
|
+
: (0, diff_1.resolveTargetPath)(selfEntry, '', workingDir, vars), workingDir, vars);
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
console.error(`Error processing ${config_1.SELF_KEY}: ${err instanceof Error ? err.message : String(err)}`);
|
|
93
|
+
return {
|
|
94
|
+
writeTargets,
|
|
95
|
+
allDiffs,
|
|
96
|
+
hasError: true,
|
|
97
|
+
shaErrors,
|
|
98
|
+
sourceRecordsByTarget,
|
|
99
|
+
skippedPaths,
|
|
100
|
+
hasUnresolvableSkippedPath,
|
|
101
|
+
insertedFragments,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
// $self was condition-skipped: protect configPath from stale cleanup so a
|
|
105
|
+
// previously-written config file is not restored or deleted on this run.
|
|
106
|
+
if (!hasSelf &&
|
|
107
|
+
configPath !== undefined &&
|
|
108
|
+
!(0, config_1.isRemoteConfigSpec)(configPath)) {
|
|
109
|
+
skippedPaths.add(configPath);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
75
112
|
for (const [key, entry] of Object.entries(config.files)) {
|
|
76
113
|
const isSelf = key === config_1.SELF_KEY;
|
|
77
|
-
if (hasSelf
|
|
114
|
+
if (hasSelf !== isSelf)
|
|
78
115
|
continue;
|
|
79
116
|
try {
|
|
80
|
-
|
|
117
|
+
if (!isSelf &&
|
|
118
|
+
!(0, condition_1.evaluateConditions)(entry['if'], entry.ifAny, () => (0, diff_1.resolveTargetPath)(entry, '', workingDir, vars), workingDir, vars)) {
|
|
119
|
+
try {
|
|
120
|
+
skippedPaths.add((0, diff_1.resolveTargetPath)(entry, '', workingDir, vars));
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
console.warn(`Warning: skipped entry has an unresolvable target path — stale cleanup disabled for this run.`);
|
|
124
|
+
hasUnresolvableSkippedPath = true;
|
|
125
|
+
}
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
const result = await (0, sources_1.fetchSource)(entry, workingDir, vars, cache, isSelf && configPath !== undefined ? () => configPath : undefined);
|
|
129
|
+
if (result.allSkipped && !isSelf) {
|
|
130
|
+
try {
|
|
131
|
+
skippedPaths.add((0, diff_1.resolveTargetPath)(entry, '', workingDir, vars));
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
console.warn(`Warning: skipped entry has an unresolvable target path — stale cleanup disabled for this run.`);
|
|
135
|
+
hasUnresolvableSkippedPath = true;
|
|
136
|
+
}
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
81
139
|
for (const rec of result.sourceRecords) {
|
|
82
140
|
if (!rec.matched && !seenShaErrorLabels.has(rec.sourceLabel)) {
|
|
83
141
|
seenShaErrorLabels.add(rec.sourceLabel);
|
|
@@ -95,11 +153,29 @@ async function runFetchLoop(config, workingDir, cache) {
|
|
|
95
153
|
let content = rawContent;
|
|
96
154
|
if (!(0, binary_1.isBinary)(content)) {
|
|
97
155
|
// Processors only operate on text; binary files are passed through unchanged.
|
|
98
|
-
|
|
156
|
+
const rawText = content.toString('utf8');
|
|
157
|
+
let text = rawText;
|
|
99
158
|
if (entry.replace?.length)
|
|
100
159
|
text = (0, replace_1.applyReplace)(text, entry.replace, vars);
|
|
101
160
|
if (entry.post)
|
|
102
161
|
text = (0, post_1.applyPost)(text, entry.post, vars);
|
|
162
|
+
if (entry.strategy === 'insert' && !isSelf) {
|
|
163
|
+
const targetPath = (0, diff_1.resolveTargetPath)(entry, relPath, workingDir, vars);
|
|
164
|
+
const lastInserted = history?.getInsertedFragment(targetPath) ?? null;
|
|
165
|
+
if (lastInserted !== null &&
|
|
166
|
+
rawText === lastInserted.raw &&
|
|
167
|
+
text === lastInserted.processed &&
|
|
168
|
+
fs.existsSync(targetPath)) {
|
|
169
|
+
skippedPaths.add(targetPath); // keep stale detection from treating this as missing
|
|
170
|
+
continue; // source and processed output unchanged — skip write entirely (no-op)
|
|
171
|
+
}
|
|
172
|
+
const processedText = text;
|
|
173
|
+
text = (0, insert_1.applyInsertMode)(entry, processedText, lastInserted?.processed ?? null, targetPath);
|
|
174
|
+
insertedFragments.set(targetPath, {
|
|
175
|
+
raw: rawText,
|
|
176
|
+
processed: processedText,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
103
179
|
content = Buffer.from(text, 'utf8');
|
|
104
180
|
}
|
|
105
181
|
if (isSelf) {
|
|
@@ -128,6 +204,9 @@ async function runFetchLoop(config, workingDir, cache) {
|
|
|
128
204
|
hasError,
|
|
129
205
|
shaErrors,
|
|
130
206
|
sourceRecordsByTarget,
|
|
207
|
+
skippedPaths,
|
|
208
|
+
hasUnresolvableSkippedPath,
|
|
209
|
+
insertedFragments,
|
|
131
210
|
selfContent,
|
|
132
211
|
selfMode,
|
|
133
212
|
selfSourceRecords,
|
|
@@ -165,8 +244,11 @@ function pullCommand() {
|
|
|
165
244
|
const historyAvailable = history.ensureStorageDir();
|
|
166
245
|
const pullId = historyAvailable ? history.openPullSession() : null;
|
|
167
246
|
const fetchCache = new Map();
|
|
168
|
-
const firstPass = await runFetchLoop(config, workingDir, fetchCache);
|
|
247
|
+
const firstPass = await runFetchLoop(config, workingDir, fetchCache, configPath, history);
|
|
169
248
|
let { writeTargets, allDiffs, sourceRecordsByTarget } = firstPass;
|
|
249
|
+
let insertedFragments = firstPass.insertedFragments;
|
|
250
|
+
let skippedPaths = firstPass.skippedPaths;
|
|
251
|
+
let hasUnresolvableSkippedPath = firstPass.hasUnresolvableSkippedPath;
|
|
170
252
|
if (firstPass.hasError) {
|
|
171
253
|
console.error('Aborting due to errors.');
|
|
172
254
|
process.exit(2);
|
|
@@ -202,7 +284,7 @@ function pullCommand() {
|
|
|
202
284
|
break;
|
|
203
285
|
}
|
|
204
286
|
console.log('$self config resolved; re-evaluating with merged config...');
|
|
205
|
-
const next = await runFetchLoop(currentConfig, workingDir, fetchCache);
|
|
287
|
+
const next = await runFetchLoop(currentConfig, workingDir, fetchCache, configPath, history);
|
|
206
288
|
if (next.hasError) {
|
|
207
289
|
console.error('Aborting due to errors in $self re-evaluated config.');
|
|
208
290
|
process.exit(2);
|
|
@@ -236,7 +318,7 @@ function pullCommand() {
|
|
|
236
318
|
filesWithoutSelf[k] = v;
|
|
237
319
|
}
|
|
238
320
|
if (Object.keys(filesWithoutSelf).length > 0) {
|
|
239
|
-
const second = await runFetchLoop({ ...stableConfig, files: filesWithoutSelf }, workingDir, fetchCache);
|
|
321
|
+
const second = await runFetchLoop({ ...stableConfig, files: filesWithoutSelf }, workingDir, fetchCache, configPath, history);
|
|
240
322
|
if (second.hasError) {
|
|
241
323
|
console.error('Aborting due to errors.');
|
|
242
324
|
process.exit(2);
|
|
@@ -249,6 +331,10 @@ function pullCommand() {
|
|
|
249
331
|
writeTargets = second.writeTargets;
|
|
250
332
|
allDiffs = second.allDiffs;
|
|
251
333
|
sourceRecordsByTarget = second.sourceRecordsByTarget;
|
|
334
|
+
insertedFragments = second.insertedFragments;
|
|
335
|
+
skippedPaths = second.skippedPaths;
|
|
336
|
+
if (second.hasUnresolvableSkippedPath)
|
|
337
|
+
hasUnresolvableSkippedPath = true;
|
|
252
338
|
const seenInSecond = new Set(firstPass.shaErrors.map((e) => e.sourceLabel));
|
|
253
339
|
for (const e of second.shaErrors) {
|
|
254
340
|
if (!seenInSecond.has(e.sourceLabel))
|
|
@@ -293,12 +379,21 @@ function pullCommand() {
|
|
|
293
379
|
const staleToDelete = [];
|
|
294
380
|
const staleToRestore = [];
|
|
295
381
|
const staleDiffs = [];
|
|
296
|
-
if (historyAvailable) {
|
|
382
|
+
if (historyAvailable && !hasUnresolvableSkippedPath) {
|
|
297
383
|
const lastFiles = history.getLastPullFiles();
|
|
298
384
|
const currentPaths = new Set(writeTargets.map((t) => t.targetPath));
|
|
385
|
+
const skippedPathsArr = [...skippedPaths];
|
|
299
386
|
for (const ref of lastFiles) {
|
|
300
387
|
if (currentPaths.has(ref.absolutePath))
|
|
301
388
|
continue;
|
|
389
|
+
// Files covered by a skipped (condition-gated) entry should not be
|
|
390
|
+
// treated as stale — the entry is still in the config, it just didn't
|
|
391
|
+
// run this time. Exact match for file entries; prefix match for
|
|
392
|
+
// directory entries (whose resolved base path is the directory itself).
|
|
393
|
+
const coveredBySkipped = skippedPathsArr.some((sp) => ref.absolutePath === sp ||
|
|
394
|
+
ref.absolutePath.startsWith(sp + path.sep));
|
|
395
|
+
if (coveredBySkipped)
|
|
396
|
+
continue;
|
|
302
397
|
const meta = history.getFileMeta(ref.absolutePath);
|
|
303
398
|
if (!meta)
|
|
304
399
|
continue;
|
|
@@ -327,6 +422,11 @@ function pullCommand() {
|
|
|
327
422
|
printShaErrors(firstPass.shaErrors);
|
|
328
423
|
}
|
|
329
424
|
if (!hasChanges && firstPass.shaErrors.length === 0) {
|
|
425
|
+
if (historyAvailable && insertedFragments.size > 0) {
|
|
426
|
+
for (const [targetPath, fragment] of insertedFragments) {
|
|
427
|
+
history.saveInsertedFragment(targetPath, fragment.raw, fragment.processed);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
330
430
|
console.log('Nothing to do.');
|
|
331
431
|
process.exit(0);
|
|
332
432
|
}
|
|
@@ -414,6 +514,12 @@ function pullCommand() {
|
|
|
414
514
|
console.error(`Write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
415
515
|
process.exit(2);
|
|
416
516
|
}
|
|
517
|
+
// Save inserted fragments to history for future idempotency detection
|
|
518
|
+
if (historyAvailable && insertedFragments.size > 0) {
|
|
519
|
+
for (const [targetPath, fragment] of insertedFragments) {
|
|
520
|
+
history.saveInsertedFragment(targetPath, fragment.raw, fragment.processed);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
417
523
|
// SHA writeback: write updated sha values into config file after all writes complete.
|
|
418
524
|
// Skipped when config was a write target and already patched in-memory above.
|
|
419
525
|
if (shaUpdates !== null && !configShaPreApplied) {
|