aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-02-24 22:01:37 -0800
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-02-24 22:01:37 -0800
commit1795b6570cae668fa75231a9be8b88cd5fe55543 (patch)
tree9aec52ae7fec28d458260d1061311b3ff334518c
parent152e3cb7bf95602e7fd7cf03273ae5e5e288d5cc (diff)
downloadbun-1795b6570cae668fa75231a9be8b88cd5fe55543.tar.gz
bun-1795b6570cae668fa75231a9be8b88cd5fe55543.tar.zst
bun-1795b6570cae668fa75231a9be8b88cd5fe55543.zip
[bun install] Skip saving the lockfile if there are no changes
Diffstat (limited to '')
-rw-r--r--Makefile10
-rw-r--r--integration/apps/bun-install-lockfile-status.sh61
-rw-r--r--src/install/install.zig38
3 files changed, 97 insertions, 12 deletions
diff --git a/Makefile b/Makefile
index 159e0ce71..3ee827c52 100644
--- a/Makefile
+++ b/Makefile
@@ -680,12 +680,18 @@ test-create-next:
test-bun-run:
cd integration/apps && BUN_BIN=$(RELEASE_BUN) bash ./bun-run-check.sh
-test-bun-install:
+test-bun-install: test-bun-install-git-status
cd integration/apps && JS_RUNTIME=$(RELEASE_BUN) NPM_CLIENT=$(RELEASE_BUN) bash ./bun-install.sh
-test-dev-bun-install:
+test-bun-install-git-status:
+ cd integration/apps && JS_RUNTIME=$(RELEASE_BUN) BUN_BIN=$(RELEASE_BUN) bash ./bun-install-lockfile-status.sh
+
+test-dev-bun-install: test-dev-bun-install-git-status
cd integration/apps && JS_RUNTIME=$(DEBUG_BUN) NPM_CLIENT=$(DEBUG_BUN) bash ./bun-install.sh
+test-dev-bun-install-git-status:
+ cd integration/apps && BUN_BIN=$(DEBUG_BUN) bash ./bun-install-lockfile-status.sh
+
test-create-react:
BUN_BIN=$(RELEASE_BUN) bash integration/apps/bun-create-react.sh
diff --git a/integration/apps/bun-install-lockfile-status.sh b/integration/apps/bun-install-lockfile-status.sh
new file mode 100644
index 000000000..72ba83878
--- /dev/null
+++ b/integration/apps/bun-install-lockfile-status.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+
+set -euo pipefail
+
+killall -9 $(basename $BUN_BIN) || echo ""
+
+dir=$(mktemp -d --suffix=bun-lockfile)
+
+cd $dir
+
+$BUN_BIN add react
+
+echo "node_modules" >.gitignore
+
+git init && git add . && git commit -am "Initial commit"
+
+$BUN_BIN install
+
+ORIG_LOCKFILE=$($BUN_BIN bun.lockb)
+
+[[ -z $(git status --untracked-files=no --porcelain) ]] || {
+ echo "ERR: Expected empty git status, got '$(git status --untracked-files=no --porcelain)'"
+ exit 1
+}
+
+$BUN_BIN add react
+
+NEW_LOCKFILE=$($BUN_BIN bun.lockb)
+
+diff <(echo "$ORIG_LOCKFILE") <(echo "$NEW_LOCKFILE") || {
+ echo "ERR: Expected lockfile to be unchanged, got '$NEW_LOCKFILE'"
+ exit 1
+}
+
+[[ -z $(git status --untracked-files=no --porcelain) ]] || {
+ echo "ERR: Expected empty git status, got '$(git status --untracked-files=no --porcelain)'"
+ exit 1
+}
+
+$BUN_BIN remove react
+$BUN_BIN add react
+
+NEW_LOCKFILE=$($BUN_BIN bun.lockb)
+
+diff <(echo "$ORIG_LOCKFILE") <(echo "$NEW_LOCKFILE") || {
+ echo "ERR: Expected lockfile to be unchanged, got '$NEW_LOCKFILE'"
+ exit 1
+}
+
+echo '{ "dependencies": { "react": "17.0.2", "react-dom": "17.0.2" } }' >package.json
+
+$BUN_BIN install
+
+echo "var {version} = JSON.parse(require(\"fs\").readFileSync('./node_modules/react-dom/package.json', 'utf8')); if (version !== '17.0.2') {throw new Error('Unexpected react-dom version');}; " >index.js
+$BUN_BIN run ./index.js
+
+echo "var {version} = JSON.parse(require(\"fs\").readFileSync('./node_modules/react/package.json', 'utf8')); if (version !== '17.0.2') {throw new Error('Unexpected react version');}; " >index.js
+$BUN_BIN run ./index.js
+
+realpath -e node_modules/react-dom
+realpath -e node_modules/react
diff --git a/src/install/install.zig b/src/install/install.zig
index 0967c87a1..68bd071fc 100644
--- a/src/install/install.zig
+++ b/src/install/install.zig
@@ -2662,20 +2662,13 @@ pub const PackageManager = struct {
this.native_bin_link_allowlist = buf;
}
- if (bun_install.production) |production| {
- if (production) {
- this.local_package_features.dev_dependencies = false;
- this.enable.fail_early = true;
- this.enable.frozen_lockfile = true;
- }
- }
-
if (bun_install.save_yarn_lockfile orelse false) {
this.do.save_yarn_lock = true;
}
if (bun_install.save_lockfile) |save_lockfile| {
this.do.save_lockfile = save_lockfile;
+ this.enable.force_save_lockfile = true;
}
if (bun_install.save_dev) |save| {
@@ -2686,6 +2679,15 @@ pub const PackageManager = struct {
this.remote_package_features.peer_dependencies = save;
}
+ if (bun_install.production) |production| {
+ if (production) {
+ this.local_package_features.dev_dependencies = false;
+ this.enable.fail_early = true;
+ this.enable.frozen_lockfile = true;
+ this.enable.force_save_lockfile = false;
+ }
+ }
+
if (bun_install.save_optional) |save| {
this.remote_package_features.optional_dependencies = save;
this.local_package_features.optional_dependencies = save;
@@ -2910,6 +2912,7 @@ pub const PackageManager = struct {
if (cli.force) {
this.enable.manifest_cache_control = false;
this.enable.force_install = true;
+ this.enable.force_save_lockfile = true;
}
this.update.development = cli.development;
@@ -2935,6 +2938,10 @@ pub const PackageManager = struct {
/// Probably need to be a little smarter
deduplicate_packages: bool = false,
+ // Don't save the lockfile unless there were actual changes
+ // unless...
+ force_save_lockfile: bool = false,
+
force_install: bool = false,
};
};
@@ -4809,7 +4816,9 @@ pub const PackageManager = struct {
// sleep on since we might not need it anymore
NetworkThread.global.pool.sleep_on_idle_network_thread = true;
- if (had_any_diffs or needs_new_lockfile or manager.package_json_updates.len > 0) {
+ const needs_clean_lockfile = had_any_diffs or needs_new_lockfile or manager.package_json_updates.len > 0;
+
+ if (needs_clean_lockfile) {
manager.lockfile = try manager.lockfile.clean(manager.package_json_updates);
}
@@ -4828,7 +4837,16 @@ pub const PackageManager = struct {
try manager.setupGlobalDir(&ctx);
}
- if (manager.options.do.save_lockfile) {
+ // We don't always save the lockfile.
+ // This is for two reasons.
+ // 1. It's unnecessary work if there are no changes
+ // 2. There is a determinism issue in the file where alignment bytes might be garbage data
+ // This is a bug that needs to be fixed, however we can work around it for now
+ // by avoiding saving the lockfile
+ if (manager.options.do.save_lockfile and (needs_clean_lockfile or
+ manager.lockfile.isEmpty() or
+ manager.options.enable.force_save_lockfile))
+ {
save: {
if (manager.lockfile.isEmpty()) {
if (!manager.options.dry_run) {