summaryrefslogtreecommitdiff
path: root/build.rs
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2025-06-11 23:29:30 -0400
committerOwen Jacobson <owen@grimoire.ca>2025-06-11 23:33:18 -0400
commitddef0916de13949e800a63fa3490a73e98996fa2 (patch)
tree83b2d65f928498a65b4518858dd736422741380c /build.rs
parent6e6b068ae2adc8c5ef8acb633dcadfbdc3221b61 (diff)
Use `npm ci` for automated package installation.
From its documentation: > This command is similar to `npm install`, except it's meant to be used in automated environments such as test platforms, continuous integration, and deployment -- or any situation where you want to make sure you're doing a clean install of your dependencies. We don't need a clean install, necessarily - just a complete one that matches the package configuration. However, this command is clearly documented as being used for automated environments, and I think integration with another build tool is close enough to that intention to fit. It also promises not to rewrite `package.json` or `package-lock.json`. (`npm install`, on the other hand, rewrites `package-lock.json` regularly.) As we do not intend to change the source tree when building it, this is the preferred behaviour. Finally, this fixes a behaviour I encountered where certain `cargo` commands - sometimes including `cargo build` - could completely reformat `package-lock.json` without any warning and without any user-visible rationale for it.
Diffstat (limited to 'build.rs')
-rw-r--r--build.rs25
1 files changed, 18 insertions, 7 deletions
diff --git a/build.rs b/build.rs
index 6d4805f..94531ab 100644
--- a/build.rs
+++ b/build.rs
@@ -4,19 +4,30 @@ fn main() -> Result<(), io::Error> {
// trigger recompilation when a new migration is added
println!("cargo::rerun-if-changed=migrations");
- // rerun npm install whenever packages or npm config are changed
+ // The following sections are intended to allow developers and packagers to create a working
+ // `pilcrow` binary in one step in a clean source tree, using Cargo, even though Pilcrow is
+ // written in two-and-a-half languages.
+ //
+ // The final binary embeds the Svelte UI. These steps build it. And, in service of that one-step
+ // build idea, they also install the NPM dependencies needed to carry out that build. (Cargo
+ // does this out of the box for Rust dependencies.)
+
+ // rerun npm ci whenever packages or npm config are changed
println!("cargo::rerun-if-changed=.npmrc");
println!("cargo::rerun-if-changed=package.json");
- // `node_modules` and `package-lock.json` are always touched if `npm install`
- // runs, leading to spurious rebuilds.
+ println!("cargo::rerun-if-changed=package-lock.json");
+ // In theory, we should rerun `npm ci` if `node_modules` has changed since the last build, to
+ // put it back into a known-good state. However, `npm ci` itself _always_ rewrites
+ // `node_modules`, so asking Cargo to rerun this build script if `node_modules` changes leads to
+ // Cargo always rerunning this build script. So, as a compromise, we assume that changes to
+ // `package-lock.json` or `package.json` are sufficient justification to rerun `npm ci`, because
+ // those are the most likely secondary indicators of changes to the installed packages.
//
- // See: <https://github.com/npm/cli/issues/7874>
- // println!("cargo::rerun-if-changed=package-lock.json");
// println!("cargo::rerun-if-changed=node_modules");
- let status = Command::new("npm").args(["install"]).status()?;
+ let status = Command::new("npm").args(["ci"]).status()?;
if !status.success() {
return Err(io::Error::other(format!(
- "'npm install' exited with status {status:?}"
+ "'npm ci' exited with status {status:?}"
)));
}