docs: document using overrideScope' (#303)

This commit is contained in:
Ivan Petkov 2023-04-16 13:55:46 -07:00 committed by GitHub
parent 0c9f468ff0
commit a4d54e5d6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 0 deletions

View File

@ -34,3 +34,6 @@
* [Trouble building when using `include_str!` (or including other non-rust files)](./faq/building-with-non-rust-includes.md)
* [Dealing with sandbox-unfriendly build scripts](./faq/sandbox-unfriendly-build-scripts.md)
* [Cargo.toml is not at the source root](./faq/workspace-not-at-source-root.md)
---
* [Advanced Techniques](./advanced/advanced.md)
* [Overriding function behavior](./advanced/overriding-function-behavior.md)

View File

@ -0,0 +1,7 @@
## Advanced Techniques
This chapter contains various "advanced" techniques for configuring
and modifying the behaviors of `crane`.
Most projects will likely not need to apply these patterns as they may require
extensive familiarity with Nix as well as `crane` internals.

View File

@ -0,0 +1,41 @@
## Overriding function behavior
At it's core, `crane` is instantiated via `pkgs.lib.newScope` which allows any
internal definition to be changed or replaced via `.overrideScope'` (which
behaves very much like applying overlays to nixpkgs). Although this mechanism is
incredibly powerful, care should be taken to avoid creating confusing or brittle
integrations built on undocumented details.
Note that `crane`'s stability guarantees (with respect to semantic versioning) only
apply to what has been [documented at the API level](../API.md). For example,
`buildPackage` is documented to delegate to `mkCargoDerivation`, so any changes
or overrides to `mkCargoDerivation`'s behavior will be observed by
`buildPackage`. Other non-documented internal details, however, may change at
any time, so take care when reaching this deep into the internals.
Here is an example:
```nix
let
craneLib = (inputs.crane.mkLib pkgs).overrideScope' (final: prev: {
# We override the behavior of `mkCargoDerivation` by adding a wrapper which
# will set a default value of `CARGO_PROFILE` when not set by the caller.
# This change will automatically be propagated to any other functions built
# on top of it (like `buildPackage`, `cargoBuild`, etc.)
mkCargoDerivation = args: prev.mkCargoDerivation ({
CARGO_PROFILE = "bench"; # E.g. always build in benchmark mode unless overridden
} // args);
});
in
{
# Build two different workspaces with the modified behavior above
foo = craneLib.buildPackage {
src = craneLib.cleanCargoSource (craneLib.path ./foo);
};
bar = craneLib.buildPackage {
src = craneLib.cleanCargoSource (craneLib.path ./bar);
};
}
```