Skip to content

Add rules_license package metadata to nuget archive BUILD files#536

Open
nickcollier wants to merge 4 commits intobazel-contrib:masterfrom
nickcollier:add_rules_license_package_metadata
Open

Add rules_license package metadata to nuget archive BUILD files#536
nickcollier wants to merge 4 commits intobazel-contrib:masterfrom
nickcollier:add_rules_license_package_metadata

Conversation

@nickcollier
Copy link
Copy Markdown

No description provided.

@nickcollier nickcollier requested a review from purkhusid as a code owner March 26, 2026 06:53
@purkhusid
Copy link
Copy Markdown
Collaborator

I think this would be a very nice feature to have but I have an issue with the end-user having to add rules_license as a direct dependency for things to work. Ideally rules_license would just come as a transitive dependency and the end-user would not have to worry about it.

If you can find a way to achieve this then and also add some tests that verify the outputs then I'm ready to merge this feature.

@nickcollier
Copy link
Copy Markdown
Author

nickcollier commented Apr 7, 2026

@purkhusid since the nuget_archive repos are currently created in the context of the end-user workspace they will not be able to directly access the rules_license bazel_dep in rules_dotnet as bzlmod isolates these.

I've listed all the options I could think of below. Each one has a link to a proof of concept branch in my fork of rules_dotnet. In these I've got them to the point you can bazel builld //... in the examples directory. Then I've been inspecting the generated BUILD.bazel files (e.g. under examples\bazel-examples\external\+example_deps_extension+nuget.expecto.v9.0.4\BUILD.bazel)

Option 1: Expose rules_license rules/targets from rules_dotnet

Similar to how def.bzl loads and then exposes private/internal functions from rules_dotnet you can just load the required rules from rules_license and expose in rules_dotnet. There are only a couple of rules that are required.

load(
    "@rules_license//rules:license.bzl",
    _license = "license",
)
load(
    "@rules_license//rules:package_info.bzl",
    _package_info = "package_info",
)

license = _license
package_info = _package_info

To expose the license_kind targets that are required you can create an alias to them in a BUILD.bazel file in rules_dotnet. There are many of these under @rules_license//licenses/spdx however you could generate the BUILD.bazel file to expose them all using a bazel query.

alias(name = "0BSD", actual = "@rules_license//licenses/spdx:0BSD")
alias(name = "3D-Slicer-1.0", actual = "@rules_license//licenses/spdx:3D-Slicer-1.0")
...

Proof of concept: nickcollier/rules_dotnet@add_rules_license_package_metadata...nickcollier:rules_dotnet:add_rules_license_package_metadata-option1

Option 2: Add module_extension to rules_dotnet so nuget_archive repos are generated in the rules_dotnet context

Currently paket2bazel generates a module_extension .bzl file however it is placed in the end-user workspace so it does not have access to any bazel_deps rules_dotnet imports. If you exposed a module_extension within rules_dotnet itself then the generated nuget_archive BUILD files would be able to access rules_license directly.

The end-user MODULE.bazel would look something like:

paket = use_extension("@rules_dotnet//dotnet:extensions.bzl", "paket")

paket.nuget_repo(
    name = "paket.example_deps",
    packages_file = ":paket.example_deps.json",
)

use_repo(paket, "paket.example_deps")

For this example to work paket2bazel would need to be updated to output the packages list of each group as a JSON file.

Proof of concept: https://github.com/nickcollier/rules_dotnet/compare/add_rules_license_package_metadata...nickcollier:rules_dotnet:add_rules_license_package_metadata-option2?expand=1

Option 3: Add global flag to control if rules_license metadata is added is added to nuget_archive repos

In this case the end-user might still have to add a direct dependency on rules_license - but only if they opt-in by enabling the flag to generate rules_license metadata. To configure this globally in a way that is exposed to the nuget_archive repo_rules you can add a config module_extension

The end-user MODULE.bazel would look like

config = use_extension("@rules_dotnet//dotnet:extensions.bzl", "config")
config.setting(name = "add_license_metadata", value = "true")

The rules dotnet MODULE.bazel would look like

config = use_extension("@rules_dotnet//dotnet:extensions.bzl", "config")
use_repo(config, "rules_dotnet_internal")

Then rules_dotnet .bzl files access the config like this

load("@rules_dotnet_internal//:config.bzl", rules_dotnet_config = "config")
...
if rules_dotnet_config["add_license_metadata"]:

This config module_extension and internal_config_repo rule were inspired by rules_python

Proof of concept: https://github.com/nickcollier/rules_dotnet/compare/add_rules_license_package_metadata...nickcollier:rules_dotnet:add_rules_license_package_metadata-option3?expand=1

Option 4: Add flag to paket2bazel to control if rules_license metadata is added to nuget_archive repos

In this case the end-user might still have to add a direct dependency on rules_license - but only if they opt-in by passing the flag to paket2bazel.

    bazel run @rules_dotnet//tools/paket2bazel -- --dependencies-file "$(pwd)"/paket.dependencies --output-folder "$(pwd)" --add-license-metadata

Proof of concept: https://github.com/nickcollier/rules_dotnet/compare/add_rules_license_package_metadata...nickcollier:rules_dotnet:add_rules_license_package_metadata-option4?expand=1

@nickcollier
Copy link
Copy Markdown
Author

nickcollier commented Apr 14, 2026

@purkhusid any thoughts on which option, if any, you would like me to go with? Personally I think Option 2 is the better long term solution as it would allow the generated BUILD files access to all rules_dotnet bazel_deps if you decided you wanted to use some other external rules/target in the future.

@purkhusid
Copy link
Copy Markdown
Collaborator

Sorry about the radio silence. Been very busy with other things. I agree that option 2 is the way to go. I want to eventually get rid of the paket2bazel tool and instead use a module extension that can just parse the paket.dependencies/paket.lock file and all repositories are just created within that module extension.

The rules_license targets could then just be part of that extension and the end-user would not have to worry about the transitive dependency on rules_license.

If you want to take a stab at this then that would be great, I'll try my best to be available for review in a timely manner.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants