Compare commits
15 commits
2d4296b9be
...
edec17510e
Author | SHA1 | Date | |
---|---|---|---|
edec17510e | |||
f7bce623bf | |||
db2705eb53 | |||
ebc59f8329 | |||
253532ab6d | |||
ea57f84002 | |||
f0a871dd91 | |||
ed0eb657e5 | |||
de8207e672 | |||
58c416f1bd | |||
d0478d8124 | |||
c1de143471 | |||
20b662a142 | |||
bfafe8bc3a | |||
fc4ad9e90b |
279 changed files with 454 additions and 158 deletions
|
@ -1 +0,0 @@
|
|||
USE_BAZEL_VERSION=6.2.0
|
5
.bazelrc
5
.bazelrc
|
@ -1,4 +1,9 @@
|
|||
common --curses=auto
|
||||
common --show_timestamps=true
|
||||
|
||||
test --keep_going
|
||||
test --test_output=errors
|
||||
test --test_tag_filters=-known-to-fail
|
||||
|
||||
# To enable flake8 on all build steps, uncomment this -
|
||||
# test --aspects="//tools/flake8:flake8.bzl%flake8_aspect" --output_groups=flake8_checks
|
||||
|
|
1
.bazelversion
Normal file
1
.bazelversion
Normal file
|
@ -0,0 +1 @@
|
|||
7.0.0
|
2
.envrc
Normal file
2
.envrc
Normal file
|
@ -0,0 +1,2 @@
|
|||
export SOURCE=$(dirname $(realpath $0))
|
||||
export PATH="${SOURCE}/bin:$PATH"
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -24,3 +24,4 @@ tmp/
|
|||
/**/*.sqlite*
|
||||
/**/config*.toml
|
||||
/**/config*.yml
|
||||
MODULE.bazel.lock
|
||||
|
|
6
MODULE.bazel
Normal file
6
MODULE.bazel
Normal file
|
@ -0,0 +1,6 @@
|
|||
###############################################################################
|
||||
# Bazel now uses Bzlmod by default to manage external dependencies.
|
||||
# Please consider migrating your external dependencies from WORKSPACE to MODULE.bazel.
|
||||
#
|
||||
# For more details, please check https://github.com/bazelbuild/bazel/issues/18958
|
||||
###############################################################################
|
76
WORKSPACE
76
WORKSPACE
|
@ -62,76 +62,14 @@ load("@arrdem_source_pypi//:requirements.bzl", "install_deps")
|
|||
# Call it to define repos for your requirements.
|
||||
install_deps()
|
||||
|
||||
git_repository(
|
||||
name = "rules_zapp",
|
||||
remote = "https://git.arrdem.com/arrdem/rules_zapp.git",
|
||||
commit = "961be891e5cff539e14f2050d5cd9e82845ce0f2",
|
||||
# tag = "0.1.2",
|
||||
)
|
||||
|
||||
# local_repository(
|
||||
# git_repository(
|
||||
# name = "rules_zapp",
|
||||
# path = "/home/arrdem/Documents/hobby/programming/lang/python/rules_zapp",
|
||||
# remote = "https://git.arrdem.com/arrdem/rules_zapp.git",
|
||||
# commit = "961be891e5cff539e14f2050d5cd9e82845ce0f2",
|
||||
# # tag = "0.1.2",
|
||||
# )
|
||||
|
||||
####################################################################################################
|
||||
# Docker support
|
||||
####################################################################################################
|
||||
|
||||
http_archive(
|
||||
name = "io_bazel_rules_docker",
|
||||
sha256 = "b1e80761a8a8243d03ebca8845e9cc1ba6c82ce7c5179ce2b295cd36f7e394bf",
|
||||
urls = ["https://github.com/bazelbuild/rules_docker/releases/download/v0.25.0/rules_docker-v0.25.0.tar.gz"],
|
||||
)
|
||||
|
||||
load("@io_bazel_rules_docker//toolchains/docker:toolchain.bzl",
|
||||
docker_toolchain_configure="toolchain_configure"
|
||||
)
|
||||
|
||||
docker_toolchain_configure(
|
||||
name = "docker_config",
|
||||
docker_flags = [
|
||||
],
|
||||
)
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_docker//repositories:repositories.bzl",
|
||||
container_repositories = "repositories",
|
||||
)
|
||||
container_repositories()
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_docker//repositories:deps.bzl",
|
||||
container_deps = "deps"
|
||||
)
|
||||
|
||||
container_deps()
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_docker//container:container.bzl",
|
||||
"container_pull",
|
||||
)
|
||||
|
||||
# container_pull(
|
||||
# name = "python_base",
|
||||
# registry = "index.docker.io",
|
||||
# repository = "library/python",
|
||||
# tag = "3.10.8-alpine"
|
||||
# # sha256 = "digest:d78a749034380426dd6cec6a0db139459ca701630533ffce112adbcdd996fddd",
|
||||
# )
|
||||
|
||||
# container_pull(
|
||||
# name = "python_base",
|
||||
# registry = "gcr.io",
|
||||
# repository = "distroless/python3-debian11",
|
||||
# tag = "latest"
|
||||
# # sha256 = "digest:d78a749034380426dd6cec6a0db139459ca701630533ffce112adbcdd996fddd",
|
||||
# )
|
||||
|
||||
container_pull(
|
||||
name = "python_base",
|
||||
registry = "index.docker.io",
|
||||
repository = "library/python",
|
||||
tag = "3.11-buster"
|
||||
# sha256 = "digest:d78a749034380426dd6cec6a0db139459ca701630533ffce112adbcdd996fddd",
|
||||
local_repository(
|
||||
name = "rules_zapp",
|
||||
path = "/home/arrdem/Documents/hobby/programming/lang/python/rules_zapp",
|
||||
)
|
||||
|
|
2
bin/bazel
Executable file
2
bin/bazel
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
exec "${SOURCE}/projects/bazelshim/src/bazelshim/__main__.py" --bazelshim_exclude="$(realpath "${SOURCE}")/bin" "$@"
|
2
bin/bazelisk
Executable file
2
bin/bazelisk
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
exec "${SOURCE}/projects/bazelshim/src/bazelshim/__main__.py" --bazelshim_exclude="$(realpath "${SOURCE}")/bin" "$@"
|
|
@ -10,6 +10,6 @@ py_project(
|
|||
py_requirement("pyyaml"),
|
||||
py_requirement("retry"),
|
||||
],
|
||||
main = "src/python/relay/__main__.py",
|
||||
main = "src/relay/__main__.py",
|
||||
shebang = "/usr/bin/env python3"
|
||||
)
|
|
@ -4,7 +4,7 @@ py_project(
|
|||
|
||||
zapp_binary(
|
||||
name = "aloe",
|
||||
main = "src/python/aloe/__main__.py",
|
||||
main = "src/aloe/__main__.py",
|
||||
deps = [
|
||||
":lib",
|
||||
py_requirement("icmplib"),
|
|
@ -15,5 +15,6 @@ zapp_binary(
|
|||
deps = [
|
||||
py_requirement("ExifRead"),
|
||||
py_requirement("yaspin"),
|
||||
]
|
||||
],
|
||||
shebang = "/usr/bin/env python3"
|
||||
)
|
4
projects/bazelshim/BUILD.bazel
Normal file
4
projects/bazelshim/BUILD.bazel
Normal file
|
@ -0,0 +1,4 @@
|
|||
py_project(
|
||||
name = "bazelshim",
|
||||
main = "src/bazelshim/__main__.py",
|
||||
)
|
217
projects/bazelshim/src/bazelshim/__main__.py
Executable file
217
projects/bazelshim/src/bazelshim/__main__.py
Executable file
|
@ -0,0 +1,217 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# Since this can't run under Bazel, we have to set up the sys.path ourselves
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
if (p := str(Path(sys.argv[0]).absolute().parent.parent)) not in sys.path:
|
||||
sys.path.pop(0) # Remove '.' / ''
|
||||
sys.path.insert(0, p) # Insert the bazelshim root
|
||||
|
||||
# Now that's out of the way...
|
||||
from dataclasses import dataclass
|
||||
from shlex import quote, split as shlex
|
||||
import sys
|
||||
import tomllib
|
||||
from pathlib import Path
|
||||
from typing import List, Optional
|
||||
from itertools import chain
|
||||
|
||||
|
||||
# FIXME: Allow user-defined extensions here
|
||||
VERBS = [
|
||||
"aquery",
|
||||
"build",
|
||||
"clean",
|
||||
"coverage",
|
||||
"cquery",
|
||||
"dump",
|
||||
"fetch",
|
||||
"help",
|
||||
"info",
|
||||
"mod",
|
||||
"query",
|
||||
"run",
|
||||
"sync",
|
||||
"test",
|
||||
"watch",
|
||||
]
|
||||
|
||||
|
||||
def path():
|
||||
for it in os.getenv("PATH").split(":"):
|
||||
yield Path(it)
|
||||
|
||||
|
||||
def which(cmd):
|
||||
for it in path():
|
||||
f: Path = (it / cmd).absolute()
|
||||
if f.exists() and f.stat().st_mode & 0x700:
|
||||
yield f
|
||||
|
||||
|
||||
def normalize_opts(args: List[str]) -> List[str]:
|
||||
acc = []
|
||||
|
||||
if args[0].endswith("bazel") or args[0].endswith("bazelis"):
|
||||
acc.append(args.pop(0))
|
||||
|
||||
while len(args) >= 2:
|
||||
if args[0] == "--":
|
||||
# Break
|
||||
acc.extend(args)
|
||||
break
|
||||
|
||||
elif "=" in args[0]:
|
||||
# If it's a k/v form pass it through
|
||||
acc.append(args.pop(0))
|
||||
|
||||
elif args[0].startswith("--no"):
|
||||
# Convert --no<foo> args to --<foo>=no
|
||||
acc.append("--" + args.pop(0).lstrip("--no") + "=false")
|
||||
|
||||
elif args[0] == "--isatty=0":
|
||||
acc.append("--isatty=false")
|
||||
args.pop(0)
|
||||
|
||||
elif (
|
||||
args[0].startswith("--")
|
||||
and not args[1].startswith("--")
|
||||
and args[1] not in VERBS
|
||||
):
|
||||
# If the next thing isn't an opt, assume it's a '--a b' form
|
||||
acc.append(args[0] + "=" + args[1])
|
||||
args.pop(0)
|
||||
args.pop(0)
|
||||
|
||||
elif args[0].startswith("--"):
|
||||
# Assume it's a boolean true flag
|
||||
acc.append(args.pop(0) + "=true")
|
||||
|
||||
else:
|
||||
acc.append(args.pop(0))
|
||||
|
||||
else:
|
||||
if args:
|
||||
acc.extend(args)
|
||||
|
||||
return acc
|
||||
|
||||
|
||||
@dataclass
|
||||
class BazelCli:
|
||||
binary: str
|
||||
startup_opts: List[str]
|
||||
command: Optional[str]
|
||||
command_opts: List[str]
|
||||
subprocess_opts: List[str]
|
||||
|
||||
@classmethod
|
||||
def parse_cli(cls, args: List[str]) -> "BazelCli":
|
||||
args = normalize_opts(args)
|
||||
binary = args.pop(0)
|
||||
|
||||
startup_opts = []
|
||||
while args and args[0].startswith("--"):
|
||||
startup_opts.append(args.pop(0))
|
||||
|
||||
command = None
|
||||
if args and args[0] in VERBS:
|
||||
command = args.pop(0)
|
||||
|
||||
command_opts = []
|
||||
while args and args[0] != "--":
|
||||
command_opts.append(args.pop(0))
|
||||
|
||||
subprocess_opts = []
|
||||
if args:
|
||||
if args[0] == "--":
|
||||
args.pop(0)
|
||||
subprocess_opts.extend(args)
|
||||
|
||||
return cls(
|
||||
binary=binary,
|
||||
startup_opts=startup_opts,
|
||||
command=command,
|
||||
command_opts=command_opts,
|
||||
subprocess_opts=subprocess_opts,
|
||||
)
|
||||
|
||||
def render_cli(self):
|
||||
acc = [
|
||||
self.binary,
|
||||
*self.startup_opts,
|
||||
]
|
||||
if self.command:
|
||||
if self.command == "watch":
|
||||
acc.extend(self.command_opts)
|
||||
else:
|
||||
acc.append(self.command)
|
||||
acc.extend(self.command_opts)
|
||||
|
||||
if self.command == "test":
|
||||
acc.extend(["--test_arg=" + it for it in self.subprocess_opts])
|
||||
elif self.command == "run":
|
||||
acc.append("--")
|
||||
acc.extend(self.subprocess_opts)
|
||||
elif self.command and not self.subprocess_opts:
|
||||
pass
|
||||
else:
|
||||
print(
|
||||
f"Warning: {self.command} does not support -- args! {self.subprocess_opts!r}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
return acc
|
||||
|
||||
def executable(self, exclude: List[Path]):
|
||||
"""Try to resolve as via which() an executable to delegate to."""
|
||||
|
||||
if self.command == "watch":
|
||||
for p in chain(which("ibazel")):
|
||||
if p.parent not in exclude:
|
||||
return str(p)
|
||||
|
||||
else:
|
||||
for p in chain(which("bazelisk"), which("bazel")):
|
||||
if p.parent not in exclude:
|
||||
return str(p)
|
||||
|
||||
def render_text(self, next):
|
||||
lines = []
|
||||
lines.append(" " + next)
|
||||
base_prefix = " "
|
||||
for arg in self.render_cli()[1:]:
|
||||
prefix = base_prefix
|
||||
if arg in VERBS or arg == self.command:
|
||||
prefix = " "
|
||||
elif arg == "--":
|
||||
base_prefix += " "
|
||||
lines.append(prefix + arg)
|
||||
return "\\\n".join(lines)
|
||||
|
||||
|
||||
# FIXME: Use some sort of plugin model here to implement interceptors
|
||||
def middleware(cli):
|
||||
return cli
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# This script has a magical flag to help with resolving bazel
|
||||
exclude = []
|
||||
while len(sys.argv) > 1 and sys.argv[1].startswith("--bazelshim_exclude"):
|
||||
exclude.append(Path(sys.argv.pop(1).split("=")[1]).absolute())
|
||||
|
||||
us = Path(sys.argv[0]).absolute()
|
||||
exclude.append(us.parent)
|
||||
|
||||
cli = BazelCli.parse_cli(["bazel"] + sys.argv[1:])
|
||||
cli = middleware(cli)
|
||||
next = cli.executable(exclude=exclude)
|
||||
if sys.stderr.isatty() and not "--isatty=false" in cli.command_opts:
|
||||
print(
|
||||
"\u001b[33mInfo\u001b[0m: Executing\n" + cli.render_text(next),
|
||||
file=sys.stderr,
|
||||
)
|
||||
os.execv(next, cli.render_cli())
|
74
projects/bazelshim/test/test_normalizer.py
Normal file
74
projects/bazelshim/test/test_normalizer.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from shlex import split as shlex
|
||||
|
||||
from bazelshim.__main__ import normalize_opts
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"a, b",
|
||||
[
|
||||
(
|
||||
"bazel clean",
|
||||
[
|
||||
"bazel",
|
||||
"clean",
|
||||
],
|
||||
),
|
||||
(
|
||||
"bazel --client_debug clean",
|
||||
[
|
||||
"bazel",
|
||||
"--client_debug=true",
|
||||
"clean",
|
||||
],
|
||||
),
|
||||
(
|
||||
"bazel build //foo:bar //baz:*",
|
||||
[
|
||||
"bazel",
|
||||
"build",
|
||||
"//foo:bar",
|
||||
"//baz:*",
|
||||
],
|
||||
),
|
||||
(
|
||||
"bazel test //foo:bar //baz:* -- -vvv",
|
||||
[
|
||||
"bazel",
|
||||
"test",
|
||||
"//foo:bar",
|
||||
"//baz:*",
|
||||
"--",
|
||||
"-vvv",
|
||||
],
|
||||
),
|
||||
(
|
||||
"bazel test --shell_executable /bin/bish //foo:bar //baz:* -- -vvv",
|
||||
[
|
||||
"bazel",
|
||||
"test",
|
||||
"--shell_executable=/bin/bish",
|
||||
"//foo:bar",
|
||||
"//baz:*",
|
||||
"--",
|
||||
"-vvv",
|
||||
],
|
||||
),
|
||||
(
|
||||
"bazel run //foo:bar -- --foo=bar --baz=qux",
|
||||
[
|
||||
"bazel",
|
||||
"run",
|
||||
"//foo:bar",
|
||||
"--",
|
||||
"--foo=bar",
|
||||
"--baz=qux",
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_normalize_opts(a, b):
|
||||
assert normalize_opts(shlex(a)) == b
|
52
projects/bazelshim/test/test_parser.py
Normal file
52
projects/bazelshim/test/test_parser.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from shlex import split as shlex
|
||||
|
||||
from bazelshim.__main__ import BazelCli
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"a, b",
|
||||
[
|
||||
(
|
||||
"bazel clean",
|
||||
BazelCli("bazel", [], "clean", [], []),
|
||||
),
|
||||
(
|
||||
"bazel --client_debug clean",
|
||||
BazelCli("bazel", ["--client_debug=true"], "clean", [], []),
|
||||
),
|
||||
(
|
||||
"bazel build //foo:bar //baz:*",
|
||||
BazelCli("bazel", [], "build", ["//foo:bar", "//baz:*"], []),
|
||||
),
|
||||
(
|
||||
"bazel test //foo:bar //baz:* -- -vvv",
|
||||
BazelCli("bazel", [], "test", ["//foo:bar", "//baz:*"], ["-vvv"]),
|
||||
),
|
||||
(
|
||||
"bazel test --shell_executable /bin/bish //foo:bar //baz:* -- -vvv",
|
||||
BazelCli(
|
||||
"bazel",
|
||||
[],
|
||||
"test",
|
||||
["--shell_executable=/bin/bish", "//foo:bar", "//baz:*"],
|
||||
["-vvv"],
|
||||
),
|
||||
),
|
||||
(
|
||||
"bazel run //foo:bar -- --foo=bar --baz=qux",
|
||||
BazelCli(
|
||||
"bazel",
|
||||
[],
|
||||
"run",
|
||||
["//foo:bar"],
|
||||
["--foo=bar", "--baz=qux"],
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_normalize_opts(a, b):
|
||||
assert BazelCli.parse_cli(shlex(a)) == b
|
|
@ -2,7 +2,7 @@ package(default_visibility = ["//visibility:public"])
|
|||
|
||||
py_library(
|
||||
name = "lib",
|
||||
srcs = glob(["src/python/**/*.py"]),
|
||||
srcs = glob(["src/**/*.py"]),
|
||||
imports = ["src/python"],
|
||||
deps = [
|
||||
py_requirement("pyrsistent"),
|
|
@ -7,7 +7,7 @@ py_project(
|
|||
|
||||
zapp_binary(
|
||||
name = "clusterctrl",
|
||||
main = "src/python/clusterctrl/__main__.py",
|
||||
main = "src/clusterctrl/__main__.py",
|
||||
imports = [
|
||||
"src/python",
|
||||
],
|
|
@ -1,6 +1,6 @@
|
|||
zapp_binary(
|
||||
name = "datalog-shell",
|
||||
main = "src/python/datalog/shell/__main__.py",
|
||||
main = "src/datalog/shell/__main__.py",
|
||||
imports = [
|
||||
"src/python"
|
||||
],
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue