buildDepsOnly: set CRANE_BUILD_DEPS_ONLY env var when running (#722)

This commit is contained in:
Ivan Petkov 2024-10-12 16:28:15 -07:00 committed by GitHub
parent adfdd217c7
commit c052ed5e84
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 78 additions and 0 deletions

View File

@ -11,6 +11,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
* `cargoDocTest` is now available as an alternative to `cargoTest` which runs
only doc tests.
### Changed
* `buildDepsOnly` now sets `CRANE_BUILD_DEPS_ONLY` as an environment variable
when it runs. Build hooks can use this as a shortcut to determine whether
running inside of a `buildDepsOnly` derivation in case they need to tailor
their behavior accordingly.
### Fixed
* Vendoring dependencies avoids creating malformed TOML configurations in
situations where registry name/url definitions cannot be found. When this

View File

@ -92,6 +92,8 @@ to influence its behavior.
* `src`: set to the result of `mkDummySrc` after applying the arguments set.
This ensures that we do not need to rebuild the cargo artifacts derivation
whenever the application source changes.
* `CRANE_BUILD_DEPS_ONLY` is exported as an environment variable, in case this
is handy for scripts or hooks which may want to customize how they run
#### Optional attributes
* `buildPhaseCargoCommand`: A command to run during the derivation's build

View File

@ -46,6 +46,7 @@
* [Cargo.toml is not at the source root](./faq/workspace-not-at-source-root.md)
* [Found invalid metadata files for crate error](./faq/invalid-metadata-files-for-crate.md)
* [A git dependency fails to find a file by a relative path](./faq/git-dep-cannot-find-relative-path.md)
* [Controlling whether or not hooks run during `buildDepsOnly`](./faq/control-when-hooks-run.md)
---
* [Advanced Techniques](./advanced/advanced.md)
* [Overriding function behavior](./advanced/overriding-function-behavior.md)

View File

@ -0,0 +1,60 @@
## Controlling whether or not hooks run during `buildDepsOnly`
A typical project configuration will build a workspace's dependencies (without
the actual sources) during the `buildDepsOnly` derivation, and later build the
project's sources in a second derivation. Sometimes this results in problems if
a build hook is accidentally configured to run in both derivations but expects
to use the real sources, for example.
### Solution 1: explicitly configure the arguments to each derivation
```nix
let
# Explicitly split out common arguments
commonArgs = {
src = ./.;
# etc.
};
# Then explicitly define the arguments to `buildDepsOnly`
cargoArtifacts = craneLib.buildDepsOnly (commonArgs // {
postConfigure = ''
echo 'I am a hook which must only run during buildDepsOnly'
'';
});
};
in
craneLib.buildPackage (commonArgs // {
inherit cargoArtifacts;
preBuild = ''
echo 'I am a hook which must run with the real sources'
'';
})
```
### Solution 2: check whether `CRANE_BUILD_DEPS_ONLY` env var is set
> Note that with this approach, changing the build hook _will rebuild all
> dependencies_, so consider the first solution above if possible.
```nix
craneLib.buildPackage {
src = ./.;
postConfigure = ''
# NB: use ''${var} to escape the ${...} so that Nix does not interpet it as
# an evaluation variable (since CRANE_BUILD_DEPS_ONLY is a shell variable)
if [ -n "''${CRANE_BUILD_DEPS_ONLY:-}"]; then
echo 'I am a hook which must only run during buildDepsOnly'
fi
'';
preBuild = ''
# NB: use ''${var} to escape the ${...} so that Nix does not interpet it as
# an evaluation variable (since CRANE_BUILD_DEPS_ONLY is a shell variable)
if [ -z "''${CRANE_BUILD_DEPS_ONLY:-}"]; then
echo 'I am a hook which must run with the real sources'
fi
'';
}
```

View File

@ -51,6 +51,14 @@ mkCargoDerivation (cleanedArgs // {
cargoArtifacts = null;
cargoVendorDir = args.cargoVendorDir or (vendorCargoDeps args);
env = (args.env or { }) // {
# Export a marker variable in case any scripts or hooks want to customize
# how they run depending on if they are running here or with the "real"
# project sources.
# NB: *just* in case someone tries to set this to something specific, honor it
CRANE_BUILD_DEPS_ONLY = args.env.CRANE_BUILD_DEPS_ONLY or 1;
};
# First we run `cargo check` to cache cargo's internal artifacts, fingerprints, etc. for all deps.
# Then we run `cargo build` to actually compile the deps and cache the results
buildPhaseCargoCommand = args.buildPhaseCargoCommand or ''