Open Place1 opened 1 year ago
I've been meaning to add support for this at some point and I wanted to follow a similar approach to how rules_js does this. The docs for rules_js can be seen here: https://github.com/aspect-build/rules_js/tree/main/docs#using-binaries-published-to-npm
I haven't had the time to look at the implementation in rules_js yet so I haven't really fleshed out any details though. If you are interested in contributing this then I would recommend looking into how rules_js does this.
Yeah that'd be great. I'm not skilled enough with bazel to figure it out unfortunately.
I think support for dotnet-tools alongside some support for generating a csproj for IDE intellisense (seperate topic) is all that's missing from rules_dotnet for my team to adopt it.
Hi, I would also really like to see this. The build system I'm working on at work requires running a .NET tool on the project before it can be built. Right now I'm trying to hackily implement it just to get it work for our particular case, using the package repository directly (@foo.bar.v1.2.3//:tools/net8.0/any/Foo.Bar.dll
), but would love to see a proper implementation.
I will share my hacky work-around to run Fantomas (F# format checker) as a Bazel test:
in WORKSPACE
:
http_archive(
name = "fantomas",
type = "zip",
sha256 = "ddb7c3dd40d7b8892a2c16f0ac79a7b2bd1edd22099c356725a9cc92547ab188",
urls = [ "https://www.nuget.org/api/v2/package/fantomas/5.0.0-beta-010" ],
build_file = "@//:BUILD.fantomas",
)
BUILD.fantomas
:
filegroup(
name = "srcs",
srcs = glob([ "**/*" ]),
visibility = [ "//visibility:public" ],
)
fantomas.bzl
:
def fantomas_check(name, editor_config, srcs, size = None):
check = [
native.package_name() + "/" + x for x in srcs
]
native.sh_test(
name = name,
srcs = [ "@//:fantomas.sh" ],
args = [
"--check",
] + check,
data = srcs + [
editor_config,
"//:fantomas",
],
size = size,
)
return name
fantomas.sh
:
#!/bin/bash
set -e
export HOME=$(mktemp -d || mktemp -d -t bazel-tmp)
trap "rm -rf $HOME" EXIT
export DOTNET_NOLOGO=1
export DOTNET_SKIP_FIRST_RUN_EXPERIENCE=1
export DOTNET_CLI_TELEMETRY_OPTOUT=1
EXEC_ROOT=$(pwd)
if test "${BUILD_WORKING_DIRECTORY+x}"; then
cd $BUILD_WORKING_DIRECTORY
fi
dotnet $EXEC_ROOT/external/fantomas/tools/net6.0/any/fantomas.dll ${@:1}
Usage:
load("//:fantomas.bzl", "fantomas_check")
fantomas_check(
name = "fantomas",
editor_config = "//:.editorconfig",
srcs = glob([
"*.fs",
]),
)
Note this uses the system dotnet
so it's not truly hermetic. If anyone knows how to wire up the rules_dotnet
toolchain, that would be a great improvement!
The way I'm currently hooking up the rules_dotnet
toolchain is doing it the way rules_dotnet
does it internally, i.e. creating a new rule and consuming @rules_dotnet//dotnet:toolchain_type
. The toolchain will have toolchain.dotnetinfo.runtime
, which is the dotnet
command you can execute. Then I just feed that into a ctx.actions.run
with the manual assembly path I set up. Obviously more work than your solution, but allows me to not have to put dotnet
on the CI machine.
we implemented tool support by getting the dotnet binary out of the DotnetInfo provider of the toolchain and essentially doing a dotnet tool install ...
. we use the --tool-path argument for dotnet to create a local installation, the tool can be executed as long as there are some specific dotnet env variable set
this is a rule doing that:
def _dotnet_tool_binary_impl(ctx):
info = ctx.attr._toolchain[DotnetInfo]
dotnet_bin = info.runtime_path
out_log = ctx.actions.declare_file(ctx.attr.name + ".log")
out_store = ctx.actions.declare_directory(ctx.attr.name + "/.store")
out_exec = ctx.actions.declare_file(ctx.attr.name + "/" + ctx.attr.tool_exec_name)
out_run_exec = ctx.actions.declare_file(ctx.attr.name + "/run.sh")
# See https://github.com/dotnet/sdk/issues/27761
arch = ""
if ctx.attr.is_darwin_arm64:
arch = "--arch arm64 "
install_cmd_parts = [
"ROOTDIR=$(pwd)",
"cd $(dirname {output})",
"DOTNET_CLI_HOME=\"$ROOTDIR/$(dirname {dotnet_bin})\" \"$ROOTDIR/{dotnet_bin}\" tool install {package} {arch} --tool-path {tool_path} > $(basename {output})",
]
install_cmd = ";".join(install_cmd_parts).format(
dotnet_bin = dotnet_bin,
package = ctx.attr.tool_install_name,
arch = arch,
tool_path = ctx.attr.name,
output = out_log.path,
)
ctx.actions.run_shell(
outputs = [out_log, out_store, out_exec],
command = install_cmd,
tools = info.runtime_files,
toolchain = "@rules_dotnet//dotnet:resolved_toolchain",
use_default_shell_env = True,
)
run_script = """#!/bin/bash
DOTNETBIN=$(readlink \"{dotnet}\")
cd $BUILD_WORKSPACE_DIRECTORY
DOTNET_ROOT=$(dirname $DOTNETBIN) {tool_bin} "$@"
"""
run_script = run_script.format(
dotnet = dotnet_bin,
tool_bin = out_exec.path,
)
ctx.actions.write(
output = out_run_exec,
content = run_script,
)
runfiles = ctx.runfiles(files = info.runtime_files + [out_exec, out_log, out_store])
return [DefaultInfo(executable = out_run_exec, runfiles = runfiles, files = depset([out_exec, out_log, out_store]))]
_dotnet_tool_binary = rule(
implementation = _dotnet_tool_binary_impl,
executable = True,
attrs = {
"tool_exec_name": attr.string(),
"tool_install_name": attr.string(),
"is_darwin_arm64": attr.bool(mandatory = True),
"_toolchain": attr.label(default = "@rules_dotnet//dotnet:resolved_toolchain"),
},
)```
Cool solution, and very close to mine! The only difference for me was using the paket2bazel
output for downloading the Nuget archive. That has its own downsides for the time being, of course.
I'd like to try and use rules_dotnet for an aspnetcore app that uses entity framework.
I can get the project to build but I'll need to be able to use the
dotnet-ef
cli tool for creating migrations.Here's the command I need run; is it possible to create a
bazel run
target for this?I was thinking to create a
sh_binary
target that depends on:@dotnet_toolchains//:resolved_toolchain
for thedotnet
executable:myapp
which would be acsharp_library
to get the built assembly, deps.json and runtimeconfig.json files.@deps//dotnet-ef
for theexternal/nuget.dotnet-ef.v7.0.2/tools/net6.0/any/tools/netcoreapp2.0/any/ef.dll
--additionalprobingpath
flag which needs to point to the nuget packages used by the assembly (I think it just looks forMicrosoft.EntityFrameworkCore.Design
).Currently I found that the
nuget_archive
rule doesn't expose any of the nuget package'stools/
folder so I can't access theef.dll
.I also found that the
:resolved_toolchain
target didn't expose the dotnet runtime files which I submitted a PR for here: https://github.com/bazelbuild/rules_dotnet/pull/336 (this fixed allows me to usedotnet exec
)Does anyone know how to proceed here? I'm also wondering if anyone else uses rules_dotnet with any dotnet-tools today?