From fb0cbc0c21fe5ae4f2f325f531f51eedc47af900 Mon Sep 17 00:00:00 2001 From: Tom de Goede Date: Tue, 28 Sep 2021 14:59:44 +0200 Subject: [PATCH 1/3] Add SourceGenerator support --- dotnet/private/actions/assembly.bzl | 23 ++++++++++++++++++++++- dotnet/private/rules/binary.bzl | 20 +++++++++++++++++--- tools/server/Program.cs | 5 +++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/dotnet/private/actions/assembly.bzl b/dotnet/private/actions/assembly.bzl index e013e3ca..9d7fd41e 100644 --- a/dotnet/private/actions/assembly.bzl +++ b/dotnet/private/actions/assembly.bzl @@ -49,6 +49,10 @@ def _make_runner_arglist(dotnet, deps, transitive_analyzers, resources, output, args.add(dotnet.analyzer_ruleset, format = "/ruleset:%s") args.add(dotnet.analyzer_config, format = "/analyzerconfig:%s") args.add_all(dotnet.analyzer_additionalfiles, format_each = "/additionalfile:%s") + else: + for a in transitive_analyzers.to_list(): + if a.path.endswith("SourceGenerator.dll"): + args.add(a, format = "/analyzer:%s") args.add_all(resources, format_each = "/resource:%s", map_each = _map_resource) args.add_all(deps, format_each = "/reference:%s") @@ -140,7 +144,7 @@ def emit_assembly_core( unused_refs = dotnet.declare_file(dotnet, path = name + ".unused") dotnet.actions.run( # ensure propsfile is build when this action runs by making it an input - inputs = depset(direct = [paramfile, propsfile] + resource_files, transitive = [all_srcs, transitive_refs]), + inputs = depset(direct = [paramfile, propsfile] + resource_files, transitive = [all_srcs, transitive_refs, transitive_analyzers]), input_manifests = input_manifests, outputs = outputs + [unused_refs], executable = server, @@ -167,6 +171,23 @@ def emit_assembly_core( ), ) + if out and out.endswith("SourceGenerator.dll"): + transitive_analyzers = depset(direct = [result], transitive = [a[DotnetLibrary].transitive_analyzers for a in deps]) + + return DotnetLibrary( + name = dotnet.label.name if not name else name, + label = dotnet.label, + analyzer = result, + transitive_analyzers = transitive_analyzers, + deps = [], + result = None, + ref_result = None, + runfiles = depset(), + transitive_refs = depset(), + transitive = depset(), + output_groups = [OutputGroupInfo(targets = [propsfile])] if propsfile else [], + ) + return dotnet.new_library( dotnet = dotnet, name = name, diff --git a/dotnet/private/rules/binary.bzl b/dotnet/private/rules/binary.bzl index 5440f642..4dac6b46 100644 --- a/dotnet/private/rules/binary.bzl +++ b/dotnet/private/rules/binary.bzl @@ -18,6 +18,17 @@ load( ) load("@bazel_skylib//lib:paths.bzl", "paths") +def _framework_transition_impl(settings, attr): + if Label("@nuget//netstandard.library") in attr.deps: + return {"@nuget//:framework" : "netstandard2.0"} + return settings + +framework_transition = transition( + implementation = _framework_transition_impl, + inputs = ["@nuget//:framework"], + outputs = ["@nuget//:framework"] +) + # DotnetContext, DotnetLibrary def create_launcher(dotnet, library, shim = None): launch_target = shim if shim else library.result @@ -92,10 +103,10 @@ def _rule_impl(ctx): if ctx.attr._target_type == "exe": shim = create_shim_exe(ctx, assembly.result) result.append(create_launcher(dotnet, assembly, shim)) - else: + elif assembly.result or assembly.analyzer: # always output a DefaultInfo with a file so directly building this target will trigger actions result.append(DefaultInfo( - files = depset([assembly.result]), + files = depset([assembly.result or assembly.analyzer]), )) return result @@ -106,7 +117,10 @@ def _rule(target_type, return rule( _rule_impl, attrs = { - "deps": attr.label_list(providers = [DotnetLibrary]), + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist" + ), + "deps": attr.label_list(providers = [DotnetLibrary], cfg = framework_transition), "resources": attr.label_list(providers = [DotnetResourceList]), "srcs": attr.label_list(allow_files = [".cs"]), "out": attr.string(), diff --git a/tools/server/Program.cs b/tools/server/Program.cs index 8e4dec1b..dfb42bb3 100644 --- a/tools/server/Program.cs +++ b/tools/server/Program.cs @@ -117,6 +117,11 @@ string ScopePath(string path) "); } + else if (line.StartsWith("/analyzer:") && line.EndsWith("SourceGenerator.dll")) + { + var analyzerPath = line.Substring(10).Replace('/', '\\'); + sb.Append($"\n\n"); + } } // obj/....csproj.bazel.props file From c277b318be3b9b6f192273f6e161272855fced11 Mon Sep 17 00:00:00 2001 From: Tom de Goede Date: Wed, 8 Dec 2021 13:38:19 +0100 Subject: [PATCH 2/3] also recognize Text.Jsons SourceGeneration.dll --- dotnet/nuget_repo.bzl | 3 --- dotnet/private/actions/assembly.bzl | 2 +- tools/server/Program.cs | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/dotnet/nuget_repo.bzl b/dotnet/nuget_repo.bzl index 9c897805..c5f7b6eb 100644 --- a/dotnet/nuget_repo.bzl +++ b/dotnet/nuget_repo.bzl @@ -23,9 +23,6 @@ def _nuget_repo_impl(ctx): if r.return_code != 0: print(r.stdout) fail("nuget_repository failed with exit code " + repr(r.return_code) + "\n\n" + r.stderr) - - ctx.file("BUILD", r""" -)""") nuget_repo = repository_rule( _nuget_repo_impl, diff --git a/dotnet/private/actions/assembly.bzl b/dotnet/private/actions/assembly.bzl index 9d7fd41e..bfe4fe35 100644 --- a/dotnet/private/actions/assembly.bzl +++ b/dotnet/private/actions/assembly.bzl @@ -51,7 +51,7 @@ def _make_runner_arglist(dotnet, deps, transitive_analyzers, resources, output, args.add_all(dotnet.analyzer_additionalfiles, format_each = "/additionalfile:%s") else: for a in transitive_analyzers.to_list(): - if a.path.endswith("SourceGenerator.dll"): + if a.path.endswith("SourceGenerator.dll") or a.path.endswith("SourceGeneration.dll"): args.add(a, format = "/analyzer:%s") args.add_all(resources, format_each = "/resource:%s", map_each = _map_resource) diff --git a/tools/server/Program.cs b/tools/server/Program.cs index dfb42bb3..ec750708 100644 --- a/tools/server/Program.cs +++ b/tools/server/Program.cs @@ -117,7 +117,7 @@ string ScopePath(string path) "); } - else if (line.StartsWith("/analyzer:") && line.EndsWith("SourceGenerator.dll")) + else if (line.StartsWith("/analyzer:") && (line.EndsWith("SourceGenerator.dll") || line.EndsWith("SourceGeneration.dll"))) { var analyzerPath = line.Substring(10).Replace('/', '\\'); sb.Append($"\n\n"); From ab6bd670c71706a2a1e956b5ff62ffa790cb3c05 Mon Sep 17 00:00:00 2001 From: Tom de Goede Date: Tue, 15 Feb 2022 18:45:11 +0100 Subject: [PATCH 3/3] quikfix for newtonsoft dep of sourcegen --- dotnet/private/actions/assembly.bzl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dotnet/private/actions/assembly.bzl b/dotnet/private/actions/assembly.bzl index bfe4fe35..80422160 100644 --- a/dotnet/private/actions/assembly.bzl +++ b/dotnet/private/actions/assembly.bzl @@ -105,6 +105,8 @@ def emit_assembly_core( # files could contain spaces. therefore quote runner_args.add_all(all_srcs, format_each = '"%s"') + runner_args.add("/analyzer:external/nuget/newtonsoft.json/current/lib/netstandard2.0/Newtonsoft.Json.dll") + runner_args.use_param_file("@%s", use_always = True) runner_args.set_param_file_format("multiline")