diff --git a/.circleci/config.yml b/.circleci/config.yml index 44e5c59ff..10d56e2d6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,9 +10,8 @@ jobs: - run: name: System dependencies command: | - export NIX_PATH=nixpkgs=$PWD/nix/default.nix apk update --no-progress && apk --no-progress add bash ca-certificates - nix-env -iA nixpkgs.bazel nixpkgs.gcc - run: name: Run tests - command: bazel test //... + command: | + nix-shell --pure --run 'bazel test //...' diff --git a/README.md b/README.md index d05c83fb4..d50cb78fd 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ nixpkgs_git_repository( nixpkgs_package( name = "hello", - repository = "@nixpkgs" + repositories = { "@nixpkgs": "nixpkgs" } ) ``` @@ -160,8 +160,15 @@ nixpkgs clone in `nix_file` or `nix_file_content`. repository

Label; optional

-

A Nixpkgs repository label. Specify one of `path` or - `repository`.

+

Deprecated, use `repositories` instead.

+ + + + repositorie + +

Label-keyed String dict; optional

+

A dictionary mapping repositoriy labels to `NIX_PATH` entries. + Specify one of `path` or `repositories`.

@@ -170,7 +177,7 @@ nixpkgs clone in `nix_file` or `nix_file_content`.

String; optional

The path to the directory containing Nixpkgs, as interpreted by `nix-build`. Specify one of `path` or - `repository`.

+ `repositories`.

