Skip to content

Commit

Permalink
Merge pull request tweag#29 from tweag/allow-multiple-repositories
Browse files Browse the repository at this point in the history
Allow passing several labels to `nixpkgs_package`
  • Loading branch information
mboes authored Oct 20, 2018
2 parents da7574a + ed40f56 commit 3087f0d
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 29 deletions.
5 changes: 2 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 //...'
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ nixpkgs_git_repository(

nixpkgs_package(
name = "hello",
repository = "@nixpkgs"
repositories = { "@nixpkgs": "nixpkgs" }
)
```

Expand Down Expand Up @@ -160,8 +160,15 @@ nixpkgs clone in `nix_file` or `nix_file_content`.
<td><code>repository</code></td>
<td>
<p><code>Label; optional</code></p>
<p>A Nixpkgs repository label. Specify one of `path` or
`repository`.</p>
<p>Deprecated, use `repositories` instead.</p>
</td>
</tr>
<tr>
<td><code>repositorie</code></td>
<td>
<p><code>Label-keyed String dict; optional</code></p>
<p>A dictionary mapping repositoriy labels to `NIX_PATH` entries.
Specify one of `path` or `repositories`.</p>
</td>
</tr>
<tr>
Expand All @@ -170,7 +177,7 @@ nixpkgs clone in `nix_file` or `nix_file_content`.
<p><code>String; optional</code></p>
<p>The path to the directory containing Nixpkgs, as
interpreted by `nix-build`. Specify one of `path` or
`repository`.</p>
`repositories`.</p>
</td>
</tr>
<tr>
Expand Down
19 changes: 6 additions & 13 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -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 <nixpkgs> {}; 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 <nixpkgs> {}",
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" },
)

41 changes: 32 additions & 9 deletions nixpkgs/nixpkgs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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 = []
Expand All @@ -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 <nixpkgs> {}"]
Expand All @@ -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):
Expand All @@ -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:
Expand All @@ -106,21 +116,34 @@ 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(),
"nix_file": attr.label(allow_single_file = [".nix"]),
"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(),
},
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
Expand Down
11 changes: 11 additions & 0 deletions shell.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{ pkgs ? import ./nix/default.nix {} }:

with pkgs;

mkShell {
buildInputs = [
bazel
gcc
nix
];
}

0 comments on commit 3087f0d

Please sign in to comment.