Add path as a convenience wrapper around builtins.path (#273)

This commit is contained in:
Ivan Petkov 2023-03-20 03:57:15 +00:00 committed by GitHub
parent 77435dad14
commit 6fd78bc66a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 142 additions and 55 deletions

View File

@ -14,6 +14,9 @@ in case a crate is used as `bin` artifact dependency.
* Add `cargoLlvmCov` to run `cargo llvm-cov`
* Add `cargoLockParsed` option to `vendorCargoDeps` to support `Cargo.lock`
files parsed as nix attribute sets.
* `craneLib.path` can now be used as a convenience wrapper on (or drop in
replacement of) `builtins.path` to ensure reproducible results whenever paths
like `./.` or `./..` are used directly.
## [0.11.3] - 2023-02-19

View File

@ -618,7 +618,7 @@ written (which may want to also call `lib.filterCargoSources`) to achieve the
desired behavior.
```nix
lib.cleanCargoSource ./.
lib.cleanCargoSource (lib.path ./.)
```
### `lib.cleanCargoToml`
@ -761,7 +761,7 @@ will retain the following files from a given source:
```nix
cleanSourceWith {
src = ./.;
src = lib.path ./.;
filter = lib.filterCargoSources;
}
```
@ -777,7 +777,7 @@ let
(markdownFilter path type) || (lib.filterCargoSources path type);
in
cleanSourceWith {
src = ./.;
src = lib.path ./.;
filter = markdownOrCargo;
}
```
@ -928,7 +928,7 @@ build caches. More specifically:
mkDummySrc {
# The _entire_ source of the project. mkDummySrc will automatically
# filter out irrelevant files as described above
src = ./.;
src = lib.path ./.;
# Note that here we scope the path to just `./.cargo` and not any other
# directories which may exist at the root of the project. Also note that
@ -959,6 +959,40 @@ can be the output of `oxalica/rust-overlay`.
crane.lib.${system}.overrideToolchain myCustomToolchain
```
### `lib.path`
`path :: path -> drv`
`path :: set -> drv`
A convenience wrapper around `builtins.path` which will automatically set the
path's `name` to the workspace's package name (or a placeholder value of
`"source"` if a name cannot be determined).
It should be used anywhere a relative path like `./.` or `./..` is needed so
that the result is reproducible and caches can be reused. Otherwise the store
path [will depend on the name of the parent
directory](https://nix.dev/anti-patterns/language#reproducibility-referencing-top-level-directory-with) which may cause unnecessary rebuilds.
```nix
crane.lib.${system}.path ./.
# "/nix/store/wbhf6c7wiw9z53hsn487a8wswivwdw81-source"
```
```nix
lib.path ./checks/simple
# "/nix/store/s9scn97c86kqskf7yv5n2k85in5y5cmy-simple"
```
It is also possible to use as a drop in replacement for `builtins.path`:
```nix
lib.path {
path = ./.;
name = "asdf";
}
# "/nix/store/23zy3c68v789cg8sysgba0rbgbfcjfhn-asdf"
```
### `lib.registryFromDownloadUrl`
`registryFromDownloadUrl :: set -> set`

View File

@ -46,6 +46,6 @@ let
});
in
cargoAwesome {
src = craneLib.cleanCargoSource ./.;
src = craneLib.cleanCargoSource (craneLib.path ./.);
}
```

View File

@ -34,7 +34,7 @@ and hooks to customize a particular build:
```nix
craneLib.buildPackage {
src = craneLib.cleanCargoSource ./.;
src = craneLib.cleanCargoSource (craneLib.path ./.);
# Define a list of function names to execute before the `configurePhase` runs
preConfigurePhases = [

View File

@ -29,7 +29,7 @@ craneLib.buildPackage {
src = patchedCargoLock;
};
src = craneLib.cleanCargoSource ./.;
src = craneLib.cleanCargoSource (craneLib.path ./.);
patches = [
./update-cargo-lock.patch

View File

@ -13,7 +13,7 @@ deeper directory:
# ./nested/Cargo.lock
# ./nested/src/*.rs
craneLib.buildPackage {
src = myLib.cleanCargoSource ./.;
src = myLib.cleanCargoSource (craneLib.path ./.);
cargoLock = ./nested/Cargo.lock;
cargoToml = ./nested/Cargo.toml;
# Use a postUnpack hook to jump into our nested directory. This will work

View File

@ -41,7 +41,7 @@ following contents at the root of your cargo workspace:
in
{
packages.default = craneLib.buildPackage {
src = craneLib.cleanCargoSource ./.;
src = craneLib.cleanCargoSource (craneLib.path ./.);
# Add extra inputs here or any other derivation settings
# doCheck = true;

View File

@ -35,7 +35,7 @@ Here's how we can set up our flake to achieve our goals:
# Common derivation arguments used for all builds
commonArgs = {
src = craneLib.cleanCargoSource ./.;
src = craneLib.cleanCargoSource (craneLib.path ./.);
buildInputs = with pkgs; [
# Add extra build inputs here, etc.

View File

@ -26,7 +26,7 @@ build.
craneLib = crane.lib.${system};
# Common derivation arguments used for all builds
commonArgs = {
src = craneLib.cleanCargoSource ./.;
src = craneLib.cleanCargoSource (craneLib.path ./.);
buildInputs = with pkgs; [
# Add extra build inputs here, etc.

View File

@ -34,7 +34,7 @@ Sample `flake.nix`:
craneLib = crane.lib.${system};
my-crate = craneLib.buildPackage {
src = craneLib.cleanCargoSource ./.;
src = craneLib.cleanCargoSource (craneLib.path ./.);
buildInputs = [
# Add additional build inputs here

View File

@ -17,7 +17,7 @@ non-Rust/non-cargo related files. It can be used like so:
```nix
craneLib.buildPackage {
# other attributes omitted
src = craneLib.cleanCargoSource ./.;
src = craneLib.cleanCargoSource (craneLib.path ./.);
}
```
@ -37,7 +37,7 @@ in
craneLib.buildPackage {
# other attributes omitted
src = lib.cleanSourceWith {
src = ./.; # The original, unfiltered source
src = craneLib.path ./.; # The original, unfiltered source
filter = markdownOrCargo;
};
}

View File

@ -52,7 +52,7 @@
];
my-crate = craneLib.buildPackage {
src = craneLib.cleanCargoSource ./.;
src = craneLib.cleanCargoSource (craneLib.path ./.);
buildInputs = [
# Add additional build inputs here

View File

@ -35,7 +35,7 @@
craneLib = (crane.mkLib pkgs).overrideToolchain rustToolchain;
my-crate = craneLib.buildPackage {
src = craneLib.cleanCargoSource ./.;
src = craneLib.cleanCargoSource (craneLib.path ./.);
CARGO_BUILD_TARGET = "x86_64-unknown-linux-musl";
CARGO_BUILD_RUSTFLAGS = "-C target-feature=+crt-static";

View File

@ -57,7 +57,7 @@
, stdenv
}:
craneLib.buildPackage {
src = craneLib.cleanCargoSource ./.;
src = craneLib.cleanCargoSource (craneLib.path ./.);
# Build-time tools which are target agnostic. build = host = target = your-machine.
# Emulators should essentially also go `nativeBuildInputs`. But with some packaging issue,

View File

@ -35,7 +35,7 @@
in
{
packages.default = craneLib.buildPackage {
src = craneLib.cleanCargoSource ./.;
src = craneLib.cleanCargoSource (craneLib.path ./.);
strictDeps = true;
doCheck = false;

View File

@ -39,7 +39,7 @@
craneLib = (crane.mkLib pkgs).overrideToolchain rustWithWasiTarget;
my-crate = craneLib.buildPackage {
src = craneLib.cleanCargoSource ./.;
src = craneLib.cleanCargoSource (craneLib.path ./.);
cargoExtraArgs = "--target wasm32-wasi";

View File

@ -21,7 +21,7 @@
craneLib = crane.lib.${system};
my-crate = craneLib.buildPackage {
src = craneLib.cleanCargoSource ./.;
src = craneLib.cleanCargoSource (craneLib.path ./.);
buildInputs = [
# Add additional build inputs here

View File

@ -34,7 +34,7 @@
inherit (pkgs) lib;
craneLib = crane.lib.${system};
src = craneLib.cleanCargoSource ./.;
src = craneLib.cleanCargoSource (craneLib.path ./.);
# Common arguments can be set here to avoid repeating them later
commonArgs = {

View File

@ -1,4 +1,5 @@
{ lib
{ internalCrateNameFromCargoToml
, lib
}:
args:
@ -29,35 +30,10 @@ let
traceMsg = tomlName: drvName: placeholder: lib.trivial.warn
"crane cannot find ${tomlName} attribute in ${debugPath}, consider setting `${drvName} = \"...\";` explicitly"
placeholder;
internalName = internalCrateNameFromCargoToml toml;
in
{
# Now that cargo supports workspace inheritance we attempt to select a name
# with the following priorities:
# - choose `[package.name]` if the value is present and a string
# (i.e. it isn't `[package.name] = { workspace = "true" }`)
# - choose `[workspace.package.name]` if it is present (and a string for good measure)
# - otherwise, fall back to a placeholder
pname =
let
packageName = toml.package.name or null;
workspacePackageName = toml.workspace.package.name or null;
in
if lib.isString packageName then packageName
else if lib.isString workspacePackageName then workspacePackageName
else traceMsg "name" "pname" "cargo-package";
# Now that cargo supports workspace inheritance we attempt to select a version
# string with the following priorities:
# - choose `[package.version]` if the value is present and a string
# (i.e. it isn't `[package.version] = { workspace = "true" }`)
# - choose `[workspace.package.version]` if it is present (and a string for good measure)
# - otherwise, fall back to a placeholder
version =
let
packageVersion = toml.package.version or null;
workspacePackageVersion = toml.workspace.package.version or null;
in
if lib.isString packageVersion then packageVersion
else if lib.isString workspacePackageVersion then workspacePackageVersion
else traceMsg "version" "version" "0.0.1";
pname = internalName.pname or (traceMsg "name" "pname" "cargo-package");
version = internalName.version or (traceMsg "version" "version" "0.0.1");
}

View File

@ -5,6 +5,8 @@
lib.makeScope newScope (self:
let
inherit (self) callPackage;
internalCrateNameFromCargoToml = callPackage ./internalCrateNameFromCargoToml.nix { };
in
{
appendCrateRegistries = input: self.overrideScope' (_final: prev: {
@ -28,7 +30,10 @@ in
configureCargoCommonVarsHook = callPackage ./setupHooks/configureCargoCommonVars.nix { };
configureCargoVendoredDepsHook = callPackage ./setupHooks/configureCargoVendoredDeps.nix { };
craneUtils = callPackage ../pkgs/crane-utils { };
crateNameFromCargoToml = callPackage ./crateNameFromCargoToml.nix { };
crateNameFromCargoToml = callPackage ./crateNameFromCargoToml.nix {
inherit internalCrateNameFromCargoToml;
};
crateRegistries = self.registryFromDownloadUrl {
dl = "https://crates.io/api/v1/crates";
@ -52,6 +57,10 @@ in
rustfmt = toolchain;
});
path = callPackage ./path.nix {
inherit internalCrateNameFromCargoToml;
};
registryFromDownloadUrl = callPackage ./registryFromDownloadUrl.nix { };
registryFromGitIndex = callPackage ./registryFromGitIndex.nix { };
removeReferencesToVendoredSourcesHook = callPackage ./setupHooks/removeReferencesToVendoredSources.nix { };

View File

@ -0,0 +1,35 @@
{ lib
}:
toml:
lib.filterAttrs (_: v: v != null) {
# Now that cargo supports workspace inheritance we attempt to select a name
# with the following priorities:
# - choose `[package.name]` if the value is present and a string
# (i.e. it isn't `[package.name] = { workspace = "true" }`)
# - choose `[workspace.package.name]` if it is present (and a string for good measure)
# - otherwise, fall back to a placeholder
pname =
let
packageName = toml.package.name or null;
workspacePackageName = toml.workspace.package.name or null;
in
if lib.isString packageName then packageName
else if lib.isString workspacePackageName then workspacePackageName
else null;
# Now that cargo supports workspace inheritance we attempt to select a version
# string with the following priorities:
# - choose `[package.version]` if the value is present and a string
# (i.e. it isn't `[package.version] = { workspace = "true" }`)
# - choose `[workspace.package.version]` if it is present (and a string for good measure)
# - otherwise, fall back to a placeholder
version =
let
packageVersion = toml.package.version or null;
workspacePackageVersion = toml.workspace.package.version or null;
in
if lib.isString packageVersion then packageVersion
else if lib.isString workspacePackageVersion then workspacePackageVersion
else null;
}

24
lib/path.nix Normal file
View File

@ -0,0 +1,24 @@
{ internalCrateNameFromCargoToml
, lib
}:
input:
let
pathArgs = if lib.isAttrs input then input else { path = input; };
cargoTomlContents =
let
emptyToml = { };
cargoToml = pathArgs.path + "/Cargo.toml";
cargoTomlContents = builtins.readFile cargoToml;
toml = builtins.tryEval (builtins.fromTOML cargoTomlContents);
in
if builtins.pathExists cargoToml
then
if toml.success then toml.value else emptyToml
else
emptyToml;
name = (internalCrateNameFromCargoToml cargoTomlContents).pname or "source";
in
builtins.path ({ inherit name; } // pathArgs)

View File

@ -3,10 +3,11 @@
, cargoClippy
, cargoFmt
, cleanCargoSource
, path
}:
let
src = cleanCargoSource ./.;
src = cleanCargoSource (path ./.);
cargoArtifacts = buildDepsOnly {
inherit src;

View File

@ -4,7 +4,7 @@
book =
let
inherit (pkgs) lib;
root = ./..;
root = myLib.path ./..;
rootPrefix = toString root;
cleanedSrc = lib.cleanSourceWith {
src = root;

View File

@ -6,6 +6,11 @@ let
sha256 = locked.narHash;
};
flake = import compat { src = ./.; };
flake = import compat {
src = builtins.path {
path = ./.;
name = "crane";
};
};
in
flake.shellNix