Skip to content

Commit

Permalink
buildDepsOnly: set CRANE_BUILD_DEPS_ONLY env var when running (#722)
Browse files Browse the repository at this point in the history
  • Loading branch information
ipetkov authored Oct 12, 2024
1 parent adfdd21 commit c052ed5
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 0 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
60 changes: 60 additions & 0 deletions docs/faq/control-when-hooks-run.md
Original file line number Diff line number Diff line change
@@ -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
'';
}
```
8 changes: 8 additions & 0 deletions lib/buildDepsOnly.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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 ''
Expand Down

0 comments on commit c052ed5

Please sign in to comment.