Skip to content

Commit

Permalink
Fix NixOS#11 - Add optional dependencies if a feature "<dep name>/fea…
Browse files Browse the repository at this point in the history
…ture" is enabled
  • Loading branch information
kolloch committed Aug 22, 2019
1 parent b24b31f commit 68ab49c
Show file tree
Hide file tree
Showing 9 changed files with 206 additions and 2 deletions.
12 changes: 11 additions & 1 deletion Cargo.nix
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ rec {
#

rootCrate = {
packageId = "crate2nix 0.5.0-alpha.0 (path+file:///home/peter/projects/crate2nix)";

# Use this attribute to refer to the derivation building your root crate package.
# You can override the features with rootCrate.build.override { features = [ "default" "feature1" ... ]; }.
build = buildRustCrateWithFeatures {
Expand All @@ -33,6 +35,7 @@ rec {
# workspaceMembers."${crateName}".build.override { features = [ "default" "feature1" ... ]; }.
workspaceMembers = {
"crate2nix" = {
packageId = "crate2nix 0.5.0-alpha.0 (path+file:///home/peter/projects/crate2nix)";
build = buildRustCrateWithFeatures {
packageId = "crate2nix 0.5.0-alpha.0 (path+file:///home/peter/projects/crate2nix)";
features = rootFeatures;
Expand Down Expand Up @@ -2597,9 +2600,16 @@ rec {
(depName: dep:
builtins.isString dep
|| dep.target or true
&& (!(dep.optional or false) || builtins.elem depName features))
&& (!(dep.optional or false) || builtins.any (doesFeatureEnableDependency depName) features))
dependencies;

/* Returns whether the given feature should enable the given dependency. */
doesFeatureEnableDependency = depName: feature:
let prefix = "${depName}/";
len = builtins.stringLength prefix;
startsWithPrefix = builtins.substring 0 len feature == prefix;
in feature == depName || startsWithPrefix;

/* Returns the expanded features for the given inputFeatures by applying the rules in featureMap.
featureMap is an attribute set which maps feature names to lists of further feature names to enable in case this
Expand Down
92 changes: 92 additions & 0 deletions sample_projects/numtest/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions sample_projects/numtest/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "numtest"
version = "0.1.0"
authors = ["Peter Kolloch <info@eigenvalue.net>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
num = "0.2.0"
10 changes: 10 additions & 0 deletions sample_projects/numtest/crate-hashes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)": "1f3bj604fyr4xh08r357hs3hpdzapiqgccvmj1jpi953ffqrp09a",
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)": "0kkql31mc46lghl2qyirk5vl6l0ij24cb5q9d23zm7bkfm05rmzx",
"num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)": "0alza0afrwvhiilqvjazkxv94sir14jqfi50cpv40rgjl1rk7xf6",
"num-complex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)": "1l8gwn4cqhx77wzhzslwxhryrr5h4vsv19ys8wr5xb1g332805m9",
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)": "1y45nh9xlp2dra9svb1wfsy65fysm3k1w4m8jynywccq645yixid",
"num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)": "003j2hysdrkia435vxn38s1qs8cllrgk04l4aapb8hd0wci109mj",
"num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)": "0igg7jnhsxffy3qdvq30pv5h58a9a20h43s4qpxviyzi5zmzqsx2",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)": "1mnlmy35n734n9xlq0qkfbgzz33x09a1s4rfj30p1976p09b862v"
}
3 changes: 3 additions & 0 deletions sample_projects/numtest/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("Hello from numtest, world!");
}
3 changes: 3 additions & 0 deletions templates/build.nix.tera
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ rec {

{% if root_package_id -%}
rootCrate = {
packageId = {{root_package_id}};

# Use this attribute to refer to the derivation building your root crate package.
# You can override the features with rootCrate.build.override { features = [ "default" "feature1" ... ]; }.
build = buildRustCrateWithFeatures {
Expand All @@ -39,6 +41,7 @@ rec {
workspaceMembers = {
{%- for name, pkg_id in workspace_members %}
{{name}} = {
packageId = {{pkg_id}};
build = buildRustCrateWithFeatures {
packageId = {{pkg_id}};
features = rootFeatures;
Expand Down
9 changes: 8 additions & 1 deletion templates/nix/crate2nix/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,16 @@ rec {
(depName: dep:
builtins.isString dep
|| dep.target or true
&& (!(dep.optional or false) || builtins.elem depName features))
&& (!(dep.optional or false) || builtins.any (doesFeatureEnableDependency depName) features))
dependencies;

/* Returns whether the given feature should enable the given dependency. */
doesFeatureEnableDependency = depName: feature:
let prefix = "${depName}/";
len = builtins.stringLength prefix;
startsWithPrefix = builtins.substring 0 len feature == prefix;
in feature == depName || startsWithPrefix;

/* Returns the expanded features for the given inputFeatures by applying the rules in featureMap.
featureMap is an attribute set which maps feature names to lists of further feature names to enable in case this
Expand Down
56 changes: 56 additions & 0 deletions templates/nix/crate2nix/tests/packageFeatures.nix
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,68 @@ let crateConfigs = {
crateName = "id3";
features = {};
};

"pkg_numtest" = {
crateName = "numtest";
dependencies = {
"num" = "pkg_num";
};
};

"pkg_num_bigint" = {
crateName = "num-bigint";
};

"pkg_num" = {
crateName = "num";
dependencies = {
"num-bigint" = {
packageId = "pkg_num_bigint";
usesDefaultFeatures = false;
optional = true;
};
};
features = {
"default" = [ "std" ];
"std" = [ "num-bigint/std" ];
};
};
};
packageFeatures = packageId: features: {
list = crate2nix.listOfPackageFeatures {inherit crateConfigs packageId features;};
merged = crate2nix.mergePackageFeatures {inherit crateConfigs packageId features;};
};
in lib.runTests {
testNumDependencies = {
expr = packageFeatures "pkg_num" ["default"];
expected = {
list = [
{ packageId = "pkg_num"; features = ["default" "num-bigint/std" "std"]; }
{ packageId = "pkg_num_bigint"; features = ["std"]; }
];
merged = {
"pkg_num" = ["default" "num-bigint/std" "std"];
"pkg_num_bigint" = ["std"];
};
};
};

testNumTestDependencies = {
expr = packageFeatures "pkg_numtest" ["default"];
expected = {
list = [
{ packageId = "pkg_numtest"; features = ["default"]; }
{ packageId = "pkg_num"; features = ["default" "num-bigint/std" "std"]; }
{ packageId = "pkg_num_bigint"; features = ["std"]; }
];
merged = {
"pkg_numtest" = ["default"];
"pkg_num" = ["default" "num-bigint/std" "std"];
"pkg_num_bigint" = ["std"];
};
};
};

testTerminalPackageDependency = {
expr = packageFeatures "pkg_id1" [];
expected = {
Expand Down
13 changes: 13 additions & 0 deletions tests/sample_projects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,19 @@ fn build_and_run_with_problematic_crates() {
assert_eq!("Hello, with_problematic_crates!\n", &output);
}

#[test]
fn build_and_run_numtest() {
let output = build_and_run(
"sample_projects/numtest/Cargo.toml",
"sample_projects/numtest",
"rootCrate",
"numtest",
&["default"],
);

assert_eq!("Hello from numtest, world!\n", &output);
}

#[test]
fn build_and_run_bin_with_lib_git_dep() {
let output = build_and_run(
Expand Down

0 comments on commit 68ab49c

Please sign in to comment.