mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-25 16:33:15 +00:00
build-support/rust/buildRustCrate: Search for matching Cargo.toml in sub directories
This is what cargo does for git repositories. See related issues: * https://github.com/kolloch/crate2nix/issues/53 * https://github.com/kolloch/crate2nix/issues/33
This commit is contained in:
parent
04e7462ee6
commit
8a6638daa9
@ -31,12 +31,25 @@ let version_ = lib.splitString "-" crateVersion;
|
||||
completeDepsDir = lib.concatStringsSep " " completeDeps;
|
||||
completeBuildDepsDir = lib.concatStringsSep " " completeBuildDeps;
|
||||
in ''
|
||||
cd ${workspace_member}
|
||||
${echo_colored colors}
|
||||
${noisily colors verbose}
|
||||
source ${./lib.sh}
|
||||
|
||||
${lib.optionalString (workspace_member != null) ''
|
||||
noisily cd "${workspace_member}"
|
||||
''}
|
||||
${lib.optionalString (workspace_member == null) ''
|
||||
echo_colored "Searching for matching Cargo.toml (${crateName})"
|
||||
local cargo_toml_dir=$(matching_cargo_toml_dir "${crateName}")
|
||||
if [ -z "$cargo_toml_dir" ]; then
|
||||
echo_error "ERROR configuring ${crateName}: No matching Cargo.toml in $(pwd) found." >&2
|
||||
exit 23
|
||||
fi
|
||||
noisily cd "$cargo_toml_dir"
|
||||
''}
|
||||
|
||||
runHook preConfigure
|
||||
|
||||
symlink_dependency() {
|
||||
# $1 is the nix-store path of a dependency
|
||||
# $2 is the target path
|
||||
|
@ -88,7 +88,7 @@ stdenv.mkDerivation (rec {
|
||||
|
||||
src = crate.src or (fetchCrate { inherit (crate) crateName version sha256; });
|
||||
name = "rust_${crate.crateName}-${crate.version}${lib.optionalString buildTests_ "-test"}";
|
||||
depsBuildBuild = [ rust stdenv.cc ];
|
||||
depsBuildBuild = [ rust stdenv.cc cargo jq ];
|
||||
buildInputs = (crate.buildInputs or []) ++ buildInputs_;
|
||||
dependencies = map lib.getLib dependencies_;
|
||||
buildDependencies = map lib.getLib buildDependencies_;
|
||||
@ -114,6 +114,8 @@ stdenv.mkDerivation (rec {
|
||||
in lib.substring 0 10 hashedMetadata;
|
||||
|
||||
build = crate.build or "";
|
||||
# Either set to a concrete sub path to the crate root
|
||||
# or use `null` for auto-detect.
|
||||
workspace_member = crate.workspace_member or ".";
|
||||
crateVersion = crate.version;
|
||||
crateDescription = crate.description or "";
|
||||
|
@ -144,3 +144,37 @@ search_for_bin_path() {
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Extracts cargo_toml_path of the matching crate.
|
||||
matching_cargo_toml_path() {
|
||||
local manifest_path="$1"
|
||||
local expected_crate_name="$2"
|
||||
|
||||
# If the Cargo.toml is not a workspace root,
|
||||
# it will only contain one package in ".packages"
|
||||
# because "--no-deps" suppressed dependency resolution.
|
||||
#
|
||||
# But to make it more general, we search for a matching
|
||||
# crate in all packages and use the manifest path that
|
||||
# is referenced there.
|
||||
cargo metadata --no-deps --format-version 1 \
|
||||
--manifest-path "$manifest_path" \
|
||||
| jq -r '.packages[]
|
||||
| select( .name == "'$expected_crate_name'")
|
||||
| .manifest_path'
|
||||
}
|
||||
|
||||
# Find a Cargo.toml in the current or any sub directory
|
||||
# with a matching crate name.
|
||||
matching_cargo_toml_dir() {
|
||||
local expected_crate_name="$1"
|
||||
|
||||
find -L -name Cargo.toml | sort | while read manifest_path; do
|
||||
echo "...checking manifest_path $manifest_path" >&2
|
||||
local matching_path="$(matching_cargo_toml_path "$manifest_path" "$expected_crate_name")"
|
||||
if [ -n "${matching_path}" ]; then
|
||||
echo "$(dirname $matching_path)"
|
||||
break
|
||||
fi
|
||||
done
|
||||
}
|
@ -8,6 +8,14 @@ let
|
||||
} // args;
|
||||
in buildRustCrate p;
|
||||
|
||||
mkCargoToml =
|
||||
{ name, crateVersion ? "0.1.0", path ? "Cargo.toml" }:
|
||||
mkFile path ''
|
||||
[package]
|
||||
name = ${builtins.toJSON name}
|
||||
version = ${builtins.toJSON crateVersion}
|
||||
'';
|
||||
|
||||
mkFile = destination: text: writeTextFile {
|
||||
name = "src";
|
||||
destination = "/${destination}";
|
||||
@ -89,7 +97,7 @@ let
|
||||
in rec {
|
||||
|
||||
tests = let
|
||||
cases = {
|
||||
cases = rec {
|
||||
libPath = { libPath = "src/my_lib.rs"; src = mkLib "src/my_lib.rs"; };
|
||||
srcLib = { src = mkLib "src/lib.rs"; };
|
||||
|
||||
@ -220,6 +228,40 @@ let
|
||||
];
|
||||
};
|
||||
};
|
||||
rustCargoTomlInSubDir = {
|
||||
# The "workspace_member" can be set to the sub directory with the crate to build.
|
||||
# By default ".", meaning the top level directory is assumed.
|
||||
# Using null will trigger a search.
|
||||
workspace_member = null;
|
||||
src = symlinkJoin rec {
|
||||
name = "find-cargo-toml";
|
||||
paths = [
|
||||
(mkCargoToml { name = "ignoreMe"; })
|
||||
(mkTestFileWithMain "src/main.rs" "ignore_main")
|
||||
|
||||
(mkCargoToml { name = "rustCargoTomlInSubDir"; path = "subdir/Cargo.toml"; })
|
||||
(mkTestFileWithMain "subdir/src/main.rs" "src_main")
|
||||
(mkTestFile "subdir/tests/foo/main.rs" "tests_foo")
|
||||
(mkTestFile "subdir/tests/bar/main.rs" "tests_bar")
|
||||
];
|
||||
};
|
||||
buildTests = true;
|
||||
expectedTestOutputs = [
|
||||
"test src_main ... ok"
|
||||
"test tests_foo ... ok"
|
||||
"test tests_bar ... ok"
|
||||
];
|
||||
};
|
||||
|
||||
rustCargoTomlInTopDir =
|
||||
let
|
||||
withoutCargoTomlSearch = builtins.removeAttrs rustCargoTomlInSubDir [ "workspace_member" ];
|
||||
in
|
||||
withoutCargoTomlSearch // {
|
||||
expectedTestOutputs = [
|
||||
"test ignore_main ... ok"
|
||||
];
|
||||
};
|
||||
};
|
||||
brotliCrates = (callPackage ./brotli-crates.nix {});
|
||||
in lib.mapAttrs (key: value: mkTest (value // lib.optionalAttrs (!value?crateName) { crateName = key; })) cases // {
|
||||
|
Loading…
Reference in New Issue
Block a user