From 41cebda4751955047d709c889ed2611bb157f235 Mon Sep 17 00:00:00 2001 From: Georgii Date: Fri, 22 Mar 2024 08:34:50 +0000 Subject: [PATCH 01/20] Adapt doxygen rules to C# --- docs/BUILD | 4 ++-- docs/{cpp => doxygen}/doxyfile.template | 0 docs/{cpp => doxygen}/rules.bzl | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) rename docs/{cpp => doxygen}/doxyfile.template (100%) rename docs/{cpp => doxygen}/rules.bzl (94%) diff --git a/docs/BUILD b/docs/BUILD index c6191aa..fe48abd 100644 --- a/docs/BUILD +++ b/docs/BUILD @@ -19,7 +19,7 @@ # under the License. # -exports_files(["cpp/doxyfile.template"]) +exports_files(["doxygen/doxyfile.template"]) load("@bazel_skylib//:bzl_library.bzl", "bzl_library") load("@vaticle_dependencies_tool_docs//:requirements.bzl", docs_requirement = "requirement") @@ -37,7 +37,7 @@ py_binary( bzl_library( name = "lib", srcs = [ - "cpp/rules.bzl", + "doxygen/rules.bzl", "python/rules.bzl", ], deps = [], diff --git a/docs/cpp/doxyfile.template b/docs/doxygen/doxyfile.template similarity index 100% rename from docs/cpp/doxyfile.template rename to docs/doxygen/doxyfile.template diff --git a/docs/cpp/rules.bzl b/docs/doxygen/rules.bzl similarity index 94% rename from docs/cpp/rules.bzl rename to docs/doxygen/rules.bzl index 6b02d2a..7a887fc 100644 --- a/docs/cpp/rules.bzl +++ b/docs/doxygen/rules.bzl @@ -26,7 +26,7 @@ def _doxygen_docs_impl(ctx): files.extend(target.files.to_list()) replacements = { - "PROJECT_NAME": ctx.attr.project_name, + "PROJECT_NAME": '"' + ctx.attr.project_name + '"', "PROJECT_NUMBER" : ctx.attr.version, "PROJECT_BRIEF" : ctx.attr.desc, "OUTPUT_DIRECTORY" : output_directory.path, @@ -90,7 +90,7 @@ doxygen_docs = rule( ), "_doxyfile_template" : attr.label( allow_single_file = True, - default = "//docs:cpp/doxyfile.template" + default = "//docs:doxygen/doxyfile.template" ), "_output_directory" : attr.string( doc = "The output directory for the doxygen docs", @@ -98,7 +98,7 @@ doxygen_docs = rule( ) }, doc = """ - Creates HTML documentation for C++ projects using Doxygen. + Creates HTML documentation for C++ and C# projects using Doxygen. This rule is not hermetic, and requires doxygen to be installed on the host. """ ) From 0c8ffb8bf4e76dd965b918cf16a20ab729a8881d Mon Sep 17 00:00:00 2001 From: Georgii Date: Mon, 25 Mar 2024 12:43:40 +0000 Subject: [PATCH 02/20] Add static members extraction for the doxygen generation --- docs/doxygen/doxyfile.template | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/doxygen/doxyfile.template b/docs/doxygen/doxyfile.template index b3654a1..883efd4 100644 --- a/docs/doxygen/doxyfile.template +++ b/docs/doxygen/doxyfile.template @@ -98,3 +98,8 @@ GENERATE_LATEX = NO HIDE_UNDOC_RELATIONS = YES CLASS_GRAPH = YES HAVE_DOT = NO ## Disables many details + +#--------------------------------------------------------------------------- +# Configuration options related to optional content included to the output +#--------------------------------------------------------------------------- +EXTRACT_STATIC = YES From 30331891a4ba7a49af75e8a095ae5f0804d2fdb5 Mon Sep 17 00:00:00 2001 From: Georgii Date: Wed, 27 Mar 2024 14:59:26 +0000 Subject: [PATCH 03/20] Add nuget_pack rule --- nuget/nuget_pack.bzl | 239 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 nuget/nuget_pack.bzl diff --git a/nuget/nuget_pack.bzl b/nuget/nuget_pack.bzl new file mode 100644 index 0000000..d7e8cbe --- /dev/null +++ b/nuget/nuget_pack.bzl @@ -0,0 +1,239 @@ +# +# Copyright (C) 2022 Vaticle +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +# This file is based on the original implementation of https://github.com/SeleniumHQ/selenium/. + +load("@rules_dotnet//dotnet/private:common.bzl", "is_debug") +load("@rules_dotnet//dotnet/private:providers.bzl", "DotnetAssemblyRuntimeInfo") + +# The change to the PATH is recommended here: +# https://learn.microsoft.com/en-us/dotnet/core/install/linux-scripted-manual?source=recommendations#set-environment-variables-system-wide +# We list our .Net installation first because we +# want it to be picked up first + +# The `MSBuildEnableWorkloadResolver` is disabled to prevent warnings +# about a missing Microsoft.NET.SDK.WorkloadAutoImportPropsLocator + +def dotnet_preamble(toolchain): + return """ +export DOTNET="$(pwd)/{dotnet}" +export DOTNET_CLI_HOME="$(dirname $DOTNET)" +export DOTNET_CLI_TELEMETRY_OPTOUT=1 +export DOTNET_NOLOGO=1 +export DOTNET_ROOT="$(dirname $DOTNET)" +export PATH=$DOTNET_ROOT:$DOTNET_ROOT/tools:$PATH +export MSBuildEnableWorkloadResolver=false +export CWD=$(pwd) + +# Required to make packing work on Windows +export APPDATA="$(pwd)" +export PROGRAMFILES="$(pwd)" + +# Required to make NuGet tool work on non-writable home path like GitHub actions +export XDG_DATA_HOME=$(mktemp -d) + +# Create `global.json` to trick .Net into using the hermetic toolchain +# https://learn.microsoft.com/en-us/dotnet/core/tools/global-json +echo '{{"sdk": {{"version": "{version}"}} }}' >$(pwd)/global.json + +""".format( + dotnet = toolchain.runtime.files_to_run.executable.path, + version = toolchain.dotnetinfo.sdk_version, + ) + + +def nuget_pack_impl(ctx): + nuspec = ctx.actions.declare_file("%s-generated.nuspec" % ctx.label.name) + + ctx.actions.expand_template( + template = ctx.file.nuspec_template, + output = nuspec, + substitutions = { + "$packageid$": ctx.attr.id, + "$version$": ctx.attr.version, + "$osx_native_lib$": ctx.attr.osx_native_lib, + "$linux_native_lib$": ctx.attr.linux_native_lib, + "$win_native_lib$": ctx.attr.win_native_lib, + "$target_framework$": ctx.attr.target_framework, + }, + ) + + build_flavor = "Debug" if is_debug(ctx) else "Release" + + # A mapping of files to the paths in which we expect to find them in the package + paths = {} + + for (lib, name) in ctx.attr.libs.items(): + assembly_info = lib[DotnetAssemblyRuntimeInfo] + + for dll in assembly_info.libs: + paths[dll] = "lib/%s/%s.dll" % (ctx.attr.target_framework, name) + for pdb in assembly_info.pdbs: + paths[pdb] = "lib/%s/%s.pdb" % (ctx.attr.target_framework, name) + for doc in assembly_info.xml_docs: + paths[doc] = "lib/%s/%s.xml" % (ctx.attr.target_framework, name) + + csproj_template = """ + + %s + %s + %s + + +""" % (ctx.attr.target_framework, ctx.attr.id, ctx.attr.id) + + csproj_file = ctx.actions.declare_file("%s-generated.csproj" % ctx.label.name) + ctx.actions.write(csproj_file, csproj_template) + paths[csproj_file] = "project.csproj" + + for (file, name) in ctx.attr.files.items(): + paths[file.files.to_list()[0]] = name + + # Zip everything up so we have the right file structure + zip_file = ctx.actions.declare_file("%s-intermediate.zip" % ctx.label.name) + args = ctx.actions.args() + args.add_all(["Cc", zip_file]) + for (file, path) in paths.items(): + args.add("%s=%s" % (path, file.path)) + args.add("project.nuspec=%s" % (nuspec.path)) + + ctx.actions.run( + executable = ctx.executable._zip, + arguments = [args], + inputs = paths.keys() + [nuspec], + outputs = [zip_file], + ) + + # Now lay everything out on disk and execute the dotnet pack rule + + # Now we have everything, let's build our package + toolchain = ctx.toolchains["@rules_dotnet//dotnet:toolchain_type"] + + nupkg_name_stem = "%s.%s" % (ctx.attr.id, ctx.attr.version) + + dotnet = toolchain.runtime.files_to_run.executable + pkg = ctx.actions.declare_file("%s.nupkg" % nupkg_name_stem) + symbols_pkg = ctx.actions.declare_file("%s.snupkg" % nupkg_name_stem) + + # Prepare our cache of nupkg files + packages = ctx.actions.declare_directory("%s-nuget-packages" % ctx.label.name) + packages_cmd = "mkdir -p %s " % packages.path + + transitive_libs = depset(transitive = [l[DotnetAssemblyRuntimeInfo].deps for l in ctx.attr.libs]).to_list() + package_files = depset([lib.nuget_info.nupkg for lib in transitive_libs if lib.nuget_info]).to_list() + + if len(package_files): + packages_cmd += "&& cp " + " ".join([f.path for f in package_files]) + " " + packages.path + + ctx.actions.run_shell( + outputs = [packages], + inputs = package_files, + command = packages_cmd, + mnemonic = "LayoutNugetPackages", + ) + + cmd = dotnet_preamble(toolchain) + \ + "mkdir %s-working-dir && " % ctx.label.name + \ + "echo $(pwd) && " + \ + "$(location @bazel_tools//tools/zip:zipper) x %s -d %s-working-dir && " % (zip_file.path, ctx.label.name) + \ + "cd %s-working-dir && " % ctx.label.name + \ + "echo '' >nuget.config && " % packages.path + \ + "$DOTNET restore --no-dependencies && " + \ + "$DOTNET pack --no-build --include-symbols -p:NuspecFile=project.nuspec --include-symbols -p:SymbolPackageFormat=snupkg -p:Configuration=%s -p:PackageId=%s -p:Version=%s -p:PackageVersion=%s -p:NuspecProperties=\"version=%s\" && " % (build_flavor, ctx.attr.id, ctx.attr.version, ctx.attr.version, ctx.attr.version) + \ + "cp bin/%s/%s.%s.nupkg ../%s && " % (build_flavor, ctx.attr.id, ctx.attr.version, pkg.path) + \ + "cp bin/%s/%s.%s.snupkg ../%s" % (build_flavor, ctx.attr.id, ctx.attr.version, symbols_pkg.path) + + cmd = ctx.expand_location( + cmd, + targets = [ + ctx.attr._zip, + ], + ) + + ctx.actions.run_shell( + outputs = [pkg, symbols_pkg], + inputs = [ + zip_file, + dotnet, + packages, + ], + tools = [ + ctx.executable._zip, + dotnet, + ] + toolchain.default.files.to_list() + toolchain.runtime.default_runfiles.files.to_list() + toolchain.runtime.data_runfiles.files.to_list(), + command = cmd, + mnemonic = "CreateNupkg", + ) + + return [ + DefaultInfo( + files = depset([pkg, symbols_pkg]), + runfiles = ctx.runfiles(files = [pkg, symbols_pkg]), + ), + ] + +nuget_pack = rule( + nuget_pack_impl, + attrs = { + "id": attr.string( + doc = "Nuget ID of the package", + mandatory = True, + ), + "version": attr.string( + mandatory = True, + ), + "libs": attr.label_keyed_string_dict( + doc = "The .Net libraries that are being published", + providers = [DotnetAssemblyRuntimeInfo], + ), + "files": attr.label_keyed_string_dict( + doc = "Mapping of files to paths within the nuget package", + allow_empty = True, + allow_files = True, + ), + "osx_native_lib": attr.string( + doc = "Name of the native lib compiled for OSX", + mandatory = True, + ), + "linux_native_lib": attr.string( + doc = "Name of the native lib compiled for Linux", + mandatory = True, + ), + "win_native_lib": attr.string( + doc = "Name of the native lib compiled for Windows", + mandatory = True, + ), + "target_framework": attr.string( + doc = "Target C# build framework", + mandatory = True, + ), + "property_group_vars": attr.string_dict( + doc = "Keys and values for variables declared in `PropertyGroup`s in the `csproj_file`", + allow_empty = True, + ), + "nuspec_template": attr.label( + mandatory = True, + allow_single_file = True, + ), + "_zip": attr.label( + default = "@bazel_tools//tools/zip:zipper", + executable = True, + cfg = "exec", + ), + }, + toolchains = ["@rules_dotnet//dotnet:toolchain_type"], +) From 542a6f04950f0292f6d1d81641ae50425f1de9cf Mon Sep 17 00:00:00 2001 From: Georgii Date: Wed, 27 Mar 2024 15:06:01 +0000 Subject: [PATCH 04/20] Fix struct and license for nuget --- nuget/BUILD | 18 ++++++++++++++++++ nuget/nuget_pack.bzl | 26 ++++++++++++++------------ 2 files changed, 32 insertions(+), 12 deletions(-) create mode 100644 nuget/BUILD diff --git a/nuget/BUILD b/nuget/BUILD new file mode 100644 index 0000000..fe95886 --- /dev/null +++ b/nuget/BUILD @@ -0,0 +1,18 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# diff --git a/nuget/nuget_pack.bzl b/nuget/nuget_pack.bzl index d7e8cbe..66262da 100644 --- a/nuget/nuget_pack.bzl +++ b/nuget/nuget_pack.bzl @@ -1,18 +1,20 @@ # -# Copyright (C) 2022 Vaticle +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at # -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. +# http://www.apache.org/licenses/LICENSE-2.0 # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. # # This file is based on the original implementation of https://github.com/SeleniumHQ/selenium/. From 567923cb4b93ae2657cdd81d06dd5b825c6c0a52 Mon Sep 17 00:00:00 2001 From: Georgii Date: Wed, 27 Mar 2024 17:52:42 +0000 Subject: [PATCH 05/20] Make native libs one per build --- nuget/nuget_pack.bzl | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/nuget/nuget_pack.bzl b/nuget/nuget_pack.bzl index 66262da..7ca3601 100644 --- a/nuget/nuget_pack.bzl +++ b/nuget/nuget_pack.bzl @@ -61,15 +61,27 @@ echo '{{"sdk": {{"version": "{version}"}} }}' >$(pwd)/global.json def nuget_pack_impl(ctx): nuspec = ctx.actions.declare_file("%s-generated.nuspec" % ctx.label.name) + native_lib_files = "" + + if ctx.attr.osx_native_lib: + native_lib_files += """ +""" % ctx.attr.osx_native_lib + + if ctx.attr.linux_native_lib: + native_lib_files += """ +""" % ctx.attr.linux_native_lib + + if ctx.attr.osx_native_lib: + native_lib_files += """ +""" % ctx.attr.osx_native_lib + ctx.actions.expand_template( template = ctx.file.nuspec_template, output = nuspec, substitutions = { "$packageid$": ctx.attr.id, "$version$": ctx.attr.version, - "$osx_native_lib$": ctx.attr.osx_native_lib, - "$linux_native_lib$": ctx.attr.linux_native_lib, - "$win_native_lib$": ctx.attr.win_native_lib, + "$native_lib_files$": native_lib_files, "$target_framework$": ctx.attr.target_framework, }, ) From 5e4c5a445ce2bbadda26776cf9b2d3b5c3f0b9dc Mon Sep 17 00:00:00 2001 From: Georgii Date: Wed, 27 Mar 2024 17:55:31 +0000 Subject: [PATCH 06/20] Remove mandatory from platforms --- nuget/nuget_pack.bzl | 3 --- 1 file changed, 3 deletions(-) diff --git a/nuget/nuget_pack.bzl b/nuget/nuget_pack.bzl index 7ca3601..b2760e0 100644 --- a/nuget/nuget_pack.bzl +++ b/nuget/nuget_pack.bzl @@ -221,15 +221,12 @@ nuget_pack = rule( ), "osx_native_lib": attr.string( doc = "Name of the native lib compiled for OSX", - mandatory = True, ), "linux_native_lib": attr.string( doc = "Name of the native lib compiled for Linux", - mandatory = True, ), "win_native_lib": attr.string( doc = "Name of the native lib compiled for Windows", - mandatory = True, ), "target_framework": attr.string( doc = "Target C# build framework", From 1f0f6c428116bda3fe99793d5a8031ce86361dcb Mon Sep 17 00:00:00 2001 From: Georgii Date: Wed, 27 Mar 2024 18:00:22 +0000 Subject: [PATCH 07/20] Fix build --- nuget/nuget_pack.bzl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nuget/nuget_pack.bzl b/nuget/nuget_pack.bzl index b2760e0..bd19111 100644 --- a/nuget/nuget_pack.bzl +++ b/nuget/nuget_pack.bzl @@ -64,15 +64,15 @@ def nuget_pack_impl(ctx): native_lib_files = "" if ctx.attr.osx_native_lib: - native_lib_files += """ + native_lib_files += """ """ % ctx.attr.osx_native_lib if ctx.attr.linux_native_lib: - native_lib_files += """ + native_lib_files += """ """ % ctx.attr.linux_native_lib if ctx.attr.osx_native_lib: - native_lib_files += """ + native_lib_files += """ """ % ctx.attr.osx_native_lib ctx.actions.expand_template( From 6445e2b1b88580fcf32921be9ddcb7d2d595754b Mon Sep 17 00:00:00 2001 From: Georgii Date: Thu, 28 Mar 2024 18:07:29 +0000 Subject: [PATCH 08/20] Add first nuget_push version --- nuget/{nuget_pack.bzl => rules.bzl} | 77 ++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 8 deletions(-) rename nuget/{nuget_pack.bzl => rules.bzl} (81%) diff --git a/nuget/nuget_pack.bzl b/nuget/rules.bzl similarity index 81% rename from nuget/nuget_pack.bzl rename to nuget/rules.bzl index bd19111..be16182 100644 --- a/nuget/nuget_pack.bzl +++ b/nuget/rules.bzl @@ -19,6 +19,7 @@ # This file is based on the original implementation of https://github.com/SeleniumHQ/selenium/. +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") load("@rules_dotnet//dotnet/private:common.bzl", "is_debug") load("@rules_dotnet//dotnet/private:providers.bzl", "DotnetAssemblyRuntimeInfo") @@ -63,17 +64,17 @@ def nuget_pack_impl(ctx): native_lib_files = "" - if ctx.attr.osx_native_lib: + if ctx.attr.mac_native_lib: native_lib_files += """ -""" % ctx.attr.osx_native_lib +""" % ctx.attr.mac_native_lib if ctx.attr.linux_native_lib: native_lib_files += """ """ % ctx.attr.linux_native_lib - if ctx.attr.osx_native_lib: + if ctx.attr.win_native_lib: native_lib_files += """ -""" % ctx.attr.osx_native_lib +""" % ctx.attr.win_native_lib ctx.actions.expand_template( template = ctx.file.nuspec_template, @@ -195,8 +196,10 @@ def nuget_pack_impl(ctx): return [ DefaultInfo( - files = depset([pkg, symbols_pkg]), - runfiles = ctx.runfiles(files = [pkg, symbols_pkg]), +# files = depset([pkg, symbols_pkg]), + files = depset([pkg]), + runfiles = ctx.runfiles(files = [pkg]), +# runfiles = ctx.runfiles(files = [pkg, symbols_pkg]), ), ] @@ -219,8 +222,8 @@ nuget_pack = rule( allow_empty = True, allow_files = True, ), - "osx_native_lib": attr.string( - doc = "Name of the native lib compiled for OSX", + "mac_native_lib": attr.string( + doc = "Name of the native lib compiled for MacOS", ), "linux_native_lib": attr.string( doc = "Name of the native lib compiled for Linux", @@ -248,3 +251,61 @@ nuget_pack = rule( }, toolchains = ["@rules_dotnet//dotnet:toolchain_type"], ) + +def _nuget_push_impl(ctx): + args = [ + "nuget", + "push", + ] + + apikey = "???" + package_to_publish = ctx.attr.src.files.to_list()[0].path + + output_file = ctx.actions.declare_file("done.txt") + ctx.actions.run_shell( + inputs = [], + outputs = [output_file], + command = "touch {}".format(output_file.path) + ) + + args.append(ctx.expand_location(ctx.attr.src.files.to_list()[0].path)) + args.append("-s") + args.append(ctx.attr.package_repository_url) + args.append("-k") + args.append(apikey) + + csharp_toolchain = ctx.toolchains["@rules_dotnet//dotnet:toolchain_type"] + tools = depset(csharp_toolchain.dotnetinfo.runtime_files) + dotnet_cli_home = ctx.actions.declare_directory("dotnet-cli-home") + env = { + "DOTNET_CLI_HOME": dotnet_cli_home.path, + } + + ctx.actions.run( + executable = csharp_toolchain.dotnetinfo.runtime_files[0].path, + progress_message = "Publishing {}".format(package_to_publish), + arguments = args, + inputs = ctx.attr.src.files.to_list(), + outputs = [dotnet_cli_home], + tools = tools, + env = env, + ) + + return DefaultInfo(files = depset([ + output_file, + ])) + +nuget_push = rule( + implementation = _nuget_push_impl, + attrs = { + "src": attr.label( +# allow_single_file = True, + ), + "package_repository_url": attr.string( + mandatory = True, + ) + }, + toolchains = [ + "@rules_dotnet//dotnet:toolchain_type", + ], +) From fc3cdfd2f8b2b7ed450ba5fc05c875cd2222bd94 Mon Sep 17 00:00:00 2001 From: Georgii Date: Mon, 1 Apr 2024 00:11:39 +0100 Subject: [PATCH 09/20] Add a good version of nuget push --- nuget/rules.bzl | 96 ++++++++++++++++++++++------------------- nuget/templates/BUILD | 20 +++++++++ nuget/templates/push.py | 45 +++++++++++++++++++ 3 files changed, 116 insertions(+), 45 deletions(-) create mode 100644 nuget/templates/BUILD create mode 100644 nuget/templates/push.py diff --git a/nuget/rules.bzl b/nuget/rules.bzl index be16182..ef5ea3f 100644 --- a/nuget/rules.bzl +++ b/nuget/rules.bzl @@ -186,20 +186,20 @@ def nuget_pack_impl(ctx): dotnet, packages, ], - tools = [ - ctx.executable._zip, - dotnet, - ] + toolchain.default.files.to_list() + toolchain.runtime.default_runfiles.files.to_list() + toolchain.runtime.data_runfiles.files.to_list(), + tools = [ctx.executable._zip, dotnet] + + toolchain.default.files.to_list() + + toolchain.runtime.default_runfiles.files.to_list() + + toolchain.runtime.data_runfiles.files.to_list(), command = cmd, mnemonic = "CreateNupkg", ) return [ DefaultInfo( -# files = depset([pkg, symbols_pkg]), - files = depset([pkg]), - runfiles = ctx.runfiles(files = [pkg]), -# runfiles = ctx.runfiles(files = [pkg, symbols_pkg]), + files = depset([pkg, symbols_pkg]), +# files = depset([pkg]), +# runfiles = ctx.runfiles(files = [pkg]), + runfiles = ctx.runfiles(files = [pkg, symbols_pkg]), ), ] @@ -253,57 +253,63 @@ nuget_pack = rule( ) def _nuget_push_impl(ctx): - args = [ - "nuget", - "push", - ] + apikey = "" - apikey = "???" - package_to_publish = ctx.attr.src.files.to_list()[0].path - - output_file = ctx.actions.declare_file("done.txt") - ctx.actions.run_shell( - inputs = [], - outputs = [output_file], - command = "touch {}".format(output_file.path) - ) + all_srcs = ctx.attr.src.files.to_list() - args.append(ctx.expand_location(ctx.attr.src.files.to_list()[0].path)) - args.append("-s") - args.append(ctx.attr.package_repository_url) - args.append("-k") - args.append(apikey) + package_files = [] + for package_file in ctx.attr.src.files.to_list(): + if package_file.extension == "snupkg": + continue # .snupkg are automatically included by the nuget push command if they are in the same dir + package_files.append(package_file) csharp_toolchain = ctx.toolchains["@rules_dotnet//dotnet:toolchain_type"] - tools = depset(csharp_toolchain.dotnetinfo.runtime_files) - dotnet_cli_home = ctx.actions.declare_directory("dotnet-cli-home") - env = { - "DOTNET_CLI_HOME": dotnet_cli_home.path, - } + dotnet_runtime = csharp_toolchain.dotnetinfo.runtime_files[0] - ctx.actions.run( - executable = csharp_toolchain.dotnetinfo.runtime_files[0].path, - progress_message = "Publishing {}".format(package_to_publish), - arguments = args, - inputs = ctx.attr.src.files.to_list(), - outputs = [dotnet_cli_home], - tools = tools, - env = env, + package_file_paths = [] + for package_file in package_files: + package_file_paths.append(ctx.expand_location(package_file.short_path)) + + package_file = package_files[0] + + ctx.actions.expand_template( + template = ctx.file._push_script_template, + output = ctx.outputs.push_script, + substitutions = { + '{dotnet_runtime_path}': dotnet_runtime.path, +# '{nupkg_path}': ctx.expand_location(package_file.short_path), + '{nupkg_path}': " ".join(package_file_paths), + '{api_key}': apikey, + '{target_repo_url}': ctx.attr.repository_url, + }, + is_executable = True, + ) + + return DefaultInfo( + executable = ctx.outputs.push_script, + runfiles = ctx.runfiles(files = all_srcs + [dotnet_runtime]) ) - return DefaultInfo(files = depset([ - output_file, - ])) nuget_push = rule( implementation = _nuget_push_impl, + executable = True, attrs = { "src": attr.label( -# allow_single_file = True, + allow_files = [".nupkg", ".snupkg"], + doc = "Nuget packages (and their debug symbol packages) to push", ), - "package_repository_url": attr.string( + "repository_url": attr.string( mandatory = True, - ) + doc = "URL of the target repository", + ), + "_push_script_template": attr.label( + allow_single_file = True, + default = "//nuget/templates:push.py", + ), + }, + outputs = { + "push_script": "push.py" }, toolchains = [ "@rules_dotnet//dotnet:toolchain_type", diff --git a/nuget/templates/BUILD b/nuget/templates/BUILD new file mode 100644 index 0000000..d696edb --- /dev/null +++ b/nuget/templates/BUILD @@ -0,0 +1,20 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +exports_files(["push.py"]) diff --git a/nuget/templates/push.py b/nuget/templates/push.py new file mode 100644 index 0000000..0824995 --- /dev/null +++ b/nuget/templates/push.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 + +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +from __future__ import print_function +import hashlib +import json +import os +import shutil +import subprocess as sp +import sys +import tempfile +import zipfile + +print("Executing nuget push for {nupkg_path}...") + +# sp.check_call([ +# '{dotnet_runtime_path}', +# 'nuget', +# 'push', +# '{nupkg_path}', +# '-k', +# '{api_key}', +# '-s', +# '{target_repo_url}']) +sp.check_call('{dotnet_runtime_path} nuget push {nupkg_path} -k {api_key} -s {target_repo_url}', shell=True) + +print("Done executing nuget push!") From 56e44a24f0f65fd265f49b8e92de448579c29e85 Mon Sep 17 00:00:00 2001 From: Georgii Date: Mon, 1 Apr 2024 19:45:33 +0100 Subject: [PATCH 10/20] Adjust the rule for packages with native and without native libs --- nuget/rules.bzl | 61 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/nuget/rules.bzl b/nuget/rules.bzl index ef5ea3f..095de9a 100644 --- a/nuget/rules.bzl +++ b/nuget/rules.bzl @@ -62,25 +62,50 @@ echo '{{"sdk": {{"version": "{version}"}} }}' >$(pwd)/global.json def nuget_pack_impl(ctx): nuspec = ctx.actions.declare_file("%s-generated.nuspec" % ctx.label.name) + current_arch = "" + native_lib_files = "" + native_lib = None + if ctx.attr.mac_native_lib: - native_lib_files += """ -""" % ctx.attr.mac_native_lib + native_lib = ctx.attr.mac_native_lib + current_arch = ".osx-x64" if ctx.attr.linux_native_lib: - native_lib_files += """ -""" % ctx.attr.linux_native_lib + native_lib = ctx.attr.linux_native_lib + current_arch = ".linux-x64" if ctx.attr.win_native_lib: - native_lib_files += """ -""" % ctx.attr.win_native_lib + native_lib = ctx.attr.win_native_lib + current_arch = ".win-x64" + + package_name = "%s%s" % (ctx.attr.id, current_arch) + + if native_lib: + target_dir = "runtimes/{}/native" + if current_arch == ".osx-arm64": + target_dir = target_dir.format("osx-arm64") + elif current_arch == ".osx-x64": + target_dir = target_dir.format("osx-x64") + elif current_arch == ".linux-arm64": + target_dir = target_dir.format("linux-arm64") + elif current_arch == ".linux-x64": + target_dir = target_dir.format("linux-x64") + elif current_arch == ".win-arm64": + target_dir = target_dir.format("win-arm64") + elif current_arch == ".win-x64": + target_dir = target_dir.format("win-x64") + + native_ref_template = """ +""" + native_lib_files += native_ref_template % (native_lib, target_dir) ctx.actions.expand_template( template = ctx.file.nuspec_template, output = nuspec, substitutions = { - "$packageid$": ctx.attr.id, + "$packageid$": package_name, "$version$": ctx.attr.version, "$native_lib_files$": native_lib_files, "$target_framework$": ctx.attr.target_framework, @@ -109,7 +134,7 @@ def nuget_pack_impl(ctx): %s -""" % (ctx.attr.target_framework, ctx.attr.id, ctx.attr.id) +""" % (ctx.attr.target_framework, package_name, ctx.attr.id) csproj_file = ctx.actions.declare_file("%s-generated.csproj" % ctx.label.name) ctx.actions.write(csproj_file, csproj_template) @@ -138,7 +163,7 @@ def nuget_pack_impl(ctx): # Now we have everything, let's build our package toolchain = ctx.toolchains["@rules_dotnet//dotnet:toolchain_type"] - nupkg_name_stem = "%s.%s" % (ctx.attr.id, ctx.attr.version) + nupkg_name_stem = "%s.%s" % (package_name, ctx.attr.version) dotnet = toolchain.runtime.files_to_run.executable pkg = ctx.actions.declare_file("%s.nupkg" % nupkg_name_stem) @@ -168,9 +193,9 @@ def nuget_pack_impl(ctx): "cd %s-working-dir && " % ctx.label.name + \ "echo '' >nuget.config && " % packages.path + \ "$DOTNET restore --no-dependencies && " + \ - "$DOTNET pack --no-build --include-symbols -p:NuspecFile=project.nuspec --include-symbols -p:SymbolPackageFormat=snupkg -p:Configuration=%s -p:PackageId=%s -p:Version=%s -p:PackageVersion=%s -p:NuspecProperties=\"version=%s\" && " % (build_flavor, ctx.attr.id, ctx.attr.version, ctx.attr.version, ctx.attr.version) + \ - "cp bin/%s/%s.%s.nupkg ../%s && " % (build_flavor, ctx.attr.id, ctx.attr.version, pkg.path) + \ - "cp bin/%s/%s.%s.snupkg ../%s" % (build_flavor, ctx.attr.id, ctx.attr.version, symbols_pkg.path) + "$DOTNET pack --no-build --include-symbols -p:NuspecFile=project.nuspec --include-symbols -p:SymbolPackageFormat=snupkg -p:Configuration=%s -p:PackageId=%s -p:Version=%s -p:PackageVersion=%s -p:NuspecProperties=\"version=%s\" && " % (build_flavor, package_name, ctx.attr.version, ctx.attr.version, ctx.attr.version) + \ + "cp bin/%s/%s.%s.nupkg ../%s && " % (build_flavor, package_name, ctx.attr.version, pkg.path) + \ + "cp bin/%s/%s.%s.snupkg ../%s" % (build_flavor, package_name, ctx.attr.version, symbols_pkg.path) cmd = ctx.expand_location( cmd, @@ -272,9 +297,11 @@ def _nuget_push_impl(ctx): package_file = package_files[0] + push_file = ctx.actions.declare_file("%s-push.py" % ctx.label.name) + ctx.actions.expand_template( template = ctx.file._push_script_template, - output = ctx.outputs.push_script, + output = push_file, substitutions = { '{dotnet_runtime_path}': dotnet_runtime.path, # '{nupkg_path}': ctx.expand_location(package_file.short_path), @@ -286,7 +313,7 @@ def _nuget_push_impl(ctx): ) return DefaultInfo( - executable = ctx.outputs.push_script, + executable = push_file, runfiles = ctx.runfiles(files = all_srcs + [dotnet_runtime]) ) @@ -308,9 +335,9 @@ nuget_push = rule( default = "//nuget/templates:push.py", ), }, - outputs = { - "push_script": "push.py" - }, +# outputs = { +# "push_script": "push.py" +# }, toolchains = [ "@rules_dotnet//dotnet:toolchain_type", ], From 5a475f046fb6afd87b339642f1b50b3470717a49 Mon Sep 17 00:00:00 2001 From: Georgii Date: Mon, 1 Apr 2024 20:44:13 +0100 Subject: [PATCH 11/20] Refactor the rule to be scalable and with better ux --- nuget/rules.bzl | 24 +++++++++--------------- nuget/templates/push.py | 41 ++++++++++++++++++++++------------------- 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/nuget/rules.bzl b/nuget/rules.bzl index 095de9a..686f041 100644 --- a/nuget/rules.bzl +++ b/nuget/rules.bzl @@ -222,8 +222,6 @@ def nuget_pack_impl(ctx): return [ DefaultInfo( files = depset([pkg, symbols_pkg]), -# files = depset([pkg]), -# runfiles = ctx.runfiles(files = [pkg]), runfiles = ctx.runfiles(files = [pkg, symbols_pkg]), ), ] @@ -278,8 +276,6 @@ nuget_pack = rule( ) def _nuget_push_impl(ctx): - apikey = "" - all_srcs = ctx.attr.src.files.to_list() package_files = [] @@ -295,8 +291,6 @@ def _nuget_push_impl(ctx): for package_file in package_files: package_file_paths.append(ctx.expand_location(package_file.short_path)) - package_file = package_files[0] - push_file = ctx.actions.declare_file("%s-push.py" % ctx.label.name) ctx.actions.expand_template( @@ -304,10 +298,9 @@ def _nuget_push_impl(ctx): output = push_file, substitutions = { '{dotnet_runtime_path}': dotnet_runtime.path, -# '{nupkg_path}': ctx.expand_location(package_file.short_path), - '{nupkg_path}': " ".join(package_file_paths), - '{api_key}': apikey, - '{target_repo_url}': ctx.attr.repository_url, + '{nupkg_paths}': " ".join(package_file_paths), + '{snapshot_url}': ctx.attr.snapshot_url, + '{release_url}': ctx.attr.release_url, }, is_executable = True, ) @@ -326,18 +319,19 @@ nuget_push = rule( allow_files = [".nupkg", ".snupkg"], doc = "Nuget packages (and their debug symbol packages) to push", ), - "repository_url": attr.string( + "snapshot_url" : attr.string( + mandatory = True, + doc = "URL of the target snapshot repository", + ), + "release_url" : attr.string( mandatory = True, - doc = "URL of the target repository", + doc = "URL of the target release repository", ), "_push_script_template": attr.label( allow_single_file = True, default = "//nuget/templates:push.py", ), }, -# outputs = { -# "push_script": "push.py" -# }, toolchains = [ "@rules_dotnet//dotnet:toolchain_type", ], diff --git a/nuget/templates/push.py b/nuget/templates/push.py index 0824995..6527b16 100644 --- a/nuget/templates/push.py +++ b/nuget/templates/push.py @@ -19,27 +19,30 @@ # under the License. # -from __future__ import print_function -import hashlib -import json -import os -import shutil -import subprocess as sp +import subprocess import sys -import tempfile -import zipfile +import os -print("Executing nuget push for {nupkg_path}...") +def unpack_args(_, arg1): + return arg1 + +if len(sys.argv) < 2: + raise ValueError("Should pass as arguments") + +repo_type = unpack_args(*sys.argv) -# sp.check_call([ -# '{dotnet_runtime_path}', -# 'nuget', -# 'push', -# '{nupkg_path}', -# '-k', -# '{api_key}', -# '-s', -# '{target_repo_url}']) -sp.check_call('{dotnet_runtime_path} nuget push {nupkg_path} -k {api_key} -s {target_repo_url}', shell=True) +nuget_repositories = { + "snapshot": "{snapshot_url}", + "release": "{release_url}", +} +target_repo_url = nuget_repositories[repo_type] + +api_key = os.getenv('DEPLOY_NUGET_API_KEY') + +if not api_key: + raise ValueError('Error: API key should be passed via $DEPLOY_NUGET_API_KEY env variable') + +print("Executing nuget push for {nupkg_path}...") +subprocess.check_call(f"{dotnet_runtime_path} nuget push {nupkg_paths} -k {api_key} -s {target_repo_url}", shell=True) print("Done executing nuget push!") From 8b9e0037b9a47c543aa53c18d1d07fe9494b7201 Mon Sep 17 00:00:00 2001 From: Georgii Date: Tue, 2 Apr 2024 15:52:16 +0100 Subject: [PATCH 12/20] Refactor the rules to generate packages for several platforms --- nuget/rules.bzl | 125 +++++++++++++++++----------------------- nuget/templates/push.py | 2 +- 2 files changed, 55 insertions(+), 72 deletions(-) diff --git a/nuget/rules.bzl b/nuget/rules.bzl index 686f041..45de8e6 100644 --- a/nuget/rules.bzl +++ b/nuget/rules.bzl @@ -59,47 +59,34 @@ echo '{{"sdk": {{"version": "{version}"}} }}' >$(pwd)/global.json ) -def nuget_pack_impl(ctx): - nuspec = ctx.actions.declare_file("%s-generated.nuspec" % ctx.label.name) - - current_arch = "" - - native_lib_files = "" +def _check_platform(platform): + allowed_values = ("osx-arm64", "osx-x64", "linux-arm64", "linux-x64", "win-arm64", "win-x64") + if platform not in allowed_values: + fail("Platform must be set to any of {}. Got {} instead!".format(allowed_values, platform)) - native_lib = None - if ctx.attr.mac_native_lib: - native_lib = ctx.attr.mac_native_lib - current_arch = ".osx-x64" +def nuget_pack_impl(ctx): + nuspec = ctx.actions.declare_file("{}-generated.nuspec".format(ctx.label.name)) - if ctx.attr.linux_native_lib: - native_lib = ctx.attr.linux_native_lib - current_arch = ".linux-x64" + # A mapping of files to the paths in which we expect to find them in the package + paths = {} + native_lib_declrs = "" - if ctx.attr.win_native_lib: - native_lib = ctx.attr.win_native_lib - current_arch = ".win-x64" + if ctx.attr.platform: + platform_suffix = ".{}".format(ctx.attr.platform) + else: + platform_suffix = "" - package_name = "%s%s" % (ctx.attr.id, current_arch) + package_name = "{}{}".format(ctx.attr.id, platform_suffix) - if native_lib: - target_dir = "runtimes/{}/native" - if current_arch == ".osx-arm64": - target_dir = target_dir.format("osx-arm64") - elif current_arch == ".osx-x64": - target_dir = target_dir.format("osx-x64") - elif current_arch == ".linux-arm64": - target_dir = target_dir.format("linux-arm64") - elif current_arch == ".linux-x64": - target_dir = target_dir.format("linux-x64") - elif current_arch == ".win-arm64": - target_dir = target_dir.format("win-arm64") - elif current_arch == ".win-x64": - target_dir = target_dir.format("win-x64") + if ctx.files.native_libs: + _check_platform(ctx.attr.platform) + native_target_dir = "runtimes/{}/native".format(ctx.attr.platform) - native_ref_template = """ -""" - native_lib_files += native_ref_template % (native_lib, target_dir) + for native_lib in ctx.files.native_libs: + paths[native_lib] = native_lib.short_path + native_lib_declrs += """ +""".format(native_lib.short_path, native_target_dir) ctx.actions.expand_template( template = ctx.file.nuspec_template, @@ -107,36 +94,33 @@ def nuget_pack_impl(ctx): substitutions = { "$packageid$": package_name, "$version$": ctx.attr.version, - "$native_lib_files$": native_lib_files, + "$native_lib_declrs$": native_lib_declrs, "$target_framework$": ctx.attr.target_framework, }, ) build_flavor = "Debug" if is_debug(ctx) else "Release" - # A mapping of files to the paths in which we expect to find them in the package - paths = {} - for (lib, name) in ctx.attr.libs.items(): assembly_info = lib[DotnetAssemblyRuntimeInfo] for dll in assembly_info.libs: - paths[dll] = "lib/%s/%s.dll" % (ctx.attr.target_framework, name) + paths[dll] = "lib/{}/{}.dll".format(ctx.attr.target_framework, name) for pdb in assembly_info.pdbs: - paths[pdb] = "lib/%s/%s.pdb" % (ctx.attr.target_framework, name) + paths[pdb] = "lib/{}/{}.pdb".format(ctx.attr.target_framework, name) for doc in assembly_info.xml_docs: - paths[doc] = "lib/%s/%s.xml" % (ctx.attr.target_framework, name) + paths[doc] = "lib/{}/{}.xml".format(ctx.attr.target_framework, name) csproj_template = """ - %s - %s - %s + {} + {} + {} -""" % (ctx.attr.target_framework, package_name, ctx.attr.id) +""".format(ctx.attr.target_framework, package_name, ctx.attr.id) - csproj_file = ctx.actions.declare_file("%s-generated.csproj" % ctx.label.name) + csproj_file = ctx.actions.declare_file("{}-generated.csproj".format(ctx.label.name)) ctx.actions.write(csproj_file, csproj_template) paths[csproj_file] = "project.csproj" @@ -144,12 +128,12 @@ def nuget_pack_impl(ctx): paths[file.files.to_list()[0]] = name # Zip everything up so we have the right file structure - zip_file = ctx.actions.declare_file("%s-intermediate.zip" % ctx.label.name) + zip_file = ctx.actions.declare_file("{}-intermediate.zip".format(ctx.label.name)) args = ctx.actions.args() args.add_all(["Cc", zip_file]) for (file, path) in paths.items(): - args.add("%s=%s" % (path, file.path)) - args.add("project.nuspec=%s" % (nuspec.path)) + args.add("{}={}".format(path, file.path)) + args.add("project.nuspec={}".format(nuspec.path)) ctx.actions.run( executable = ctx.executable._zip, @@ -163,15 +147,15 @@ def nuget_pack_impl(ctx): # Now we have everything, let's build our package toolchain = ctx.toolchains["@rules_dotnet//dotnet:toolchain_type"] - nupkg_name_stem = "%s.%s" % (package_name, ctx.attr.version) + nupkg_name_stem = "{}.{}".format(package_name, ctx.attr.version) dotnet = toolchain.runtime.files_to_run.executable - pkg = ctx.actions.declare_file("%s.nupkg" % nupkg_name_stem) - symbols_pkg = ctx.actions.declare_file("%s.snupkg" % nupkg_name_stem) + pkg = ctx.actions.declare_file("{}.nupkg".format(nupkg_name_stem)) + symbols_pkg = ctx.actions.declare_file("{}.snupkg".format(nupkg_name_stem)) # Prepare our cache of nupkg files - packages = ctx.actions.declare_directory("%s-nuget-packages" % ctx.label.name) - packages_cmd = "mkdir -p %s " % packages.path + packages = ctx.actions.declare_directory("{}-nuget-packages".format(ctx.label.name)) + packages_cmd = "mkdir -p {} ".format(packages.path) transitive_libs = depset(transitive = [l[DotnetAssemblyRuntimeInfo].deps for l in ctx.attr.libs]).to_list() package_files = depset([lib.nuget_info.nupkg for lib in transitive_libs if lib.nuget_info]).to_list() @@ -187,15 +171,15 @@ def nuget_pack_impl(ctx): ) cmd = dotnet_preamble(toolchain) + \ - "mkdir %s-working-dir && " % ctx.label.name + \ + "mkdir {}-working-dir && ".format(ctx.label.name) + \ "echo $(pwd) && " + \ - "$(location @bazel_tools//tools/zip:zipper) x %s -d %s-working-dir && " % (zip_file.path, ctx.label.name) + \ - "cd %s-working-dir && " % ctx.label.name + \ - "echo '' >nuget.config && " % packages.path + \ + "$(location @bazel_tools//tools/zip:zipper) x {} -d {}-working-dir && ".format(zip_file.path, ctx.label.name) + \ + "cd {}-working-dir && ".format(ctx.label.name) + \ + "echo '' >nuget.config && ".format(packages.path) + \ "$DOTNET restore --no-dependencies && " + \ - "$DOTNET pack --no-build --include-symbols -p:NuspecFile=project.nuspec --include-symbols -p:SymbolPackageFormat=snupkg -p:Configuration=%s -p:PackageId=%s -p:Version=%s -p:PackageVersion=%s -p:NuspecProperties=\"version=%s\" && " % (build_flavor, package_name, ctx.attr.version, ctx.attr.version, ctx.attr.version) + \ - "cp bin/%s/%s.%s.nupkg ../%s && " % (build_flavor, package_name, ctx.attr.version, pkg.path) + \ - "cp bin/%s/%s.%s.snupkg ../%s" % (build_flavor, package_name, ctx.attr.version, symbols_pkg.path) + "$DOTNET pack --no-build --include-symbols -p:NuspecFile=project.nuspec --include-symbols -p:SymbolPackageFormat=snupkg -p:Configuration={} -p:PackageId={} -p:Version={} -p:PackageVersion={} -p:NuspecProperties=\"version={}\" && ".format(build_flavor, package_name, ctx.attr.version, ctx.attr.version, ctx.attr.version) + \ + "cp bin/{}/{}.{}.nupkg ../{} && ".format(build_flavor, package_name, ctx.attr.version, pkg.path) + \ + "cp bin/{}/{}.{}.snupkg ../{}".format(build_flavor, package_name, ctx.attr.version, symbols_pkg.path) cmd = ctx.expand_location( cmd, @@ -245,14 +229,12 @@ nuget_pack = rule( allow_empty = True, allow_files = True, ), - "mac_native_lib": attr.string( - doc = "Name of the native lib compiled for MacOS", + "platform": attr.string( + doc = "Target platform and architecture for platform-specific packages: {platform}-{arch}.", + default = "", ), - "linux_native_lib": attr.string( - doc = "Name of the native lib compiled for Linux", - ), - "win_native_lib": attr.string( - doc = "Name of the native lib compiled for Windows", + "native_libs": attr.label_list( + doc = "Native libs to include into the package", ), "target_framework": attr.string( doc = "Target C# build framework", @@ -263,6 +245,7 @@ nuget_pack = rule( allow_empty = True, ), "nuspec_template": attr.label( + doc = "Template .nuspec file with the project description", mandatory = True, allow_single_file = True, ), @@ -284,14 +267,14 @@ def _nuget_push_impl(ctx): continue # .snupkg are automatically included by the nuget push command if they are in the same dir package_files.append(package_file) - csharp_toolchain = ctx.toolchains["@rules_dotnet//dotnet:toolchain_type"] - dotnet_runtime = csharp_toolchain.dotnetinfo.runtime_files[0] + toolchain = ctx.toolchains["@rules_dotnet//dotnet:toolchain_type"] + dotnet_runtime = toolchain.runtime.files_to_run.executable package_file_paths = [] for package_file in package_files: package_file_paths.append(ctx.expand_location(package_file.short_path)) - push_file = ctx.actions.declare_file("%s-push.py" % ctx.label.name) + push_file = ctx.actions.declare_file("{}-push.py".format(ctx.label.name)) ctx.actions.expand_template( template = ctx.file._push_script_template, diff --git a/nuget/templates/push.py b/nuget/templates/push.py index 6527b16..4d15b00 100644 --- a/nuget/templates/push.py +++ b/nuget/templates/push.py @@ -42,7 +42,7 @@ def unpack_args(_, arg1): if not api_key: raise ValueError('Error: API key should be passed via $DEPLOY_NUGET_API_KEY env variable') -print("Executing nuget push for {nupkg_path}...") +print(f"Executing nuget push for {nupkg_paths}...") subprocess.check_call(f"{dotnet_runtime_path} nuget push {nupkg_paths} -k {api_key} -s {target_repo_url}", shell=True) print("Done executing nuget push!") From 99ced9280129aca8dc94de48e01e9b5b6262166a Mon Sep 17 00:00:00 2001 From: Georgii Date: Tue, 2 Apr 2024 17:45:14 +0100 Subject: [PATCH 13/20] Support version var --- nuget/BUILD | 2 -- nuget/rules.bzl | 31 +++++++++++++++++++++---------- nuget/templates/BUILD | 2 -- nuget/templates/push.py | 3 --- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/nuget/BUILD b/nuget/BUILD index fe95886..13a8339 100644 --- a/nuget/BUILD +++ b/nuget/BUILD @@ -1,4 +1,3 @@ -# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information @@ -15,4 +14,3 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -# diff --git a/nuget/rules.bzl b/nuget/rules.bzl index 45de8e6..9e17b5a 100644 --- a/nuget/rules.bzl +++ b/nuget/rules.bzl @@ -1,4 +1,3 @@ -# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information @@ -15,7 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -# # This file is based on the original implementation of https://github.com/SeleniumHQ/selenium/. @@ -65,7 +63,16 @@ def _check_platform(platform): fail("Platform must be set to any of {}. Got {} instead!".format(allowed_values, platform)) -def nuget_pack_impl(ctx): +def _parse_version(ctx): + version = ctx.attr.version + if not version: + version = ctx.var.get("version", "0.0.0") + + return version + + +def _nuget_pack_impl(ctx): + version = _parse_version(ctx) nuspec = ctx.actions.declare_file("{}-generated.nuspec".format(ctx.label.name)) # A mapping of files to the paths in which we expect to find them in the package @@ -93,7 +100,7 @@ def nuget_pack_impl(ctx): output = nuspec, substitutions = { "$packageid$": package_name, - "$version$": ctx.attr.version, + "$version$": version, "$native_lib_declrs$": native_lib_declrs, "$target_framework$": ctx.attr.target_framework, }, @@ -147,7 +154,7 @@ def nuget_pack_impl(ctx): # Now we have everything, let's build our package toolchain = ctx.toolchains["@rules_dotnet//dotnet:toolchain_type"] - nupkg_name_stem = "{}.{}".format(package_name, ctx.attr.version) + nupkg_name_stem = "{}.{}".format(package_name, version) dotnet = toolchain.runtime.files_to_run.executable pkg = ctx.actions.declare_file("{}.nupkg".format(nupkg_name_stem)) @@ -177,9 +184,9 @@ def nuget_pack_impl(ctx): "cd {}-working-dir && ".format(ctx.label.name) + \ "echo '' >nuget.config && ".format(packages.path) + \ "$DOTNET restore --no-dependencies && " + \ - "$DOTNET pack --no-build --include-symbols -p:NuspecFile=project.nuspec --include-symbols -p:SymbolPackageFormat=snupkg -p:Configuration={} -p:PackageId={} -p:Version={} -p:PackageVersion={} -p:NuspecProperties=\"version={}\" && ".format(build_flavor, package_name, ctx.attr.version, ctx.attr.version, ctx.attr.version) + \ - "cp bin/{}/{}.{}.nupkg ../{} && ".format(build_flavor, package_name, ctx.attr.version, pkg.path) + \ - "cp bin/{}/{}.{}.snupkg ../{}".format(build_flavor, package_name, ctx.attr.version, symbols_pkg.path) + "$DOTNET pack --no-build --include-symbols -p:NuspecFile=project.nuspec --include-symbols -p:SymbolPackageFormat=snupkg -p:Configuration={} -p:PackageId={} -p:Version={} -p:PackageVersion={} -p:NuspecProperties=\"version={}\" && ".format(build_flavor, package_name, version, version, version) + \ + "cp bin/{}/{}.{}.nupkg ../{} && ".format(build_flavor, package_name, version, pkg.path) + \ + "cp bin/{}/{}.{}.snupkg ../{}".format(build_flavor, package_name, version, symbols_pkg.path) cmd = ctx.expand_location( cmd, @@ -211,14 +218,18 @@ def nuget_pack_impl(ctx): ] nuget_pack = rule( - nuget_pack_impl, + _nuget_pack_impl, attrs = { "id": attr.string( doc = "Nuget ID of the package", mandatory = True, ), "version": attr.string( - mandatory = True, + doc = """ + Target package's version. + Alternatively, pass --define version=VERSION to Bazel invocation. + Not specifying version at all defaults to '0.0.0' + """, ), "libs": attr.label_keyed_string_dict( doc = "The .Net libraries that are being published", diff --git a/nuget/templates/BUILD b/nuget/templates/BUILD index d696edb..40a5992 100644 --- a/nuget/templates/BUILD +++ b/nuget/templates/BUILD @@ -1,4 +1,3 @@ -# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information @@ -15,6 +14,5 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -# exports_files(["push.py"]) diff --git a/nuget/templates/push.py b/nuget/templates/push.py index 4d15b00..f6c5644 100644 --- a/nuget/templates/push.py +++ b/nuget/templates/push.py @@ -1,6 +1,4 @@ #!/usr/bin/env python3 - -# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information @@ -17,7 +15,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -# import subprocess import sys From de5963285798a920d8d3eccf4a8118ac061f6e58 Mon Sep 17 00:00:00 2001 From: Georgii Date: Wed, 3 Apr 2024 15:46:04 +0100 Subject: [PATCH 14/20] Make the rule executable for windows --- nuget/rules.bzl | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/nuget/rules.bzl b/nuget/rules.bzl index 9e17b5a..9d9462b 100644 --- a/nuget/rules.bzl +++ b/nuget/rules.bzl @@ -285,7 +285,7 @@ def _nuget_push_impl(ctx): for package_file in package_files: package_file_paths.append(ctx.expand_location(package_file.short_path)) - push_file = ctx.actions.declare_file("{}-push.py".format(ctx.label.name)) + push_file = ctx.actions.declare_file(ctx.attr.script_file_name) ctx.actions.expand_template( template = ctx.file._push_script_template, @@ -305,7 +305,7 @@ def _nuget_push_impl(ctx): ) -nuget_push = rule( +_nuget_push = rule( implementation = _nuget_push_impl, executable = True, attrs = { @@ -321,6 +321,10 @@ nuget_push = rule( mandatory = True, doc = "URL of the target release repository", ), + "script_file_name": attr.string( + mandatory = True, + doc = "Name of instantiated deployment script" + ), "_push_script_template": attr.label( allow_single_file = True, default = "//nuget/templates:push.py", @@ -330,3 +334,23 @@ nuget_push = rule( "@rules_dotnet//dotnet:toolchain_type", ], ) + + +def nuget_push(name, src, snapshot_url, release_url, **kwargs): + push_script_name = "{}_script".format(name) + push_script_file_name = "{}-push.py".format(push_script_name) + + _nuget_push( + name = push_script_name, + script_file_name = push_script_file_name, + src = src, + snapshot_url = snapshot_url, + release_url = release_url, + **kwargs + ) + + native.py_binary( + name = name, + srcs = [push_script_name], + main = push_script_file_name + ) From b43e2407187e31ecf3bf1f64396a1640d1b27946 Mon Sep 17 00:00:00 2001 From: Georgii Date: Wed, 3 Apr 2024 17:14:41 +0100 Subject: [PATCH 15/20] Try to change subprocess call to args list --- nuget/templates/push.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/nuget/templates/push.py b/nuget/templates/push.py index f6c5644..8a44af9 100644 --- a/nuget/templates/push.py +++ b/nuget/templates/push.py @@ -16,9 +16,10 @@ # specific language governing permissions and limitations # under the License. +import tempfile +import os import subprocess import sys -import os def unpack_args(_, arg1): return arg1 @@ -39,7 +40,21 @@ def unpack_args(_, arg1): if not api_key: raise ValueError('Error: API key should be passed via $DEPLOY_NUGET_API_KEY env variable') +args = [ + "{dotnet_runtime_path}", + "nuget", + "push", +] +args += "{nupkg_paths}".split() +args += [ + "-k", + f"{api_key}", + "-s", + f"{target_repo_url}", +] + print(f"Executing nuget push for {nupkg_paths}...") -subprocess.check_call(f"{dotnet_runtime_path} nuget push {nupkg_paths} -k {api_key} -s {target_repo_url}", shell=True) + +subprocess.check_call(args) print("Done executing nuget push!") From 36a5e5dfd82f0c7a70b544ad23d5731ee599c762 Mon Sep 17 00:00:00 2001 From: Georgii Date: Wed, 3 Apr 2024 22:06:51 +0100 Subject: [PATCH 16/20] Add prints to check paths --- nuget/rules.bzl | 5 ++++- nuget/templates/push.py | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/nuget/rules.bzl b/nuget/rules.bzl index 9d9462b..d360026 100644 --- a/nuget/rules.bzl +++ b/nuget/rules.bzl @@ -299,9 +299,12 @@ def _nuget_push_impl(ctx): is_executable = True, ) + print("DOTNETPATH: {}".format(ctx.expand_location(dotnet_runtime.path))) + print("PUSHFILE: {}".format(push_file.path)) + return DefaultInfo( executable = push_file, - runfiles = ctx.runfiles(files = all_srcs + [dotnet_runtime]) + runfiles = ctx.runfiles(files = all_srcs + [dotnet_runtime]), ) diff --git a/nuget/templates/push.py b/nuget/templates/push.py index 8a44af9..f5d8a2e 100644 --- a/nuget/templates/push.py +++ b/nuget/templates/push.py @@ -16,7 +16,6 @@ # specific language governing permissions and limitations # under the License. -import tempfile import os import subprocess import sys @@ -54,6 +53,20 @@ def unpack_args(_, arg1): ] print(f"Executing nuget push for {nupkg_paths}...") +print(f"Runtime information:\n Dotnet path: {dotnet_runtime_path}") +path = os.path.dirname(os.path.realpath(__file__)) +print(f"Current path: {path}") +def files_in(path_to_parent): + for fname in os.listdir(path_to_parent): + subpath = os.path.join(path_to_parent,fname) + if os.path.isdir(subpath): + for file in files_in(subpath): + yield file + if 'dotnet' in os.path.join(path_to_parent,fname): yield os.path.join(path_to_parent,fname) + +print("Subdirs and files with dotnet:") +for file in set(files_in(path)): + print(file) subprocess.check_call(args) From 6c1f209024e0c0ea0bb6c48ec0631f7edca13343 Mon Sep 17 00:00:00 2001 From: Georgii Date: Wed, 3 Apr 2024 22:42:27 +0100 Subject: [PATCH 17/20] Add subdirs logging to the python script for debugging --- nuget/templates/push.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nuget/templates/push.py b/nuget/templates/push.py index f5d8a2e..e338559 100644 --- a/nuget/templates/push.py +++ b/nuget/templates/push.py @@ -62,9 +62,9 @@ def files_in(path_to_parent): if os.path.isdir(subpath): for file in files_in(subpath): yield file - if 'dotnet' in os.path.join(path_to_parent,fname): yield os.path.join(path_to_parent,fname) + yield os.path.join(path_to_parent,fname) -print("Subdirs and files with dotnet:") +print("Subdirs and files of the current dir:") for file in set(files_in(path)): print(file) From 316fbd2398ac8f8bf340fa08c784cc7882a55f98 Mon Sep 17 00:00:00 2001 From: Georgii Date: Thu, 4 Apr 2024 10:40:54 +0100 Subject: [PATCH 18/20] Add more logs for path in python script --- nuget/templates/push.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nuget/templates/push.py b/nuget/templates/push.py index e338559..74fb21c 100644 --- a/nuget/templates/push.py +++ b/nuget/templates/push.py @@ -65,7 +65,7 @@ def files_in(path_to_parent): yield os.path.join(path_to_parent,fname) print("Subdirs and files of the current dir:") -for file in set(files_in(path)): +for file in set(files_in(os.path.join(path, "../../"))): print(file) subprocess.check_call(args) From 454decb0361d8c335a51132ee2affc0598fd8bf1 Mon Sep 17 00:00:00 2001 From: Georgii Date: Thu, 4 Apr 2024 11:24:38 +0100 Subject: [PATCH 19/20] Add more runtime files for push for windows --- nuget/rules.bzl | 2 +- nuget/templates/push.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nuget/rules.bzl b/nuget/rules.bzl index d360026..8d91ce1 100644 --- a/nuget/rules.bzl +++ b/nuget/rules.bzl @@ -304,7 +304,7 @@ def _nuget_push_impl(ctx): return DefaultInfo( executable = push_file, - runfiles = ctx.runfiles(files = all_srcs + [dotnet_runtime]), + runfiles = ctx.runfiles(files = all_srcs + toolchain.dotnetinfo.runtime_files), ) diff --git a/nuget/templates/push.py b/nuget/templates/push.py index 74fb21c..e338559 100644 --- a/nuget/templates/push.py +++ b/nuget/templates/push.py @@ -65,7 +65,7 @@ def files_in(path_to_parent): yield os.path.join(path_to_parent,fname) print("Subdirs and files of the current dir:") -for file in set(files_in(os.path.join(path, "../../"))): +for file in set(files_in(path)): print(file) subprocess.check_call(args) From 6888571f433ff4e91bb6296bd632c7abb706bdd2 Mon Sep 17 00:00:00 2001 From: Georgii Date: Thu, 4 Apr 2024 11:42:03 +0100 Subject: [PATCH 20/20] Remove prints --- nuget/rules.bzl | 3 --- nuget/templates/push.py | 14 -------------- 2 files changed, 17 deletions(-) diff --git a/nuget/rules.bzl b/nuget/rules.bzl index 8d91ce1..c94176a 100644 --- a/nuget/rules.bzl +++ b/nuget/rules.bzl @@ -299,9 +299,6 @@ def _nuget_push_impl(ctx): is_executable = True, ) - print("DOTNETPATH: {}".format(ctx.expand_location(dotnet_runtime.path))) - print("PUSHFILE: {}".format(push_file.path)) - return DefaultInfo( executable = push_file, runfiles = ctx.runfiles(files = all_srcs + toolchain.dotnetinfo.runtime_files), diff --git a/nuget/templates/push.py b/nuget/templates/push.py index e338559..07de561 100644 --- a/nuget/templates/push.py +++ b/nuget/templates/push.py @@ -53,20 +53,6 @@ def unpack_args(_, arg1): ] print(f"Executing nuget push for {nupkg_paths}...") -print(f"Runtime information:\n Dotnet path: {dotnet_runtime_path}") -path = os.path.dirname(os.path.realpath(__file__)) -print(f"Current path: {path}") -def files_in(path_to_parent): - for fname in os.listdir(path_to_parent): - subpath = os.path.join(path_to_parent,fname) - if os.path.isdir(subpath): - for file in files_in(subpath): - yield file - yield os.path.join(path_to_parent,fname) - -print("Subdirs and files of the current dir:") -for file in set(files_in(path)): - print(file) subprocess.check_call(args)