buninu 0.4.0 → 0.4.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/CHANGELOG.md +21 -0
- package/bin/install.js +41 -12
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.1 - 2026-08-30
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- A freshly installed tree no longer reports files as locally changed when
|
|
8
|
+
only their file mode differs. Publishing normalises modes, so a file can come
|
|
9
|
+
back from the registry with a different executable bit and byte-identical
|
|
10
|
+
contents, which `bun pm diff` counts as a modification; an update was
|
|
11
|
+
listing those and asking about files nobody had touched. They are now
|
|
12
|
+
recognised by the mode having changed while the contents did not, and left
|
|
13
|
+
out of the list, with a line saying how many were ignored so the count still
|
|
14
|
+
adds up against the command below.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- An update prints the `bun pm diff` command it is about to run, on a line of
|
|
19
|
+
its own before the result. Run it by hand without `--json` to read the list
|
|
20
|
+
directly, or without `--name-only` to see the changes themselves rather than
|
|
21
|
+
which files hold them. It goes to stdout rather than stderr with the rest of
|
|
22
|
+
the output, so `2>/dev/null` leaves just the command.
|
|
23
|
+
|
|
3
24
|
## 0.4.0 - 2026-08-30
|
|
4
25
|
|
|
5
26
|
### Added
|
package/bin/install.js
CHANGED
|
@@ -195,14 +195,20 @@ const DIFF_TIMEOUT_MS = 60_000;
|
|
|
195
195
|
// the user changed. Files it calls added are theirs and are never deleted by
|
|
196
196
|
// an update; only modified ones are about to be written over.
|
|
197
197
|
async function findLocalChanges(destination, version) {
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
198
|
+
const argv = [
|
|
199
|
+
process.execPath, "pm", "diff",
|
|
200
|
+
`${pkg.name}@${version}`, destination,
|
|
201
|
+
"--name-only", "--json",
|
|
202
|
+
];
|
|
203
|
+
|
|
204
|
+
// On a line of its own, unprefixed, and on stdout rather than stderr with
|
|
205
|
+
// the rest of the output, so it stands out and `2>/dev/null` leaves just the
|
|
206
|
+
// command: copy it and run it by hand without --json to read the list, or
|
|
207
|
+
// without --name-only to see the changes themselves rather than which files
|
|
208
|
+
// hold them.
|
|
209
|
+
console.log(` ${argv.join(" ")}`);
|
|
210
|
+
|
|
211
|
+
const child = Bun.spawn(argv, { stdin: "ignore", stdout: "pipe", stderr: "pipe" });
|
|
206
212
|
|
|
207
213
|
let timedOut = false;
|
|
208
214
|
const timer = setTimeout(() => {
|
|
@@ -241,14 +247,28 @@ async function findLocalChanges(destination, version) {
|
|
|
241
247
|
return { files: null, error: "bun pm diff did not return JSON" };
|
|
242
248
|
}
|
|
243
249
|
|
|
250
|
+
const modified = (report.files ?? [])
|
|
251
|
+
.filter((file) => file.status === "modified" && !MERGED_PATHS.has(file.path));
|
|
252
|
+
|
|
244
253
|
return {
|
|
245
|
-
files: (
|
|
246
|
-
|
|
247
|
-
.map((file) => file.path),
|
|
254
|
+
files: modified.filter((file) => !isModeOnlyChange(file)).map((file) => file.path),
|
|
255
|
+
modeOnly: modified.filter(isModeOnlyChange).length,
|
|
248
256
|
error: null,
|
|
249
257
|
};
|
|
250
258
|
}
|
|
251
259
|
|
|
260
|
+
// Publishing normalises file modes, so a file can come back from the registry
|
|
261
|
+
// with a different executable bit and identical contents. bun pm diff calls
|
|
262
|
+
// that a modification, and reporting it would mean a freshly installed tree
|
|
263
|
+
// listing files nobody has touched. modeBefore and modeAfter are only present
|
|
264
|
+
// when the mode differs at all; the rest is what says the bytes did not.
|
|
265
|
+
function isModeOnlyChange(file) {
|
|
266
|
+
return file.modeBefore !== undefined &&
|
|
267
|
+
file.linesAdded === 0 &&
|
|
268
|
+
file.linesRemoved === 0 &&
|
|
269
|
+
file.bytesBefore === file.bytesAfter;
|
|
270
|
+
}
|
|
271
|
+
|
|
252
272
|
// Returns null when there is no terminal to ask at, which the caller reports
|
|
253
273
|
// rather than treating as either answer.
|
|
254
274
|
async function confirm(question) {
|
|
@@ -426,7 +446,7 @@ async function confirmLocalChanges(destination, version, options) {
|
|
|
426
446
|
// sit there for a while with nothing on screen to explain the wait.
|
|
427
447
|
console.error(`${pkg.name}: comparing it against the published ${version} for local changes...`);
|
|
428
448
|
|
|
429
|
-
const { files, error } = await findLocalChanges(destination, version);
|
|
449
|
+
const { files, modeOnly, error } = await findLocalChanges(destination, version);
|
|
430
450
|
|
|
431
451
|
// The check needs the registry, so it cannot run offline or against a version
|
|
432
452
|
// that was never published. Whether anything was edited locally is then
|
|
@@ -448,6 +468,15 @@ async function confirmLocalChanges(destination, version, options) {
|
|
|
448
468
|
return false;
|
|
449
469
|
}
|
|
450
470
|
|
|
471
|
+
// Worth saying rather than hiding: it explains why the count here is smaller
|
|
472
|
+
// than the one the printed command reports, and a mode that keeps coming back
|
|
473
|
+
// is worth knowing about even though an update is not what changed it.
|
|
474
|
+
if (modeOnly) {
|
|
475
|
+
console.error(
|
|
476
|
+
`${pkg.name}: ${modeOnly} file(s) differ only in file mode, with identical contents; ignoring them`,
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
|
|
451
480
|
if (!files.length) return false;
|
|
452
481
|
|
|
453
482
|
console.error(
|
package/package.json
CHANGED