Show one option for end-to-end usage
diff --git a/examples/poetry/BUILD.bazel b/examples/poetry/BUILD.bazel new file mode 100644 index 0000000..3ecdbe4 --- /dev/null +++ b/examples/poetry/BUILD.bazel
@@ -0,0 +1,53 @@ +load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") +load("@aspect_bazel_lib//lib:run_binary.bzl", "run_binary") +load("@aspect_bazel_lib//lib:write_source_files.bzl", "write_source_file") +load("@pypi//:requirements.bzl", "requirement") +load("@rules_python//python:defs.bzl", "py_binary") + +# METHOD 1 (see README.md) +# run `poetry export` as an action and write_source_files back to src +# BUT how to get the ones for other platforms updated?? +# +copy_to_bin( + name = "copy_poetry_inputs", + srcs = [ + "poetry.lock", + "pyproject.toml", + ], +) + +run_binary( + name = "poetry_export", + srcs = [":copy_poetry_inputs"], + outs = ["requirements.txt"], + args = [ + "export", + "--directory", + "$(RULEDIR)", + "--output", + "$(location requirements.txt)", + ], + tool = "@poetry_poetry//:bin", +) + +[ + write_source_file( + name = "vendor_{}_requirements".format(os), + in_file = ":requirements.txt", + out_file = "requirements_{}.txt".format(os), + target_compatible_with = ["@platforms//os:" + os], + ) + for os in [ + "macos", + "linux", + "windows", + ] +] + +# Prove that it worked + +py_binary( + name = "main", + srcs = ["main.py"], + deps = [requirement("pendulum")], +)
diff --git a/examples/poetry/README.md b/examples/poetry/README.md index 2a62d01..7325077 100644 --- a/examples/poetry/README.md +++ b/examples/poetry/README.md
@@ -35,4 +35,7 @@ To illustrate the translation, you can `bazel run @poetry_poetry//:bin export` to write a `requirements.txt` file to stdout. This is what we do internally. -TODO: write a `poetry_export` repository rule around it? +TODO: figure out the workflow: + +1. vendor the requirements.txt files into the repo, nice because it avoids work in a repo rule, but reintroduces the problem of having to write the macos file on macos, etc. We want it to be based on the host platform automatically? +2. write a `poetry_export` repository rule around it, but how to execute a py_binary from a repo rule? See /poetry/defs.bzl
diff --git a/examples/poetry/WORKSPACE.bazel b/examples/poetry/WORKSPACE.bazel index 221e54c..a6bac24 100644 --- a/examples/poetry/WORKSPACE.bazel +++ b/examples/poetry/WORKSPACE.bazel
@@ -4,6 +4,13 @@ name = "rules_python", path = "../..", ) +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +http_archive( + name = "aspect_bazel_lib", + sha256 = "e3151d87910f69cf1fc88755392d7c878034a69d6499b287bcfc00b1cf9bb415", + strip_prefix = "bazel-lib-1.32.1", + url = "https://github.com/aspect-build/bazel-lib/releases/download/v1.32.1/bazel-lib-v1.32.1.tar.gz", +) load("@rules_python//python:repositories.bzl", "py_repositories", "python_register_toolchains") @@ -27,22 +34,32 @@ python_interpreter_target = interpreter, ) +load("@rules_python//python:pip.bzl", "pip_parse") -# TODO: +# METHOD 1 (see README.md) + +# load("@rules_python//poetry:defs.bzl", "poetry_export") +# # poetry_export( # name = "poetry_deps", -# lockfile=poetry.lock -#) - -# load("@rules_python//python:pip.bzl", "pip_parse") +# lockfile = "//:poetry.lock", +# ) +# # pip_parse( -# name = "pip", -# requirements_txt = "@poetry_deps//:requirements.txt", +# name = "pypi", +# requirements_lock = "@poetry_deps//:requirements.txt", # ) -# OR MAYBE syntax sugar, as pip parse could parse more formats? +# METHOD 2 (see README.md) -# pip_parse( -# name = "pip", -# poetry_lock = "poetry.lock", -# ) +pip_parse( + name = "pypi", + requirements_darwin = "//:requirements_macos.txt", + requirements_linux = "//:requirements_linux.txt", + requirements_lock = "//:requirements_linux.txt", + requirements_windows = "//:requirements_windows.txt", +) + +load("@pypi//:requirements.bzl", "install_deps") + +install_deps(python_interpreter_target = interpreter) \ No newline at end of file
diff --git a/examples/poetry/main.py b/examples/poetry/main.py new file mode 100644 index 0000000..246dd99 --- /dev/null +++ b/examples/poetry/main.py
@@ -0,0 +1,14 @@ +import pendulum + +now = pendulum.now("Europe/Paris") + +# Changing timezone +now.in_timezone("America/Toronto") + +# Default support for common datetime formats +now.to_iso8601_string() + +# Shifting +now.add(days=2) + +print(now)
diff --git a/examples/poetry/requirements_linux.txt b/examples/poetry/requirements_linux.txt new file mode 100644 index 0000000..b59907d --- /dev/null +++ b/examples/poetry/requirements_linux.txt
@@ -0,0 +1,31 @@ +pendulum==2.1.2 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394 \ + --hash=sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b \ + --hash=sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a \ + --hash=sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087 \ + --hash=sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739 \ + --hash=sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269 \ + --hash=sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0 \ + --hash=sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5 \ + --hash=sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be \ + --hash=sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7 \ + --hash=sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3 \ + --hash=sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207 \ + --hash=sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe \ + --hash=sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360 \ + --hash=sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0 \ + --hash=sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b \ + --hash=sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052 \ + --hash=sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002 \ + --hash=sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116 \ + --hash=sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db \ + --hash=sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b +python-dateutil==2.8.2 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \ + --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9 +pytzdata==2020.1 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540 \ + --hash=sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f +six==1.16.0 ; python_version >= "3.10" and python_version < "4.0" \ + --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ + --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
diff --git a/examples/poetry/requirements_macos.txt b/examples/poetry/requirements_macos.txt new file mode 100644 index 0000000..6fe8fd6 --- /dev/null +++ b/examples/poetry/requirements_macos.txt
@@ -0,0 +1 @@ +¯\_(ツ)_/¯ \ No newline at end of file
diff --git a/examples/poetry/requirements_windows.txt b/examples/poetry/requirements_windows.txt new file mode 100644 index 0000000..6fe8fd6 --- /dev/null +++ b/examples/poetry/requirements_windows.txt
@@ -0,0 +1 @@ +¯\_(ツ)_/¯ \ No newline at end of file
diff --git a/poetry/defs.bzl b/poetry/defs.bzl new file mode 100644 index 0000000..e672011 --- /dev/null +++ b/poetry/defs.bzl
@@ -0,0 +1,32 @@ +"""Repository rule that can export a poetry.lock to a requirements.txt for the host platform + +(or the exec platform, if you're using RBE-hosted repo rule execution?) +""" + +def _poetry_export_impl(rctx): + # FIXME: this doesn't work!! + bin = rctx.path(rctx.attr.poetry_bin) + cmd = [bin, "export"] + + for group in rctx.attr.groups: + cmd.append("--with=" + group) + + result = rctx.execute( + cmd, + working_directory = str(rctx.path(rctx.attr.lockfile).dirname), + ) + + if result.return_code != 0: + fail("Failed to execute poetry. Error: ", result.stderr) + + rctx.file("requirements_lock.txt", result.stdout) + rctx.file("BUILD", "# no targets") + +poetry_export = repository_rule( + implementation = _poetry_export_impl, + attrs = { + "groups": attr.string_list(default = ["dev"]), + "lockfile": attr.label(allow_single_file = [".lock"], mandatory = True), + "poetry_bin": attr.label(default = "@poetry_poetry//:bin"), + }, +)