-
Notifications
You must be signed in to change notification settings - Fork 83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature: nixpkgs_flake_package #380
Conversation
@@ -1,4 +1,4 @@ | |||
"""<!-- Edit the docstring in `core/nixpkgs.bzl` and run `bazel run //docs:update-README.md` to change this repository's `README.md`. --> | |||
"""<!-- Edit the docstring in `core/nixpkgs.bzl` and run `bazel run @rules_nixpkgs_docs//:update-readme` to change this repository's `README.md`. --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to match //nixpkgs/nixpkgs.bzl
.
core/nixpkgs.bzl
Outdated
@@ -453,6 +454,7 @@ def _nixpkgs_package_impl(repository_ctx): | |||
else: | |||
# No user supplied build file, we may create the default one. | |||
create_build_file_if_needed = True | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Auto-added by Buildifier.
core/nixpkgs.bzl
Outdated
# Is nix supported on this platform? | ||
not_supported = not is_supported_platform(repository_ctx) | ||
|
||
# Should we fail if Nix is not supported? | ||
fail_not_supported = repository_ctx.attr.fail_not_supported | ||
|
||
if not_supported and fail_not_supported: | ||
fail("Platform is not supported: `nix` not found in PATH. See attribute `fail_not_supported` if you don't want to use Nix.") | ||
elif not_supported: | ||
return | ||
|
||
# If true, a BUILD file will be created from a template if it does not | ||
# exist. | ||
# However this will happen AFTER the nix-build command. | ||
create_build_file_if_needed = False | ||
if repository_ctx.attr.build_file and repository_ctx.attr.build_file_content: | ||
fail("Specify one of 'build_file' or 'build_file_content', but not both.") | ||
elif repository_ctx.attr.build_file: | ||
repository_ctx.symlink(repository_ctx.attr.build_file, "BUILD") | ||
elif repository_ctx.attr.build_file_content: | ||
repository_ctx.file("BUILD", content = repository_ctx.attr.build_file_content) | ||
else: | ||
# No user supplied build file, we may create the default one. | ||
create_build_file_if_needed = True | ||
|
||
# Workaround to bazelbuild/bazel#4533 | ||
repository_ctx.path("BUILD") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could potentially be pulled out of here and nixpkgs_package()
. I don't think there's a good way to deduplicate the docstring though?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Factoring out the common parts between nixpkgs_package
and nixpkgs_flake_package
would be great. There is a fair bit of complexity around invoking Nix that was tricky to get right. I'd be wary of duplicating it and risk it diverging.
nix_flake_file_deps = {} | ||
for dep_lbl, dep_str in repository_ctx.attr.nix_flake_file_deps.items(): | ||
nix_flake_file_deps[dep_str] = cp(repository_ctx, dep_lbl) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could potentially be grouped with the expand_location()
call below and pulled out to be shared with nixpkgs_package()
.
expr_args.extend([ | ||
expand_location( | ||
repository_ctx = repository_ctx, | ||
string = opt, | ||
labels = nix_flake_file_deps, | ||
attr = "nixopts", | ||
) | ||
for opt in repository_ctx.attr.nixopts | ||
]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
core/nixpkgs.bzl
Outdated
# Create a default BUILD file only if it does not exists and is not | ||
# provided by `build_file` or `build_file_content`. | ||
if create_build_file_if_needed: | ||
p = repository_ctx.path("BUILD") | ||
if not p.exists: | ||
repository_ctx.template("BUILD", Label("@rules_nixpkgs_core//:BUILD.bazel.tpl")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could potentially be pulled into the BUILD file function mentioned above.
nix_flake_file, | ||
nix_flake_lock_file, | ||
nix_flake_file_deps = [], | ||
package = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would attribute_path
be a better name than package
? That would be consistent with nixpkgs_package()
. I chose package
here initially as it matches the name of one of the known Flake output fields.
Looking at |
The tests for core live under Further tests for core should also go there. |
core/nixpkgs.bzl
Outdated
package: Nix Flake package to make available. The default package will be used if not specified. | ||
build_file: The file to use as the BUILD file for this repository. | ||
|
||
Its contents are copied copied into the file `BUILD` in root of the nix output folder. The Label does not need to be named `BUILD`, but can be. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its contents are copied copied into the file `BUILD` in root of the nix output folder. The Label does not need to be named `BUILD`, but can be. | |
Its contents are copied into the file `BUILD` in root of the nix output folder. The Label does not need to be named `BUILD`, but can be. |
core/nixpkgs.bzl
Outdated
# Is nix supported on this platform? | ||
not_supported = not is_supported_platform(repository_ctx) | ||
|
||
# Should we fail if Nix is not supported? | ||
fail_not_supported = repository_ctx.attr.fail_not_supported | ||
|
||
if not_supported and fail_not_supported: | ||
fail("Platform is not supported: `nix` not found in PATH. See attribute `fail_not_supported` if you don't want to use Nix.") | ||
elif not_supported: | ||
return | ||
|
||
# If true, a BUILD file will be created from a template if it does not | ||
# exist. | ||
# However this will happen AFTER the nix-build command. | ||
create_build_file_if_needed = False | ||
if repository_ctx.attr.build_file and repository_ctx.attr.build_file_content: | ||
fail("Specify one of 'build_file' or 'build_file_content', but not both.") | ||
elif repository_ctx.attr.build_file: | ||
repository_ctx.symlink(repository_ctx.attr.build_file, "BUILD") | ||
elif repository_ctx.attr.build_file_content: | ||
repository_ctx.file("BUILD", content = repository_ctx.attr.build_file_content) | ||
else: | ||
# No user supplied build file, we may create the default one. | ||
create_build_file_if_needed = True | ||
|
||
# Workaround to bazelbuild/bazel#4533 | ||
repository_ctx.path("BUILD") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Factoring out the common parts between nixpkgs_package
and nixpkgs_flake_package
would be great. There is a fair bit of complexity around invoking Nix that was tricky to get right. I'd be wary of duplicating it and risk it diverging.
The The
You can reproduce this locally by running the following in the
I started looking into how the bzlmod code path would need to change to fix this but didn't figure it out yet. I'm guessing |
testing/core/tests/BUILD.bazel
Outdated
"flake-hello", | ||
"flake-hello-with-build-file", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In reply to #380 (comment).
The issue is that these tests were added here. This list comprehension is only valid for tests of packages that are imported using a bzlmod Bazel module extension. However, no such extension exists for the flake part, yet.
You can fix this by adding another instance of the list comprehension like this (unverified code):
[
# All of these tests use the "hello" binary to see
# whether different invocations of `nixpkgs_flake_package`
# produce a valid bazel repository.
sh_test(
name = "run-{0}".format(test),
timeout = "short",
srcs = ["test_bin.sh"],
args = ["$(location @{0}//:bin)".format(test)],
data = ["@{0}//:bin".format(test)],
)
for test in [
"flake-hello",
"flake-hello-with-build-file",
(If you go through the Git history of this file, you'll find instances of such code from when not all tests had been converted to use the module extension, yet)
You'll also need to add use_repo
entries to MODULE.bazel
to import these two repositories from the non_module_deps
extension.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that just a temporary workaround or the proper fix? It seems like my work here is only half done, as I presumably need to write @rules_nixpkgs_core//extensions:flake_package.bzl
(or whatever bikeshed)? This is based on my observation that nix_pkg = use_extension("@rules_nixpkgs_core//extensions:package.bzl", "nix_pkg")
seems to be a bzlmod wrapper/validator around nixpkgs_package()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a temporary workaround until there is direct bzlmod support for flake with a module extension.
However, I would keep that out of this PR and defer for later. This will require some design work first - right know I don't really have a good picture for what a module extension for flake support should look like. As mentioned in #348 (comment), I don't know how or if we'd want to approach globally unified packages.
Flakes also bring their own dependency management features. There's a question of whether we'd want to integrate those with bzlmod somehow. Part of the bzlmod design is to provide support for package manager integration via module extensions and tags, with a distinct resolution phase before fetching/importing individual deps. So, from that point of view it could make sense to integrate with Nix flake's dependency management features.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bzlmod test fixes pushed. Not sure if they work as the CI jobs don't seem to run automatically?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we have to run them manually for contributors from outside the organization. Looks like CI is passing now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to see _nixpkgs_package_impl
being broken up a little - it was getting pretty big for a single macro. Thanks for this contribution @rickvanprim!
Introduces a new repository rule
nixpkgs_flake_package
that invokesnix build <label>#<package>
and makes the output available as a Bazel repository. This allows all the Nix version pinning to happen as part of the Nix Flake functionality withflake.lock
and simplifies the Bazel side implementation by not having to fetchnixpkgs
(or any other Nix repositories) outside of Nix and inject them in.Contributes to #348.