diff --git a/WORKSPACE b/WORKSPACE index bf50b5675..a35b5ddc0 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -4,44 +4,37 @@ load("//nixpkgs:nixpkgs.bzl", "nixpkgs_git_repository", "nixpkgs_package") # For tests -nixpkgs_git_repository( - name = "nixpkgs", - revision = "17.09", - sha256 = "405f1d6ba523630c83fbabef93f0da11ea388510a576adf2ded26a744fbf793e", -) - -nixpkgs_package(name = "hello", repository = "//:nix/default.nix") +nixpkgs_package(name = "hello", repositories = { "nixpkgs": "//:nix/default.nix" }) nixpkgs_package( name = "expr-test", nix_file_content = "let pkgs = import {}; in pkgs.hello", - repository = "//:nix/default.nix" + repositories = { "nixpkgs": "//:nix/default.nix" } ) nixpkgs_package( name = "attribute-test", attribute_path = "hello", - repository = "//:nix/default.nix" + repositories = { "nixpkgs": "//:nix/default.nix" } ) nixpkgs_package( name = "expr-attribute-test", nix_file_content = "import {}", attribute_path = "hello", - repository = "//:nix/default.nix", + repositories = { "nixpkgs": "//:nix/default.nix" }, ) nixpkgs_package( name = "nix-file-test", nix_file = "//tests:nixpkgs.nix", attribute_path = "hello", - repository = "//:nix/default.nix", + repositories = { "nixpkgs": "//:nix/default.nix" }, ) nixpkgs_package( name = "nix-file-deps-test", nix_file = "//tests:hello.nix", nix_file_deps = ["//tests:pkgname.nix"], - repository = "//:nix/default.nix", + repositories = { "nixpkgs": "//:nix/default.nix" }, ) - diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl index 218d85404..90f02f36f 100644 --- a/nixpkgs/nixpkgs.bzl +++ b/nixpkgs/nixpkgs.bzl @@ -21,6 +21,15 @@ nixpkgs_git_repository = repository_rule( ) def _nixpkgs_package_impl(ctx): + repositories = None + if ctx.attr.repositories: + repositories = ctx.attr.repositories + + if ctx.attr.repository: + print("The 'repository' attribute is deprecated, use 'repositories' instead") + repositories = { ctx.attr.repository: "nixpkgs" } + \ + (repositories if repositories else {}) + if ctx.attr.build_file and ctx.attr.build_file_content: fail("Specify one of 'build_file' or 'build_file_content', but not both.") elif ctx.attr.build_file: @@ -31,7 +40,7 @@ def _nixpkgs_package_impl(ctx): ctx.template("BUILD", Label("@io_tweag_rules_nixpkgs//nixpkgs:BUILD.pkg")) strFailureImplicitNixpkgs = ( - "One of 'path', 'repository', 'nix_file' or 'nix_file_content' must be provided. " + "One of 'path', 'repositories', 'nix_file' or 'nix_file_content' must be provided. " + "The NIX_PATH environment variable is not inherited.") expr_args = [] @@ -41,7 +50,7 @@ def _nixpkgs_package_impl(ctx): ctx.symlink(ctx.attr.nix_file, "default.nix") elif ctx.attr.nix_file_content: expr_args = ["-E", ctx.attr.nix_file_content] - elif not (ctx.attr.path or ctx.attr.repository): + elif not (ctx.attr.path or repositories): fail(strFailureImplicitNixpkgs) else: expr_args = ["-E", "import {}"] @@ -66,17 +75,18 @@ def _nixpkgs_package_impl(ctx): "--out-link", "bazel-support/nix-out-link" ]) - # If neither repository or path are set, leave empty which will use + # If neither repositories or path are set, leave empty which will use # default value from NIX_PATH, which will fail unless a pinned nixpkgs is # set in the 'nix_file' attribute. nix_path = "" - if ctx.attr.repository and ctx.attr.path: - fail("'repository' and 'path' attributes are mutually exclusive.") - elif ctx.attr.repository: + if repositories and ctx.attr.path: + fail("'repositories' and 'path' attributes are mutually exclusive.") + elif repositories: # 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. - nix_path = str(ctx.path(ctx.attr.repository).dirname) + nix_path = ":".join([(path_name + "=" + str(ctx.path(path).dirname)) \ + for (path, path_name) in repositories.items()]) elif ctx.attr.path: nix_path = str(ctx.attr_path) elif not (ctx.attr.nix_file or ctx.attr.nix_file_content): @@ -94,7 +104,7 @@ def _nixpkgs_package_impl(ctx): timeout = 1073741824 res = ctx.execute(nix_build, quiet = False, timeout = timeout, - environment=dict(NIX_PATH="nixpkgs=" + nix_path)) + environment=dict(NIX_PATH=nix_path)) if res.return_code == 0: output_path = res.stdout.splitlines()[-1] else: @@ -106,7 +116,7 @@ def _nixpkgs_package_impl(ctx): _symlink_children(output_path, ctx) -nixpkgs_package = repository_rule( +_nixpkgs_package = repository_rule( implementation = _nixpkgs_package_impl, attrs = { "attribute_path": attr.string(), @@ -114,6 +124,7 @@ nixpkgs_package = repository_rule( "nix_file_deps": attr.label_list(), "nix_file_content": attr.string(), "path": attr.string(), + "repositories": attr.label_keyed_string_dict(), "repository": attr.label(), "build_file": attr.label(), "build_file_content": attr.string(), @@ -121,6 +132,18 @@ nixpkgs_package = repository_rule( local = True, ) +def nixpkgs_package(repositories, *args, **kwargs): + # Because of https://github.com/bazelbuild/bazel/issues/5356 we can't + # directly pass a dict from strings to labels to the rule (which we'd like + # for the `repositories` arguments), but we can pass a dict from labels to + # strings. So we swap the keys and the values (assuming they all are + # distinct). + inversed_repositories = { value: key for (key, value) in repositories.items() } + _nixpkgs_package( + repositories = inversed_repositories, + *args, + **kwargs + ) def _symlink_children(target_dir, rep_ctx): """Create a symlink to all children of `target_dir` in the current diff --git a/shell.nix b/shell.nix new file mode 100644 index 000000000..19d33dff5 --- /dev/null +++ b/shell.nix @@ -0,0 +1,11 @@ +{ pkgs ? import ./nix/default.nix {} }: + +with pkgs; + +mkShell { + buildInputs = [ + bazel + gcc + nix + ]; +}