From bc9b16183558cad0faa3f2e6c6be13c634c4469a Mon Sep 17 00:00:00 2001 From: Chris Brown <77508021+peakschris@users.noreply.github.com> Date: Tue, 30 Sep 2025 09:52:06 -0400 Subject: [PATCH 1/6] fix appsettings.json not always copied --- dotnet/private/rules/csharp/actions/csharp_assembly.bzl | 3 ++- dotnet/private/rules/fsharp/actions/fsharp_assembly.bzl | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dotnet/private/rules/csharp/actions/csharp_assembly.bzl b/dotnet/private/rules/csharp/actions/csharp_assembly.bzl index 7d948f71..cd5e2cf9 100644 --- a/dotnet/private/rules/csharp/actions/csharp_assembly.bzl +++ b/dotnet/private/rules/csharp/actions/csharp_assembly.bzl @@ -353,7 +353,7 @@ def AssemblyAction( resource_assemblies = [], pdbs = [out_pdb] if out_pdb else [], xml_docs = [out_xml] if out_xml else [], - data = data, + data = data + out_appsettings, appsetting_files = depset(out_appsettings), native = [], deps = depset( @@ -396,6 +396,7 @@ def _compile( nullable, run_analyzers, compiler_options, + resources_namespace, out_dll = None, out_ref = None, out_pdb = None, diff --git a/dotnet/private/rules/fsharp/actions/fsharp_assembly.bzl b/dotnet/private/rules/fsharp/actions/fsharp_assembly.bzl index 0103be5b..2fa05783 100644 --- a/dotnet/private/rules/fsharp/actions/fsharp_assembly.bzl +++ b/dotnet/private/rules/fsharp/actions/fsharp_assembly.bzl @@ -306,7 +306,7 @@ def AssemblyAction( resource_assemblies = [], pdbs = [out_pdb] if out_pdb else [], xml_docs = [out_xml] if out_xml else [], - data = data, + data = data + out_appsettings, appsetting_files = depset(out_appsettings), native = [], deps = depset([dep[DotnetAssemblyRuntimeInfo] for dep in deps], transitive = [dep[DotnetAssemblyRuntimeInfo].deps for dep in deps]), From 87f24cdd08e6e80d35a725b11c772150aff3d643 Mon Sep 17 00:00:00 2001 From: Chris Brown <77508021+peakschris@users.noreply.github.com> Date: Tue, 30 Sep 2025 09:52:34 -0400 Subject: [PATCH 2/6] more debug on appsettings copy and deduce namespace from filename --- dotnet/private/common.bzl | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/dotnet/private/common.bzl b/dotnet/private/common.bzl index 33de2af6..cd568b0b 100644 --- a/dotnet/private/common.bzl +++ b/dotnet/private/common.bzl @@ -757,8 +757,11 @@ def copy_files_to_dir(target_name, actions, is_windows, files, out_dir): inputs.append(src) outputs.append(dst) if is_windows: - script_body.append("if not exist \"{dir}\" @mkdir \"{dir}\" >NUL".format(dir = dst.dirname.replace("/", "\\"))) - script_body.append("@copy /Y \"{src}\" \"{dst}\" >NUL".format(src = src.path.replace("/", "\\"), dst = dst.path.replace("/", "\\"))) + script_body.append("if not exist \"{dir}\" mkdir \"{dir}\"".format(dir = dst.dirname.replace("/", "\\"))) + script_body.append("copy /Y \"{src}\" \"{dst}\" >NUL".format(src = src.path.replace("/", "\\"), dst = dst.path.replace("/", "\\"))) + script_body.append("if not exist \"{dst}\" echo Failed to copy to \"{dst}\"".format(dst = dst.path.replace("/", "\\"))) + script_body.append("if not exist \"{dst}\" exit /b 1".format(dst = dst.path.replace("/", "\\"))) + script_body.append("") else: script_body.append("mkdir -p {dir} && cp -f {src} {dst}".format(dir = shell.quote(dst.dirname), src = shell.quote(src.path), dst = shell.quote(dst.path))) @@ -809,10 +812,15 @@ def map_resource_arg(file, target_label, out_dll, language): # the basename of the file. simple_resource_name = "{}.{}".format(out_dll[:-4], file.basename) - if file.owner != None and file.owner.repo_name != target_label.repo_name: + if len(file.basename.split(".")) > 2: + # Resgen encourages naming resource files with dot-delimited full namespace. + # If named like this, we will use the full name as-is. + # eg Foo.Bar.a.b.c.resources + resource_name = file.basename + elif file.owner != None and file.owner.repo_name != target_label.repo_name: # Fallback to the basename if the file comes from a different repository. resource_name = simple_resource_name - if not file.short_path.startswith(target_label.package): + elif not file.short_path.startswith(target_label.package) and not file.short_path.startswith("bazel-bin/"+target_label.package): # Fallback to the basename if the file is not in the target's package, because # the path will not be normalized. resource_name = simple_resource_name From 5e2d3a9bed222e9bfa0c171154355f8e91f5e21b Mon Sep 17 00:00:00 2001 From: Chris Brown <77508021+peakschris@users.noreply.github.com> Date: Tue, 30 Sep 2025 10:13:22 -0400 Subject: [PATCH 3/6] code --- dotnet/private/rules/csharp/actions/csharp_assembly.bzl | 1 - 1 file changed, 1 deletion(-) diff --git a/dotnet/private/rules/csharp/actions/csharp_assembly.bzl b/dotnet/private/rules/csharp/actions/csharp_assembly.bzl index cd5e2cf9..899576c0 100644 --- a/dotnet/private/rules/csharp/actions/csharp_assembly.bzl +++ b/dotnet/private/rules/csharp/actions/csharp_assembly.bzl @@ -396,7 +396,6 @@ def _compile( nullable, run_analyzers, compiler_options, - resources_namespace, out_dll = None, out_ref = None, out_pdb = None, From 3394150778353c18e78164eb820c0c93ce66dd7a Mon Sep 17 00:00:00 2001 From: Chris Brown <77508021+peakschris@users.noreply.github.com> Date: Tue, 30 Sep 2025 10:18:10 -0400 Subject: [PATCH 4/6] buildifier --- dotnet/private/common.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/private/common.bzl b/dotnet/private/common.bzl index cd568b0b..9ed764b2 100644 --- a/dotnet/private/common.bzl +++ b/dotnet/private/common.bzl @@ -820,7 +820,7 @@ def map_resource_arg(file, target_label, out_dll, language): elif file.owner != None and file.owner.repo_name != target_label.repo_name: # Fallback to the basename if the file comes from a different repository. resource_name = simple_resource_name - elif not file.short_path.startswith(target_label.package) and not file.short_path.startswith("bazel-bin/"+target_label.package): + elif not file.short_path.startswith(target_label.package) and not file.short_path.startswith("bazel-bin/" + target_label.package): # Fallback to the basename if the file is not in the target's package, because # the path will not be normalized. resource_name = simple_resource_name From 01f86e412357b8a957a2e2497977ec1fc7a7213c Mon Sep 17 00:00:00 2001 From: Chris Brown <77508021+peakschris@users.noreply.github.com> Date: Sat, 4 Oct 2025 14:17:52 -0400 Subject: [PATCH 5/6] avoid duplicate analyzers --- dotnet/private/common.bzl | 58 +++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/dotnet/private/common.bzl b/dotnet/private/common.bzl index 9ed764b2..f411b4ff 100644 --- a/dotnet/private/common.bzl +++ b/dotnet/private/common.bzl @@ -271,6 +271,7 @@ def collect_compile_info(name, deps, targeting_pack, exports, strict_deps): targeting_pack_overrides = {} framework_list = {} framework_files = [] + analyzer_dlls = [] if targeting_pack: targeting_pack_info = targeting_pack[DotnetTargetingPackInfo] @@ -286,6 +287,8 @@ def collect_compile_info(name, deps, targeting_pack, exports, strict_deps): if len(nuget_info.framework_list) == 0: framework_files.extend(compile_info.irefs) + analyzer_dlls.extend([a.basename for a in compile_info.analyzers + compile_info.analyzers_csharp + compile_info.analyzers_fsharp + compile_info.analyzers_vb]) + direct_analyzers.extend(compile_info.analyzers) direct_analyzers_csharp.extend(compile_info.analyzers_csharp) direct_analyzers_fsharp.extend(compile_info.analyzers_fsharp) @@ -312,10 +315,35 @@ def collect_compile_info(name, deps, targeting_pack, exports, strict_deps): if add_to_output: direct_iref.extend(assembly.irefs if name in assembly.internals_visible_to else assembly.refs) direct_ref.extend(assembly.refs) - direct_analyzers.extend(assembly.analyzers) - direct_analyzers_csharp.extend(assembly.analyzers_csharp) - direct_analyzers_fsharp.extend(assembly.analyzers_fsharp) - direct_analyzers_vb.extend(assembly.analyzers_vb) + + # Only add new analyzer DLLs that are not already in the list; for targets that use both + # a targetting pack and other framework dependencies we can end up with duplicates. + # eg: + # target_frameworks = ["net8.0"], + # deps = ["@paket.main//microsoft.aspnetcore.app.ref"], + # results in these duplicates: + # "Microsoft.AspNetCore.App.Analyzers.dll", + # "Microsoft.AspNetCore.App.CodeFixes.dll", + # "Microsoft.AspNetCore.Components.Analyzers.dll", + # "Microsoft.AspNetCore.Http.RequestDelegateGenerator.dll", + # "Microsoft.Extensions.Configuration.Binder.SourceGeneration.dll", + # "Microsoft.Extensions.Logging.Generators.dll" + new_analyzers = [a for a in assembly.analyzers if a.basename not in analyzer_dlls] + direct_analyzers.extend(new_analyzers) + analyzer_dlls.extend([a.basename for a in new_analyzers]) + + new_analyzers = [a for a in assembly.analyzers_csharp if a.basename not in analyzer_dlls] + direct_analyzers_csharp.extend(new_analyzers) + analyzer_dlls.extend([a.basename for a in new_analyzers]) + + new_analyzers = [a for a in assembly.analyzers_fsharp if a.basename not in analyzer_dlls] + direct_analyzers_fsharp.extend(new_analyzers) + analyzer_dlls.extend([a.basename for a in new_analyzers]) + + new_analyzers = [a for a in assembly.analyzers_vb if a.basename not in analyzer_dlls] + direct_analyzers_vb.extend(new_analyzers) + analyzer_dlls.extend([a.basename for a in new_analyzers]) + direct_compile_data.extend(assembly.compile_data) # We take all the exports of each dependency and add them @@ -333,10 +361,24 @@ def collect_compile_info(name, deps, targeting_pack, exports, strict_deps): add_to_output = False if add_to_output: transitive_ref.append(transitive_assembly) - transitive_analyzers.append(assembly.transitive_analyzers) - transitive_analyzers_csharp.append(assembly.transitive_analyzers_csharp) - transitive_analyzers_fsharp.append(assembly.transitive_analyzers_fsharp) - transitive_analyzers_vb.append(assembly.transitive_analyzers_vb) + + # avoid duplicate analyzers (see above) + new_analyzers = [a for a in assembly.transitive_analyzers.to_list() if a.basename not in analyzer_dlls] + transitive_analyzers.extend(new_analyzers) + analyzer_dlls.extend([a.basename for a in new_analyzers]) + + new_analyzers = [a for a in assembly.transitive_analyzers_csharp.to_list() if a.basename not in analyzer_dlls] + transitive_analyzers_csharp.extend(new_analyzers) + analyzer_dlls.extend([a.basename for a in new_analyzers]) + + new_analyzers = [a for a in assembly.transitive_analyzers_fsharp.to_list() if a.basename not in analyzer_dlls] + transitive_analyzers_fsharp.extend(new_analyzers) + analyzer_dlls.extend([a.basename for a in new_analyzers]) + + new_analyzers = [a for a in assembly.transitive_analyzers_vb.to_list() if a.basename not in analyzer_dlls] + transitive_analyzers_vb.extend(new_analyzers) + analyzer_dlls.extend([a.basename for a in new_analyzers]) + transitive_compile_data.append(assembly.transitive_compile_data) for file in framework_list.values(): From 318928bb4fc1d747deeb26e31cbafe8f169e8a1e Mon Sep 17 00:00:00 2001 From: Chris Brown <77508021+peakschris@users.noreply.github.com> Date: Mon, 6 Oct 2025 10:54:05 -0400 Subject: [PATCH 6/6] fix --- dotnet/private/common.bzl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dotnet/private/common.bzl b/dotnet/private/common.bzl index f411b4ff..18664c6b 100644 --- a/dotnet/private/common.bzl +++ b/dotnet/private/common.bzl @@ -364,19 +364,19 @@ def collect_compile_info(name, deps, targeting_pack, exports, strict_deps): # avoid duplicate analyzers (see above) new_analyzers = [a for a in assembly.transitive_analyzers.to_list() if a.basename not in analyzer_dlls] - transitive_analyzers.extend(new_analyzers) + transitive_analyzers.append(depset(new_analyzers)) analyzer_dlls.extend([a.basename for a in new_analyzers]) new_analyzers = [a for a in assembly.transitive_analyzers_csharp.to_list() if a.basename not in analyzer_dlls] - transitive_analyzers_csharp.extend(new_analyzers) + transitive_analyzers_csharp.append(depset(new_analyzers)) analyzer_dlls.extend([a.basename for a in new_analyzers]) new_analyzers = [a for a in assembly.transitive_analyzers_fsharp.to_list() if a.basename not in analyzer_dlls] - transitive_analyzers_fsharp.extend(new_analyzers) + transitive_analyzers_fsharp.append(depset(new_analyzers)) analyzer_dlls.extend([a.basename for a in new_analyzers]) new_analyzers = [a for a in assembly.transitive_analyzers_vb.to_list() if a.basename not in analyzer_dlls] - transitive_analyzers_vb.extend(new_analyzers) + transitive_analyzers_vb.append(depset(new_analyzers)) analyzer_dlls.extend([a.basename for a in new_analyzers]) transitive_compile_data.append(assembly.transitive_compile_data)