Skip to content

Commit

Permalink
NuGet resolution fixes (#366)
Browse files Browse the repository at this point in the history
## What?
* Fix resolution in packages that have disjoint lib and ref folders.
* Make `nuget_repo` take in a map of TFM to deps so that the dependency graph for each TFM is more accurate
* Update paket2bazel so that it generates correct deps per TFM
  • Loading branch information
purkhusid authored Aug 24, 2023
1 parent 1912a7a commit 8a0668e
Show file tree
Hide file tree
Showing 15 changed files with 339 additions and 246 deletions.
194 changes: 97 additions & 97 deletions dotnet/paket2bazel_dependencies.bzl

Large diffs are not rendered by default.

14 changes: 13 additions & 1 deletion dotnet/private/rules/nuget/nuget_archive.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -360,13 +360,25 @@ def _nuget_archive_impl(ctx):

_process_key_and_file(groups, key, file)

# in some runtime specific edge cases there exist certain tfm refs but the libs are not shipped
if groups.get("ref") and groups.get("lib"):
libs = groups.get("lib")
refs = groups.get("ref")

# in some runtime specific edge cases there exist certain tfm refs but the libs are not shipped
for (tfm, _) in groups.get("ref").items():
if tfm not in libs:
libs[tfm] = []

# We add an empty entry for each tfm that does not exist in the refs
# because that way the generated select statement will contain all the
# supported tfms and thus we can omit an default case in the select which
# would make the build graph more fragile and harder to debug since instead
# of Bazel complaining that a some tfm is not supported for a package you would
# possibly get an error during compilation
for (tfm, _) in groups.get("lib").items():
if tfm not in refs:
refs[tfm] = []

ctx.file("BUILD.bazel", r"""package(default_visibility = ["//visibility:public"])
exports_files(glob(["**"]))
load("@rules_dotnet//dotnet/private/rules/nuget:nuget_archive.bzl", "tfm_filegroup", "rid_filegroup")
Expand Down
34 changes: 22 additions & 12 deletions dotnet/private/rules/nuget/nuget_repo.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,18 @@ load("@rules_dotnet//dotnet/private/rules/nuget:nuget_archive.bzl", "nuget_archi
_GLOBAL_NUGET_PREFIX = "nuget"

def _nuget_repo_impl(ctx):
for (name_version, deps) in ctx.attr.packages.items():
[name, version, sha512] = name_version.split("|")
for package in ctx.attr.packages:
package = json.decode(package)
name = package["id"]
version = package["version"]
sha512 = package["sha512"]
deps = package["dependencies"]

# deps = []
# for (tfm, tfm_deps) in dependencies.items():
# for dep in tfm_deps:
# if dep not in deps:
# deps.append(dep)

targeting_pack_overrides = ctx.attr.targeting_pack_overrides[name.lower()]
template = Label("@rules_dotnet//dotnet/private/rules/nuget:template.BUILD")
Expand All @@ -17,7 +27,7 @@ def _nuget_repo_impl(ctx):
"{NAME}": name,
"{NAME_LOWER}": name.lower(),
"{VERSION}": version,
"{DEPS}": ",".join(["\n \"@{}//{}\"".format(ctx.name.lower(), d.lower()) for d in deps]),
"{DEPS}": ",".join(["\n \"@rules_dotnet//dotnet:tfm_{tfm}\": [{deps_list}]".format(tfm = tfm, deps_list = ",".join(["\"@{nuget_repo_name}//{dep_name}\"".format(dep_name = d.lower(), nuget_repo_name = ctx.name.lower()) for d in tfm_deps])) for (tfm, tfm_deps) in deps.items()]),
"{TARGETING_PACK_OVERRIDES}": json.encode({override.lower().split("|")[0]: override.lower().split("|")[1] for override in targeting_pack_overrides}),
"{SHA_512}": sha512,
})
Expand All @@ -31,7 +41,7 @@ alias(name = "content_files", actual = "@{prefix}.{name}.v{version}//:content_fi
_nuget_repo = repository_rule(
_nuget_repo_impl,
attrs = {
"packages": attr.string_list_dict(
"packages": attr.string_list(
mandatory = True,
allow_empty = False,
),
Expand All @@ -46,24 +56,24 @@ _nuget_repo = repository_rule(
def nuget_repo(name, packages):
# TODO: Add docs
# scaffold individual nuget archives
for (package_name, version, sha512, sources, netrc, _deps, _targeting_pack_overrides) in packages:
package_name = package_name.lower()
version = version.lower()
for package in packages:
package_name = package["id"].lower()
version = package["version"].lower()

# maybe another nuget_repo has the same nuget package dependency
maybe(
nuget_archive,
name = "{}.{}.v{}".format(_GLOBAL_NUGET_PREFIX, package_name, version),
sources = sources,
netrc = netrc,
sources = package["sources"],
netrc = package.get("netrc", None),
id = package_name,
version = version,
sha512 = sha512,
sha512 = package["sha512"],
)

# scaffold transitive @name// dependency tree
_nuget_repo(
name = name,
packages = {"{}|{}|{}".format(name, version, sha512): deps for (name, version, sha512, _sources, _netrc, deps, _) in packages},
targeting_pack_overrides = {"{}".format(name.lower()): targeting_pack_overrides for (name, _, _, _, _, _, targeting_pack_overrides) in packages},
packages = [json.encode(package) for package in packages],
targeting_pack_overrides = {"{}".format(package["id"].lower()): package["targeting_pack_overrides"] for package in packages},
)
4 changes: 3 additions & 1 deletion dotnet/private/rules/nuget/template.BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ import_library(
sha512 = "{SHA_512}",
targeting_pack_overrides = {TARGETING_PACK_OVERRIDES},
version = "{VERSION}",
deps = [{DEPS}],
deps = select({
{DEPS},
}),
)
3 changes: 3 additions & 0 deletions dotnet/private/tests/nuget_structure/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load(":runtimes.bzl", "runtimes_structure")
load(":typeproviders.bzl", "typeproviders_structure")
load(":resolution.bzl", "resolution_structure")

typeproviders_structure()

runtimes_structure()

resolution_structure()

bzl_library(
name = "common",
srcs = ["common.bzl"],
Expand Down
20 changes: 20 additions & 0 deletions dotnet/private/tests/nuget_structure/resolution.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"NuGet structure tests"

load("//dotnet/private/tests/nuget_structure:common.bzl", "nuget_structure_test", "nuget_test_wrapper")

# buildifier: disable=unnamed-macro
def resolution_structure():
"Tests for the resolution of files depending on target framework"
nuget_test_wrapper(
name = "System.Memory.netstandard2.0",
target_framework = "netstandard2.0",
runtime_identifier = "linux-x64",
package = "@rules_dotnet_dev_nuget_packages//system.memory",
)

nuget_structure_test(
name = "should_resolve_system.memory_netstandard2.0_linux-x64_correctly",
target_under_test = ":System.Memory.netstandard2.0",
expected_libs = ["lib/netstandard2.0/System.Memory.dll"],
expected_refs = [],
)
Loading

0 comments on commit 8a0668e

Please sign in to comment.