* This allows for fewer assumptions about the project structure
* The old behavior can easily be brought back by setting `cargoExtraArgs
= "--workspace";` in any derivation
* Previously we would manually copy over any Cargo.lock file from the
source to the dummified source
* Now, `mkDummySrc` will implicitly copy the file if it is present, or
ignore it if missing, so this check is a bit overzealous now
* Loosening this check also allows callers to sneak in their own
Cargo.lock file (e.g. through a patch phase) while still avoiding IFD
when trying to use crane with a non local src (eg, not `./.`) we get the error
```
$ nix flake show
<...>
error: access to absolute path '/Cargo.toml' is forbidden in pure eval mode (use '--impure' to override)
(use '--show-trace' to show detailed location information)
```
To fix this, we quote the relative paths so to properly append them to the base path.
https://nixos.wiki/wiki/Nix_Expression_Language#Coercing_a_relative_path_with_interpolated_variables_to_an_absolute_path_.28for_imports.29
## Reproduction flake
```
{
description = "Build a cargo project without extra checks";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
crane = {
url = "github:ipetkov/crane";
inputs.nixpkgs.follows = "nixpkgs";
};
external-crate-source = {
url = "github:ray-kast/empress";
flake = false;
};
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, crane, flake-utils, external-crate-source, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
test-crate = crane.lib.${system}.buildPackage {
src = external-crate-source.outPath;
};
in
{
packages.default = test-crate;
});
}
```
* When Nix fetches a git repo it will only look for the specified
revision only starting from the main branch (apparently fetching
arbitrary revisions from a repository has some security implications)
* If a ref (i.e. branch or tag) is not specified, Nix will only fetch
the repo's main branch
* To remedy this we will supply Nix with the branch or tag (if specified
in the Cargo.lock) to help it find the specified revision
* If cargo does not specify a branch or tag for us, we'll set `allRefs =
true` so that Nix can try fetching all possible branches and tags
before trying to check out the locked revision
* Previously all build hooks were instantiated in a single
`callPackages` call which led to several issues:
- changes via `lib.overrideScope'` were ignored because the build
hooks were only ever instantiated with the nixpkgs instance of our
flake (not whatever overlays the caller may have made)
- the pkgs splicing was not done quite right, meaning when we pull in
the build hooks as nativeBuildInputs the splicing wasn't picking up
the overridden versions of `cargo` but was instead trying to
recompile the nixpkgs version each time
* Seems like Nix can get unhappy if a path fragment is evaluated too
eagerly, giving errors like
`error: access to absolute path '/Cargo.toml' is forbidden in pure eval mode (use '--impure' to override)`
* Changing to using string manipulation seems to resolve the issue
* Rather than recursively look up all paths in a given project and then
filtering for cargo-specific files, we now use our own customized
traversal method to only capture the results we want.
* Previously the check was overzealous and it was impossible to only
specify `cargoToml` (since both other parameters would be null)
* Instead, we take advantage of Nix's laziness and only throw when
needed
* Similarly rename `installCargoTargetDirHook` to
`installCargoArtifactsHook`
* The intention is to highlight that "install" implies "copy to output"
and not anywhere else
* Also avoids the potential confusion of "cargo target dir" (location of
cargo's artifacts) with "cargo target" (which is the target
architecture/platform we want cargo to build for)
* There are some edge cases where cargo will allow a lib.rs file to be
present but not a main.rs (e.g. a binary cannot be called "examples",
which will happen if the crate is called that and a main.rs file is
present)