diff --git a/.bazelrc b/.bazelrc index 78a0c5f3f8a0df33f2363ce00b2c91e56a5e2cd9..290ce56fcd624c5736f14d5c5b8f6c5735f80eb9 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,7 +1,7 @@ # Use pre-release registry. Remove when available in BCR common --registry https://bcr.bazel.build -common --registry=https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads -common --registry=https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads +common --registry=https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads +common --registry=https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.1/downloads # Enable hermetic `rules_python` common --@rules_python//python/config_settings:bootstrap_impl=script diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b9d0edff77930f81f8a04ea30a9700c72fc70801..955dc75601f6d4ea8018ca98697276e83e5ba8e7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,10 @@ include: - component: "${CI_SERVER_HOST}/ci/component/bazelisk/ruleset@v1.2.0" inputs: + oses: + - linux + - windows + - macos versions: - 7.4.0 - 7.x @@ -10,3 +14,4 @@ include: default: tags: - arm64 + - linux diff --git a/MODULE.bazel b/MODULE.bazel index 6e899cb66f8aab6ca0bc9e1bfbb615976b90d1c1..a9031fc515b77ce825f96284f998dd8ec5ce702a 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -7,8 +7,8 @@ module( bazel_dep(name = "bazel_skylib", version = "1.7.1") bazel_dep(name = "platforms", version = "0.0.10") -bazel_dep(name = "toolchain_utils", version = "1.0.1") -bazel_dep(name = "download_utils", version = "1.0.0") +bazel_dep(name = "toolchain_utils", version = "1.0.2") +bazel_dep(name = "download_utils", version = "1.0.1") bazel_dep(name = "rules_license", version = "1.0.0") bazel_dep(name = "rules_python", version = "1.0.0") @@ -57,6 +57,9 @@ download_file( executable = False, integrity = "sha256-eK954gq7s/malzVZWbWb1YlJVkBkrbdU8DAuurtL96M=", output = "ape-m1.c", + patches = [ + "//:ape-m1.patch", + ], urls = [ "https://gitlab.arm.com/api/v4/projects/bazel%2Fape/packages/generic/cosmos.zip/4.0.2/ape-m1.c", "https://raw.githubusercontent.com/jart/cosmopolitan/4.0.2/ape/ape-m1.c", @@ -68,13 +71,23 @@ compile = use_repo_rule("//ape/compile:repository.bzl", "compile") compile( name = "ape-arm64.macho", srcs = ["@ape-m1.c"], - output = "ape", + links = { + "entrypoint": "binary", + }, + output = "binary", + target = "{cpu}-macos-none", zig = "@zig//:entrypoint", ) pe = use_repo_rule("//ape/pe:repository.bzl", "pe") -pe(name = "ape.pe") +pe( + name = "ape.pe", + links = { + "entrypoint": "binary", + }, + output = "binary", +) select( name = "launcher", diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 47ef20620818fe613dd371e26b534f3060523b3e..3b47ba49b223ab0717eee5d70af82b592fe6696c 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -35,7 +35,7 @@ "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/source.json": "f121b43eeefc7c29efbd51b83d08631e2347297c95aac9764a701f2a6a2bb953", "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84", "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8", - "https://bcr.bazel.build/modules/download_utils/1.0.0/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/download_utils/1.0.1/MODULE.bazel": "not found", "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", @@ -135,19 +135,19 @@ "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7", "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", - "https://bcr.bazel.build/modules/toolchain_utils/1.0.1/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/toolchain_utils/1.0.2/MODULE.bazel": "not found", "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79", "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/source.json": "2be409ac3c7601245958cd4fcdff4288be79ed23bd690b4b951f500d54ee6e7d", "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198", - "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/bazel_registry.json": "not found", - "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/modules/download_utils/1.0.0/MODULE.bazel": "d4715447bb11903353fdc2483b7d7b13c9872d39fb8b852c2510665ca6eee22c", - "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/modules/download_utils/1.0.0/source.json": "653b08947e894656b6d515992fd55272cdc9456a1bd26bdfbd4c523acaa21be2", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads/bazel_registry.json": "not found", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads/modules/download_utils/1.0.0/MODULE.bazel": "not found", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads/modules/toolchain_utils/1.0.1/MODULE.bazel": "e490baaaa201408bcb3757f3827f1d9f096fad10af26a12c74897a5550246110", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads/modules/toolchain_utils/1.0.1/source.json": "afe923f3f5f0b93ba3928ee5150065103418eae05757846595840e5bb9a1a400" + "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.1/downloads/bazel_registry.json": "not found", + "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.1/downloads/modules/download_utils/1.0.1/MODULE.bazel": "f1d0afade59e37de978506d6bbf08d7fe5f94964e86944aaf58efcead827b41b", + "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.1/downloads/modules/download_utils/1.0.1/source.json": "9f871ab1f82c8867c19e0224dc411288ababb578fe5c67d7e4a54fb6968d6ba1", + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/bazel_registry.json": "not found", + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/download_utils/1.0.1/MODULE.bazel": "not found", + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/toolchain_utils/1.0.2/MODULE.bazel": "9b8be503a4fcfd3b8b952525bff0869177a5234d5c35dc3e566b9f5ca2f755a1", + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/toolchain_utils/1.0.2/source.json": "f70c533c9f1c9e27d4f6be8e985dbd2e9ddfe50b59953ff02c38568b3fa16729" }, "selectedYankedVersions": {}, "moduleExtensions": { diff --git a/ape-m1.patch b/ape-m1.patch new file mode 100644 index 0000000000000000000000000000000000000000..a73435e3da09c1759fe1b283dacfca8c89512d65 --- /dev/null +++ b/ape-m1.patch @@ -0,0 +1,97 @@ +--- a/ape-m1.c 2025-02-10 16:59:25 ++++ b/ape-m1.c 2025-02-11 13:48:53 +@@ -325,6 +325,66 @@ + return tail - arg0; + } + return 0; ++} ++ ++static ssize_t WalkToIndirect(const char *restrict path, char *restrict const buf, size_t bufsiz) { ++ char linkname[MAXPATHLEN + 1], a[MAXPATHLEN + 1], b[MAXPATHLEN + 1]; ++ size_t s; ++ ssize_t ss; ++ const char *filepath = path; ++ char *p, *buffer = a; ++ a[0] = '\0'; ++ b[0] = '\0'; ++ do { ++ s = readlink(filepath, linkname, sizeof(linkname)); ++ if (s == -1) { ++ if (errno != EINVAL) ++ return -errno; ++ ++ filepath = filepath == a ? b : a; ++ ++ if (filepath[0] == '\0') ++ return 0; ++ ++ s = StrLen(filepath); ++ if (s >= bufsiz) ++ return s + 1; ++ ++ if(strlcpy(buf, filepath, bufsiz) >= bufsiz) ++ return -EOVERFLOW; ++ ++ return 0; ++ } ++ linkname[s] = '\0'; ++ ++ if (linkname[0] == '/') { ++ if (strlcpy(buffer, linkname, sizeof(a)) >= sizeof(a)) ++ return -EOVERFLOW; ++ goto flip; ++ } ++ ++ s = strlcpy(buffer, filepath, sizeof(a)); ++ if (s >= sizeof(a)) ++ return -EOVERFLOW; ++ ++ for (p = &buffer[s]; p != buffer; --p) { ++ if (*p == '/') { ++ *(++p) = '\0'; ++ break; ++ } ++ } ++ ++ if (strlcat(buffer, linkname, sizeof(a)) >= sizeof(a)) ++ return -EOVERFLOW; ++ ++flip: ++ filepath = buffer; ++ buffer = buffer == a ? b : a; ++ } while (true); ++ ++ return -ENOSYS; + } + + static void Perror(const char *thing, long rc, const char *reason) { +@@ -941,7 +997,8 @@ + struct ApeLoader *M; + long *sp, *sp2, *auxv; + union ElfEhdrBuf *ebuf; +- char *p, *pe, *exe, *prog, *execfn; ++ char *p, *pe, *exe, *prog, *execfn, *buffer; ++ ssize_t s; + + /* allocate loader memory in program's arg block */ + n = sizeof(struct ApeLoader); +@@ -1019,6 +1076,19 @@ + execfn = prog; + } + ++ /* walk symlink chain to possible indirect */ ++ if ((s = WalkToIndirect(prog, prog, StrLen(prog) + 1))) { ++ if (s < 0) ++ Pexit(prog, s, "failed to walk symlinks"); ++ ++ buffer = __builtin_alloca(s); ++ ++ if ((s = WalkToIndirect(prog, buffer, s))) ++ Pexit(prog, s, "failed to perform allocated symlink walk"); ++ ++ prog = buffer; ++ } ++ + /* sneak the system five abi back out of args */ + sp = (long *)(argv - 1); + auxv = (long *)(envp + i + 1); diff --git a/ape/assimilate/rule.bzl b/ape/assimilate/rule.bzl index 3dd14a4713503e071123cc01d8e945b802895b8a..aea60c8a089d2f328a3fb2c4aa7598424d17f5e9 100644 --- a/ape/assimilate/rule.bzl +++ b/ape/assimilate/rule.bzl @@ -50,16 +50,12 @@ def implementation(ctx): if ctx.target_platform_has_constraint(windows) and not basename.endswith(".exe"): basename += ".exe" - executable = ctx.actions.declare_file("{}.ape/{}".format(ctx.label.name, basename)) - if ctx.target_platform_has_constraint(windows): - runfiles = _symlink(ctx, executable) + executable, files, runfiles = _direct(ctx, basename) elif ctx.target_platform_has_constraint(macos) and ctx.target_platform_has_constraint(arm64): - runfiles = _symlink(ctx, executable) + executable, files, runfiles = _indirect(ctx, basename) else: - runfiles = _assimilate(ctx, executable) - - files = depset([executable]) + executable, files, runfiles = _assimilate(ctx, basename) return DefaultInfo( executable = executable, @@ -67,7 +63,8 @@ def implementation(ctx): runfiles = runfiles, ) -def _assimilate(ctx, executable): +def _assimilate(ctx, basename): + executable = ctx.actions.declare_file("{}/{}".format(ctx.label.name, basename)) ape = ctx.toolchains["//ape/toolchain/ape:type"] windows = ctx.attr._windows[platform_common.ConstraintValueInfo] @@ -81,9 +78,9 @@ def _assimilate(ctx, executable): # Executable format if ctx.target_platform_has_constraint(windows): - fail("Cannot assimilate on Windows, APE are already PE format. Symlink instead.") + fail("Cannot assimilate on Windows, APE are already PE format. Use direct symlink instead.") elif ctx.target_platform_has_constraint(macos) and ctx.target_platform_has_constraint(arm64): - fail("Cannot assimilate on Apple Silicon, assimilate binaries are not runnable without APE loader. Symlink instead.") + fail("Cannot assimilate on Apple Silicon, assimilate binaries are not runnable without APE loader. Use indirect symlink instead.") elif ctx.target_platform_has_constraint(macos): args.add("-m") # MachO else: @@ -112,19 +109,51 @@ def _assimilate(ctx, executable): toolchain = "//ape/toolchain/ape:type", ) - return ctx.runfiles([executable]) + files = depset([executable]) + runfiles = None + + return executable, files, runfiles + +def _direct(ctx, basename): + executable = ctx.actions.declare_file("{}/{}".format(ctx.label.name, basename)) -def _symlink(ctx, executable): ctx.actions.symlink( output = executable, target_file = ctx.file.src, is_executable = True, ) + files = depset([executable]) runfiles = ctx.runfiles([executable, ctx.file.src]) runfiles.merge(ctx.attr.src.default_runfiles) - return runfiles + return executable, files, runfiles + +def _indirect(ctx, basename): + indirect = ctx.actions.declare_file("{}/{}.ape".format(ctx.label.name, basename)) + ape = ctx.toolchains["//ape/toolchain/ape:type"] + + ctx.actions.symlink( + output = indirect, + target_file = ape.executable, + is_executable = True, + ) + + direct = ctx.actions.declare_file(basename, sibling = indirect) + + ctx.actions.symlink( + output = direct, + target_file = ctx.file.src, + is_executable = True, + ) + + files = depset([indirect, direct]) + + runfiles = ctx.runfiles([indirect, direct, ctx.file.src, ape.executable]) + runfiles.merge(ctx.attr.src.default_runfiles) + runfiles.merge(ape.default.default_runfiles) + + return indirect, files, runfiles ape_assimilate = rule( doc = DOC, diff --git a/ape/compile/BUILD.tmpl.bazel b/ape/compile/BUILD.tmpl.bazel index 74f43591031644f8aee5def5cf9b9eb1f06b0b90..b65b0ad510e406462e4a3c6582dfa58e87625d5e 100644 --- a/ape/compile/BUILD.tmpl.bazel +++ b/ape/compile/BUILD.tmpl.bazel @@ -1 +1 @@ -exports_files([{{output}}]) +exports_files({{exports}}) diff --git a/ape/compile/repository.bzl b/ape/compile/repository.bzl index dc9530ee0b8225979bf751e57fa9f40a3de25438..ea8ce19ddc6dd1365d03d9ab2f887761e6729626 100644 --- a/ape/compile/repository.bzl +++ b/ape/compile/repository.bzl @@ -1,3 +1,5 @@ +load("@toolchain_utils//toolchain/triplet:local.bzl", "TRIPLET") + visibility("//ape/...") DOC = """Performs repository time compilation of source files.""" @@ -13,10 +15,17 @@ ATTRS = { allow_files = [".c"], allow_empty = False, ), + "target": attr.string( + doc = "`zig` target triplet to build for. Can use `{cpu}`/`{os}`/`{libc}` replacements", + default = "{cpu}-{os}-{libc}", + ), "output": attr.string( doc = "The compiled output file.", mandatory = True, ), + "links": attr.string_dict( + doc = 'Creates links in the downloaded repository as `{" < target > ": " < link > "}`. Depending on the platform, either symbolic or hard links are created.', + ), "zig": attr.label( doc = "The `zig` compiler to use.", allow_single_file = True, @@ -27,20 +36,40 @@ ATTRS = { } def implementation(rctx): + map = { + "amd64": "x86_64", + "arm64": "aarch64", + } + + triplet = rctx.attr.target.format( + cpu = map.get(TRIPLET.cpu, TRIPLET.cpu), + os = TRIPLET.os.kind, + libc = TRIPLET.libc.kind, + ) + cmd = [ rctx.attr.zig, "cc", + "-target", + triplet, "-o", rctx.attr.output, ] cmd.extend(rctx.attr.srcs) + rctx.watch(rctx.attr.zig) + for src in rctx.attr.srcs: + rctx.watch(src) + result = rctx.execute(cmd) if result.return_code != 0: fail("Failed to compile: {}".format(result.stderr)) + for target, linkname in rctx.attr.links.items(): + rctx.symlink(linkname, target) + rctx.template("BUILD.bazel", rctx.attr.build, { - "{{output}}": repr(rctx.attr.output), + "{{exports}}": repr([rctx.attr.output] + rctx.attr.links.keys()), }) compile = repository_rule( diff --git a/ape/pe/repository.bzl b/ape/pe/repository.bzl index 05795ca0daf22bc364908912df4df4b877d1ed89..7b7a422eb79bd693c5670fdd11a228b0eabfdbcc 100644 --- a/ape/pe/repository.bzl +++ b/ape/pe/repository.bzl @@ -8,6 +8,13 @@ The repository is used to make the APE host select consistent. """ ATTRS = { + "output": attr.string( + doc = "The output file to create", + mandatory = True, + ), + "links": attr.string_dict( + doc = 'Creates links in the downloaded repository as `{" < target > ": " < link > "}`. Depending on the platform, either symbolic or hard links are created.', + ), "build": attr.label( doc = "The `BUILD.bazel` template.", allow_single_file = True, @@ -56,12 +63,12 @@ def implementation(rctx): if result.return_code != 0: fail("Failed to compile C# APE: {}".format(result.stdout)) - rctx.symlink("ape.exe", "ape") - rctx.symlink("ape.exe", "binary") - rctx.symlink("ape.exe", "entrypoint") + rctx.symlink("ape.exe", rctx.attr.output) + for target, linkname in rctx.attr.links.items(): + rctx.symlink(linkname, target) rctx.template("BUILD.bazel", rctx.attr.build, { - "{{exports}}": repr(["ape", "binary", "entrypoint"]), + "{{exports}}": repr([rctx.attr.output] + rctx.attr.links.keys()), }) pe = repository_rule( diff --git a/e2e/.bazelrc b/e2e/.bazelrc index 78a0c5f3f8a0df33f2363ce00b2c91e56a5e2cd9..290ce56fcd624c5736f14d5c5b8f6c5735f80eb9 100644 --- a/e2e/.bazelrc +++ b/e2e/.bazelrc @@ -1,7 +1,7 @@ # Use pre-release registry. Remove when available in BCR common --registry https://bcr.bazel.build -common --registry=https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads -common --registry=https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads +common --registry=https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads +common --registry=https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.1/downloads # Enable hermetic `rules_python` common --@rules_python//python/config_settings:bootstrap_impl=script diff --git a/e2e/MODULE.bazel b/e2e/MODULE.bazel index 596aa35d80fd4b4fde0d18cb208da381ea3828ab..ecfd0b16e39bcd9af88169b20767731c3445dd99 100644 --- a/e2e/MODULE.bazel +++ b/e2e/MODULE.bazel @@ -36,7 +36,7 @@ pip.parse( ) use_repo(pip, pytest = "ape-e2e-pytest") -bazel_dep(name = "toolchain_utils", version = "1.0.1") +bazel_dep(name = "toolchain_utils", version = "1.0.2") bazel_dep(name = "ape", version = "0.0.0") local_path_override( module_name = "ape", diff --git a/e2e/MODULE.bazel.lock b/e2e/MODULE.bazel.lock index 645727076702a8cd3e39908857964a8f8ee309f0..5308d037abe69933cd8ccc553e11383d20405d8e 100644 --- a/e2e/MODULE.bazel.lock +++ b/e2e/MODULE.bazel.lock @@ -40,7 +40,7 @@ "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8", "https://bcr.bazel.build/modules/caseyduquettesc_rules_python_pytest/1.1.1/MODULE.bazel": "6e5383ad5f0b4a28829f811683a3dd64a655209b9f6620a0fe68cd6321b7e174", "https://bcr.bazel.build/modules/caseyduquettesc_rules_python_pytest/1.1.1/source.json": "cfa8011e462d3f3eb42ea1ce6aa7f945b944d0499ffd6747789cd87dc64fe015", - "https://bcr.bazel.build/modules/download_utils/1.0.0/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/download_utils/1.0.1/MODULE.bazel": "not found", "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", @@ -152,20 +152,20 @@ "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7", "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", - "https://bcr.bazel.build/modules/toolchain_utils/1.0.1/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/toolchain_utils/1.0.2/MODULE.bazel": "not found", "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9", "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79", "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/source.json": "2be409ac3c7601245958cd4fcdff4288be79ed23bd690b4b951f500d54ee6e7d", "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198", - "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/bazel_registry.json": "not found", - "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/modules/download_utils/1.0.0/MODULE.bazel": "d4715447bb11903353fdc2483b7d7b13c9872d39fb8b852c2510665ca6eee22c", - "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.0/downloads/modules/download_utils/1.0.0/source.json": "653b08947e894656b6d515992fd55272cdc9456a1bd26bdfbd4c523acaa21be2", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads/bazel_registry.json": "not found", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads/modules/download_utils/1.0.0/MODULE.bazel": "not found", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads/modules/toolchain_utils/1.0.1/MODULE.bazel": "e490baaaa201408bcb3757f3827f1d9f096fad10af26a12c74897a5550246110", - "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.1/downloads/modules/toolchain_utils/1.0.1/source.json": "afe923f3f5f0b93ba3928ee5150065103418eae05757846595840e5bb9a1a400" + "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.1/downloads/bazel_registry.json": "not found", + "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.1/downloads/modules/download_utils/1.0.1/MODULE.bazel": "f1d0afade59e37de978506d6bbf08d7fe5f94964e86944aaf58efcead827b41b", + "https://gitlab.arm.com/bazel/download_utils/-/releases/v1.0.1/downloads/modules/download_utils/1.0.1/source.json": "9f871ab1f82c8867c19e0224dc411288ababb578fe5c67d7e4a54fb6968d6ba1", + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/bazel_registry.json": "not found", + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/download_utils/1.0.1/MODULE.bazel": "not found", + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/toolchain_utils/1.0.2/MODULE.bazel": "9b8be503a4fcfd3b8b952525bff0869177a5234d5c35dc3e566b9f5ca2f755a1", + "https://gitlab.arm.com/bazel/toolchain_utils/-/releases/v1.0.2/downloads/modules/toolchain_utils/1.0.2/source.json": "f70c533c9f1c9e27d4f6be8e985dbd2e9ddfe50b59953ff02c38568b3fa16729" }, "selectedYankedVersions": {}, "moduleExtensions": { diff --git a/e2e/binary/__init__.py b/e2e/binary/__init__.py index 1798572fc09e0e4c3487ff1a70a38e5a051f1319..0c485f0bbcf04fa4b1ba05ba6758963b257249fc 100644 --- a/e2e/binary/__init__.py +++ b/e2e/binary/__init__.py @@ -2,7 +2,8 @@ from __future__ import annotations from binary.difference import Diff from binary.relative import Relative +from binary.runfile import Env from binary.sniff import sniff from binary.tool import Tool -__all__ = ("sniff", "Diff", "Tool", "Relative") +__all__ = ("sniff", "Diff", "Tool", "Relative", "Env") diff --git a/e2e/binary/conftest.py b/e2e/binary/conftest.py index b83c6382a4b39cefd427fd277fc03af73b0818f7..b645b614147b259c1dfc99e08810588070383880 100644 --- a/e2e/binary/conftest.py +++ b/e2e/binary/conftest.py @@ -1,17 +1,27 @@ from __future__ import annotations +from os import environ + from pytest import fixture from .difference import repr as diff from .relative import Relative -from .runfile import Runfile, SupportsRlocation, create +from .runfile import ( + Env, + EnvVars, + Runfile, + Runfiles, + SupportsEnvVars, + SupportsRlocation, + create, +) from .tool import Tool -__all__ = ("Relative", "Tool", "Runfile") +__all__ = ("Relative", "Tool", "Runfile", "Env") @fixture -def runfiles() -> SupportsRlocation: +def runfiles() -> Runfiles: return create() @@ -20,6 +30,16 @@ def runfile(runfiles: SupportsRlocation) -> Runfile: return Runfile(runfiles) +@fixture +def env_vars(runfiles: SupportsEnvVars) -> EnvVars: + return runfiles.EnvVars() + + +@fixture +def env(env_vars: EnvVars) -> Env: + return environ | env_vars + + @fixture def tool(runfile: Runfile) -> Tool: return Tool(runfile) diff --git a/e2e/binary/curl/head.py b/e2e/binary/curl/head.py index 937d8587ac94311d0d2869da6183dc9338dc70ef..cc195b6e5b3675d7e59c9803e44b086ab9656be7 100644 --- a/e2e/binary/curl/head.py +++ b/e2e/binary/curl/head.py @@ -17,6 +17,7 @@ def ping(url: str) -> bool: # FIXME: remove this when the CI image works with Python SSL verification import ssl + context = ssl._create_unverified_context() try: diff --git a/e2e/binary/runfile.py b/e2e/binary/runfile.py index 1f6033f0e3bb3a834d5a36ab6b4e72981f5131f6..e25f0284350bcd3382cb3d6a3f2e772bbecbde42 100644 --- a/e2e/binary/runfile.py +++ b/e2e/binary/runfile.py @@ -1,9 +1,13 @@ from __future__ import annotations +from collections.abc import Mapping from pathlib import Path, PurePath -from typing import Protocol, runtime_checkable +from typing import Protocol, TypeAlias, runtime_checkable -from python.runfiles import Runfiles +from python.runfiles import Runfiles as runfiles + +EnvVars: TypeAlias = Mapping[str, str] +Env: TypeAlias = EnvVars @runtime_checkable @@ -11,13 +15,23 @@ class SupportsRlocation(Protocol): def Rlocation(self, path: str) -> str | None: ... +@runtime_checkable +class SupportsEnvVars(Protocol): + def EnvVars(self) -> EnvVars: ... + + +@runtime_checkable +class Runfiles(SupportsRlocation, SupportsEnvVars, Protocol): + pass + + class RunfilesError(RuntimeError): pass -def create() -> SupportsRlocation: - created = Runfiles.Create() - if not isinstance(created, SupportsRlocation): +def create() -> Runfiles: + created = runfiles.Create() + if not isinstance(created, Runfiles): raise RunfilesError("failed to create runfiles object") return created diff --git a/e2e/binary/tool.py b/e2e/binary/tool.py index e9af2b7c300e767b42bd1982c415d6f7735dd07e..ff7fdfa7fc0567a2b90d6ad4f05e7340629e2d95 100644 --- a/e2e/binary/tool.py +++ b/e2e/binary/tool.py @@ -1,7 +1,7 @@ from __future__ import annotations from pathlib import Path -from sys import platform +from platform import uname from .runfile import Runfile @@ -11,6 +11,9 @@ class Tool: self.__runfile = runfile def __call__(self, name: str) -> Path: - if platform == "win32": - return self.__runfile(f"ape/ape/assimilate/{name}.ape/{name}.exe") - return self.__runfile(f"ape/ape/assimilate/{name}.ape/{name}") + u = uname() + if u.system == "Windows": + return self.__runfile(f"ape/ape/assimilate/{name}/{name}.exe") + if u.system == "Darwin" and u.machine in {"aarch64", "arm64"}: + return self.__runfile(f"ape/ape/assimilate/{name}/{name}.ape") + return self.__runfile(f"ape/ape/assimilate/{name}/{name}") diff --git a/e2e/symlink/test/rule.bzl b/e2e/symlink/test/rule.bzl index 6b0af5e724960e21f84b027b3bcbe3248245106b..34beb88981e481481a2930dd5c14c053110565fe 100644 --- a/e2e/symlink/test/rule.bzl +++ b/e2e/symlink/test/rule.bzl @@ -6,7 +6,6 @@ ATTRS = { "_test": attr.label( executable = True, cfg = "exec", - allow_single_file = True, default = "@ape//ape:true", ), } @@ -16,17 +15,14 @@ def implementation(ctx): ctx.actions.symlink( output = output, - target_file = ctx.file._test, + target_file = ctx.executable._test, is_executable = True, ) - runfiles = ctx.runfiles((ctx.file._test, output)) - runfiles.merge(ctx.attr._test.default_runfiles) - return DefaultInfo( executable = output, files = depset([output]), - runfiles = runfiles, + runfiles = ctx.attr._test.default_runfiles, ) e2e_symlink_test = rule(