Fixed unsound issue in wheel examples
diff --git a/examples/wheel/BUILD b/examples/wheel/BUILD index f745dc3..28268b5 100644 --- a/examples/wheel/BUILD +++ b/examples/wheel/BUILD
@@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +load("//examples/wheel/private:wheel_utils.bzl", "directory_writer") load("//python:defs.bzl", "py_library", "py_test") load("//python:packaging.bzl", "py_package", "py_wheel") load("//python:versions.bzl", "gen_python_config_settings") @@ -40,10 +41,10 @@ ], ) -genrule( +directory_writer( name = "gen_dir", - outs = ["someDir"], - cmd = "mkdir -p $@ && touch $@/foo.py", + out = "someDir", + files = {"foo.py": ""}, ) # Package just a specific py_libraries, without their dependencies @@ -188,8 +189,8 @@ ) py_wheel( - name = "use_genrule_with_dir_in_outs", - distribution = "use_genrule_with_dir_in_outs", + name = "use_rule_with_dir_in_outs", + distribution = "use_rule_with_dir_in_outs", python_tag = "py3", version = "0.0.1", deps = [ @@ -240,6 +241,6 @@ ":minimal_with_py_package", ":python_abi3_binary_wheel", ":python_requires_in_a_package", - ":use_genrule_with_dir_in_outs", + ":use_rule_with_dir_in_outs", ], )
diff --git a/examples/wheel/private/BUILD b/examples/wheel/private/BUILD new file mode 100644 index 0000000..3462d35 --- /dev/null +++ b/examples/wheel/private/BUILD
@@ -0,0 +1,7 @@ +load("@rules_python//python:defs.bzl", "py_binary") + +py_binary( + name = "directory_writer", + srcs = ["directory_writer.py"], + visibility = ["//:__subpackages__"], +)
diff --git a/examples/wheel/private/directory_writer.py b/examples/wheel/private/directory_writer.py new file mode 100644 index 0000000..dd604c6 --- /dev/null +++ b/examples/wheel/private/directory_writer.py
@@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +"""The action executable of the `@rules_python//examples/wheel/private:wheel_utils.bzl%directory_writer` rule.""" + +import argparse +import json +from pathlib import Path +from typing import Tuple + + +def _file_input(value) -> Tuple[Path, str]: + path, content = value.split("=", maxsplit=1) + return (Path(path), json.loads(content)) + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + + parser.add_argument( + "--output", type=Path, required=True, help="The output directory to create." + ) + parser.add_argument( + "--file", + dest="files", + type=_file_input, + action="append", + help="Files to create within the `output` directory.", + ) + + return parser.parse_args() + + +def main() -> None: + args = parse_args() + + args.output.mkdir(parents=True, exist_ok=True) + + for (path, content) in args.files: + new_file = args.output / path + new_file.parent.mkdir(parents=True, exist_ok=True) + new_file.write_text(content) + + +if __name__ == "__main__": + main()
diff --git a/examples/wheel/private/wheel_utils.bzl b/examples/wheel/private/wheel_utils.bzl new file mode 100644 index 0000000..25ef9b4 --- /dev/null +++ b/examples/wheel/private/wheel_utils.bzl
@@ -0,0 +1,42 @@ +"""Helper rules for demonstrating `py_wheel` examples""" + +def _directory_writer_impl(ctx): + output = ctx.actions.declare_directory(ctx.attr.out) + + args = ctx.actions.args() + args.add("--output", output.path) + + for path, content in ctx.attr.files.items(): + args.add("--file={}={}".format( + path, + json.encode(content), + )) + + ctx.actions.run( + outputs = [output], + arguments = [args], + executable = ctx.executable._writer, + ) + + return [DefaultInfo( + files = depset([output]), + runfiles = ctx.runfiles(files = [output]), + )] + +directory_writer = rule( + implementation = _directory_writer_impl, + doc = "A rule for generating a directory with the requested content.", + attrs = { + "files": attr.string_dict( + doc = "A mapping of file name to content to create relative to the generated `out` directory.", + ), + "out": attr.string( + doc = "The name of the directory to create", + ), + "_writer": attr.label( + executable = True, + cfg = "exec", + default = Label("//examples/wheel/private:directory_writer"), + ), + }, +)