From 25f83618bdfeae24b922656d4bc0acfd8b7069fd Mon Sep 17 00:00:00 2001 From: Mateusz Kowalczyk Date: Thu, 14 Dec 2017 16:02:22 +0000 Subject: [PATCH 1/3] Allow arbitrary expressions in nixpkgs_package This allows us to be much more flexible when we want to be while maintaining convenience for simple attribute cases. --- CONTRIBUTORS | 1 + WORKSPACE | 19 +++++++++++++++++++ nixpkgs/nixpkgs.bzl | 33 +++++++++++++++++++++++++++------ tests/BUILD | 15 ++++++++++----- 4 files changed, 57 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 6a765791..4b3b9890 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -10,3 +10,4 @@ # Name Mathieu Boespflug +Mateusz Kowalczyk diff --git a/WORKSPACE b/WORKSPACE index 5d06ecc3..dc7fa191 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -10,3 +10,22 @@ nixpkgs_git_repository( ) nixpkgs_package(name = "hello", repository = "@nixpkgs") + +nixpkgs_package( + name = "expr-test", + expression = "let pkgs = import {}; in pkgs.hello", + repository = "@nixpkgs" +) + +nixpkgs_package( + name = "attribute-test", + attribute = "hello", + repository = "@nixpkgs" +) + +nixpkgs_package( + name = "expr-attribute-test", + expression = "import {}", + attribute = "hello", + repository = "@nixpkgs", +) diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl index 6f850626..b3783dc6 100644 --- a/nixpkgs/nixpkgs.bzl +++ b/nixpkgs/nixpkgs.bzl @@ -15,6 +15,19 @@ nixpkgs_git_repository = repository_rule( local = False, ) +def _mk_build_expression(ctx): + """Generate a nix expression that picks a package from nixpkgs. + """ + # If user specified expression only, use expression only: they may + # be picking their attributes in the expression itself already. + if ctx.attr.expression and not ctx.attr.attribute: + return ["-E", ctx.attr.expression] + # In all other cases we can craft a correct query by using user's + # input with some defaults. + else: + return ["-E", ctx.attr.expression or "import {}", + "-A", ctx.attr.attribute or ctx.attr.name] + def _nixpkgs_package_impl(ctx): if ctx.attr.build_file and ctx.attr.build_file_content: fail("Specify one of 'build_file' or 'build_file_content', but not both.") @@ -25,19 +38,22 @@ def _nixpkgs_package_impl(ctx): else: ctx.template("BUILD", Label("@io_tweag_rules_nixpkgs//nixpkgs:BUILD.pkg")) - path = '' + # If neither repository or path are set, leave empty which will use + # default value from NIX_PATH + path = [] if ctx.attr.repository and ctx.attr.path: fail("'repository' and 'path' fields are mutually exclusive.") if ctx.attr.repository: # XXX Another hack: the repository label typically resolves to # some top-level package in the external workspace. So we use # dirname to get the actual workspace path. - path = ctx.path(ctx.attr.repository).dirname + path = ["-I", "nixpkgs={0}".format(ctx.path(ctx.attr.repository).dirname)] if ctx.attr.path: - path = ctx.attr.path + path = ["-I", "nixpkgs={0}".format(ctx.attr.path)] + + buildExpr = _mk_build_expression(ctx) + buildCmd = ["nix-build"] + path + ["--no-out-link"] + buildExpr - attr_path = ctx.attr.attribute_path or ctx.name - buildCmd = ["nix-build", path, "-A", attr_path, "--no-out-link"] res = ctx.execute(buildCmd, quiet = False) if res.return_code == 0: output_path = res.stdout.splitlines()[-1] @@ -48,7 +64,12 @@ def _nixpkgs_package_impl(ctx): nixpkgs_package = repository_rule( implementation = _nixpkgs_package_impl, attrs = { - "attribute_path": attr.string(), + "attribute": attr.string( + doc="Nix attribute to build. Exclusive to expression." + ), + "expression": attr.string( + doc="Nix expression to build. Rule name used as attribute if not present.", + ), "path": attr.string(), "repository": attr.label(), "build_file": attr.label(), diff --git a/tests/BUILD b/tests/BUILD index 42e02273..1937ff54 100644 --- a/tests/BUILD +++ b/tests/BUILD @@ -1,9 +1,14 @@ package(default_testonly = 1) -sh_test( - name = "run-hello", +[sh_test( + name= "run-{0}".format(test), srcs = ["test_bin.sh"], - args = ["$(location @hello//:bin)"], - data = ["@hello//:bin"], + args=["$(location @{0}//:bin)".format(test)], + data = ["@{0}//:bin".format(test)], timeout = "short", -) +) for test in [ + "hello", + "expr-test", + "attribute-test", + "expr-attribute-test", +]] From 085bd696a28d0ff6c2a694c54ec920bad5565975 Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Tue, 26 Dec 2017 23:35:59 +0100 Subject: [PATCH 2/3] Revert to using "attribute_path" as field name. We really are passing an attribute *path*, not a Nix attribute. The Nix documentation defines an attribute path as a dot separated sequence of attributes. --- WORKSPACE | 4 ++-- nixpkgs/nixpkgs.bzl | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index dc7fa191..5050a51d 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -19,13 +19,13 @@ nixpkgs_package( nixpkgs_package( name = "attribute-test", - attribute = "hello", + attribute_path = "hello", repository = "@nixpkgs" ) nixpkgs_package( name = "expr-attribute-test", expression = "import {}", - attribute = "hello", + attribute_path = "hello", repository = "@nixpkgs", ) diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl index b3783dc6..7b6b8e63 100644 --- a/nixpkgs/nixpkgs.bzl +++ b/nixpkgs/nixpkgs.bzl @@ -20,13 +20,13 @@ def _mk_build_expression(ctx): """ # If user specified expression only, use expression only: they may # be picking their attributes in the expression itself already. - if ctx.attr.expression and not ctx.attr.attribute: + if ctx.attr.expression and not ctx.attr.attribute_path: return ["-E", ctx.attr.expression] # In all other cases we can craft a correct query by using user's # input with some defaults. else: return ["-E", ctx.attr.expression or "import {}", - "-A", ctx.attr.attribute or ctx.attr.name] + "-A", ctx.attr.attribute_path or ctx.attr.name] def _nixpkgs_package_impl(ctx): if ctx.attr.build_file and ctx.attr.build_file_content: @@ -64,7 +64,7 @@ def _nixpkgs_package_impl(ctx): nixpkgs_package = repository_rule( implementation = _nixpkgs_package_impl, attrs = { - "attribute": attr.string( + "attribute_path": attr.string( doc="Nix attribute to build. Exclusive to expression." ), "expression": attr.string( From 5e34b6ed1a04e9dd72a560399ce6013f19e588ca Mon Sep 17 00:00:00 2001 From: Mathieu Boespflug Date: Wed, 27 Dec 2017 00:16:58 +0100 Subject: [PATCH 3/3] Simplify attribute selection logic. --- nixpkgs/nixpkgs.bzl | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl index 7b6b8e63..b9c682c9 100644 --- a/nixpkgs/nixpkgs.bzl +++ b/nixpkgs/nixpkgs.bzl @@ -15,19 +15,6 @@ nixpkgs_git_repository = repository_rule( local = False, ) -def _mk_build_expression(ctx): - """Generate a nix expression that picks a package from nixpkgs. - """ - # If user specified expression only, use expression only: they may - # be picking their attributes in the expression itself already. - if ctx.attr.expression and not ctx.attr.attribute_path: - return ["-E", ctx.attr.expression] - # In all other cases we can craft a correct query by using user's - # input with some defaults. - else: - return ["-E", ctx.attr.expression or "import {}", - "-A", ctx.attr.attribute_path or ctx.attr.name] - def _nixpkgs_package_impl(ctx): if ctx.attr.build_file and ctx.attr.build_file_content: fail("Specify one of 'build_file' or 'build_file_content', but not both.") @@ -39,7 +26,7 @@ def _nixpkgs_package_impl(ctx): ctx.template("BUILD", Label("@io_tweag_rules_nixpkgs//nixpkgs:BUILD.pkg")) # If neither repository or path are set, leave empty which will use - # default value from NIX_PATH + # default value from NIX_PATH. path = [] if ctx.attr.repository and ctx.attr.path: fail("'repository' and 'path' fields are mutually exclusive.") @@ -51,8 +38,13 @@ def _nixpkgs_package_impl(ctx): if ctx.attr.path: path = ["-I", "nixpkgs={0}".format(ctx.attr.path)] - buildExpr = _mk_build_expression(ctx) - buildCmd = ["nix-build"] + path + ["--no-out-link"] + buildExpr + extraArgs = [ + "-E", ctx.attr.expression or "import {}", + "-A", ctx.attr.attribute_path + if ctx.attr.expression + else ctx.attr.attribute_path or ctx.attr.name, + ] + buildCmd = ["nix-build"] + path + ["--no-out-link"] + extraArgs res = ctx.execute(buildCmd, quiet = False) if res.return_code == 0: