reslop 0.1.8 → 0.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/CHANGELOG.md +25 -1
- package/README.md +27 -38
- package/bin/reslop.js +2 -2
- package/lib/ansi.js +6 -2
- package/lib/api.js +2 -2
- package/lib/capabilities.js +10 -14
- package/lib/cli.js +28 -47
- package/lib/clipboard.js +1 -1
- package/lib/deps-diff.js +712 -0
- package/lib/deps.js +556 -32
- package/lib/detect.js +1 -7
- package/lib/diff/align.js +7 -10
- package/lib/diff/diff.js +53 -0
- package/lib/diff/display.js +5 -4
- package/lib/diff/inline.js +26 -21
- package/lib/diff/items.js +6 -4
- package/lib/diff/patch.js +1 -3
- package/lib/diff/unit.js +392 -0
- package/lib/files.js +34 -8
- package/lib/{git/branches.js → git-branches.js} +103 -10
- package/lib/{git/dependencies.js → git-deps.js} +111 -38
- package/lib/git.js +592 -65
- package/lib/github.js +28 -197
- package/lib/gitlab.js +24 -195
- package/lib/highlight/bash.js +1 -3
- package/lib/highlight/css.js +1 -3
- package/lib/highlight/js.js +11 -14
- package/lib/highlight.js +6 -9
- package/lib/keys.js +22 -9
- package/lib/manifest.js +330 -0
- package/lib/remote.js +374 -0
- package/lib/render/branches.js +34 -66
- package/lib/render/chrome.js +57 -22
- package/lib/render/commits.js +85 -0
- package/lib/render/diff.js +16 -16
- package/lib/render/files.js +29 -37
- package/lib/render/frame.js +29 -13
- package/lib/render/notes.js +4 -3
- package/lib/render/primitives.js +46 -1
- package/lib/{render.js → render/render.js} +6 -7
- package/lib/render/unit.js +41 -0
- package/lib/review.js +750 -14
- package/lib/select.js +5 -10
- package/lib/session/accessors.js +9 -1
- package/lib/session/actions.js +93 -36
- package/lib/session/branches.js +130 -144
- package/lib/session/change-actions.js +206 -124
- package/lib/session/commit.js +217 -62
- package/lib/session/compose.js +158 -13
- package/lib/session/dispatch.js +109 -55
- package/lib/session/files-pane.js +145 -142
- package/lib/session/items.js +131 -34
- package/lib/session/lifecycle.js +82 -42
- package/lib/session/load.js +19 -33
- package/lib/session/navigation.js +15 -3
- package/lib/session/ops.js +28 -41
- package/lib/session/pointer.js +58 -54
- package/lib/session/review.js +23 -37
- package/lib/session/terminal.js +6 -12
- package/lib/session/todos.js +8 -12
- package/lib/session/unit.js +208 -0
- package/lib/session/update.js +33 -46
- package/lib/session/view.js +82 -11
- package/lib/session/watch.js +11 -19
- package/lib/session.js +29 -226
- package/lib/source.js +3 -3
- package/lib/update.js +40 -75
- package/lib/{git/proc.js → utilities.js} +75 -11
- package/lib/wrap.js +1 -3
- package/package.json +2 -2
- package/lib/deps/changes.js +0 -331
- package/lib/deps/items.js +0 -131
- package/lib/deps/manifest.js +0 -145
- package/lib/deps/merge.js +0 -120
- package/lib/deps/proposals.js +0 -164
- package/lib/deps/reports.js +0 -180
- package/lib/deps/rows.js +0 -177
- package/lib/deps/scan.js +0 -138
- package/lib/deps/usage.js +0 -68
- package/lib/deps/versions.js +0 -119
- package/lib/diff.js +0 -33
- package/lib/git/changes.js +0 -164
- package/lib/git/read.js +0 -253
- package/lib/git/run.js +0 -100
- package/lib/npm/commands.js +0 -100
- package/lib/remote/changes.js +0 -37
- package/lib/remote/headers.js +0 -36
- package/lib/remote/http.js +0 -122
- package/lib/remote/notes.js +0 -94
- package/lib/review/format.js +0 -434
- package/lib/review/storage.js +0 -150
- package/lib/review/store.js +0 -178
- package/lib/review/templates.js +0 -49
- package/lib/session/origins.js +0 -7
- package/lib/sys.js +0 -84
|
@@ -1,15 +1,75 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const { spawn, spawnSync } = require('node:child_process');
|
|
4
|
+
const { split } = require('metautil');
|
|
4
5
|
|
|
5
|
-
const
|
|
6
|
-
|
|
6
|
+
const IS_WIN = process.platform === 'win32';
|
|
7
7
|
const DEFAULT_ENCODING = 'utf8';
|
|
8
8
|
const DEFAULT_MAX_BUFFER = 32 * 1024 * 1024;
|
|
9
9
|
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
const UNIX_CLIP = [
|
|
11
|
+
{ cmd: 'wl-copy', args: [] },
|
|
12
|
+
{ cmd: 'xclip', args: ['-selection', 'clipboard'] },
|
|
13
|
+
{ cmd: 'xsel', args: ['--clipboard', '--input'] },
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const parseVersion = (text) => {
|
|
17
|
+
const match = /^(\d+)\.(\d+)\.(\d+)/.exec(`${text ?? ''}`);
|
|
18
|
+
if (!match) return null;
|
|
19
|
+
const [, major, minor, patch] = match.map(Number);
|
|
20
|
+
return { major, minor, patch };
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const cmpVersion = (left, right) =>
|
|
24
|
+
left.major - right.major ||
|
|
25
|
+
left.minor - right.minor ||
|
|
26
|
+
left.patch - right.patch;
|
|
27
|
+
|
|
28
|
+
const oneLine = (text, fallback = '') =>
|
|
29
|
+
split(`${text ?? ''}`.trim(), '\n')[0] || fallback;
|
|
30
|
+
|
|
31
|
+
const npmBin = (platform = process.platform) =>
|
|
32
|
+
platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
33
|
+
|
|
34
|
+
const spawnBase = (extra = {}) => ({ windowsHide: true, ...extra });
|
|
35
|
+
|
|
36
|
+
const npmOpts = (extra = {}, platform = process.platform) =>
|
|
37
|
+
spawnBase({ shell: platform === 'win32', ...extra });
|
|
38
|
+
|
|
39
|
+
const clipTools = (platform = process.platform) => {
|
|
40
|
+
if (platform === 'win32') return [{ cmd: 'clip', args: [] }];
|
|
41
|
+
if (platform === 'darwin') return [{ cmd: 'pbcopy', args: [] }];
|
|
42
|
+
return UNIX_CLIP;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const listen = (emitter, event, handler) => {
|
|
46
|
+
if (!emitter || typeof emitter.on !== 'function') return () => {};
|
|
47
|
+
emitter.on(event, handler);
|
|
48
|
+
return () => {
|
|
49
|
+
if (typeof emitter.removeListener === 'function') {
|
|
50
|
+
return void emitter.removeListener(event, handler);
|
|
51
|
+
}
|
|
52
|
+
if (typeof emitter.off === 'function') emitter.off(event, handler);
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const watchResize = (stdout, proc, onResize, signal) => {
|
|
57
|
+
const stopStdout = listen(stdout, 'resize', onResize);
|
|
58
|
+
let stopProc = () => {};
|
|
59
|
+
try {
|
|
60
|
+
stopProc = listen(proc, 'SIGWINCH', onResize);
|
|
61
|
+
} catch {
|
|
62
|
+
// SIGWINCH is not available on Windows
|
|
63
|
+
}
|
|
64
|
+
const stop = () => {
|
|
65
|
+
stopStdout();
|
|
66
|
+
stopProc();
|
|
67
|
+
};
|
|
68
|
+
if (signal) {
|
|
69
|
+
if (signal.aborted) stop();
|
|
70
|
+
else signal.addEventListener('abort', stop, { once: true });
|
|
71
|
+
}
|
|
72
|
+
return stop;
|
|
13
73
|
};
|
|
14
74
|
|
|
15
75
|
const abortError = () => {
|
|
@@ -51,12 +111,7 @@ const spawnOptions = (options = {}) => {
|
|
|
51
111
|
|
|
52
112
|
const runProcSync = (cmd, args, options = {}) => {
|
|
53
113
|
const result = spawnSync(cmd, args, spawnOptions(options));
|
|
54
|
-
return procResult(
|
|
55
|
-
status: result.status,
|
|
56
|
-
stdout: result.stdout,
|
|
57
|
-
stderr: result.stderr,
|
|
58
|
-
error: result.error,
|
|
59
|
-
});
|
|
114
|
+
return procResult(result);
|
|
60
115
|
};
|
|
61
116
|
|
|
62
117
|
const attachOutput = (stream, encoding, onChunk) => {
|
|
@@ -151,9 +206,18 @@ const runProc = (cmd, args, options = {}) =>
|
|
|
151
206
|
});
|
|
152
207
|
|
|
153
208
|
module.exports = {
|
|
209
|
+
IS_WIN,
|
|
154
210
|
DEFAULT_ENCODING,
|
|
155
211
|
DEFAULT_MAX_BUFFER,
|
|
212
|
+
parseVersion,
|
|
213
|
+
cmpVersion,
|
|
156
214
|
oneLine,
|
|
215
|
+
npmBin,
|
|
216
|
+
spawnBase,
|
|
217
|
+
npmOpts,
|
|
218
|
+
clipTools,
|
|
219
|
+
listen,
|
|
220
|
+
watchResize,
|
|
157
221
|
abortError,
|
|
158
222
|
isAbort,
|
|
159
223
|
procResult,
|
package/lib/wrap.js
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
const { graphemes, graphemeWidth, visibleWidth } = require('./ansi.js');
|
|
4
4
|
|
|
5
|
-
const isWrapBreak = (ch) => ch === ' ' || ch === '\t';
|
|
6
|
-
|
|
7
5
|
const wrapPlain = (text, width) => {
|
|
8
6
|
if (width <= 0) return [''];
|
|
9
7
|
if (visibleWidth(text) <= width) return [text];
|
|
@@ -36,7 +34,7 @@ const wrapPlain = (text, width) => {
|
|
|
36
34
|
continue;
|
|
37
35
|
}
|
|
38
36
|
col += w;
|
|
39
|
-
if (
|
|
37
|
+
if (ch === ' ' || ch === '\t') lastBreak = i;
|
|
40
38
|
i += 1;
|
|
41
39
|
}
|
|
42
40
|
rows.push(slice(start, parts.length));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reslop",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Interactive code review and repair planning for AI-assisted changes",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"code-review",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"eslint": "^9.39.4",
|
|
60
60
|
"eslint-config-metarhia": "^9.1.9",
|
|
61
61
|
"metaskills": "^1.0.5",
|
|
62
|
-
"prettier": "^3.9.
|
|
62
|
+
"prettier": "^3.9.8"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"metautil": "^5.5.2"
|
package/lib/deps/changes.js
DELETED
|
@@ -1,331 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { itemPath } = require('../files.js');
|
|
4
|
-
|
|
5
|
-
const manifest = require('./manifest.js');
|
|
6
|
-
const { MANIFEST, LOCKFILE, SECTION_KEYS, depFileMeta, relOf } = manifest;
|
|
7
|
-
const { parseJson, readSections, emptySectionMaps } = manifest;
|
|
8
|
-
const { lockRootSections, lockEntries, lockPackageCount } = manifest;
|
|
9
|
-
|
|
10
|
-
const SECTION_ORDER = [...SECTION_KEYS, 'resolved', 'field'];
|
|
11
|
-
const ACTION_ORDER = ['added', 'removed', 'changed', 'vulnerable'];
|
|
12
|
-
const SECTION_NAMES = SECTION_KEYS.join('|');
|
|
13
|
-
const SECTION_OPEN = new RegExp(`^\\s*"(${SECTION_NAMES})"\\s*:\\s*\\{\\s*$`);
|
|
14
|
-
const SECTION_END = /^\s*\},?\s*$/;
|
|
15
|
-
const DEP_ENTRY = /^\s*"([^"]+)"\s*:\s*"([^"]*)"\s*,?\s*$/;
|
|
16
|
-
|
|
17
|
-
const diffMaps = (oldMap, newMap, section) => {
|
|
18
|
-
const keys = [...oldMap.keys(), ...newMap.keys()];
|
|
19
|
-
const names = [...new Set(keys)];
|
|
20
|
-
names.sort();
|
|
21
|
-
const changes = [];
|
|
22
|
-
for (const name of names) {
|
|
23
|
-
const from = oldMap.has(name) ? oldMap.get(name) : '';
|
|
24
|
-
const to = newMap.has(name) ? newMap.get(name) : '';
|
|
25
|
-
if (from === to) continue;
|
|
26
|
-
let action = 'changed';
|
|
27
|
-
if (!oldMap.has(name)) action = 'added';
|
|
28
|
-
else if (!newMap.has(name)) action = 'removed';
|
|
29
|
-
changes.push({ name, section, action, from, to });
|
|
30
|
-
}
|
|
31
|
-
return changes;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const diffSections = (oldMaps, newMaps) => {
|
|
35
|
-
const changes = [];
|
|
36
|
-
for (const key of SECTION_KEYS) {
|
|
37
|
-
const found = diffMaps(oldMaps[key], newMaps[key], key);
|
|
38
|
-
for (const change of found) changes.push(change);
|
|
39
|
-
}
|
|
40
|
-
return changes;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const fieldText = (value) => {
|
|
44
|
-
if (value === undefined) return '';
|
|
45
|
-
if (typeof value === 'string') return value;
|
|
46
|
-
return JSON.stringify(value);
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const sameJson = (left, right) =>
|
|
50
|
-
JSON.stringify(left) === JSON.stringify(right);
|
|
51
|
-
|
|
52
|
-
const diffOtherFields = (oldPkg, newPkg) => {
|
|
53
|
-
if (!oldPkg && !newPkg) return [];
|
|
54
|
-
const oldObj = oldPkg ?? {};
|
|
55
|
-
const newObj = newPkg ?? {};
|
|
56
|
-
const keys = [...Object.keys(oldObj), ...Object.keys(newObj)];
|
|
57
|
-
const names = [...new Set(keys)];
|
|
58
|
-
names.sort();
|
|
59
|
-
const changes = [];
|
|
60
|
-
for (const name of names) {
|
|
61
|
-
if (SECTION_KEYS.includes(name)) continue;
|
|
62
|
-
const prev = oldObj[name];
|
|
63
|
-
const next = newObj[name];
|
|
64
|
-
if (sameJson(prev, next)) continue;
|
|
65
|
-
let action = 'changed';
|
|
66
|
-
if (!Object.hasOwn(oldObj, name)) action = 'added';
|
|
67
|
-
else if (!Object.hasOwn(newObj, name)) action = 'removed';
|
|
68
|
-
const from = fieldText(prev);
|
|
69
|
-
const to = fieldText(next);
|
|
70
|
-
const section = 'field';
|
|
71
|
-
changes.push({ name, section, action, from, to });
|
|
72
|
-
}
|
|
73
|
-
return changes;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
const onlyDepEdits = (items) => {
|
|
77
|
-
if (!items.length) return false;
|
|
78
|
-
for (const item of items) {
|
|
79
|
-
if (!item.hunk) return false;
|
|
80
|
-
const blockId = item.blockId;
|
|
81
|
-
const scoped = typeof blockId === 'number';
|
|
82
|
-
let section = '';
|
|
83
|
-
for (const line of item.hunk.lines) {
|
|
84
|
-
const open = SECTION_OPEN.exec(line.text);
|
|
85
|
-
let nextSection = section;
|
|
86
|
-
if (open) nextSection = open[1];
|
|
87
|
-
else if (section && SECTION_END.test(line.text)) nextSection = '';
|
|
88
|
-
const inBlock = !scoped || line.blockId === blockId;
|
|
89
|
-
if (inBlock && line.type !== 'ctx') {
|
|
90
|
-
const inDep = !!(open || section);
|
|
91
|
-
if (!inDep) return false;
|
|
92
|
-
const isEntry = DEP_ENTRY.test(line.text);
|
|
93
|
-
const isClose = SECTION_END.test(line.text);
|
|
94
|
-
if (!open && !isEntry && !isClose) return false;
|
|
95
|
-
}
|
|
96
|
-
section = nextSection;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return true;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
const mapsFromHunks = (items) => {
|
|
103
|
-
const oldMaps = emptySectionMaps();
|
|
104
|
-
const newMaps = emptySectionMaps();
|
|
105
|
-
let section = '';
|
|
106
|
-
for (const item of items) {
|
|
107
|
-
if (!item.hunk) continue;
|
|
108
|
-
for (const line of item.hunk.lines) {
|
|
109
|
-
const open = SECTION_OPEN.exec(line.text);
|
|
110
|
-
if (open) {
|
|
111
|
-
section = open[1];
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
if (section && SECTION_END.test(line.text)) {
|
|
115
|
-
section = '';
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
if (!section) continue;
|
|
119
|
-
const entry = DEP_ENTRY.exec(line.text);
|
|
120
|
-
if (!entry) continue;
|
|
121
|
-
const name = entry[1];
|
|
122
|
-
const version = entry[2];
|
|
123
|
-
if (line.type === 'del' || line.type === 'ctx') {
|
|
124
|
-
oldMaps[section].set(name, version);
|
|
125
|
-
}
|
|
126
|
-
if (line.type === 'add' || line.type === 'ctx') {
|
|
127
|
-
newMaps[section].set(name, version);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return { oldMaps, newMaps };
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
const directNames = (oldMaps, newMaps) => {
|
|
135
|
-
const names = new Set();
|
|
136
|
-
for (const key of SECTION_KEYS) {
|
|
137
|
-
for (const name of oldMaps[key].keys()) names.add(name);
|
|
138
|
-
for (const name of newMaps[key].keys()) names.add(name);
|
|
139
|
-
}
|
|
140
|
-
return names;
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
const mergeResolved = (changes, oldResolved, newResolved, oldMaps, newMaps) => {
|
|
144
|
-
const seen = new Set();
|
|
145
|
-
const merged = [];
|
|
146
|
-
for (const change of changes) {
|
|
147
|
-
seen.add(change.name);
|
|
148
|
-
const resolvedFrom = oldResolved.get(change.name) ?? '';
|
|
149
|
-
const resolvedTo = newResolved.get(change.name) ?? '';
|
|
150
|
-
merged.push({ ...change, resolvedFrom, resolvedTo });
|
|
151
|
-
}
|
|
152
|
-
const names = [...directNames(oldMaps, newMaps)];
|
|
153
|
-
names.sort();
|
|
154
|
-
for (const name of names) {
|
|
155
|
-
if (seen.has(name)) continue;
|
|
156
|
-
const from = oldResolved.get(name) ?? '';
|
|
157
|
-
const to = newResolved.get(name) ?? '';
|
|
158
|
-
if (from === to) continue;
|
|
159
|
-
if (!from && !to) continue;
|
|
160
|
-
let action = 'changed';
|
|
161
|
-
if (!from) action = 'added';
|
|
162
|
-
else if (!to) action = 'removed';
|
|
163
|
-
const section = 'resolved';
|
|
164
|
-
const resolvedFrom = from;
|
|
165
|
-
const resolvedTo = to;
|
|
166
|
-
merged.push({ name, section, action, from, to, resolvedFrom, resolvedTo });
|
|
167
|
-
}
|
|
168
|
-
return merged;
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
const compareChangeOrder = (left, right) => {
|
|
172
|
-
const section = SECTION_ORDER.indexOf(left.section);
|
|
173
|
-
const other = SECTION_ORDER.indexOf(right.section);
|
|
174
|
-
if (section !== other) return section - other;
|
|
175
|
-
const leftAction = ACTION_ORDER.indexOf(left.action);
|
|
176
|
-
const rightAction = ACTION_ORDER.indexOf(right.action);
|
|
177
|
-
if (leftAction !== rightAction) return leftAction - rightAction;
|
|
178
|
-
return left.name.localeCompare(right.name);
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
const orderedChanges = (changes) => [...changes].sort(compareChangeOrder);
|
|
182
|
-
|
|
183
|
-
const kindItems = (items, kind) => {
|
|
184
|
-
const matched = [];
|
|
185
|
-
for (const item of items) {
|
|
186
|
-
const rel = itemPath(item);
|
|
187
|
-
const meta = depFileMeta(rel);
|
|
188
|
-
if (meta && meta.kind === kind) matched.push(item);
|
|
189
|
-
}
|
|
190
|
-
return matched;
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
const readGroupSnapshot = (group, readSides) => {
|
|
194
|
-
const origin = group.origin;
|
|
195
|
-
const dir = group.dir;
|
|
196
|
-
const groupItems = group.items;
|
|
197
|
-
const manifestItems = kindItems(groupItems, 'manifest');
|
|
198
|
-
const lockItems = kindItems(groupItems, 'lockfile');
|
|
199
|
-
const manifestRel = relOf(dir, MANIFEST);
|
|
200
|
-
const lockRel = relOf(dir, LOCKFILE);
|
|
201
|
-
const manifestSides = readSides(origin, manifestRel);
|
|
202
|
-
const lockSides = readSides(origin, lockRel);
|
|
203
|
-
const oldPkg = parseJson(manifestSides.oldText);
|
|
204
|
-
const newPkg = parseJson(manifestSides.newText);
|
|
205
|
-
const oldLock = parseJson(lockSides.oldText);
|
|
206
|
-
const newLock = parseJson(lockSides.newText);
|
|
207
|
-
const parsedManifest = !!(oldPkg || newPkg);
|
|
208
|
-
return {
|
|
209
|
-
origin,
|
|
210
|
-
dir,
|
|
211
|
-
groupItems,
|
|
212
|
-
manifestItems,
|
|
213
|
-
lockItems,
|
|
214
|
-
oldPkg,
|
|
215
|
-
newPkg,
|
|
216
|
-
oldLock,
|
|
217
|
-
newLock,
|
|
218
|
-
parsedManifest,
|
|
219
|
-
};
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
const sectionMapsOf = (snapshot) => {
|
|
223
|
-
if (snapshot.parsedManifest) {
|
|
224
|
-
const oldMaps = readSections(snapshot.oldPkg);
|
|
225
|
-
const newMaps = readSections(snapshot.newPkg);
|
|
226
|
-
return { oldMaps, newMaps };
|
|
227
|
-
}
|
|
228
|
-
if (snapshot.manifestItems.length) {
|
|
229
|
-
return mapsFromHunks(snapshot.manifestItems);
|
|
230
|
-
}
|
|
231
|
-
const oldMaps = lockRootSections(snapshot.oldLock);
|
|
232
|
-
const newMaps = lockRootSections(snapshot.newLock);
|
|
233
|
-
return { oldMaps, newMaps };
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
const comparedChanges = (snapshot) => {
|
|
237
|
-
const maps = sectionMapsOf(snapshot);
|
|
238
|
-
const oldMaps = maps.oldMaps;
|
|
239
|
-
const newMaps = maps.newMaps;
|
|
240
|
-
const manifestChanges = diffSections(oldMaps, newMaps);
|
|
241
|
-
const parsed = snapshot.parsedManifest;
|
|
242
|
-
let otherChanges = [];
|
|
243
|
-
if (parsed) {
|
|
244
|
-
otherChanges = diffOtherFields(snapshot.oldPkg, snapshot.newPkg);
|
|
245
|
-
}
|
|
246
|
-
const oldResolved = lockEntries(snapshot.oldLock);
|
|
247
|
-
const newResolved = lockEntries(snapshot.newLock);
|
|
248
|
-
const changes = mergeResolved(
|
|
249
|
-
manifestChanges,
|
|
250
|
-
oldResolved,
|
|
251
|
-
newResolved,
|
|
252
|
-
oldMaps,
|
|
253
|
-
newMaps,
|
|
254
|
-
);
|
|
255
|
-
const oldCount = lockPackageCount(snapshot.oldLock);
|
|
256
|
-
const newCount = lockPackageCount(snapshot.newLock);
|
|
257
|
-
return { changes, otherChanges, oldCount, newCount };
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
const foldingPolicy = (snapshot, compared) => {
|
|
261
|
-
const foldLock = snapshot.lockItems.length > 0;
|
|
262
|
-
const hasDepChanges = compared.changes.length > 0;
|
|
263
|
-
if (!snapshot.manifestItems.length) {
|
|
264
|
-
const foldManifest = false;
|
|
265
|
-
const takeAllManifest = false;
|
|
266
|
-
return { foldLock, foldManifest, takeAllManifest };
|
|
267
|
-
}
|
|
268
|
-
if (snapshot.parsedManifest) {
|
|
269
|
-
const foldManifest = hasDepChanges;
|
|
270
|
-
const takeAllManifest = hasDepChanges && compared.otherChanges.length === 0;
|
|
271
|
-
return { foldLock, foldManifest, takeAllManifest };
|
|
272
|
-
}
|
|
273
|
-
const foldManifest = hasDepChanges && onlyDepEdits(snapshot.manifestItems);
|
|
274
|
-
const takeAllManifest = foldManifest;
|
|
275
|
-
return { foldLock, foldManifest, takeAllManifest };
|
|
276
|
-
};
|
|
277
|
-
|
|
278
|
-
const summarizeGroup = (group, readSides) => {
|
|
279
|
-
const snapshot = readGroupSnapshot(group, readSides);
|
|
280
|
-
const compared = comparedChanges(snapshot);
|
|
281
|
-
const policy = foldingPolicy(snapshot, compared);
|
|
282
|
-
return {
|
|
283
|
-
changes: compared.changes,
|
|
284
|
-
oldCount: compared.oldCount,
|
|
285
|
-
newCount: compared.newCount,
|
|
286
|
-
foldLock: policy.foldLock,
|
|
287
|
-
foldManifest: policy.foldManifest,
|
|
288
|
-
takeAllManifest: policy.takeAllManifest,
|
|
289
|
-
manifestItems: snapshot.manifestItems,
|
|
290
|
-
lockItems: snapshot.lockItems,
|
|
291
|
-
pkg: snapshot.newPkg || snapshot.oldPkg,
|
|
292
|
-
};
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
const collectGroups = (items) => {
|
|
296
|
-
const groups = new Map();
|
|
297
|
-
for (const item of items) {
|
|
298
|
-
const rel = itemPath(item);
|
|
299
|
-
const meta = depFileMeta(rel);
|
|
300
|
-
if (!meta) continue;
|
|
301
|
-
const key = `${item.origin}\0${meta.dir}`;
|
|
302
|
-
let group = groups.get(key);
|
|
303
|
-
if (!group) {
|
|
304
|
-
const dir = meta.dir;
|
|
305
|
-
const origin = item.origin;
|
|
306
|
-
group = { dir, origin, items: [] };
|
|
307
|
-
groups.set(key, group);
|
|
308
|
-
}
|
|
309
|
-
group.items.push(item);
|
|
310
|
-
}
|
|
311
|
-
return groups;
|
|
312
|
-
};
|
|
313
|
-
|
|
314
|
-
const takeManifestItems = (summary) => {
|
|
315
|
-
if (!summary.foldManifest) return [];
|
|
316
|
-
if (summary.takeAllManifest) return [...summary.manifestItems];
|
|
317
|
-
const taken = [];
|
|
318
|
-
for (const item of summary.manifestItems) {
|
|
319
|
-
if (onlyDepEdits([item])) taken.push(item);
|
|
320
|
-
}
|
|
321
|
-
return taken;
|
|
322
|
-
};
|
|
323
|
-
|
|
324
|
-
module.exports = {
|
|
325
|
-
diffSections,
|
|
326
|
-
mergeResolved,
|
|
327
|
-
orderedChanges,
|
|
328
|
-
summarizeGroup,
|
|
329
|
-
collectGroups,
|
|
330
|
-
takeManifestItems,
|
|
331
|
-
};
|
package/lib/deps/items.js
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { itemPath } = require('../files.js');
|
|
4
|
-
|
|
5
|
-
const { depFileMeta } = require('./manifest.js');
|
|
6
|
-
const { orderedChanges } = require('./changes.js');
|
|
7
|
-
const { buildRows, makeHunk } = require('./rows.js');
|
|
8
|
-
|
|
9
|
-
const uniquePaths = (items) => {
|
|
10
|
-
const files = [];
|
|
11
|
-
const seen = new Set();
|
|
12
|
-
for (const item of items) {
|
|
13
|
-
const rel = itemPath(item);
|
|
14
|
-
if (!rel || seen.has(rel)) continue;
|
|
15
|
-
seen.add(rel);
|
|
16
|
-
files.push(rel);
|
|
17
|
-
}
|
|
18
|
-
return files;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const filesForChange = (change, files) => {
|
|
22
|
-
const manifest = [];
|
|
23
|
-
const lockfile = [];
|
|
24
|
-
for (const rel of files) {
|
|
25
|
-
const meta = depFileMeta(rel);
|
|
26
|
-
if (!meta) continue;
|
|
27
|
-
if (meta.kind === 'manifest') manifest.push(rel);
|
|
28
|
-
else lockfile.push(rel);
|
|
29
|
-
}
|
|
30
|
-
if (change.section === 'field') {
|
|
31
|
-
if (manifest.length) return manifest;
|
|
32
|
-
return files;
|
|
33
|
-
}
|
|
34
|
-
if (change.section === 'resolved') {
|
|
35
|
-
if (lockfile.length) return lockfile;
|
|
36
|
-
return files;
|
|
37
|
-
}
|
|
38
|
-
if (change.propose) {
|
|
39
|
-
if (manifest.length) return manifest;
|
|
40
|
-
return files;
|
|
41
|
-
}
|
|
42
|
-
const both = [...manifest, ...lockfile];
|
|
43
|
-
if (both.length) return both;
|
|
44
|
-
return files;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const pickPrimary = (items) => {
|
|
48
|
-
for (const item of items) {
|
|
49
|
-
const rel = itemPath(item);
|
|
50
|
-
const meta = depFileMeta(rel);
|
|
51
|
-
if (meta && meta.kind === 'manifest') return item;
|
|
52
|
-
}
|
|
53
|
-
return items[0];
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const makeDepItem = (origin, fileItems, hidden, change, extra, blockId) => {
|
|
57
|
-
const allFiles = uniquePaths(fileItems);
|
|
58
|
-
const files = change ? filesForChange(change, allFiles) : allFiles;
|
|
59
|
-
const primary = pickPrimary(fileItems);
|
|
60
|
-
const oldPath = itemPath(primary);
|
|
61
|
-
const newPath = oldPath;
|
|
62
|
-
const isNew = fileItems.some((item) => item.file && item.file.isNew);
|
|
63
|
-
const isDeleted = fileItems.every((item) => item.file && item.file.isDeleted);
|
|
64
|
-
let oldCount = 0;
|
|
65
|
-
let newCount = 0;
|
|
66
|
-
if (!change) {
|
|
67
|
-
oldCount = extra.oldCount ?? 0;
|
|
68
|
-
newCount = extra.newCount ?? 0;
|
|
69
|
-
}
|
|
70
|
-
const rows = buildRows(change, oldCount, newCount);
|
|
71
|
-
const hunk = makeHunk(rows, blockId);
|
|
72
|
-
const isBinary = false;
|
|
73
|
-
const preamble = [];
|
|
74
|
-
const hunks = [hunk];
|
|
75
|
-
const file = {
|
|
76
|
-
oldPath,
|
|
77
|
-
newPath,
|
|
78
|
-
isNew,
|
|
79
|
-
isDeleted,
|
|
80
|
-
isBinary,
|
|
81
|
-
preamble,
|
|
82
|
-
hunks,
|
|
83
|
-
};
|
|
84
|
-
const patchAdd = '';
|
|
85
|
-
const patchRevert = '';
|
|
86
|
-
const items = hidden;
|
|
87
|
-
const dep = { files, items, change };
|
|
88
|
-
const reload = !!(change && change.propose);
|
|
89
|
-
return { origin, file, hunk, blockId, patchAdd, patchRevert, dep, reload };
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const makeDepItems = (origin, fileItems, hidden, summary) => {
|
|
93
|
-
const ordered = orderedChanges(summary.changes);
|
|
94
|
-
if (!ordered.length) {
|
|
95
|
-
return [makeDepItem(origin, fileItems, hidden, null, summary, 0)];
|
|
96
|
-
}
|
|
97
|
-
const items = [];
|
|
98
|
-
let blockId = 0;
|
|
99
|
-
for (const change of ordered) {
|
|
100
|
-
const made = makeDepItem(
|
|
101
|
-
origin,
|
|
102
|
-
fileItems,
|
|
103
|
-
hidden,
|
|
104
|
-
change,
|
|
105
|
-
summary,
|
|
106
|
-
blockId,
|
|
107
|
-
);
|
|
108
|
-
items.push(made);
|
|
109
|
-
blockId += 1;
|
|
110
|
-
}
|
|
111
|
-
return items;
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
const stubFileItem = (rel, origin) => {
|
|
115
|
-
const file = {
|
|
116
|
-
oldPath: rel,
|
|
117
|
-
newPath: rel,
|
|
118
|
-
isNew: false,
|
|
119
|
-
isDeleted: false,
|
|
120
|
-
isBinary: false,
|
|
121
|
-
preamble: [],
|
|
122
|
-
hunks: [],
|
|
123
|
-
};
|
|
124
|
-
const hunk = null;
|
|
125
|
-
const blockId = 0;
|
|
126
|
-
const patchAdd = '';
|
|
127
|
-
const patchRevert = '';
|
|
128
|
-
return { origin, file, hunk, blockId, patchAdd, patchRevert };
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
module.exports = { makeDepItems, stubFileItem };
|