|
| 1 | +load( |
| 2 | + "@io_bazel_rules_dotnet//dotnet/private:context.bzl", |
| 3 | + "dotnet_context", |
| 4 | +) |
| 5 | +load( |
| 6 | + "@io_bazel_rules_dotnet//dotnet/private:providers.bzl", |
| 7 | + "DotnetLibrary", |
| 8 | + "DotnetResource", |
| 9 | +) |
| 10 | + |
| 11 | +TEST_RUNNER_SCRIPT_CONTENT = """{script_prefix} |
| 12 | +{runner} {test} --result={result_location};transform={xslt} {additional_args} |
| 13 | +""" |
| 14 | + |
| 15 | +def _is_windows(): |
| 16 | + return select({ |
| 17 | + "@bazel_tools//src/conditions:windows": True, |
| 18 | + "//conditions:default": False, |
| 19 | + }) |
| 20 | + |
| 21 | +def _convert_path(input_path, is_windows = False): |
| 22 | + if (is_windows): |
| 23 | + return input_path.replace("/", "\\") |
| 24 | + return input_path |
| 25 | + |
| 26 | +def _nunit_test_impl(ctx): |
| 27 | + dotnet = dotnet_context(ctx) |
| 28 | + name = ctx.label.name |
| 29 | + |
| 30 | + test_assembly = dotnet.assembly( |
| 31 | + dotnet, |
| 32 | + name = ctx.label.name, |
| 33 | + srcs = ctx.attr.srcs, |
| 34 | + deps = ctx.attr.deps, |
| 35 | + resources = ctx.attr.resources, |
| 36 | + out = ctx.attr.out, |
| 37 | + defines = ctx.attr.defines, |
| 38 | + unsafe = ctx.attr.unsafe, |
| 39 | + data = ctx.attr.data, |
| 40 | + executable = False, |
| 41 | + keyfile = ctx.attr.keyfile, |
| 42 | + ) |
| 43 | + |
| 44 | + args = [test_assembly.result.path] + ctx.attr.args |
| 45 | + |
| 46 | + file_inputs = [test_assembly.result] |
| 47 | + for dep in ctx.attr.deps: |
| 48 | + src_file = dep.files.to_list()[0] |
| 49 | + dest_file = ctx.actions.declare_file(src_file.basename) |
| 50 | + file_inputs.append(dest_file) |
| 51 | + ctx.actions.run( |
| 52 | + outputs = [dest_file], |
| 53 | + inputs = [src_file], |
| 54 | + executable = ctx.attr._copy.files.to_list()[0], |
| 55 | + arguments = [dest_file.path, src_file.path], |
| 56 | + mnemonic = "CopyDependencyAssembly", |
| 57 | + ) |
| 58 | + |
| 59 | + runner_executable = None |
| 60 | + for runner_file in ctx.attr.test_runner.files.to_list(): |
| 61 | + dest_runner_file = ctx.actions.declare_file("runner/" + runner_file.basename) |
| 62 | + file_inputs.append(dest_runner_file) |
| 63 | + if runner_file.basename == "nunit3-console.exe": |
| 64 | + runner_executable = dest_runner_file |
| 65 | + |
| 66 | + ctx.actions.run( |
| 67 | + outputs = [dest_runner_file], |
| 68 | + inputs = [runner_file], |
| 69 | + executable = ctx.attr._copy.files.to_list()[0], |
| 70 | + arguments = [dest_runner_file.path, runner_file.path], |
| 71 | + mnemonic = "CopyTestRunner", |
| 72 | + ) |
| 73 | + |
| 74 | + # Determining platform isn't available during the analysis phase, |
| 75 | + # so there's no opportunity to give the script file a proper extention. |
| 76 | + # Luckily, as long as the file is marked with the executable attribute |
| 77 | + # in the OS, there's nothing preventing a file named '.bat' being a |
| 78 | + # valid executable shell script on non-Windows OSes. If this changes, |
| 79 | + # this comment can be removed, and the below line changed to give the |
| 80 | + # generated script file a proper extension of '.sh'. |
| 81 | + script_file_extension = "bat" |
| 82 | + additional_args = "$@" |
| 83 | + result_location = "$XML_OUTPUT_FILE" |
| 84 | + script_prefix = "#!/bin/bash" |
| 85 | + is_windows = _is_windows() |
| 86 | + if (is_windows): |
| 87 | + script_file_extension = "bat" |
| 88 | + additional_args = "%*" |
| 89 | + result_location = "%XML_OUTPUT_FILE%" |
| 90 | + script_prefix = "@echo off" |
| 91 | + |
| 92 | + script_file_name = "{}.{}".format(name, script_file_extension) |
| 93 | + script_file = ctx.actions.declare_file(script_file_name) |
| 94 | + script_content = TEST_RUNNER_SCRIPT_CONTENT.format( |
| 95 | + script_prefix = script_prefix, |
| 96 | + runner = _convert_path(runner_executable.path, is_windows), |
| 97 | + test = _convert_path(test_assembly.result.path, is_windows), |
| 98 | + result_location = result_location, |
| 99 | + xslt = _convert_path(ctx.attr._xslt.files.to_list()[0].path, is_windows), |
| 100 | + additional_args = additional_args, |
| 101 | + ) |
| 102 | + |
| 103 | + ctx.actions.write(script_file, script_content, True) |
| 104 | + |
| 105 | + extra = [] if ctx.attr.data == None else [d.files for d in ctx.attr.data] |
| 106 | + runfiles = ctx.runfiles( |
| 107 | + files = file_inputs, |
| 108 | + transitive_files = depset(transitive = [d[DotnetLibrary].runfiles for d in ctx.attr.deps] + extra), |
| 109 | + ) |
| 110 | + |
| 111 | + info = DefaultInfo( |
| 112 | + files = depset([test_assembly.result, runner_executable, script_file]), |
| 113 | + runfiles = runfiles, |
| 114 | + executable = script_file, |
| 115 | + ) |
| 116 | + |
| 117 | + return [ |
| 118 | + info, |
| 119 | + test_assembly, |
| 120 | + ] |
| 121 | + |
| 122 | +nunit_test = rule( |
| 123 | + implementation = _nunit_test_impl, |
| 124 | + attrs = { |
| 125 | + "deps": attr.label_list(providers = [DotnetLibrary]), |
| 126 | + "resources": attr.label_list(providers = [DotnetResource]), |
| 127 | + "srcs": attr.label_list(allow_files = [".cs"]), |
| 128 | + "out": attr.string(), |
| 129 | + "defines": attr.string_list(), |
| 130 | + "unsafe": attr.bool(default = False), |
| 131 | + "keyfile": attr.label(allow_files = True), |
| 132 | + "data": attr.label_list(allow_files = True), |
| 133 | + "dotnet_context_data": attr.label(default = Label("@io_bazel_rules_dotnet//:dotnet_context_data")), |
| 134 | + "test_runner": attr.label( |
| 135 | + default = Label("//third_party/dotnet/nunit.console-3.10.0/bin/net35:nunitconsole"), |
| 136 | + allow_files = True |
| 137 | + ), |
| 138 | + "_copy": attr.label(default = Label("@io_bazel_rules_dotnet//dotnet/tools/copy")), |
| 139 | + "_xslt": attr.label(default = Label("@io_bazel_rules_dotnet//tools/converttests:n3.xslt"), allow_files = True), |
| 140 | + }, |
| 141 | + toolchains = ["@io_bazel_rules_dotnet//dotnet:toolchain_net"], |
| 142 | + test = True, |
| 143 | +) |
0 commit comments