From 28a3591f4bd68486f5b5b6246c46a85e177a3656 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Mon, 26 Jan 2026 09:39:49 -0800 Subject: [PATCH 01/65] init --- .aspect/config-1.axl | 32 ++++++++++++++++++++++++++++++++ .aspect/config.axl | 33 +-------------------------------- 2 files changed, 33 insertions(+), 32 deletions(-) create mode 100644 .aspect/config-1.axl mode change 100644 => 120000 .aspect/config.axl diff --git a/.aspect/config-1.axl b/.aspect/config-1.axl new file mode 100644 index 000000000..809994865 --- /dev/null +++ b/.aspect/config-1.axl @@ -0,0 +1,32 @@ +load("./lambda.axl", "lambda_with_global_bind") +load("./user-task.axl", "UserTaskConfig") + +def _user_task_impl(ctx: TaskContext) -> int: + print("I am a task added by .aspect/config.axl") + return 0 + +_user_task = task( + name = "user-task-added-by-config", + group = ["user"], + implementation = _user_task_impl, + args = {} +) + +def _customize_message(s: str, a: str) -> str: + return s + a + +def config(ctx: ConfigContext): + # assert we can call a lambda with a global bind from another module in a config script + lambda_with_global_bind()("assert") + + # add a new task + ctx.tasks.add(_user_task) + + # customize a task + for task in ctx.tasks: + if task.name == "user_task" and task.group == ["user"]: + task.config = UserTaskConfig( + message = "hello axl", + count = 2, + customize_message = lambda s: _customize_message(s, "!") + ) diff --git a/.aspect/config.axl b/.aspect/config.axl deleted file mode 100644 index 809994865..000000000 --- a/.aspect/config.axl +++ /dev/null @@ -1,32 +0,0 @@ -load("./lambda.axl", "lambda_with_global_bind") -load("./user-task.axl", "UserTaskConfig") - -def _user_task_impl(ctx: TaskContext) -> int: - print("I am a task added by .aspect/config.axl") - return 0 - -_user_task = task( - name = "user-task-added-by-config", - group = ["user"], - implementation = _user_task_impl, - args = {} -) - -def _customize_message(s: str, a: str) -> str: - return s + a - -def config(ctx: ConfigContext): - # assert we can call a lambda with a global bind from another module in a config script - lambda_with_global_bind()("assert") - - # add a new task - ctx.tasks.add(_user_task) - - # customize a task - for task in ctx.tasks: - if task.name == "user_task" and task.group == ["user"]: - task.config = UserTaskConfig( - message = "hello axl", - count = 2, - customize_message = lambda s: _customize_message(s, "!") - ) diff --git a/.aspect/config.axl b/.aspect/config.axl new file mode 120000 index 000000000..0422de96b --- /dev/null +++ b/.aspect/config.axl @@ -0,0 +1 @@ +../axel-f/config.axl \ No newline at end of file From 4bb7f938476812539f4e7d00edee2b8e6d646829 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Mon, 26 Jan 2026 09:41:03 -0800 Subject: [PATCH 02/65] wip --- MODULE.aspect | 6 + axel-f/MODULE.aspect | 4 + axel-f/buildifier.axl | 85 +++++ axel-f/config.axl | 180 ++++++++++ axel-f/configure.axl | 164 ++++++++++ axel-f/gazelle.axl | 80 +++++ axel-f/migrate.axl | 741 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 1260 insertions(+) create mode 100644 axel-f/MODULE.aspect create mode 100644 axel-f/buildifier.axl create mode 100644 axel-f/config.axl create mode 100644 axel-f/configure.axl create mode 100644 axel-f/gazelle.axl create mode 100644 axel-f/migrate.axl diff --git a/MODULE.aspect b/MODULE.aspect index d204f69bd..d6eae2e67 100644 --- a/MODULE.aspect +++ b/MODULE.aspect @@ -10,6 +10,12 @@ axl_local_dep( auto_use_tasks = True, ) +axl_local_dep( + name = "axel-f", + path = "axel-f", + auto_use_tasks = True, +) + axl_archive_dep( name = "aspect_rules_lint", urls = ["https://github.com/aspect-build/rules_lint/archive/65525d871f677071877d3ea1ec096499ff7dd147.tar.gz"], diff --git a/axel-f/MODULE.aspect b/axel-f/MODULE.aspect new file mode 100644 index 000000000..83ed6e5b6 --- /dev/null +++ b/axel-f/MODULE.aspect @@ -0,0 +1,4 @@ +use_task("configure.axl", "configure") +use_task("gazelle.axl", "gazelle") +use_task("buildifier.axl", "buildifier") +use_task("migrate.axl", "migrate") diff --git a/axel-f/buildifier.axl b/axel-f/buildifier.axl new file mode 100644 index 000000000..d7788a5f9 --- /dev/null +++ b/axel-f/buildifier.axl @@ -0,0 +1,85 @@ +""" +Buildifier Task Implementation + +Runs 'bazel run ' to check if Buildifier-managed files are properly formatted. +This is the AXL equivalent of rosetta's buildifier.task.ts. +""" + +# Default targets for buildifier check and fix +DEFAULT_CHECK_TARGET = "//:buildifier.check" +DEFAULT_FIX_TARGET = "//:buildifier" + +# URL to buildifier lint warnings documentation +BUILDIFIER_LINT_WARNINGS_URL = "https://github.com/bazelbuild/buildtools/blob/master/WARNINGS.md" + + +def _buildifier_impl(ctx: TaskContext) -> int: + """ + Implementation of the buildifier task. + + Runs 'bazel run ' which executes the buildifier check target. + This target should be configured to run buildifier in diff/check mode + and exit non-zero if there are formatting issues. + + Args: + ctx: TaskContext with access to std library and args + + Returns: + Exit code (0 for success, non-zero for failure) + """ + # Get the target to run (from args or default) + target = ctx.args.target + if not target: + target = DEFAULT_CHECK_TARGET + + fix_target = ctx.args.fix_target + if not fix_target: + fix_target = DEFAULT_FIX_TARGET + + # Build startup flags + startup_flags = [] + for flag in ctx.args.bazel_startup_flag: + startup_flags.append(flag) + + # Build command flags + cmd_flags = ["--isatty=" + str(int(ctx.std.io.stdout.is_tty))] + for flag in ctx.args.bazel_flag: + cmd_flags.append(flag) + + # Run bazel run with the buildifier target + build = ctx.bazel.build( + target, + flags = cmd_flags, + startup_flags = startup_flags, + ) + + # Wait for completion + status = build.wait() + + # Handle exit codes + if status.code == 0: + print("Buildifier check passed - files are properly formatted") + return 0 + else: + print("Buildifier check failed - files need formatting or have lint issues") + print("Run 'bazel run {}' to apply formatting fixes".format(fix_target)) + print("Some lint failures may require manual fixes.") + print("For more information on lint warnings, see: {}".format(BUILDIFIER_LINT_WARNINGS_URL)) + return status.code + + +# Register the buildifier task +buildifier = task( + name = "buildifier", + implementation = _buildifier_impl, + args = { + # The target to run for the check (default: //:buildifier.check) + "target": args.string(default = DEFAULT_CHECK_TARGET), + # The target to run for fixing (shown in error message) + "fix_target": args.string(default = DEFAULT_FIX_TARGET), + # Additional bazel flags + "bazel_flag": args.string_list(), + # Bazel startup flags + "bazel_startup_flag": args.string_list(), + }, +) diff --git a/axel-f/config.axl b/axel-f/config.axl new file mode 100644 index 000000000..57c4be1ac --- /dev/null +++ b/axel-f/config.axl @@ -0,0 +1,180 @@ +""" +AXL Configuration Loader + +Reads .aspect/workflows/config.yaml and registers tasks dynamically. +This replaces rosetta's task registration with AXL-native task definitions. +""" + +# Load pre-installed task implementations from @aspect +load("@aspect//build.axl", "build") +load("@aspect//test.axl", "test") + +# Load custom task implementations from this module +load("@axel-f//configure.axl", "configure") +load("@axel-f//gazelle.axl", "gazelle") +load("@axel-f//buildifier.axl", "buildifier") +load("@axel-f//migrate.axl", "migrate") + +# Task type to implementation mapping +# Maps config.yaml task types to AXL task implementations +TASK_IMPLS = { + "build": build, + "test": test, + "configure": configure, + "gazelle": gazelle, + "buildifier": buildifier, + # lint and format are handled by @aspect-build/rules_lint if available + # "lint": lint, + # "format": format, +} + +# Tasks that are NOT Bazel-related and should be skipped +# These are handled by static CI config generation +EXCLUDED_TASK_TYPES = [ + "checkout", + "delivery", + "delivery_manifest", + "warming", + "bazel_health_probe", + "finalization", + "noop", +] + + +def parse_yaml(ctx, content: str) -> dict: + """ + Parse YAML content to a dictionary using yq. + + Args: + ctx: ConfigContext with access to std library + content: YAML content as string + + Returns: + Parsed dictionary from YAML + """ + child = ctx.std.process.command("yq") \ + .arg("-o=json") \ + .arg(".") \ + .stdin("piped") \ + .stdout("piped") \ + .stderr("piped") \ + .spawn() + + stdin = child.stdin() + stdin.write(content) + stdin.close() + + stdout = child.stdout() + json_output = stdout.read_to_string() + + status = child.wait() + if status.code != 0: + stderr = child.stderr() + error_msg = stderr.read_to_string() + fail("Failed to parse YAML: " + error_msg) + + return json.decode(json_output) + + +def get_task_entry(task_def: dict) -> tuple: + """ + Extract task name, type, and config from a task definition. + + Config.yaml tasks are structured as: + - task_type: {config...} OR + - task_type_N: {config...} (for multiple tasks of same type, e.g., build_2) + + Args: + task_def: A single task entry from the tasks array + + Returns: + Tuple of (task_name, task_type, task_config) + """ + if type(task_def) != "dict" or len(task_def) == 0: + return (None, None, None) + + # Get the first (and only) key-value pair + for task_name, task_config in task_def.items(): + # Extract base task type from name (e.g., "build_2" -> "build") + task_type = task_name + + # Check for numbered suffix pattern (e.g., build_2, test_3) + parts = task_name.rsplit("_", 1) + if len(parts) == 2 and parts[1].isdigit(): + task_type = parts[0] + + # Handle case where config might be None or empty + if task_config == None: + task_config = {} + + return (task_name, task_type, task_config) + + return (None, None, None) + + +def register_task(ctx, task_name: str, task_type: str, task_config: dict): + """ + Register a task with the AXL task system. + + Args: + ctx: ConfigContext with tasks attribute + task_name: Name to register the task under (e.g., "build_2") + task_type: Base type of the task (e.g., "build") + task_config: Configuration dict for the task + """ + # Skip non-Bazel tasks + if task_type in EXCLUDED_TASK_TYPES: + return + + # Get the implementation for this task type + impl = TASK_IMPLS.get(task_type) + if impl == None: + # Unknown task type - skip with a warning + print("Warning: Unknown task type '{}' for task '{}', skipping".format(task_type, task_name)) + return + + # Find and customize the task in ctx.tasks + for task in ctx.tasks: + if task.name == task_type: + # Found the base task, customize if needed + # Note: In the future, we may want to clone and rename tasks + # For now, the built-in tasks are already registered + return + + # Task not found in defaults - it should already be registered by the load statements + # The load() statements at the top register the tasks automatically + + +def config(ctx: ConfigContext): + """ + Main configuration function called by aspect-cli. + + Reads the workflows config.yaml and registers tasks dynamically. + """ + root = ctx.std.env.root_dir() + + # Path to the legacy config.yaml + config_path = root + "/.aspect/workflows/config.yaml" + + # Check if config file exists + if not ctx.std.fs.exists(config_path): + # No config file - nothing to configure + # The default build/test tasks from @aspect are still available + return + + # Read the config file + content = ctx.std.fs.read_to_string(config_path) + + # Parse YAML to get task definitions + config_data = parse_yaml(ctx, content) + + # Get the tasks array + tasks = config_data.get("tasks", []) + if type(tasks) != "list": + tasks = [] + + # Register each task + for task_def in tasks: + task_name, task_type, task_config = get_task_entry(task_def) + if task_name != None: + register_task(ctx, task_name, task_type, task_config) diff --git a/axel-f/configure.axl b/axel-f/configure.axl new file mode 100644 index 000000000..1d9e64cfd --- /dev/null +++ b/axel-f/configure.axl @@ -0,0 +1,164 @@ +""" +Configure Task Implementation + +Downloads and runs the gazelle binary from aspect-gazelle releases to check +if BUILD files are up-to-date. This is the AXL equivalent of rosetta's configure.task.ts. + +The configure command is no longer part of aspect-cli. It must be downloaded from: +https://github.com/aspect-build/aspect-gazelle/releases +""" + +# Release version and SHA256 hashes for each platform +GAZELLE_VERSION = "2025.40.148+4396cce" +GAZELLE_HASHES = { + "darwin_arm64": "2dce01cde75c03c0190a9e40f0713e3b80844e1bed1af3ed73d684263d823896", + "linux_amd64": "516da161c2a6997fb7e7e2880447428da01bf0220747fb0c35619bacd283f2af", + "linux_arm64": "60a09694ddc455ac6cd458d6d89f21b82f3a7813b290dcd52307cd8dde74b5b3", +} + +# Exit code when configure finds differences that need to be applied +CONFIGURE_DIFF_EXIT_CODE = 5 + + +def get_platform(ctx) -> tuple: + """ + Detect OS and architecture using uname. + + Returns: + Tuple of (os_name, arch) e.g., ("darwin", "arm64") or ("linux", "amd64") + """ + # Get OS (Darwin -> darwin, Linux -> linux) + child_os = ctx.std.process.command("uname") \ + .arg("-s") \ + .stdout("piped") \ + .spawn() + os_name = child_os.stdout().read_to_string().strip().lower() + child_os.wait() + + # Get arch (x86_64 -> amd64, arm64/aarch64 -> arm64) + child_arch = ctx.std.process.command("uname") \ + .arg("-m") \ + .stdout("piped") \ + .spawn() + arch = child_arch.stdout().read_to_string().strip() + child_arch.wait() + + # Map architecture names to standard names + arch_map = {"x86_64": "amd64", "aarch64": "arm64"} + normalized_arch = arch_map.get(arch, arch) + + return (os_name, normalized_arch) + + +def download_gazelle(ctx) -> str: + """ + Download and cache the gazelle binary for the current platform. + + Args: + ctx: TaskContext with access to std library and http + + Returns: + Path to the cached gazelle binary + """ + os_name, arch = get_platform(ctx) + platform_key = os_name + "_" + arch + binary_name = "gazelle-" + platform_key + "_cgo" + + # Cache in user home directory + home = ctx.std.env.home_dir() + if home == None: + fail("Could not determine home directory for caching gazelle binary") + + cache_dir = home + "/.cache/aspect-gazelle/" + GAZELLE_VERSION + cached_path = cache_dir + "/" + binary_name + + # Check if binary is already cached + if ctx.std.fs.exists(cached_path): + return cached_path + + # Create cache directory if it doesn't exist + if not ctx.std.fs.exists(cache_dir): + ctx.std.fs.create_dir_all(cache_dir) + + # Build download URL + url = "https://github.com/aspect-build/aspect-gazelle/releases/download/{}/{}".format( + GAZELLE_VERSION, binary_name + ) + + # Get expected SHA256 hash + expected_sha256 = GAZELLE_HASHES.get(platform_key) + if expected_sha256 == None: + fail("Unsupported platform: {}. Supported platforms: {}".format( + platform_key, ", ".join(GAZELLE_HASHES.keys()) + )) + + print("Downloading gazelle binary for {}...".format(platform_key)) + print("URL: {}".format(url)) + + # Download the binary with executable permissions (0755) + ctx.http().download( + url = url, + output = cached_path, + mode = 0o755, + ).block() + + print("Downloaded to: {}".format(cached_path)) + + return cached_path + + +def _configure_impl(ctx: TaskContext) -> int: + """ + Implementation of the configure task. + + Downloads the gazelle binary from aspect-gazelle releases and runs it + with '--mode=diff' to check if BUILD files are up-to-date. If there are + differences, it exits with code 5 and prints a diff. + + Args: + ctx: TaskContext with access to std library and args + + Returns: + Exit code (0 for success, non-zero for failure) + """ + # Download/get cached gazelle binary + gazelle_binary = download_gazelle(ctx) + + # Build command arguments + cmd_args = ["--mode=diff"] + + # Add any additional flags from args + for flag in ctx.args.flag: + cmd_args.append(flag) + + # Create and run the command + child = ctx.std.process.command(gazelle_binary) \ + .args(cmd_args) \ + .current_dir(ctx.std.env.root_dir()) \ + .spawn() + + # Wait for completion + status = child.wait() + + # Handle exit codes + if status.code == 0: + print("Configure check passed - BUILD files are up-to-date") + return 0 + elif status.code == CONFIGURE_DIFF_EXIT_CODE: + print("Configure found BUILD files that require updating") + print("Run 'aspect configure' to apply the suggested fixes") + return CONFIGURE_DIFF_EXIT_CODE + else: + print("Configure failed with exit code: {}".format(status.code)) + return status.code + + +# Register the configure task +configure = task( + name = "configure", + implementation = _configure_impl, + args = { + # Additional flags to pass to configure command + "flag": args.string_list(), + }, +) diff --git a/axel-f/gazelle.axl b/axel-f/gazelle.axl new file mode 100644 index 000000000..df3e5f73a --- /dev/null +++ b/axel-f/gazelle.axl @@ -0,0 +1,80 @@ +""" +Gazelle Task Implementation + +Runs 'bazel run ' to check if Gazelle-managed BUILD files are up-to-date. +This is the AXL equivalent of rosetta's gazelle.task.ts. +""" + +# Default targets for gazelle check and fix +DEFAULT_CHECK_TARGET = "//:gazelle.check" +DEFAULT_FIX_TARGET = "//:gazelle" + + +def _gazelle_impl(ctx: TaskContext) -> int: + """ + Implementation of the gazelle task. + + Runs 'bazel run ' which executes the gazelle check target. + This target should be configured to run gazelle in diff/check mode + and exit non-zero if there are changes needed. + + Args: + ctx: TaskContext with access to std library and args + + Returns: + Exit code (0 for success, non-zero for failure) + """ + # Get the target to run (from args or default) + target = ctx.args.target + if not target: + target = DEFAULT_CHECK_TARGET + + fix_target = ctx.args.fix_target + if not fix_target: + fix_target = DEFAULT_FIX_TARGET + + # Build startup flags + startup_flags = [] + for flag in ctx.args.bazel_startup_flag: + startup_flags.append(flag) + + # Build command flags + cmd_flags = ["--isatty=" + str(int(ctx.std.io.stdout.is_tty))] + for flag in ctx.args.bazel_flag: + cmd_flags.append(flag) + + # Run bazel run with the gazelle target + build = ctx.bazel.build( + target, + flags = cmd_flags, + startup_flags = startup_flags, + ) + + # Wait for completion + status = build.wait() + + # Handle exit codes + if status.code == 0: + print("Gazelle check passed - BUILD files are up-to-date") + return 0 + else: + print("Gazelle check failed - BUILD files need updating") + print("Run 'bazel run {}' to apply the suggested fixes".format(fix_target)) + return status.code + + +# Register the gazelle task +gazelle = task( + name = "gazelle", + implementation = _gazelle_impl, + args = { + # The target to run for the check (default: //:gazelle.check) + "target": args.string(default = DEFAULT_CHECK_TARGET), + # The target to run for fixing (shown in error message) + "fix_target": args.string(default = DEFAULT_FIX_TARGET), + # Additional bazel flags + "bazel_flag": args.string_list(), + # Bazel startup flags + "bazel_startup_flag": args.string_list(), + }, +) diff --git a/axel-f/migrate.axl b/axel-f/migrate.axl new file mode 100644 index 000000000..d67e561e4 --- /dev/null +++ b/axel-f/migrate.axl @@ -0,0 +1,741 @@ +""" +CI Config Generator Task + +Generates CI workflow files (GitHub Actions, Buildkite, etc.) from +.aspect/workflows/config.yaml. + +Usage: + aspect workflows migrate --host=github --config=.aspect/workflows/config.yaml + +This generates a standalone workflow file at .github/workflows/aspect-workflows.yaml +""" + +# Task types that should generate CI jobs +BAZEL_TASK_TYPES = [ + "build", + "test", + "lint", + "format", + "configure", + "gazelle", + "buildifier", +] + +# Task types that are pre-task hooks +PRE_TASK_TYPES = [ + "checkout", + "bazel_health_probe", +] + +# Task types that are post-task hooks +POST_TASK_TYPES = [ + "finalization", + "delivery_manifest", +] + +# Task types that are CI infrastructure (not Bazel tasks, not hooks) +EXCLUDED_TASK_TYPES = [ + "delivery", + "warming", + "noop", +] + +# Tasks that need deeper git history for diff operations +NEEDS_DEEP_CHECKOUT = [ + "lint", + "format", +] + +# Default timeout in minutes for tasks +DEFAULT_TIMEOUT = 60 + + +def parse_yaml(ctx, content: str) -> dict: + """Parse YAML content to a dictionary using yq.""" + child = ctx.std.process.command("yq") \ + .arg("-o=json") \ + .arg(".") \ + .stdin("piped") \ + .stdout("piped") \ + .stderr("piped") \ + .spawn() + + stdin = child.stdin() + stdin.write(content) + stdin.close() + + stdout = child.stdout() + json_output = stdout.read_to_string() + + status = child.wait() + if status.code != 0: + stderr = child.stderr() + error_msg = stderr.read_to_string() + fail("Failed to parse YAML: " + error_msg) + + return json.decode(json_output) + + +def get_task_entry(task_def: dict) -> tuple: + """ + Extract task name, type, and config from a task definition. + + Returns: + Tuple of (task_name, task_type, task_config) + """ + if type(task_def) != "dict" or len(task_def) == 0: + return (None, None, None) + + for task_name, task_config in task_def.items(): + task_type = task_name + parts = task_name.rsplit("_", 1) + if len(parts) == 2 and parts[1].isdigit(): + task_type = parts[0] + + if task_config == None: + task_config = {} + + return (task_name, task_type, task_config) + + return (None, None, None) + + +def find_task_config(tasks: list, task_type: str): + """Find a task config by type in the tasks list. Returns None if not found or disabled.""" + for task_def in tasks: + name, ttype, config = get_task_entry(task_def) + if ttype == task_type: + # Check if task is disabled + if config.get("without", False): + return None + return config + return None + + +def generate_checkout_step(task_type: str) -> list: + """ + Generate checkout step for a job. + + Args: + task_type: The main task type (affects fetch-depth) + + Returns: + List of YAML lines for checkout step + """ + lines = [] + + # Determine fetch-depth based on task type + # lint/format need 2 commits for diff comparison + fetch_depth = 1 + if task_type in NEEDS_DEEP_CHECKOUT: + fetch_depth = 2 + + lines.append("- uses: actions/checkout@v4") + if fetch_depth != 1: + lines.append(" with:") + lines.append(" fetch-depth: " + str(fetch_depth)) + + return lines + + +def generate_pre_hooks(tasks: list, task_type: str) -> list: + """ + Generate pre-task hook steps. + + Args: + tasks: Full tasks list from config + task_type: The main task type + + Returns: + List of YAML lines for pre-hook steps + """ + lines = [] + + # Note: checkout task with update_strategy (rebase/merge) is handled by + # the Aspect Workflows infrastructure via branch_freshness_strategy binary. + # In standalone GitHub Actions, this is not available - users should + # configure branch protection rules or use GitHub's merge queue instead. + + # Check for bazel_health_probe task + health_config = find_task_config(tasks, "bazel_health_probe") + if health_config != None: + timeout = health_config.get("timeout_in_minutes", 10) + lines.append("- name: Bazel health check") + lines.append(" run: aspect bazel_health_probe") + lines.append(" timeout-minutes: " + str(timeout)) + + return lines + + +def generate_post_hooks(tasks: list, task_name: str) -> list: + """ + Generate post-task hook steps. + + Args: + tasks: Full tasks list from config + task_name: The main task name (for delivery manifest) + + Returns: + List of YAML lines for post-hook steps + """ + lines = [] + + # Check for delivery_manifest task + manifest_config = find_task_config(tasks, "delivery_manifest") + if manifest_config != None: + timeout = manifest_config.get("timeout_in_minutes", 10) + lines.append("- name: Delivery manifest") + lines.append(" if: success()") + lines.append(" run: aspect delivery_manifest --data TARGETS_SOURCE=" + task_name) + lines.append(" timeout-minutes: " + str(timeout)) + + # Check for finalization task + finalize_config = find_task_config(tasks, "finalization") + if finalize_config != None: + timeout = finalize_config.get("timeout_in_minutes", 10) + lines.append("- name: Finalization") + lines.append(" if: always()") + lines.append(" run: aspect finalization") + lines.append(" timeout-minutes: " + str(timeout)) + + return lines + + +def generate_task_hooks(task_config: dict, hook_type: str) -> list: + """ + Generate task-specific hook steps (before_task or after_task). + + Args: + task_config: The task's configuration dict + hook_type: Either "before_task" or "after_task" + + Returns: + List of YAML lines for hook steps + """ + lines = [] + + hooks = task_config.get("hooks", []) + if type(hooks) != "list": + return lines + + hook_index = 0 + for hook in hooks: + if type(hook) != "dict": + continue + + if hook.get("type") != hook_type: + continue + + command = hook.get("command", "") + if not command: + continue + + hook_index += 1 + hook_name = hook_type.replace("_", " ").title() + if hook_index > 1: + hook_name = hook_name + " " + str(hook_index) + + # Check if command is multiline + if "\n" in command: + lines.append("- name: " + hook_name) + lines.append(" run: |") + for cmd_line in command.split("\n"): + lines.append(" " + cmd_line) + else: + lines.append("- name: " + hook_name) + lines.append(" run: " + command) + + return lines + + +def generate_github_workflow(ctx, config_data: dict, config_path: str, workflow_name: str) -> str: + """ + Generate a GitHub Actions workflow YAML from config data. + + Args: + ctx: TaskContext + config_data: Parsed config.yaml data + config_path: Path to config file (for reference in workflow) + workflow_name: Name for the workflow + + Returns: + Generated workflow YAML as string + """ + tasks = config_data.get("tasks", []) + workspaces = config_data.get("workspaces", ["."]) + env_vars = config_data.get("env", {}) + default_queue = config_data.get("queue", "aspect-default") + + # Normalize workspaces to list + if type(workspaces) != "list": + workspaces = ["."] + + # Build the workflow structure + lines = [] + lines.append("# Generated by: aspect workflows migrate --host=github") + lines.append("# Source: " + config_path) + lines.append("# DO NOT EDIT - regenerate with 'aspect workflows migrate'") + lines.append("") + lines.append("name: " + workflow_name) + lines.append("") + lines.append("on:") + lines.append(" push:") + lines.append(" branches: [main]") + lines.append(" pull_request:") + lines.append(" branches: [main]") + lines.append(" workflow_dispatch:") + lines.append("") + + # Add global env vars if present + if env_vars and len(env_vars) > 0: + lines.append("env:") + for key, value in env_vars.items(): + lines.append(" " + key + ": " + json.encode(str(value))) + lines.append("") + + lines.append("jobs:") + + # Generate a job for each Bazel task + job_count = 0 + for task_def in tasks: + task_name, task_type, task_config = get_task_entry(task_def) + + if task_name == None: + continue + + # Skip non-Bazel tasks and hooks (hooks are embedded in jobs) + if task_type in EXCLUDED_TASK_TYPES: + continue + if task_type in PRE_TASK_TYPES: + continue + if task_type in POST_TASK_TYPES: + continue + + if task_type not in BAZEL_TASK_TYPES: + print("Warning: Unknown task type '{}', skipping".format(task_type)) + continue + + # Check if task is disabled + if task_config.get("without", False): + continue + + # Get task-specific config + timeout = task_config.get("timeout_in_minutes", DEFAULT_TIMEOUT) + queue = task_config.get("queue", default_queue) + nice_name = task_config.get("name", task_name.replace("_", " ").title()) + + # Get task-specific hooks + before_task_hooks = generate_task_hooks(task_config, "before_task") + after_task_hooks = generate_task_hooks(task_config, "after_task") + + # Get task-specific env vars + task_env = task_config.get("env", {}) + if task_env == None: + task_env = {} + + # Get task-specific artifact paths + artifact_paths = task_config.get("artifact_paths", []) + if artifact_paths == None: + artifact_paths = [] + + # Determine if using matrix for multiple workspaces + use_matrix = len(workspaces) > 1 + + job_id = task_name.replace("-", "_") + lines.append("") + lines.append(" " + job_id + ":") + + if use_matrix: + lines.append(" name: " + nice_name + " (${{ matrix.workspace }})") + else: + lines.append(" name: " + nice_name) + + lines.append(" runs-on: [self-hosted, aspect-workflows, " + queue + "]") + + if use_matrix: + lines.append(" strategy:") + lines.append(" fail-fast: false") + lines.append(" matrix:") + lines.append(" workspace:") + for ws in workspaces: + lines.append(" - " + json.encode(ws)) + lines.append(" defaults:") + lines.append(" run:") + lines.append(" working-directory: ${{ matrix.workspace }}") + else: + workspace = workspaces[0] + if workspace != ".": + lines.append(" defaults:") + lines.append(" run:") + lines.append(" working-directory: " + workspace) + + lines.append(" steps:") + + # 1. Checkout step + checkout_lines = generate_checkout_step(task_type) + for line in checkout_lines: + lines.append(" " + line) + + # 2. Pre-task hooks (checkout, health probe) + pre_hook_lines = generate_pre_hooks(tasks, task_type) + for line in pre_hook_lines: + lines.append(" " + line) + + # 3. Task-specific before_task hooks + for line in before_task_hooks: + lines.append(" " + line) + + # 4. Main task + lines.append(" - name: " + nice_name) + lines.append(" run: aspect " + task_name) + lines.append(" timeout-minutes: " + str(timeout)) + if task_env and len(task_env) > 0: + lines.append(" env:") + for env_key, env_value in task_env.items(): + lines.append(" " + env_key + ": " + json.encode(str(env_value))) + + # 5. Task-specific after_task hooks + for line in after_task_hooks: + lines.append(" " + line) + + # 6. Post-task hooks (delivery manifest, finalization) + post_hook_lines = generate_post_hooks(tasks, task_name) + for line in post_hook_lines: + lines.append(" " + line) + + # 7. Upload artifacts (always, even on failure) + lines.append(" - name: Upload artifacts") + lines.append(" if: always()") + lines.append(" uses: actions/upload-artifact@v4") + lines.append(" with:") + lines.append(" name: " + task_name + "-artifacts") + lines.append(" path: |") + lines.append(" bazel-out/**/testlogs/**") + lines.append(" bazel-out/**/test.log") + # Add custom artifact paths + for artifact_path in artifact_paths: + lines.append(" " + artifact_path) + lines.append(" if-no-files-found: ignore") + + job_count += 1 + + if job_count == 0: + fail("No Bazel tasks found in config. Expected tasks like: build, test, lint, format, configure, gazelle, buildifier") + + lines.append("") + return "\n".join(lines) + + +def generate_buildkite_pipeline(ctx, config_data: dict, config_path: str) -> str: + """ + Generate a Buildkite pipeline YAML from config data. + + Args: + ctx: TaskContext + config_data: Parsed config.yaml data + config_path: Path to config file (for reference) + + Returns: + Generated pipeline YAML as string + """ + tasks = config_data.get("tasks", []) + workspaces = config_data.get("workspaces", ["."]) + env_vars = config_data.get("env", {}) + default_queue = config_data.get("queue", "aspect-default") + + # Normalize workspaces to list of strings + workspace_list = [] + if type(workspaces) == "list": + for ws in workspaces: + if type(ws) == "str": + workspace_list.append(ws) + elif type(ws) == "dict": + for ws_name in ws.keys(): + workspace_list.append(ws_name) + else: + workspace_list = ["."] + + lines = [] + lines.append("# Generated by: aspect workflows migrate --host=buildkite") + lines.append("# Source: " + config_path) + lines.append("# DO NOT EDIT - regenerate with 'aspect workflows migrate'") + lines.append("") + lines.append("steps:") + + # Collect step keys for finalization depends_on + step_keys = [] + + # Generate steps for each task and workspace combination + for task_def in tasks: + task_name, task_type, task_config = get_task_entry(task_def) + + if task_name == None: + continue + + # Skip non-Bazel tasks and hooks + if task_type in EXCLUDED_TASK_TYPES: + continue + if task_type in PRE_TASK_TYPES: + continue + if task_type in POST_TASK_TYPES: + continue + + if task_type not in BAZEL_TASK_TYPES: + print("Warning: Unknown task type '{}', skipping".format(task_type)) + continue + + # Check if task is disabled + if task_config.get("without", False): + continue + + # Get task-specific config + timeout = task_config.get("timeout_in_minutes", DEFAULT_TIMEOUT) + queue = task_config.get("queue", default_queue) + nice_name = task_config.get("name", task_name.replace("_", " ").title()) + icon = task_config.get("icon", "bazel") + + # Get task-specific env, hooks, and artifact paths + task_env = task_config.get("env", {}) + if task_env == None: + task_env = {} + before_hooks = get_task_hook_commands(task_config, "before_task") + after_hooks = get_task_hook_commands(task_config, "after_task") + artifact_paths = task_config.get("artifact_paths", []) + if artifact_paths == None: + artifact_paths = [] + + # Generate step for each workspace + for workspace in workspace_list: + workspace_key = workspace.replace("/", "-").replace(".", "__main__") + step_key = workspace_key + "::" + task_name + step_keys.append(step_key) + + # Label with workspace suffix if multiple workspaces + if len(workspace_list) > 1 and workspace != ".": + label = ":{}: {} - {}".format(icon, nice_name, workspace) + else: + label = ":{}: {}".format(icon, nice_name) + + lines.append(" - key: " + step_key) + lines.append(" label: \"" + label + "\"") + lines.append(" agents:") + lines.append(" queue: " + queue) + lines.append(" timeout_in_minutes: " + str(timeout)) + + # Environment variables + lines.append(" env:") + lines.append(" ASPECT_WORKFLOWS_CONFIG: " + config_path) + for key, value in env_vars.items(): + lines.append(" " + key + ": " + json.encode(str(value))) + for key, value in task_env.items(): + lines.append(" " + key + ": " + json.encode(str(value))) + + # Commands + lines.append(" command:") + + # Before task hooks + for cmd in before_hooks: + if "\n" in cmd: + lines.append(" - |") + for cmd_line in cmd.split("\n"): + lines.append(" " + cmd_line) + else: + lines.append(" - " + json.encode(cmd)) + + # Main task command + if workspace != ".": + lines.append(" - 'echo \"--- :{}: {}\"'".format(icon, nice_name)) + lines.append(" - aspect " + task_name + " --workspace " + workspace) + else: + lines.append(" - 'echo \"--- :{}: {}\"'".format(icon, nice_name)) + lines.append(" - aspect " + task_name) + + # After task hooks + for cmd in after_hooks: + if "\n" in cmd: + lines.append(" - |") + for cmd_line in cmd.split("\n"): + lines.append(" " + cmd_line) + else: + lines.append(" - " + json.encode(cmd)) + + # Artifact paths + if len(artifact_paths) > 0: + lines.append(" artifact_paths:") + for path in artifact_paths: + lines.append(" - " + json.encode(path)) + + # Retry config + lines.append(" retry:") + lines.append(" automatic:") + lines.append(" - exit_status: -1") + lines.append(" limit: 1") + lines.append(" manual:") + lines.append(" allowed: true") + lines.append(" permit_on_passed: false") + lines.append("") + + # Add finalization step if configured + finalize_config = find_task_config(tasks, "finalization") + if finalize_config != None and len(step_keys) > 0: + timeout = finalize_config.get("timeout_in_minutes", 10) + lines.append(" - key: finalization") + lines.append(" label: \":checkered_flag: Finalization\"") + lines.append(" agents:") + lines.append(" queue: " + default_queue) + lines.append(" timeout_in_minutes: " + str(timeout)) + lines.append(" command:") + lines.append(" - aspect finalization") + lines.append(" depends_on:") + for key in step_keys: + lines.append(" - step: " + key) + lines.append(" allow_failure: true") + lines.append(" soft_fail: true") + lines.append("") + + return "\n".join(lines) + + +def get_task_hook_commands(task_config: dict, hook_type: str) -> list: + """ + Get list of commands from task hooks. + + Args: + task_config: Task configuration dict + hook_type: Either "before_task" or "after_task" + + Returns: + List of command strings + """ + commands = [] + hooks = task_config.get("hooks", []) + if type(hooks) != "list": + return commands + + for hook in hooks: + if type(hook) != "dict": + continue + if hook.get("type") != hook_type: + continue + command = hook.get("command", "") + if command: + commands.append(command) + + return commands + + +def _migrate_impl(ctx: TaskContext) -> int: + """ + Implementation of the migrate task. + + Reads config.yaml and generates CI workflow files. + """ + host = ctx.args.host + config_path = ctx.args.config + output = ctx.args.output + workflow_name = ctx.args.name + + # Validate host + supported_hosts = ["github", "buildkite"] + if host not in supported_hosts: + print("Error: Unsupported host '{}'. Supported hosts: {}".format( + host, ", ".join(supported_hosts) + )) + return 1 + + # Resolve config path + root = ctx.std.env.root_dir() + if not config_path.startswith("/"): + full_config_path = root + "/" + config_path + else: + full_config_path = config_path + + # Check if config exists + if not ctx.std.fs.exists(full_config_path): + print("Error: Config file not found: " + full_config_path) + return 1 + + # Read and parse config + print("Reading config: " + full_config_path) + content = ctx.std.fs.read_to_string(full_config_path) + config_data = parse_yaml(ctx, content) + + # Determine output path + if not output: + if host == "github": + output = root + "/.github/workflows/aspect-workflows.yaml" + elif host == "buildkite": + output = root + "/.buildkite/pipeline.yaml" + + # Ensure output directory exists + output_dir = output.rsplit("/", 1)[0] + if not ctx.std.fs.exists(output_dir): + ctx.std.fs.create_dir_all(output_dir) + + # Generate workflow + print("Generating {} workflow...".format(host)) + + workflow_content = "" + if host == "github": + workflow_content = generate_github_workflow( + ctx, + config_data, + config_path, # Use original relative path in comment + workflow_name, + ) + elif host == "buildkite": + workflow_content = generate_buildkite_pipeline( + ctx, + config_data, + config_path, + ) + + # Write output + print("Writing: " + output) + ctx.std.fs.write(output, workflow_content) + + print("") + print("Generated workflow file: " + output) + print("") + print("Features enabled:") + + # Report what hooks were detected + tasks = config_data.get("tasks", []) + if find_task_config(tasks, "bazel_health_probe") != None: + print(" - Bazel health probe") + if find_task_config(tasks, "finalization") != None: + print(" - Finalization hook (runs on success/failure)") + if find_task_config(tasks, "delivery_manifest") != None: + print(" - Delivery manifest generation") + + # Warn about features not supported in standalone mode + if find_task_config(tasks, "checkout") != None: + print("") + print("Note: 'checkout' task with update_strategy is not supported in standalone mode.") + print(" Use GitHub branch protection rules or merge queue instead.") + + print("") + print("To use this workflow:") + print(" 1. Commit the generated file to your repository") + print(" 2. Push to trigger the workflow") + print("") + + return 0 + + +# Register the migrate task +migrate = task( + name = "migrate", + group = ["workflows"], + implementation = _migrate_impl, + args = { + # CI host platform + "host": args.string(default = "github"), + # Path to workflows config.yaml + "config": args.string(default = ".aspect/workflows/config.yaml"), + # Output file path (auto-detected if not specified) + "output": args.string(default = ""), + # Workflow name + "name": args.string(default = "Aspect Workflows"), + }, +) From 627b9f31baee0260b79c5166e0d4c7893704bf36 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Mon, 26 Jan 2026 09:42:05 -0800 Subject: [PATCH 03/65] config --- .buildkite/pipeline.yaml | 101 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 .buildkite/pipeline.yaml diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml new file mode 100644 index 000000000..39225c681 --- /dev/null +++ b/.buildkite/pipeline.yaml @@ -0,0 +1,101 @@ +# Generated by: aspect workflows migrate --host=buildkite +# Source: .aspect/workflows/config_aws.yaml +# DO NOT EDIT - regenerate with 'aspect workflows migrate' + +steps: + - key: __main__::lint + label: ":bazel: Lint" + agents: + queue: aspect-default + timeout_in_minutes: 60 + env: + ASPECT_WORKFLOWS_CONFIG: .aspect/workflows/config_aws.yaml + command: + - 'echo "--- :bazel: Lint"' + - aspect lint + retry: + automatic: + - exit_status: -1 + limit: 1 + manual: + allowed: true + permit_on_passed: false + + - key: __main__::format + label: ":bazel: Format" + agents: + queue: aspect-default + timeout_in_minutes: 60 + env: + ASPECT_WORKFLOWS_CONFIG: .aspect/workflows/config_aws.yaml + command: + - 'echo "--- :bazel: Format"' + - aspect format + retry: + automatic: + - exit_status: -1 + limit: 1 + manual: + allowed: true + permit_on_passed: false + + - key: __main__::buildifier + label: ":bazel: Buildifier" + agents: + queue: aspect-default + timeout_in_minutes: 60 + env: + ASPECT_WORKFLOWS_CONFIG: .aspect/workflows/config_aws.yaml + command: + - 'echo "--- :bazel: Buildifier"' + - aspect buildifier + retry: + automatic: + - exit_status: -1 + limit: 1 + manual: + allowed: true + permit_on_passed: false + + - key: __main__::gazelle + label: ":bazel: Gazelle" + agents: + queue: aspect-default + timeout_in_minutes: 60 + command: + - 'echo "--- :bazel: Gazelle"' + - aspect gazelle + retry: + automatic: + - exit_status: -1 + limit: 1 + manual: + allowed: true + permit_on_passed: false + + - key: __main__::test + label: ":bazel: Test" + agents: + queue: aspect-default + timeout_in_minutes: 60 + env: + ASPECT_WORKFLOWS_CONFIG: .aspect/workflows/config_aws.yaml + ASPECT_BEP_USE_PIPE: "1" + command: + - "vmstat -a -S M -t 5 2>&1 > vmstat.out &" + - 'echo "--- :bazel: Test"' + - aspect test + - "cp /etc/bazel.bazelrc workflows-etc-bazel.bazelrc" + artifact_paths: + - "vmstat.out" + - "workflows-etc-bazel.bazelrc" + - "bes.pb" + - "bes.json" + - "compact.exec.log" + retry: + automatic: + - exit_status: -1 + limit: 1 + manual: + allowed: true + permit_on_passed: false From 47e9e9f49d1b3f9bfcc2bc341164bbb6a98d5020 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Mon, 26 Jan 2026 09:52:08 -0800 Subject: [PATCH 04/65] wip --- .buildkite/hooks/environment | 2 ++ .buildkite/hooks/pre-command | 33 +++++++++++++++++++++++++++++++++ .buildkite/pipeline.yaml | 9 --------- 3 files changed, 35 insertions(+), 9 deletions(-) create mode 100755 .buildkite/hooks/environment create mode 100755 .buildkite/hooks/pre-command diff --git a/.buildkite/hooks/environment b/.buildkite/hooks/environment new file mode 100755 index 000000000..159d0af79 --- /dev/null +++ b/.buildkite/hooks/environment @@ -0,0 +1,2 @@ +#!/bin/sh +export PATH="$HOME/.aspect/bin:$PATH" diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command new file mode 100755 index 000000000..662c651c3 --- /dev/null +++ b/.buildkite/hooks/pre-command @@ -0,0 +1,33 @@ +#!/bin/sh +set -eu + +ASPECT_BIN_DIR="$HOME/.aspect/bin" + +# Skip if bazel is not installed +if ! command -v bazel >/dev/null 2>&1; then + exit 0 +fi + +# Check if aspect binary exists +if [ -x "$ASPECT_BIN_DIR/aspect" ]; then + # Skip if it's the new version (contains "programmable" in help) + if "$ASPECT_BIN_DIR/aspect" --help 2>&1 | grep -q programmable; then + exit 0 + fi + # Remove old version + rm -f "$ASPECT_BIN_DIR/aspect" +fi + +# Build aspect-cli and install +echo "--- Building aspect-cli" +bazel build //:cli + +# Create target directory and copy binary +mkdir -p "$ASPECT_BIN_DIR" +cp -f "$(bazel cquery --output=files //:cli 2>/dev/null)" "$ASPECT_BIN_DIR/aspect" +chmod 0755 "$ASPECT_BIN_DIR/aspect" + +# Add to PATH for subsequent commands +export PATH="$ASPECT_BIN_DIR:$PATH" + +echo "aspect-cli installed to $ASPECT_BIN_DIR/aspect" diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index 39225c681..f7d783a12 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -8,8 +8,6 @@ steps: agents: queue: aspect-default timeout_in_minutes: 60 - env: - ASPECT_WORKFLOWS_CONFIG: .aspect/workflows/config_aws.yaml command: - 'echo "--- :bazel: Lint"' - aspect lint @@ -26,8 +24,6 @@ steps: agents: queue: aspect-default timeout_in_minutes: 60 - env: - ASPECT_WORKFLOWS_CONFIG: .aspect/workflows/config_aws.yaml command: - 'echo "--- :bazel: Format"' - aspect format @@ -44,8 +40,6 @@ steps: agents: queue: aspect-default timeout_in_minutes: 60 - env: - ASPECT_WORKFLOWS_CONFIG: .aspect/workflows/config_aws.yaml command: - 'echo "--- :bazel: Buildifier"' - aspect buildifier @@ -78,9 +72,6 @@ steps: agents: queue: aspect-default timeout_in_minutes: 60 - env: - ASPECT_WORKFLOWS_CONFIG: .aspect/workflows/config_aws.yaml - ASPECT_BEP_USE_PIPE: "1" command: - "vmstat -a -S M -t 5 2>&1 > vmstat.out &" - 'echo "--- :bazel: Test"' From ac30c4480aaf7ea6c5ea769132f85ee59e8b4c17 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Mon, 26 Jan 2026 15:05:09 -0800 Subject: [PATCH 05/65] export axl config --- .aspect/config-1.axl | 32 ----------------------- .aspect/config.axl | 33 +++++++++++++++++++++++- .buildkite/hooks/environment | 1 + crates/aspect-cli/src/helpers.rs | 44 ++++++++++++++++++++++++++++++++ crates/aspect-cli/src/main.rs | 32 ++++++++++++++++++++++- 5 files changed, 108 insertions(+), 34 deletions(-) delete mode 100644 .aspect/config-1.axl mode change 120000 => 100644 .aspect/config.axl diff --git a/.aspect/config-1.axl b/.aspect/config-1.axl deleted file mode 100644 index 809994865..000000000 --- a/.aspect/config-1.axl +++ /dev/null @@ -1,32 +0,0 @@ -load("./lambda.axl", "lambda_with_global_bind") -load("./user-task.axl", "UserTaskConfig") - -def _user_task_impl(ctx: TaskContext) -> int: - print("I am a task added by .aspect/config.axl") - return 0 - -_user_task = task( - name = "user-task-added-by-config", - group = ["user"], - implementation = _user_task_impl, - args = {} -) - -def _customize_message(s: str, a: str) -> str: - return s + a - -def config(ctx: ConfigContext): - # assert we can call a lambda with a global bind from another module in a config script - lambda_with_global_bind()("assert") - - # add a new task - ctx.tasks.add(_user_task) - - # customize a task - for task in ctx.tasks: - if task.name == "user_task" and task.group == ["user"]: - task.config = UserTaskConfig( - message = "hello axl", - count = 2, - customize_message = lambda s: _customize_message(s, "!") - ) diff --git a/.aspect/config.axl b/.aspect/config.axl deleted file mode 120000 index 0422de96b..000000000 --- a/.aspect/config.axl +++ /dev/null @@ -1 +0,0 @@ -../axel-f/config.axl \ No newline at end of file diff --git a/.aspect/config.axl b/.aspect/config.axl new file mode 100644 index 000000000..809994865 --- /dev/null +++ b/.aspect/config.axl @@ -0,0 +1,32 @@ +load("./lambda.axl", "lambda_with_global_bind") +load("./user-task.axl", "UserTaskConfig") + +def _user_task_impl(ctx: TaskContext) -> int: + print("I am a task added by .aspect/config.axl") + return 0 + +_user_task = task( + name = "user-task-added-by-config", + group = ["user"], + implementation = _user_task_impl, + args = {} +) + +def _customize_message(s: str, a: str) -> str: + return s + a + +def config(ctx: ConfigContext): + # assert we can call a lambda with a global bind from another module in a config script + lambda_with_global_bind()("assert") + + # add a new task + ctx.tasks.add(_user_task) + + # customize a task + for task in ctx.tasks: + if task.name == "user_task" and task.group == ["user"]: + task.config = UserTaskConfig( + message = "hello axl", + count = 2, + customize_message = lambda s: _customize_message(s, "!") + ) diff --git a/.buildkite/hooks/environment b/.buildkite/hooks/environment index 159d0af79..1912c8600 100755 --- a/.buildkite/hooks/environment +++ b/.buildkite/hooks/environment @@ -1,2 +1,3 @@ #!/bin/sh export PATH="$HOME/.aspect/bin:$PATH" +export AXL_CONFIG=axel-f/config.axl diff --git a/crates/aspect-cli/src/helpers.rs b/crates/aspect-cli/src/helpers.rs index 5ff94f13e..5a1b5cdc7 100644 --- a/crates/aspect-cli/src/helpers.rs +++ b/crates/aspect-cli/src/helpers.rs @@ -6,6 +6,50 @@ use axl_runtime::module::{ use tokio::fs; use tracing::instrument; +/// Parse the AXL_CONFIG environment variable for additional config paths. +/// Supports both individual .config.axl files and directories to scan. +/// Paths are separated by ':' on Unix and ';' on Windows. +pub async fn parse_axl_config_env() -> Result, std::io::Error> { + let separator = if cfg!(windows) { ';' } else { ':' }; + + let env_val = match std::env::var("AXL_CONFIG") { + Ok(val) if !val.is_empty() => val, + _ => return Ok(vec![]), + }; + + let mut configs = Vec::new(); + + for path_str in env_val.split(separator) { + let path = PathBuf::from(path_str.trim()); + + if !path.exists() { + eprintln!( + "warning: AXL_CONFIG path does not exist: {}", + path.display() + ); + continue; + } + + if path.is_file() { + // Check it's a .config.axl file + if path.to_string_lossy().ends_with(AXL_CONFIG_EXTENSION) { + configs.push(path); + } else { + eprintln!( + "warning: AXL_CONFIG file is not a .config.axl file: {}", + path.display() + ); + } + } else if path.is_dir() { + // Scan directory for .config.axl files + let (_, dir_configs) = search_sources(&vec![path]).await?; + configs.extend(dir_configs); + } + } + + Ok(configs) +} + // Constants for special directory names used in module resolution. // These define the structure for local modules (e.g., .aspect/axl/module_name). pub const DOT_ASPECT_FOLDER: &str = ".aspect"; diff --git a/crates/aspect-cli/src/main.rs b/crates/aspect-cli/src/main.rs index c998ebabc..b7d99bf5f 100644 --- a/crates/aspect-cli/src/main.rs +++ b/crates/aspect-cli/src/main.rs @@ -25,7 +25,9 @@ use tokio::task::spawn_blocking; use tracing::info_span; use crate::cmd_tree::{BUILTIN_COMMAND_DISPLAY_ORDER, CommandTree, make_command_from_task}; -use crate::helpers::{find_repo_root, get_default_axl_search_paths, search_sources}; +use crate::helpers::{ + find_repo_root, get_default_axl_search_paths, parse_axl_config_env, search_sources, +}; // Helper function to check if debug mode is enabled based on the ASPECT_DEBUG environment variable. fn debug_mode() -> bool { @@ -124,6 +126,9 @@ async fn main() -> miette::Result { let search_paths = get_default_axl_search_paths(¤t_work_dir, &repo_root); let (scripts, configs) = search_sources(&search_paths).await.into_diagnostic()?; + // Get additional configs from AXL_CONFIG environment variable + let env_configs = parse_axl_config_env().await.into_diagnostic()?; + // Enter a tracing span for evaluation of scripts and configs. let espan = info_span!("eval"); @@ -246,6 +251,31 @@ async fn main() -> miette::Result { ) .into_diagnostic()?; + // Run environment configs, each with scope derived from parent directory + if debug_mode() && !env_configs.is_empty() { + eprintln!("AXL_CONFIG configs:"); + for path in &env_configs { + eprintln!( + " - {} (scope: {})", + path.display(), + path.parent() + .map_or("repo root".to_string(), |p| p.display().to_string()) + ); + } + } + + let mut tasks = tasks; + for config_path in env_configs.iter() { + let parent = config_path.parent().unwrap_or(&repo_root); + let scope = ModuleScope { + name: AXL_ROOT_MODULE_NAME.to_string(), + path: parent.to_path_buf(), + }; + tasks = config_eval + .run_all(scope, vec![config_path.clone()], tasks) + .into_diagnostic()?; + } + // Build the command tree from the evaluated and configured tasks. let mut tree = CommandTree::default(); From 502b61dfb86a190bb7d0fda2bba708ea51450daf Mon Sep 17 00:00:00 2001 From: thesayyn Date: Tue, 27 Jan 2026 12:49:27 -0800 Subject: [PATCH 06/65] flag generation --- MODULE.aspect | 6 - axel-f/MODULE.aspect | 4 - axel-f/config.axl | 216 ++------- axel-f/platform-config.axl | 669 ++++++++++++++++++++++++++ axel-f/platform.axl | 0 crates/aspect-cli/src/main.rs | 33 +- crates/axl-runtime/src/eval/config.rs | 14 +- 7 files changed, 733 insertions(+), 209 deletions(-) delete mode 100644 axel-f/MODULE.aspect create mode 100644 axel-f/platform-config.axl create mode 100644 axel-f/platform.axl diff --git a/MODULE.aspect b/MODULE.aspect index d6eae2e67..d204f69bd 100644 --- a/MODULE.aspect +++ b/MODULE.aspect @@ -10,12 +10,6 @@ axl_local_dep( auto_use_tasks = True, ) -axl_local_dep( - name = "axel-f", - path = "axel-f", - auto_use_tasks = True, -) - axl_archive_dep( name = "aspect_rules_lint", urls = ["https://github.com/aspect-build/rules_lint/archive/65525d871f677071877d3ea1ec096499ff7dd147.tar.gz"], diff --git a/axel-f/MODULE.aspect b/axel-f/MODULE.aspect deleted file mode 100644 index 83ed6e5b6..000000000 --- a/axel-f/MODULE.aspect +++ /dev/null @@ -1,4 +0,0 @@ -use_task("configure.axl", "configure") -use_task("gazelle.axl", "gazelle") -use_task("buildifier.axl", "buildifier") -use_task("migrate.axl", "migrate") diff --git a/axel-f/config.axl b/axel-f/config.axl index 57c4be1ac..040e2449c 100644 --- a/axel-f/config.axl +++ b/axel-f/config.axl @@ -1,180 +1,44 @@ -""" -AXL Configuration Loader +"""Workflows Configuration""" -Reads .aspect/workflows/config.yaml and registers tasks dynamically. -This replaces rosetta's task registration with AXL-native task definitions. -""" - -# Load pre-installed task implementations from @aspect -load("@aspect//build.axl", "build") -load("@aspect//test.axl", "test") - -# Load custom task implementations from this module -load("@axel-f//configure.axl", "configure") -load("@axel-f//gazelle.axl", "gazelle") -load("@axel-f//buildifier.axl", "buildifier") -load("@axel-f//migrate.axl", "migrate") - -# Task type to implementation mapping -# Maps config.yaml task types to AXL task implementations -TASK_IMPLS = { - "build": build, - "test": test, - "configure": configure, - "gazelle": gazelle, - "buildifier": buildifier, - # lint and format are handled by @aspect-build/rules_lint if available - # "lint": lint, - # "format": format, -} - -# Tasks that are NOT Bazel-related and should be skipped -# These are handled by static CI config generation -EXCLUDED_TASK_TYPES = [ - "checkout", - "delivery", - "delivery_manifest", - "warming", - "bazel_health_probe", - "finalization", - "noop", -] - - -def parse_yaml(ctx, content: str) -> dict: - """ - Parse YAML content to a dictionary using yq. - - Args: - ctx: ConfigContext with access to std library - content: YAML content as string - - Returns: - Parsed dictionary from YAML - """ - child = ctx.std.process.command("yq") \ - .arg("-o=json") \ - .arg(".") \ - .stdin("piped") \ - .stdout("piped") \ - .stderr("piped") \ - .spawn() - - stdin = child.stdin() - stdin.write(content) - stdin.close() - - stdout = child.stdout() - json_output = stdout.read_to_string() - - status = child.wait() - if status.code != 0: - stderr = child.stderr() - error_msg = stderr.read_to_string() - fail("Failed to parse YAML: " + error_msg) - - return json.decode(json_output) - - -def get_task_entry(task_def: dict) -> tuple: - """ - Extract task name, type, and config from a task definition. - - Config.yaml tasks are structured as: - - task_type: {config...} OR - - task_type_N: {config...} (for multiple tasks of same type, e.g., build_2) - - Args: - task_def: A single task entry from the tasks array - - Returns: - Tuple of (task_name, task_type, task_config) - """ - if type(task_def) != "dict" or len(task_def) == 0: - return (None, None, None) - - # Get the first (and only) key-value pair - for task_name, task_config in task_def.items(): - # Extract base task type from name (e.g., "build_2" -> "build") - task_type = task_name - - # Check for numbered suffix pattern (e.g., build_2, test_3) - parts = task_name.rsplit("_", 1) - if len(parts) == 2 and parts[1].isdigit(): - task_type = parts[0] - - # Handle case where config might be None or empty - if task_config == None: - task_config = {} - - return (task_name, task_type, task_config) - - return (None, None, None) - - -def register_task(ctx, task_name: str, task_type: str, task_config: dict): - """ - Register a task with the AXL task system. - - Args: - ctx: ConfigContext with tasks attribute - task_name: Name to register the task under (e.g., "build_2") - task_type: Base type of the task (e.g., "build") - task_config: Configuration dict for the task - """ - # Skip non-Bazel tasks - if task_type in EXCLUDED_TASK_TYPES: - return - - # Get the implementation for this task type - impl = TASK_IMPLS.get(task_type) - if impl == None: - # Unknown task type - skip with a warning - print("Warning: Unknown task type '{}' for task '{}', skipping".format(task_type, task_name)) - return - - # Find and customize the task in ctx.tasks - for task in ctx.tasks: - if task.name == task_type: - # Found the base task, customize if needed - # Note: In the future, we may want to clone and rename tasks - # For now, the built-in tasks are already registered - return - - # Task not found in defaults - it should already be registered by the load statements - # The load() statements at the top register the tasks automatically +load("./configure.axl", "configure") +load("./gazelle.axl", "gazelle") +load("./buildifier.axl", "buildifier") +load("./migrate.axl", "migrate") +load("./platform-config.axl", + "read_platform_config", + "read_host_config", + "get_bazelrc_content", +) +PLATFORM_DIR = "/etc/aspect/workflows/platform" def config(ctx: ConfigContext): - """ - Main configuration function called by aspect-cli. - - Reads the workflows config.yaml and registers tasks dynamically. - """ - root = ctx.std.env.root_dir() - - # Path to the legacy config.yaml - config_path = root + "/.aspect/workflows/config.yaml" - - # Check if config file exists - if not ctx.std.fs.exists(config_path): - # No config file - nothing to configure - # The default build/test tasks from @aspect are still available - return - - # Read the config file - content = ctx.std.fs.read_to_string(config_path) - - # Parse YAML to get task definitions - config_data = parse_yaml(ctx, content) - - # Get the tasks array - tasks = config_data.get("tasks", []) - if type(tasks) != "list": - tasks = [] - - # Register each task - for task_def in tasks: - task_name, task_type, task_config = get_task_entry(task_def) - if task_name != None: - register_task(ctx, task_name, task_type, task_config) + print(ctx.tasks) + + # Read platform config from disk + platform_config = read_platform_config( + ctx.std.fs, + platform_dir = PLATFORM_DIR, + ) + print(platform_config) + + # Read host config from environment + host_config = read_host_config(ctx.std.env, ctx.std.io) + + print(host_config) + + # Generate bazelrc content + content = get_bazelrc_content( + platform_config = platform_config, + host_config = host_config, + bazel_version = "7.0.0", + task_types = ["build"], + workspace = ".", + ) + + print(content) + + # ctx.tasks.add(configure) + # ctx.tasks.add(gazelle) + # ctx.tasks.add(buildifier) + # ctx.tasks.add(migrate) diff --git a/axel-f/platform-config.axl b/axel-f/platform-config.axl new file mode 100644 index 000000000..338d8c1cf --- /dev/null +++ b/axel-f/platform-config.axl @@ -0,0 +1,669 @@ +""" +Platform Configuration and Bazelrc Flag Generation Library + +A pure Starlark library for generating .bazelrc content for Aspect Workflows. +All functions are pure and take explicit parameters - no side effects or implicit +environment reading. + +This is a library, not a task. All configuration is passed as function parameters. + +Usage: + load("@axel-f//platform-config.axl", + "read_platform_config", + "read_host_config", + "get_bazelrc_content", + ) + + # In a task implementation: + platform_config = read_platform_config(ctx.std.fs) + host_config = read_host_config(ctx.std.env, ctx.std.io) + content = get_bazelrc_content(platform_config, host_config) +""" + +# ============================================================================= +# Constants +# ============================================================================= + +DEFAULT_STORAGE_PATH = "/mnt/ephemeral" +DEFAULT_PLATFORM_DIR = "/etc/aspect/workflows/platform" + +# Map of logical config keys to filenames in the platform directory +PLATFORM_CONFIG_KEYS = { + "remote_cache_endpoint": "remote_cache_endpoint", + "remote_cache_address": "remote_cache_address", + "storage_path": "storage_path", +} + +# All Bazel commands +BAZEL_COMMANDS_ALL = [ + "analyze-profile", + "aquery", + "build", + "canonicalize-flags", + "clean", + "config", + "coverage", + "cquery", + "dump", + "fetch", + "help", + "info", + "license", + "mobile-install", + "print_action", + "query", + "run", + "shutdown", + "sync", + "test", + "version", +] + +# Commands that involve building +BAZEL_COMMANDS_BUILD = [ + "aquery", + "build", + "canonicalize-flags", + "clean", + "config", + "coverage", + "cquery", + "fetch", + "info", + "mobile-install", + "print_action", + "query", + "run", + "sync", + "test", +] + +# Commands for action-related flags +BAZEL_COMMANDS_ACTIONS = [ + "aquery", + "build", + "canonicalize-flags", + "clean", + "config", + "coverage", + "cquery", + "info", + "mobile-install", + "print_action", + "run", + "test", +] + +# Commands with symlink support +BAZEL_COMMANDS_SYMLINK = [ + "aquery", + "build", + "canonicalize-flags", + "clean", + "config", + "coverage", + "cquery", + "info", + "mobile-install", + "print_action", + "run", + "test", +] + +# Commands for jobs flag +BAZEL_COMMANDS_JOBS = [ + "build", + "coverage", + "cquery", + "run", + "test", +] + +# ============================================================================= +# Flag Definitions +# ============================================================================= + +# Static boolean flags (no value) +STATIC_BOOLEAN_FLAGS = [ + {"name": "show_timestamps", "commands": BAZEL_COMMANDS_ALL}, + {"name": "remote_upload_local_results", "commands": BAZEL_COMMANDS_BUILD}, + {"name": "heap_dump_on_oom", "commands": BAZEL_COMMANDS_ALL}, + {"name": "keep_going", "commands": BAZEL_COMMANDS_BUILD}, + {"name": "generate_json_trace_profile", "commands": BAZEL_COMMANDS_ALL}, + {"name": "experimental_profile_include_target_label", "commands": BAZEL_COMMANDS_ALL}, + {"name": "incompatible_strict_action_env", "commands": BAZEL_COMMANDS_ACTIONS}, + {"name": "experimental_repository_cache_hardlinks", "commands": BAZEL_COMMANDS_ALL}, + {"name": "incompatible_exclusive_test_sandboxed", "commands": BAZEL_COMMANDS_ACTIONS}, + {"name": "experimental_reuse_sandbox_directories", "commands": BAZEL_COMMANDS_ACTIONS}, + {"name": "incompatible_default_to_explicit_init_py", "commands": BAZEL_COMMANDS_ACTIONS}, + {"name": "remote_accept_cached", "commands": BAZEL_COMMANDS_BUILD}, +] + +# Static value flags +STATIC_VALUE_FLAGS = [ + {"name": "tool_tag", "value": "aspect-workflows", "commands": BAZEL_COMMANDS_ALL}, + {"name": "color", "value": "yes", "commands": BAZEL_COMMANDS_ALL}, + {"name": "isatty", "value": "0", "commands": BAZEL_COMMANDS_ALL}, + {"name": "terminal_columns", "value": "143", "commands": BAZEL_COMMANDS_ALL}, + {"name": "disk_cache", "value": "", "commands": BAZEL_COMMANDS_BUILD}, + {"name": "symlink_prefix", "value": "bazel-", "commands": BAZEL_COMMANDS_SYMLINK}, + {"name": "experimental_convenience_symlinks", "value": "normal", "commands": BAZEL_COMMANDS_SYMLINK}, + {"name": "max_config_changes_to_show", "value": "-1", "commands": BAZEL_COMMANDS_ACTIONS}, + {"name": "remote_timeout", "value": "3600", "commands": BAZEL_COMMANDS_BUILD}, + {"name": "remote_retries", "value": "360", "commands": BAZEL_COMMANDS_BUILD}, + {"name": "grpc_keepalive_timeout", "value": "30s", "commands": BAZEL_COMMANDS_ALL}, + {"name": "bes_upload_mode", "value": "wait_for_upload_complete", "commands": BAZEL_COMMANDS_ALL}, + {"name": "experimental_repository_downloader_retries", "value": "2", "commands": BAZEL_COMMANDS_ALL}, +] + +# Version-specific static flags +VERSION_SPECIFIC_FLAGS = [ + # incompatible_remote_results_ignore_disk removed in Bazel 7 + {"name": "incompatible_remote_results_ignore_disk", "commands": BAZEL_COMMANDS_BUILD, "versions": "< 7"}, + # Build event upload flag renamed in Bazel 7 + {"name": "experimental_remote_build_event_upload", "value": "minimal", "commands": BAZEL_COMMANDS_BUILD, "versions": ">= 6 < 7"}, + {"name": "remote_build_event_upload", "value": "minimal", "commands": BAZEL_COMMANDS_BUILD, "versions": ">= 7"}, + # Cache compression flag renamed in Bazel 8 + {"name": "noexperimental_remote_cache_compression", "commands": BAZEL_COMMANDS_BUILD, "versions": "< 8"}, + {"name": "noremote_cache_compression", "commands": BAZEL_COMMANDS_BUILD, "versions": ">= 8"}, +] + +# Dynamic flags - value resolved from config dicts +DYNAMIC_FLAGS = [ + {"name": "remote_cache", "value": "dynamic:platform.remote_cache_endpoint", "commands": BAZEL_COMMANDS_BUILD}, + {"name": "remote_bytestream_uri_prefix", "value": "dynamic:platform.remote_cache_address", "commands": BAZEL_COMMANDS_BUILD}, + {"name": "repository_cache", "value": "dynamic:computed.repository_cache", "commands": BAZEL_COMMANDS_ALL}, + {"name": "curses", "value": "dynamic:host.curses", "commands": BAZEL_COMMANDS_ALL}, + {"name": "show_progress_rate_limit", "value": "dynamic:host.progress_rate_limit", "commands": BAZEL_COMMANDS_ALL}, + # RBE flags (omit if not configured) + {"name": "remote_executor", "value": "dynamic:rbe.remote_executor", "commands": BAZEL_COMMANDS_BUILD, "omit_if_none": True}, + {"name": "jobs", "value": "dynamic:rbe.jobs", "commands": BAZEL_COMMANDS_JOBS, "omit_if_none": True}, +] + +# Startup flags +STARTUP_FLAGS = [ + {"name": "output_user_root", "value": "dynamic:computed.output_user_root"}, + {"name": "output_base", "value": "dynamic:computed.output_base"}, +] + + +# ============================================================================= +# Version Comparison Functions +# ============================================================================= + +def parse_version(version_str): + """ + Parse version string to tuple (major, minor, patch). + + Args: + version_str: Version string like "7.0.0" or "7.1.2-rc1" + + Returns: + Tuple of (major, minor, patch) as integers + """ + if not version_str: + return (0, 0, 0) + + parts = version_str.split(".") + major = int(parts[0]) if len(parts) > 0 and parts[0].isdigit() else 0 + + minor = 0 + if len(parts) > 1: + minor_part = parts[1] + if minor_part.isdigit(): + minor = int(minor_part) + + patch = 0 + if len(parts) > 2: + # Handle versions like "7.0.0-rc1" + patch_part = parts[2].split("-")[0] + if patch_part.isdigit(): + patch = int(patch_part) + + return (major, minor, patch) + + +def _compare_versions(v1, v2): + """ + Compare two version tuples. + + Returns: + -1 if v1 < v2, 0 if v1 == v2, 1 if v1 > v2 + """ + for i in range(3): + if v1[i] < v2[i]: + return -1 + elif v1[i] > v2[i]: + return 1 + return 0 + + +def version_satisfies(version, constraint): + """ + Check if version satisfies semver constraint. + + Args: + version: Version string like "7.0.0" or None + constraint: Semver constraint like "< 7", ">= 6 < 7", ">= 8", or "*" + + Returns: + True if version satisfies constraint, False otherwise + + Examples: + version_satisfies("7.0.0", "< 8") -> True + version_satisfies("7.0.0", ">= 7") -> True + version_satisfies("6.5.0", ">= 7") -> False + version_satisfies("6.5.0", ">= 6 < 7") -> True + version_satisfies(None, "< 7") -> True (no version means include all) + """ + if not version or constraint == "*" or not constraint: + return True + + v = parse_version(version) + + # Parse constraint like "< 7", ">= 6 < 7", ">= 8" + # Tokenize the constraint string + tokens = [] + current = "" + for c in constraint.elems(): + if c == " ": + if current: + tokens.append(current) + current = "" + else: + current += c + if current: + tokens.append(current) + + # Process tokens in pairs (operator, version) + # Tokens are like [">=", "6", "<", "7"] for ">= 6 < 7" + num_pairs = len(tokens) // 2 + for pair_idx in range(num_pairs): + i = pair_idx * 2 + op = tokens[i] + target_str = tokens[i + 1] + target = parse_version(target_str) + cmp = _compare_versions(v, target) + + if op == "<": + if cmp >= 0: + return False + elif op == "<=": + if cmp > 0: + return False + elif op == ">": + if cmp <= 0: + return False + elif op == ">=": + if cmp < 0: + return False + elif op == "=": + if cmp != 0: + return False + + return True + + +# ============================================================================= +# Configuration Reader Functions +# ============================================================================= + +def read_platform_config(fs, platform_dir = DEFAULT_PLATFORM_DIR): + """ + Read platform configuration from disk. + + Args: + fs: Filesystem interface (ctx.std.fs) + platform_dir: Path to platform config directory + + Returns: + dict with keys: remote_cache_endpoint, remote_cache_address, storage_path + """ + config = {} + + for key, filename in PLATFORM_CONFIG_KEYS.items(): + path = platform_dir + "/" + filename + if fs.exists(path): + content = fs.read_to_string(path) + if content: + config[key] = content.strip() + + # Apply defaults + if "storage_path" not in config: + config["storage_path"] = DEFAULT_STORAGE_PATH + + return config + + +def read_host_config(env, io): + """ + Read host/CI configuration from environment. + + Args: + env: Environment interface (ctx.std.env) + io: IO interface (ctx.std.io) + + Returns: + dict with keys: supports_curses, scm_repo_name, ci_host + """ + config = { + "supports_curses": io.stdout.is_tty if hasattr(io, "stdout") else False, + "scm_repo_name": None, + "ci_host": None, + } + + # Detect CI host and repo name + # BuildKite + buildkite_repo = env.var("BUILDKITE_REPO") + if buildkite_repo: + config["ci_host"] = "buildkite" + config["scm_repo_name"] = _parse_git_url_name(buildkite_repo) + config["supports_curses"] = True # BuildKite supports curses + return config + + # GitHub Actions + github_repo = env.var("GITHUB_REPOSITORY") + if github_repo: + config["ci_host"] = "github" + if "/" in github_repo: + config["scm_repo_name"] = github_repo.split("/")[-1] + else: + config["scm_repo_name"] = github_repo + return config + + # CircleCI + circle_repo = env.var("CIRCLE_PROJECT_REPONAME") + if circle_repo: + config["ci_host"] = "circleci" + config["scm_repo_name"] = circle_repo + return config + + # GitLab CI + gitlab_project = env.var("CI_PROJECT_NAME") + if gitlab_project: + config["ci_host"] = "gitlab" + config["scm_repo_name"] = gitlab_project + return config + + return config + + +def _parse_git_url_name(url): + """ + Extract repo name from git URL. + + Args: + url: Git URL like "git@github.com:org/repo.git" or "https://github.com/org/repo" + + Returns: + Repository name or None + """ + if not url: + return None + + name = url.rstrip("/") + + # Remove .git suffix + if name.endswith(".git"): + name = name[:-4] + + # Handle SSH URLs like git@github.com:org/repo + if ":" in name and "@" in name: + # Split by : and take last part + name = name.split(":")[-1] + + # Handle HTTP URLs - take last path segment + if "/" in name: + name = name.split("/")[-1] + + return name + + +# ============================================================================= +# Dynamic Value Resolution +# ============================================================================= + +def _sanitize_filename(name): + """ + Sanitize string for use in filesystem paths. + + Args: + name: Input string + + Returns: + Sanitized string with only alphanumeric, dash, underscore, and dot + """ + if not name: + return "" + + result = "" + for c in name: + if c.isalnum() or c in "-_.": + result += c + else: + result += "_" + return result + + +def _compute_output_path(platform_config, host_config, segment, workspace): + """ + Compute output_base or output_user_root path. + + Args: + platform_config: Platform configuration dict + host_config: Host configuration dict + segment: Path segment ("bazel" or "output") + workspace: Workspace name + + Returns: + Computed path string + """ + mount = platform_config.get("storage_path", DEFAULT_STORAGE_PATH) + + # Normalize workspace name + if workspace == "." or not workspace: + subdir = "__main__" + else: + subdir = workspace.replace("/", "_") + + # Include repo name if available + repo_name = host_config.get("scm_repo_name") + if repo_name: + return mount + "/" + segment + "/" + _sanitize_filename(repo_name) + "/" + subdir + else: + return mount + "/" + segment + "/" + subdir + + +def resolve_dynamic_value(key, platform_config, host_config, workspace, rbe_config = None): + """ + Resolve a dynamic value from config dicts. + + Args: + key: Dynamic key like "platform.remote_cache_endpoint" or "computed.repository_cache" + platform_config: Platform configuration dict + host_config: Host configuration dict + workspace: Workspace name + rbe_config: Optional RBE configuration dict with "enabled" and "jobs" keys + + Returns: + Resolved value string or None + """ + if key.startswith("platform."): + config_key = key[len("platform."):] + return platform_config.get(config_key) + + elif key.startswith("host."): + host_key = key[len("host."):] + if host_key == "curses": + return "yes" if host_config.get("supports_curses") else "no" + elif host_key == "progress_rate_limit": + return "5" if host_config.get("supports_curses") else "60" + return host_config.get(host_key) + + elif key.startswith("computed."): + computed_key = key[len("computed."):] + if computed_key == "repository_cache": + mount = platform_config.get("storage_path", DEFAULT_STORAGE_PATH) + return mount + "/caches/repository" + elif computed_key == "output_user_root": + return _compute_output_path(platform_config, host_config, "bazel", workspace) + elif computed_key == "output_base": + return _compute_output_path(platform_config, host_config, "output", workspace) + + elif key.startswith("rbe."): + if not rbe_config or not rbe_config.get("enabled"): + return None + rbe_key = key[len("rbe."):] + if rbe_key == "remote_executor": + # When RBE is enabled, use the remote cache endpoint as the executor + return platform_config.get("remote_cache_endpoint") + elif rbe_key == "jobs": + jobs = rbe_config.get("jobs") + return str(jobs) if jobs else None + + return None + + +# ============================================================================= +# Flag Resolution Functions +# ============================================================================= + +def resolve_flag_value(flag_def, platform_config, host_config, workspace, rbe_config = None): + """ + Resolve a flag's value from config dicts. + + Args: + flag_def: Flag definition dict + platform_config: Platform configuration dict + host_config: Host configuration dict + workspace: Workspace name + rbe_config: Optional RBE configuration dict + + Returns: + Resolved value string or None (for boolean flags) + """ + value = flag_def.get("value") + + if value == None: + return None # Boolean flag, no value + + if type(value) == "string" and value.startswith("dynamic:"): + dynamic_key = value[len("dynamic:"):] + return resolve_dynamic_value(dynamic_key, platform_config, host_config, workspace, rbe_config) + + return value # Static value + + +def stringify_flag(name, value): + """ + Convert flag name and value to string. + + Args: + name: Flag name + value: Flag value or None for boolean flags + + Returns: + Flag string like "--name=value" or "--name" + """ + if value == None: + return "--" + name + return "--" + name + "=" + str(value) + + +def should_include_flag(flag_def, version, task_types): + """ + Check if flag should be included based on version and task types. + + Args: + flag_def: Flag definition dict + version: Bazel version string or None + task_types: List of task type strings + + Returns: + True if flag should be included, False otherwise + """ + # Check version constraint + constraint = flag_def.get("versions", "*") + if not version_satisfies(version, constraint): + return False + + # Check task type requirement + required_types = flag_def.get("task_types") + if required_types: + for t in required_types: + if t in task_types: + return True + return False + + return True + + +# ============================================================================= +# Main Bazelrc Generation Function +# ============================================================================= + +def get_bazelrc_content( + platform_config, + host_config, + bazel_version = None, + task_types = None, + workspace = ".", + rbe_config = None, +): + """ + Generate complete .bazelrc content. + + Args: + platform_config: dict from read_platform_config() + host_config: dict from read_host_config() + bazel_version: str like "7.0.0" or None + task_types: list of task type strings (e.g., ["lint", "test"]) + workspace: workspace name (default ".") + rbe_config: Optional dict with RBE configuration {"enabled": bool, "jobs": int} + + Returns: + str: Complete .bazelrc file content + """ + if task_types == None: + task_types = [] + + lines = [ + "#### Aspect Workflows", + "#### Generated bazelrc file, do not edit", + "", + "#### Common Flags", + "", + ] + + # Combine all flag lists + all_flags = STATIC_BOOLEAN_FLAGS + STATIC_VALUE_FLAGS + VERSION_SPECIFIC_FLAGS + DYNAMIC_FLAGS + + for flag_def in all_flags: + if not should_include_flag(flag_def, bazel_version, task_types): + continue + + value = resolve_flag_value(flag_def, platform_config, host_config, workspace, rbe_config) + + # Skip if omit_if_none and value is None (for dynamic flags) + if flag_def.get("omit_if_none") and value == None: + continue + + # For boolean flags without explicit value, value will be None which is correct + flag_str = stringify_flag(flag_def["name"], value) + + # Add for each applicable command + for cmd in flag_def.get("commands", ["build"]): + lines.append(cmd + " " + flag_str) + + # Add startup flags section + lines.append("") + lines.append("#### Startup Flags") + lines.append("") + + for flag_def in STARTUP_FLAGS: + value = resolve_flag_value(flag_def, platform_config, host_config, workspace, rbe_config) + if value: + lines.append("startup " + stringify_flag(flag_def["name"], value)) + + lines.append("") + return "\n".join(lines) diff --git a/axel-f/platform.axl b/axel-f/platform.axl new file mode 100644 index 000000000..e69de29bb diff --git a/crates/aspect-cli/src/main.rs b/crates/aspect-cli/src/main.rs index b7d99bf5f..fd12e73fb 100644 --- a/crates/aspect-cli/src/main.rs +++ b/crates/aspect-cli/src/main.rs @@ -239,17 +239,16 @@ async fn main() -> miette::Result { } } - // Run all config functions, passing in vector of tasks for configuration - let tasks = config_eval - .run_all( - ModuleScope { - name: AXL_ROOT_MODULE_NAME.to_string(), - path: repo_root.clone(), - }, - configs.clone(), - tasks, - ) - .into_diagnostic()?; + // Build scoped configs list combining regular configs and env configs + let root_scope = ModuleScope { + name: AXL_ROOT_MODULE_NAME.to_string(), + path: repo_root.clone(), + }; + + let mut scoped_configs: Vec<(ModuleScope, PathBuf)> = configs + .iter() + .map(|path| (root_scope.clone(), path.clone())) + .collect(); // Run environment configs, each with scope derived from parent directory if debug_mode() && !env_configs.is_empty() { @@ -264,18 +263,20 @@ async fn main() -> miette::Result { } } - let mut tasks = tasks; for config_path in env_configs.iter() { let parent = config_path.parent().unwrap_or(&repo_root); let scope = ModuleScope { - name: AXL_ROOT_MODULE_NAME.to_string(), + name: "".to_string(), path: parent.to_path_buf(), }; - tasks = config_eval - .run_all(scope, vec![config_path.clone()], tasks) - .into_diagnostic()?; + scoped_configs.push((scope, config_path.clone())); } + // Run all config functions, passing in vector of tasks for configuration + let tasks = config_eval + .run_all(scoped_configs, tasks) + .into_diagnostic()?; + // Build the command tree from the evaluated and configured tasks. let mut tree = CommandTree::default(); diff --git a/crates/axl-runtime/src/eval/config.rs b/crates/axl-runtime/src/eval/config.rs index 70561b0e4..e9d116726 100644 --- a/crates/axl-runtime/src/eval/config.rs +++ b/crates/axl-runtime/src/eval/config.rs @@ -53,12 +53,9 @@ impl<'l, 'p> ConfigEvaluator<'l, 'p> { /// The tasks are modified in place via set_attr calls from config functions. pub fn run_all( &self, - scope: ModuleScope, - config_paths: Vec, + scoped_configs: Vec<(ModuleScope, PathBuf)>, tasks: Vec, ) -> Result, EvalError> { - self.loader.module_stack.borrow_mut().push(scope.clone()); - // Create temporary modules for evaluation let eval_module = Box::leak(Box::new(Module::new())); let context_module = Box::leak(Box::new(Module::new())); @@ -70,8 +67,10 @@ impl<'l, 'p> ConfigEvaluator<'l, 'p> { .downcast_ref::() .expect("just allocated ConfigContext"); - // Evaluate each config file - for path in &config_paths { + // Evaluate each config file with its associated scope + for (scope, path) in &scoped_configs { + self.loader.module_stack.borrow_mut().push(scope.clone()); + let rel_path = path .strip_prefix(&scope.path) .map_err(|e| EvalError::UnknownError(anyhow!("Failed to strip prefix: {e}")))? @@ -107,12 +106,13 @@ impl<'l, 'p> ConfigEvaluator<'l, 'p> { // Keep the frozen module alive for the duration ctx.add_config_module(frozen); + + self.loader.module_stack.borrow_mut().pop(); } // Clone tasks from the context to return let result_tasks: Vec = ctx.tasks().iter().map(|t| (*t).clone()).collect(); - self.loader.module_stack.borrow_mut().pop(); Ok(result_tasks) } } From 17dbca95af858a4e85090680455e05b1dab616e8 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Tue, 27 Jan 2026 15:09:07 -0800 Subject: [PATCH 07/65] configuration --- .aspect/user-task.axl | 2 +- BUILD.bazel | 7 + axel-f/config.axl | 19 +- axel-f/platform-config.axl | 2 +- axel-f/platform.axl | 0 .../axl-runtime/src/builtins/aspect/build.axl | 21 + .../axl-runtime/src/engine/config/context.rs | 6 + .../engine/config/tasks/configured_task.rs | 136 ++- .../src/engine/config/tasks/value.rs | 30 +- crates/axl-runtime/src/engine/mod.rs | 1 + crates/axl-runtime/src/engine/task.rs | 4 +- crates/axl-runtime/src/engine/types/mod.rs | 1 + crates/axl-runtime/src/engine/types/record.rs | 848 ++++++++++++++++++ crates/axl-runtime/src/engine/wasm/mod.rs | 1 + crates/axl-runtime/src/eval/config.rs | 17 +- crates/axl-runtime/src/eval/task.rs | 10 +- 16 files changed, 1047 insertions(+), 58 deletions(-) delete mode 100644 axel-f/platform.axl create mode 100644 crates/axl-runtime/src/engine/types/record.rs diff --git a/.aspect/user-task.axl b/.aspect/user-task.axl index d85135450..b0fd7ce33 100644 --- a/.aspect/user-task.axl +++ b/.aspect/user-task.axl @@ -26,5 +26,5 @@ user_task = task( group = ["user"], implementation = _impl, args = {}, - config = UserTaskConfig(), + config = UserTaskConfig, ) diff --git a/BUILD.bazel b/BUILD.bazel index d38de46e3..a9a43859c 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -3,6 +3,13 @@ alias( actual = "//crates/aspect-launcher", ) +genrule( + name = "hello", + srcs = [], + outs = ["hello.txt"], + cmd = "echo 'Hello, World!' > $@", +) + alias( name = "cli", actual = "//crates/aspect-cli", diff --git a/axel-f/config.axl b/axel-f/config.axl index 040e2449c..50ba44846 100644 --- a/axel-f/config.axl +++ b/axel-f/config.axl @@ -13,7 +13,8 @@ load("./platform-config.axl", PLATFORM_DIR = "/etc/aspect/workflows/platform" def config(ctx: ConfigContext): - print(ctx.tasks) + if ctx.std.env.var("BUILDKITE"): + print("--- Configuring Workflows") # Read platform config from disk platform_config = read_platform_config( @@ -36,9 +37,17 @@ def config(ctx: ConfigContext): workspace = ".", ) + ctx.std.fs.write("/tmp/bazelrc", content) + + for task in ctx.tasks: + if task.name == "build" and task.path.endswith("aspect/build.axl"): + task.config.startup_flags = lambda flags: flags + ["--bazelrc=/tmp/bazelrc"] + task.config.flags = lambda flags: flags + task.config.build_start = lambda: print("+++ Building") + task.config.build_end = lambda status: print(f"--- Build done {status}") print(content) - # ctx.tasks.add(configure) - # ctx.tasks.add(gazelle) - # ctx.tasks.add(buildifier) - # ctx.tasks.add(migrate) + ctx.tasks.add(configure) + ctx.tasks.add(gazelle) + ctx.tasks.add(buildifier) + ctx.tasks.add(migrate) diff --git a/axel-f/platform-config.axl b/axel-f/platform-config.axl index 338d8c1cf..b0dc3e11c 100644 --- a/axel-f/platform-config.axl +++ b/axel-f/platform-config.axl @@ -437,7 +437,7 @@ def _sanitize_filename(name): return "" result = "" - for c in name: + for c in name.elems(): if c.isalnum() or c in "-_.": result += c else: diff --git a/axel-f/platform.axl b/axel-f/platform.axl deleted file mode 100644 index e69de29bb..000000000 diff --git a/crates/axl-runtime/src/builtins/aspect/build.axl b/crates/axl-runtime/src/builtins/aspect/build.axl index 28a27304e..8ca1c90bf 100644 --- a/crates/axl-runtime/src/builtins/aspect/build.axl +++ b/crates/axl-runtime/src/builtins/aspect/build.axl @@ -2,6 +2,15 @@ A default 'build' task that wraps a 'bazel build' command. """ +BuildConfig = spec( + startup_flags = attr(typing.Callable[[list[str]], list[str]], lambda flags: flags), + flags = attr(typing.Callable[[list[str]], list[str]], lambda flags: flags), + # TODO: build event sinks configuration + # Lifecycle + build_start = attr(typing.Callable[[], None], lambda: None), + build_end = attr(typing.Callable[[int], None], lambda status: None) +) + def impl(ctx: TaskContext) -> int: stdout = ctx.std.io.stdout @@ -28,6 +37,12 @@ def impl(ctx: TaskContext) -> int: for flag in ctx.args.bazel_startup_flag: bazel_startup_flags.append(flag) + # Apply flags and startup flags by config + bazel_flags = ctx.config.flags(bazel_flags) + bazel_startup_flags = ctx.config.startup_flags(bazel_startup_flags) + + ctx.config.build_start() + build = ctx.bazel.build( build_events = build_events, flags = bazel_flags, @@ -36,16 +51,22 @@ def impl(ctx: TaskContext) -> int: ) build_status = build.wait() + + ctx.config.build_end(build_status.code) + return build_status.code build = task( implementation = impl, + config = BuildConfig, args = { # TODO: Support a long --pattern_file like bazel does (@./targets) # TODO: Support - (list from stdin) "target_pattern": args.positional(minimum = 1, maximum = 512, default = ["..."]), "bazel_flag": args.string_list(), "bazel_startup_flag": args.string_list(), + "remote_executor": args.string(), + "remote_cache": args.string(), "bes_backend": args.string_list(), "bes_header": args.string_list(), } diff --git a/crates/axl-runtime/src/engine/config/context.rs b/crates/axl-runtime/src/engine/config/context.rs index 34af5f023..c09279f3e 100644 --- a/crates/axl-runtime/src/engine/config/context.rs +++ b/crates/axl-runtime/src/engine/config/context.rs @@ -70,6 +70,12 @@ impl<'v> ConfigContext<'v> { .collect() } + /// Get task values for iteration (used during config evaluation). + pub fn task_values(&self) -> Vec> { + let list = self.tasks.downcast_ref::().unwrap(); + list.0.borrow().content.clone() + } + /// Add a config module for lifetime management. pub fn add_config_module(&self, module: FrozenModule) { self.config_modules.borrow_mut().push(module); diff --git a/crates/axl-runtime/src/engine/config/tasks/configured_task.rs b/crates/axl-runtime/src/engine/config/tasks/configured_task.rs index 1c2926133..9d7a94d90 100644 --- a/crates/axl-runtime/src/engine/config/tasks/configured_task.rs +++ b/crates/axl-runtime/src/engine/config/tasks/configured_task.rs @@ -1,7 +1,4 @@ -//! ConfiguredTask - A task with its configuration, using frozen values. -//! -//! This type uses `OwnedFrozenValue` to manage heap lifetimes automatically, -//! following Buck2's pattern for safe frozen value management. +//! ConfiguredTask - A task with its configuration. use std::cell::RefCell; use std::path::PathBuf; @@ -13,6 +10,7 @@ use starlark::environment::FrozenModule; use starlark::environment::Methods; use starlark::environment::MethodsBuilder; use starlark::environment::MethodsStatic; +use starlark::eval::Evaluator; use starlark::starlark_module; use starlark::values; use starlark::values::Heap; @@ -32,16 +30,14 @@ use crate::engine::task::FrozenTask; use crate::engine::task::TaskLike; use crate::eval::EvalError; -use super::frozen::freeze_value; - -/// A task bundled with its configuration, using frozen values for safe heap management. +/// A task bundled with its configuration. /// /// This type: /// - Has no lifetime parameter (easy to store and pass around) -/// - Uses `OwnedFrozenValue` to keep heaps alive automatically +/// - Uses `OwnedFrozenValue` for frozen values (task definition) +/// - Stores config binding for lazy evaluation during config phase /// - Is a `StarlarkValue` that config functions can modify via `set_attr` -/// - Can be created from a `FrozenModule` -#[derive(Debug, Clone, ProvidesStaticType, Display, NoSerialize, Allocative)] +#[derive(Debug, ProvidesStaticType, Display, NoSerialize, Allocative, Clone)] #[display("")] pub struct ConfiguredTask { /// The frozen task definition (contains implementation function) @@ -51,26 +47,34 @@ pub struct ConfiguredTask { pub name: RefCell, /// Task group (may be overridden by config) pub group: RefCell>, - /// Configured config value + /// The frozen config binding (callable that returns config) + #[allocative(skip)] + config_binding: OwnedFrozenValue, + /// The lazily evaluated config value (mutable, stays on the heap) + /// SAFETY: This value lives on the same heap as ConfiguredTask + /// None until evaluate_config() is called #[allocative(skip)] - pub config: RefCell, + evaluated_config: RefCell>>, /// Symbol name in the module pub symbol: String, /// Path to the .axl file pub path: PathBuf, } -// ConfiguredTask doesn't need tracing since it only contains frozen values unsafe impl Trace<'_> for ConfiguredTask { fn trace(&mut self, _tracer: &values::Tracer<'_>) { - // OwnedFrozenValue manages its own heap lifetime, no tracing needed + // The evaluated_config value uses 'static lifetime as a workaround, but the actual + // value lives on the same heap as ConfiguredTask. Since ConfiguredTask + // is allocated with alloc_complex_no_freeze, the heap manages tracing. + // The config_binding is an OwnedFrozenValue which manages its own lifetime. } } impl ConfiguredTask { /// Create a ConfiguredTask from a FrozenModule. /// - /// Extracts the task definition and initial config from the frozen module. + /// Stores the config binding for lazy evaluation. Call `evaluate_config()` + /// during config phase when an Evaluator is available. pub fn from_frozen_module( frozen: &FrozenModule, symbol: &str, @@ -94,18 +98,72 @@ impl ConfiguredTask { frozen_task.name.clone() }; let group = frozen_task.group.clone(); - let initial_config = OwnedFrozenValue::alloc(frozen_task.config); + + // Store the config binding for lazy evaluation + let config_binding = task_def.map(|_| frozen_task.config()); Ok(ConfiguredTask { task_def, name: RefCell::new(name), group: RefCell::new(group), - config: RefCell::new(initial_config), + config_binding, + evaluated_config: RefCell::new(None), symbol: symbol.to_string(), path, }) } + /// Evaluate the config binding and store the result. + /// + /// This must be called during config phase when an Evaluator is available. + /// After this call, `get_config()` will return the evaluated value. + pub fn evaluate_config<'v>(&self, eval: &mut Evaluator<'v, '_, '_>) -> Result<(), EvalError> { + // Get the frozen binding value - this has 'static lifetime from OwnedFrozenValue + let binding = self.config_binding.value(); + // SAFETY: FrozenValue has 'static lifetime, we need to convert to Value<'v> + // to call eval_function. The actual value is frozen and valid for 'static. + let binding_value: Value<'v> = unsafe { std::mem::transmute(binding) }; + + let config_value: Value<'v> = if binding_value.is_none() { + binding_value + } else { + eval.eval_function(binding_value, &[], &[]).map_err(|e| { + EvalError::UnknownError(anyhow!("failed to evaluate config binding: {:?}", e)) + })? + }; + + // SAFETY: The config value lives on the evaluator's heap. The lifetime is valid + // as long as the heap outlives this ConfiguredTask. + let config: Value<'static> = unsafe { std::mem::transmute(config_value) }; + self.evaluated_config.replace(Some(config)); + Ok(()) + } + + /// Create a ConfiguredTask with an already-evaluated config value. + /// + /// Use this when an Evaluator is available (e.g., in task_list.add()). + pub fn new_with_evaluated_config<'v>( + task_def: OwnedFrozenValue, + config_binding: OwnedFrozenValue, + name: String, + group: Vec, + config: Value<'v>, + symbol: String, + path: PathBuf, + ) -> Self { + // SAFETY: Same as evaluate_config - config lives on the same heap + let config: Value<'static> = unsafe { std::mem::transmute(config) }; + ConfiguredTask { + task_def, + config_binding, + name: RefCell::new(name), + group: RefCell::new(group), + evaluated_config: RefCell::new(Some(config)), + symbol, + path, + } + } + /// Get a reference to the underlying FrozenTask. pub fn as_frozen_task(&self) -> Option<&FrozenTask> { self.task_def.value().downcast_ref::() @@ -123,8 +181,29 @@ impl ConfiguredTask { } /// Get the current config value. - pub fn get_config(&self) -> OwnedFrozenValue { - self.config.borrow().clone() + /// + /// Panics if `evaluate_config()` has not been called. + pub fn get_config<'v>(&self) -> Value<'v> { + let config = self.evaluated_config.borrow(); + let config = config.expect("config not yet evaluated - call evaluate_config() first"); + // SAFETY: Transmute back to the caller's lifetime - valid because + // the heap outlives this call + unsafe { std::mem::transmute(config) } + } + + /// Try to get the current config value, returning None if not yet evaluated. + pub fn try_get_config<'v>(&self) -> Option> { + let config = *self.evaluated_config.borrow(); + // SAFETY: Transmute back to the caller's lifetime - valid because + // the heap outlives this call + config.map(|c| unsafe { std::mem::transmute(c) }) + } + + /// Set the config value. + pub fn set_config<'v>(&self, value: Value<'v>) { + // SAFETY: Same lifetime reasoning as get_config + let value: Value<'static> = unsafe { std::mem::transmute(value) }; + self.evaluated_config.replace(Some(value)); } /// Get the current name. @@ -136,6 +215,11 @@ impl ConfiguredTask { pub fn get_group(&self) -> Vec { self.group.borrow().clone() } + + /// Get the config binding (for creating new ConfiguredTasks with evaluated config). + pub fn config_binding(&self) -> &OwnedFrozenValue { + &self.config_binding + } } #[starlark_value(type = "ConfiguredTask")] @@ -151,10 +235,7 @@ impl<'v> values::StarlarkValue<'v> for ConfiguredTask { self.group.replace(unpack.items); } "config" => { - // Freeze the config value so it can be safely stored - let frozen = - freeze_value(value).map_err(|e| anyhow!("failed to freeze config: {:?}", e))?; - self.config.replace(frozen); + self.set_config(value); } _ => return ValueError::unsupported(self, &format!(".{}=", attribute)), }; @@ -165,14 +246,7 @@ impl<'v> values::StarlarkValue<'v> for ConfiguredTask { match attribute { "name" => Some(heap.alloc_str(&self.name.borrow()).to_value()), "group" => Some(heap.alloc(AllocList(self.group.borrow().iter()))), - "config" => { - // Return the frozen config value - let config = self.config.borrow(); - let value = config.value(); - // SAFETY: The OwnedFrozenValue keeps its heap alive, and we're - // returning a Value that will be used within this evaluation. - Some(unsafe { std::mem::transmute::, Value<'v>>(value) }) - } + "config" => Some(self.get_config()), "symbol" => Some(heap.alloc_str(&self.symbol).to_value()), "path" => Some(heap.alloc_str(&self.path.to_string_lossy()).to_value()), _ => None, diff --git a/crates/axl-runtime/src/engine/config/tasks/value.rs b/crates/axl-runtime/src/engine/config/tasks/value.rs index dafc08a8b..4c99e71fb 100644 --- a/crates/axl-runtime/src/engine/config/tasks/value.rs +++ b/crates/axl-runtime/src/engine/config/tasks/value.rs @@ -16,7 +16,6 @@ use starlark::typing::Ty; use starlark::values::AllocValue; use starlark::values::Heap; use starlark::values::NoSerialize; -use starlark::values::OwnedFrozenValue; use starlark::values::StarlarkValue; use starlark::values::Trace; use starlark::values::Value; @@ -80,22 +79,33 @@ pub(crate) fn task_list_methods(registry: &mut MethodsBuilder) { .get(&symbol) .map_err(|e| anyhow::anyhow!("failed to get frozen task: {:?}", e))?; - // Get initial config from the frozen task + // Get config binding from the frozen task and evaluate it let frozen_task = task_def .value() .downcast_ref::() .ok_or_else(|| anyhow::anyhow!("expected FrozenTask after freeze"))?; - let initial_config = OwnedFrozenValue::alloc(frozen_task.config); - // Create ConfiguredTask with frozen values - let task_mut = ConfiguredTask { + // Get the config binding as OwnedFrozenValue + let config_binding = task_def.map(|_| frozen_task.config()); + + // Evaluate the config binding (always a callable) + let binding = frozen_task.config(); + let config_value = if binding.to_value().is_none() { + binding.to_value() + } else { + eval.eval_function(binding.to_value(), &[], &[])? + }; + + // Create ConfiguredTask with evaluated config + let task_mut = ConfiguredTask::new_with_evaluated_config( task_def, - name: RefCell::new(name), - group: RefCell::new(task_like.group().to_vec()), - config: RefCell::new(initial_config), + config_binding, + name, + task_like.group().to_vec(), + config_value, symbol, - path: PathBuf::from(store.script_path.to_string_lossy().to_string()), - }; + PathBuf::from(store.script_path.to_string_lossy().to_string()), + ); this.aref.content.push(eval.heap().alloc(task_mut)); Ok(NoneType) diff --git a/crates/axl-runtime/src/engine/mod.rs b/crates/axl-runtime/src/engine/mod.rs index 7634a7136..3952eb93c 100644 --- a/crates/axl-runtime/src/engine/mod.rs +++ b/crates/axl-runtime/src/engine/mod.rs @@ -37,6 +37,7 @@ pub fn register_globals(globals: &mut GlobalsBuilder) { globals::register_globals(globals); r#async::register_globals(globals); task::register_globals(globals); + types::record::register_globals(globals); globals.namespace("args", task_arg::register_globals); globals.namespace("bazel", bazel::register_globals); diff --git a/crates/axl-runtime/src/engine/task.rs b/crates/axl-runtime/src/engine/task.rs index 6f1bba3ac..921a8aa2f 100644 --- a/crates/axl-runtime/src/engine/task.rs +++ b/crates/axl-runtime/src/engine/task.rs @@ -190,7 +190,7 @@ pub fn register_globals(globals: &mut GlobalsBuilder) { /// task_args = { /// "target": args.string(), /// }, - /// config = None # Optional user-defined config (e.g., a record); defaults to None if not provided + /// config = lambda: MyConfig(key = "value") # Optional lambda that returns config; evaluated at task creation /// ) /// ``` fn task<'v>( @@ -222,7 +222,7 @@ pub fn register_globals(globals: &mut GlobalsBuilder) { description, group: group.items, name, - config: config.into_option().unwrap_or(values::Value::new_none()), + config: config.into_option().unwrap_or(Value::new_none()), }) } } diff --git a/crates/axl-runtime/src/engine/types/mod.rs b/crates/axl-runtime/src/engine/types/mod.rs index ad0049c4c..9afd7fe17 100644 --- a/crates/axl-runtime/src/engine/types/mod.rs +++ b/crates/axl-runtime/src/engine/types/mod.rs @@ -1 +1,2 @@ pub mod bytes; +pub mod record; diff --git a/crates/axl-runtime/src/engine/types/record.rs b/crates/axl-runtime/src/engine/types/record.rs new file mode 100644 index 000000000..021a68d3c --- /dev/null +++ b/crates/axl-runtime/src/engine/types/record.rs @@ -0,0 +1,848 @@ +use std::cell::Cell; +use std::fmt::{self, Display, Write}; +use std::sync::atomic::{AtomicU64, Ordering}; + +use allocative::Allocative; +use dupe::Dupe; +use starlark::environment::{GlobalsBuilder, Methods, MethodsBuilder, MethodsStatic}; +use starlark::starlark_module; +use starlark::values::typing::TypeCompiled; +use starlark::values::{ + starlark_value, AllocFrozenValue, AllocValue, Freeze, FreezeError, Freezer, FrozenHeap, + FrozenValue, Heap, NoSerialize, ProvidesStaticType, StarlarkValue, Trace, Tracer, Value, + ValueLike, +}; +use starlark_map::small_map::SmallMap; + +static RECORD_TYPE_ID: AtomicU64 = AtomicU64::new(0); + +fn next_record_type_id() -> u64 { + RECORD_TYPE_ID.fetch_add(1, Ordering::SeqCst) +} + +// ----------------------------------------------------------------------------- +// Field +// ----------------------------------------------------------------------------- + +/// A field definition for a record, containing a type and optional default value. +#[derive(Debug, Clone, ProvidesStaticType, Allocative)] +pub struct Field<'v> { + pub(crate) typ: TypeCompiled>, + pub(crate) default: Option>, +} + +impl<'v> Display for Field<'v> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self.default { + None => write!(f, "field({})", self.typ), + Some(d) => write!(f, "field({}, {})", self.typ, d), + } + } +} + +unsafe impl<'v> Trace<'v> for Field<'v> { + fn trace(&mut self, tracer: &Tracer<'v>) { + self.typ.trace(tracer); + if let Some(ref mut d) = self.default { + d.trace(tracer); + } + } +} + +impl<'v> Field<'v> { + pub fn freeze(self, freezer: &Freezer) -> Result { + Ok(FrozenField { + typ: self.typ.freeze(freezer)?, + default: self.default.map(|d| d.freeze(freezer)).transpose()?, + }) + } +} + +/// A frozen field definition. +#[derive(Debug, Clone, ProvidesStaticType, Allocative)] +pub struct FrozenField { + pub(crate) typ: TypeCompiled, + pub(crate) default: Option, +} + +impl Display for FrozenField { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self.default { + None => write!(f, "field({})", self.typ), + Some(d) => write!(f, "field({}, {})", self.typ, d), + } + } +} + +// ----------------------------------------------------------------------------- +// FieldValue - a wrapper for field() function return +// ----------------------------------------------------------------------------- + +#[derive(Debug, ProvidesStaticType, NoSerialize, Allocative)] +pub struct FieldValue<'v> { + pub(crate) typ: TypeCompiled>, + pub(crate) default: Option>, +} + +impl<'v> Display for FieldValue<'v> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self.default { + None => write!(f, "field({})", self.typ), + Some(d) => write!(f, "field({}, {})", self.typ, d), + } + } +} + +unsafe impl<'v> Trace<'v> for FieldValue<'v> { + fn trace(&mut self, tracer: &Tracer<'v>) { + self.typ.trace(tracer); + if let Some(ref mut d) = self.default { + d.trace(tracer); + } + } +} + +impl<'v> AllocValue<'v> for FieldValue<'v> { + fn alloc_value(self, heap: &'v Heap) -> Value<'v> { + heap.alloc_complex(self) + } +} + +#[starlark_value(type = "field")] +impl<'v> StarlarkValue<'v> for FieldValue<'v> { + fn collect_repr(&self, collector: &mut String) { + write!(collector, "{}", self).unwrap(); + } +} + +/// Frozen version of FieldValue. +#[derive(Debug, ProvidesStaticType, NoSerialize, Allocative)] +pub struct FrozenFieldValue { + pub(crate) typ: TypeCompiled, + pub(crate) default: Option, +} + +impl Display for FrozenFieldValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self.default { + None => write!(f, "field({})", self.typ), + Some(d) => write!(f, "field({}, {})", self.typ, d), + } + } +} + +unsafe impl<'v> Trace<'v> for FrozenFieldValue { + fn trace(&mut self, _tracer: &Tracer<'v>) { + // Frozen values don't need tracing + } +} + +impl AllocFrozenValue for FrozenFieldValue { + fn alloc_frozen_value(self, heap: &FrozenHeap) -> FrozenValue { + heap.alloc_simple(self) + } +} + +#[starlark_value(type = "field")] +impl<'v> StarlarkValue<'v> for FrozenFieldValue { + type Canonical = FieldValue<'v>; + + fn collect_repr(&self, collector: &mut String) { + write!(collector, "{}", self).unwrap(); + } +} + +impl Freeze for FieldValue<'_> { + type Frozen = FrozenFieldValue; + + fn freeze(self, freezer: &Freezer) -> Result { + Ok(FrozenFieldValue { + typ: self.typ.freeze(freezer)?, + default: self.default.map(|d| d.freeze(freezer)).transpose()?, + }) + } +} + +// ----------------------------------------------------------------------------- +// RecordType +// ----------------------------------------------------------------------------- + +/// The type of a record, created by `record(field1=type1, field2=type2, ...)`. +/// Calling this type creates a `Record` instance. +#[derive(Debug, ProvidesStaticType, NoSerialize, Allocative)] +pub struct RecordType<'v> { + /// Unique identifier for this record type + pub(crate) id: u64, + /// Name of the record type (set when assigned to a variable) + pub(crate) name: Option, + /// Fields with their types and optional defaults + pub(crate) fields: SmallMap>, +} + +impl<'v> Display for RecordType<'v> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self.name { + Some(name) => write!(f, "record[{}]", name), + None => write!(f, "record[anon]"), + } + } +} + +unsafe impl<'v> Trace<'v> for RecordType<'v> { + fn trace(&mut self, tracer: &Tracer<'v>) { + for (_, field) in self.fields.iter_mut() { + field.trace(tracer); + } + } +} + +impl<'v> AllocValue<'v> for RecordType<'v> { + fn alloc_value(self, heap: &'v Heap) -> Value<'v> { + heap.alloc_complex(self) + } +} + +#[starlark_value(type = "record_type")] +impl<'v> StarlarkValue<'v> for RecordType<'v> { + fn collect_repr(&self, collector: &mut String) { + write!(collector, "{}", self).unwrap(); + } + + fn export_as( + &self, + variable_name: &str, + _eval: &mut starlark::eval::Evaluator<'v, '_, '_>, + ) -> starlark::Result<()> { + // This is called when the record type is assigned to a variable. + // We use unsafe to mutate the name, which is safe because this is only + // called during module loading. + let this = self as *const Self as *mut Self; + unsafe { + (*this).name = Some(variable_name.to_string()); + } + Ok(()) + } + + fn invoke( + &self, + _me: Value<'v>, + args: &starlark::eval::Arguments<'v, '_>, + eval: &mut starlark::eval::Evaluator<'v, '_, '_>, + ) -> starlark::Result> { + // Parse the arguments according to our field definitions + let mut values: Vec>> = Vec::with_capacity(self.fields.len()); + + // Get the named arguments + args.no_positional_args(eval.heap())?; + let kwargs = args.names_map()?; + + // Build values in field order + for (field_name, field) in self.fields.iter() { + let value = if let Some(v) = kwargs.get(field_name.as_str()) { + *v + } else if let Some(default) = field.default { + default + } else { + return Err(starlark::Error::new_other(anyhow::anyhow!( + "Missing required field `{}` for {}", + field_name, + self + ))); + }; + + // Type check the value + if !field.typ.matches(value) { + return Err(starlark::Error::new_other(anyhow::anyhow!( + "Field `{}` expected type `{}`, got `{}`", + field_name, + field.typ, + value.get_type() + ))); + } + + values.push(Cell::new(value)); + } + + // Check for unexpected kwargs + for (name, _) in kwargs.iter() { + if !self.fields.contains_key(name.as_str()) { + return Err(starlark::Error::new_other(anyhow::anyhow!( + "Unexpected field `{}` for {}", + name, + self + ))); + } + } + + let record = Record { + typ: _me, + values: values.into_boxed_slice(), + }; + Ok(eval.heap().alloc(record)) + } + + fn get_methods() -> Option<&'static Methods> { + static RES: MethodsStatic = MethodsStatic::new(); + RES.methods(record_type_methods) + } +} + +#[starlark_module] +fn record_type_methods(_builder: &mut MethodsBuilder) {} + +// ----------------------------------------------------------------------------- +// FrozenRecordType +// ----------------------------------------------------------------------------- + +/// Frozen version of RecordType. +#[derive(Debug, ProvidesStaticType, NoSerialize, Allocative)] +pub struct FrozenRecordType { + pub(crate) id: u64, + pub(crate) name: Option, + pub(crate) fields: SmallMap, +} + +impl Display for FrozenRecordType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self.name { + Some(name) => write!(f, "record[{}]", name), + None => write!(f, "record[anon]"), + } + } +} + +unsafe impl<'v> Trace<'v> for FrozenRecordType { + fn trace(&mut self, _tracer: &Tracer<'v>) { + // Frozen values don't need tracing + } +} + +impl AllocFrozenValue for FrozenRecordType { + fn alloc_frozen_value(self, heap: &FrozenHeap) -> FrozenValue { + heap.alloc_simple(self) + } +} + +#[starlark_value(type = "record_type")] +impl<'v> StarlarkValue<'v> for FrozenRecordType { + type Canonical = RecordType<'v>; + + fn collect_repr(&self, collector: &mut String) { + write!(collector, "{}", self).unwrap(); + } + + fn invoke( + &self, + _me: Value<'v>, + args: &starlark::eval::Arguments<'v, '_>, + eval: &mut starlark::eval::Evaluator<'v, '_, '_>, + ) -> starlark::Result> { + let mut values: Vec>> = Vec::with_capacity(self.fields.len()); + + args.no_positional_args(eval.heap())?; + let kwargs = args.names_map()?; + + for (field_name, field) in self.fields.iter() { + let value = if let Some(v) = kwargs.get(field_name.as_str()) { + *v + } else if let Some(default) = field.default { + default.to_value() + } else { + return Err(starlark::Error::new_other(anyhow::anyhow!( + "Missing required field `{}` for {}", + field_name, + self + ))); + }; + + // Type check using matches on the value representation + if !field.typ.matches(value) { + return Err(starlark::Error::new_other(anyhow::anyhow!( + "Field `{}` expected type `{}`, got `{}`", + field_name, + field.typ, + value.get_type() + ))); + } + + values.push(Cell::new(value)); + } + + for (name, _) in kwargs.iter() { + if !self.fields.contains_key(name.as_str()) { + return Err(starlark::Error::new_other(anyhow::anyhow!( + "Unexpected field `{}` for {}", + name, + self + ))); + } + } + + let record = Record { + typ: _me, + values: values.into_boxed_slice(), + }; + Ok(eval.heap().alloc(record)) + } + + fn get_methods() -> Option<&'static Methods> { + static RES: MethodsStatic = MethodsStatic::new(); + RES.methods(record_type_methods) + } +} + +impl Freeze for RecordType<'_> { + type Frozen = FrozenRecordType; + + fn freeze(self, freezer: &Freezer) -> Result { + let mut frozen_fields = SmallMap::with_capacity(self.fields.len()); + for (name, field) in self.fields.into_iter() { + frozen_fields.insert(name, field.freeze(freezer)?); + } + Ok(FrozenRecordType { + id: self.id, + name: self.name, + fields: frozen_fields, + }) + } +} + +// ----------------------------------------------------------------------------- +// Record +// ----------------------------------------------------------------------------- + +/// An instance of a record type, containing field values. +#[derive(Debug, ProvidesStaticType, NoSerialize, Allocative)] +pub struct Record<'v> { + /// The record type this instance belongs to + pub(crate) typ: Value<'v>, + /// Field values in the same order as the type's field definitions (mutable via Cell) + #[allocative(skip)] + pub(crate) values: Box<[Cell>]>, +} + +impl<'v> Display for Record<'v> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}(", self.typ)?; + if let Some(record_type) = self.typ.downcast_ref::() { + let mut first = true; + for ((name, _), value) in record_type.fields.iter().zip(self.values.iter()) { + if !first { + write!(f, ", ")?; + } + first = false; + write!(f, "{}={}", name, value.get())?; + } + } else if let Some(frozen_type) = self.typ.downcast_ref::() { + let mut first = true; + for ((name, _), value) in frozen_type.fields.iter().zip(self.values.iter()) { + if !first { + write!(f, ", ")?; + } + first = false; + write!(f, "{}={}", name, value.get())?; + } + } + write!(f, ")") + } +} + +unsafe impl<'v> Trace<'v> for Record<'v> { + fn trace(&mut self, tracer: &Tracer<'v>) { + self.typ.trace(tracer); + for cell in self.values.iter() { + let mut v = cell.get(); + v.trace(tracer); + cell.set(v); + } + } +} + +impl<'v> AllocValue<'v> for Record<'v> { + fn alloc_value(self, heap: &'v Heap) -> Value<'v> { + heap.alloc_complex(self) + } +} + +impl<'v> Record<'v> { + fn get_field_names(&self) -> Vec<&str> { + if let Some(record_type) = self.typ.downcast_ref::() { + record_type.fields.keys().map(|s| s.as_str()).collect() + } else if let Some(frozen_type) = self.typ.downcast_ref::() { + frozen_type.fields.keys().map(|s| s.as_str()).collect() + } else { + vec![] + } + } +} + +#[starlark_value(type = "record")] +impl<'v> StarlarkValue<'v> for Record<'v> { + fn collect_repr(&self, collector: &mut String) { + write!(collector, "{}", self).unwrap(); + } + + fn get_attr(&self, attribute: &str, _heap: &'v Heap) -> Option> { + if let Some(record_type) = self.typ.downcast_ref::() { + if let Some(idx) = record_type.fields.get_index_of(attribute) { + return Some(self.values[idx].get()); + } + } else if let Some(frozen_type) = self.typ.downcast_ref::() { + if let Some(idx) = frozen_type.fields.get_index_of(attribute) { + return Some(self.values[idx].get()); + } + } + None + } + + fn set_attr(&self, attribute: &str, value: Value<'v>) -> starlark::Result<()> { + // Get field info and index + let (idx, field_typ) = if let Some(record_type) = self.typ.downcast_ref::() { + if let Some(idx) = record_type.fields.get_index_of(attribute) { + (idx, &record_type.fields.get_index(idx).unwrap().1.typ) + } else { + return Err(starlark::Error::new_other(anyhow::anyhow!( + "Record {} has no field `{}`", + self.typ, + attribute + ))); + } + } else if let Some(frozen_type) = self.typ.downcast_ref::() { + if let Some(idx) = frozen_type.fields.get_index_of(attribute) { + // For frozen types, we need to check against the frozen field's type + let field = frozen_type.fields.get_index(idx).unwrap().1; + if !field.typ.matches(value) { + return Err(starlark::Error::new_other(anyhow::anyhow!( + "Field `{}` expected type `{}`, got `{}`", + attribute, + field.typ, + value.get_type() + ))); + } + self.values[idx].set(value); + return Ok(()); + } else { + return Err(starlark::Error::new_other(anyhow::anyhow!( + "Record {} has no field `{}`", + self.typ, + attribute + ))); + } + } else { + return Err(starlark::Error::new_other(anyhow::anyhow!( + "Invalid record type" + ))); + }; + + // Type check the value + if !field_typ.matches(value) { + return Err(starlark::Error::new_other(anyhow::anyhow!( + "Field `{}` expected type `{}`, got `{}`", + attribute, + field_typ, + value.get_type() + ))); + } + + // Set the value + self.values[idx].set(value); + Ok(()) + } + + fn has_attr(&self, attribute: &str, _heap: &'v Heap) -> bool { + if let Some(record_type) = self.typ.downcast_ref::() { + record_type.fields.contains_key(attribute) + } else if let Some(frozen_type) = self.typ.downcast_ref::() { + frozen_type.fields.contains_key(attribute) + } else { + false + } + } + + fn dir_attr(&self) -> Vec { + self.get_field_names() + .into_iter() + .map(|s| s.to_string()) + .collect() + } + + fn equals(&self, other: Value<'v>) -> starlark::Result { + if let Some(other_record) = other.downcast_ref::() { + // Check that they have the same record type + let self_id = self + .typ + .downcast_ref::() + .map(|t| t.id) + .or_else(|| self.typ.downcast_ref::().map(|t| t.id)); + let other_id = other_record + .typ + .downcast_ref::() + .map(|t| t.id) + .or_else(|| { + other_record + .typ + .downcast_ref::() + .map(|t| t.id) + }); + + if self_id != other_id { + return Ok(false); + } + + // Compare all values + if self.values.len() != other_record.values.len() { + return Ok(false); + } + for (a, b) in self.values.iter().zip(other_record.values.iter()) { + if !a.get().equals(b.get())? { + return Ok(false); + } + } + Ok(true) + } else if let Some(other_frozen) = other.downcast_ref::() { + let self_id = self + .typ + .downcast_ref::() + .map(|t| t.id) + .or_else(|| self.typ.downcast_ref::().map(|t| t.id)); + let other_id = other_frozen + .typ + .downcast_ref::() + .map(|t| t.id); + + if self_id != other_id { + return Ok(false); + } + + if self.values.len() != other_frozen.values.len() { + return Ok(false); + } + for (a, b) in self.values.iter().zip(other_frozen.values.iter()) { + if !a.get().equals(b.to_value())? { + return Ok(false); + } + } + Ok(true) + } else { + Ok(false) + } + } +} + +// ----------------------------------------------------------------------------- +// FrozenRecord +// ----------------------------------------------------------------------------- + +/// Frozen version of Record. +#[derive(Debug, ProvidesStaticType, NoSerialize, Allocative)] +pub struct FrozenRecord { + pub(crate) typ: FrozenValue, + pub(crate) values: Box<[FrozenValue]>, +} + +impl Display for FrozenRecord { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}(", self.typ)?; + if let Some(frozen_type) = self.typ.downcast_ref::() { + let mut first = true; + for ((name, _), value) in frozen_type.fields.iter().zip(self.values.iter()) { + if !first { + write!(f, ", ")?; + } + first = false; + write!(f, "{}={}", name, value)?; + } + } + write!(f, ")") + } +} + +unsafe impl<'v> Trace<'v> for FrozenRecord { + fn trace(&mut self, _tracer: &Tracer<'v>) { + // Frozen values don't need tracing + } +} + +impl AllocFrozenValue for FrozenRecord { + fn alloc_frozen_value(self, heap: &FrozenHeap) -> FrozenValue { + heap.alloc_simple(self) + } +} + +#[starlark_value(type = "record")] +impl<'v> StarlarkValue<'v> for FrozenRecord { + type Canonical = Record<'v>; + + fn collect_repr(&self, collector: &mut String) { + write!(collector, "{}", self).unwrap(); + } + + fn get_attr(&self, attribute: &str, _heap: &'v Heap) -> Option> { + if let Some(frozen_type) = self.typ.downcast_ref::() { + if let Some(idx) = frozen_type.fields.get_index_of(attribute) { + return Some(self.values[idx].to_value()); + } + } + None + } + + fn has_attr(&self, attribute: &str, _heap: &'v Heap) -> bool { + if let Some(frozen_type) = self.typ.downcast_ref::() { + frozen_type.fields.contains_key(attribute) + } else { + false + } + } + + fn dir_attr(&self) -> Vec { + if let Some(frozen_type) = self.typ.downcast_ref::() { + frozen_type.fields.keys().map(|s| s.to_string()).collect() + } else { + vec![] + } + } + + fn equals(&self, other: Value<'v>) -> starlark::Result { + if let Some(other_frozen) = other.downcast_ref::() { + let self_id = self.typ.downcast_ref::().map(|t| t.id); + let other_id = other_frozen + .typ + .downcast_ref::() + .map(|t| t.id); + + if self_id != other_id { + return Ok(false); + } + + if self.values.len() != other_frozen.values.len() { + return Ok(false); + } + for (a, b) in self.values.iter().zip(other_frozen.values.iter()) { + if !a.to_value().equals(b.to_value())? { + return Ok(false); + } + } + Ok(true) + } else if let Some(other_record) = other.downcast_ref::() { + let self_id = self.typ.downcast_ref::().map(|t| t.id); + let other_id = other_record + .typ + .downcast_ref::() + .map(|t| t.id) + .or_else(|| { + other_record + .typ + .downcast_ref::() + .map(|t| t.id) + }); + + if self_id != other_id { + return Ok(false); + } + + if self.values.len() != other_record.values.len() { + return Ok(false); + } + for (a, b) in self.values.iter().zip(other_record.values.iter()) { + if !a.to_value().equals(b.get())? { + return Ok(false); + } + } + Ok(true) + } else { + Ok(false) + } + } +} + +impl Freeze for Record<'_> { + type Frozen = FrozenRecord; + + fn freeze(self, freezer: &Freezer) -> Result { + let typ = self.typ.freeze(freezer)?; + let values: Result, _> = self + .values + .iter() + .map(|v| v.get().freeze(freezer)) + .collect(); + Ok(FrozenRecord { + typ, + values: values?.into_boxed_slice(), + }) + } +} + +// ----------------------------------------------------------------------------- +// Global functions +// ----------------------------------------------------------------------------- + +#[starlark_module] +pub fn register_globals(globals: &mut GlobalsBuilder) { + /// Creates a record type with the given fields. + /// + /// Example: + /// ```starlark + /// MyRecord = spec(host=str, port=int) + /// r = MyRecord(host="localhost", port=80) + /// print(r.host) # "localhost" + /// print(r.port) # 80 + /// ``` + fn spec<'v>( + #[starlark(kwargs)] kwargs: SmallMap<&str, Value<'v>>, + eval: &mut starlark::eval::Evaluator<'v, '_, '_>, + ) -> starlark::Result> { + let mut fields = SmallMap::with_capacity(kwargs.len()); + + for (name, value) in kwargs.into_iter() { + let field = if let Some(field_value) = value.downcast_ref::() { + // It's already a field() definition + Field { + typ: field_value.typ.dupe(), + default: field_value.default, + } + } else { + // It's a type, convert to a field without default + let typ = TypeCompiled::new(value, eval.heap())?; + Field { typ, default: None } + }; + fields.insert(name.to_string(), field); + } + + Ok(RecordType { + id: next_record_type_id(), + name: None, + fields, + }) + } + + /// Creates a field definition with a type and optional default value. + /// + /// Example: + /// ```starlark + /// MyRecord = spec(host=str, port=attr(int, 80)) + /// r = MyRecord(host="localhost") # port defaults to 80 + /// ``` + fn attr<'v>( + #[starlark(require = pos)] typ: Value<'v>, + #[starlark(require = pos)] default: Option>, + eval: &mut starlark::eval::Evaluator<'v, '_, '_>, + ) -> starlark::Result> { + let compiled_type = TypeCompiled::new(typ, eval.heap())?; + + // Validate that the default matches the type if provided + if let Some(d) = default { + if !compiled_type.matches(d) { + return Err(starlark::Error::new_other(anyhow::anyhow!( + "Default value `{}` does not match field type `{}`", + d, + compiled_type + ))); + } + } + + Ok(FieldValue { + typ: compiled_type, + default, + }) + } +} diff --git a/crates/axl-runtime/src/engine/wasm/mod.rs b/crates/axl-runtime/src/engine/wasm/mod.rs index 6df64c131..86578614b 100644 --- a/crates/axl-runtime/src/engine/wasm/mod.rs +++ b/crates/axl-runtime/src/engine/wasm/mod.rs @@ -298,6 +298,7 @@ fn instantiate_with_imports<'v>( // Use instantiate() instead of instantiate_and_start() so that _start // is not called automatically. The user should call instance.start() manually. + #[allow(deprecated)] let pre_instance = linker.instantiate(&mut store, &module)?; let instance = pre_instance.ensure_no_start(&mut store).map_err(|e| { anyhow::anyhow!("WASM module has start function that must be called: {}", e) diff --git a/crates/axl-runtime/src/eval/config.rs b/crates/axl-runtime/src/eval/config.rs index e9d116726..bbb3c675e 100644 --- a/crates/axl-runtime/src/eval/config.rs +++ b/crates/axl-runtime/src/eval/config.rs @@ -47,8 +47,9 @@ impl<'l, 'p> ConfigEvaluator<'l, 'p> { /// /// This method: /// 1. Creates a ConfigContext with the tasks - /// 2. Evaluates each config file, calling its `config` function - /// 3. Returns references to the modified tasks + /// 2. Evaluates config bindings for all tasks (lazy evaluation) + /// 3. Evaluates each config file, calling its `config` function + /// 4. Returns references to the modified tasks /// /// The tasks are modified in place via set_attr calls from config functions. pub fn run_all( @@ -67,6 +68,18 @@ impl<'l, 'p> ConfigEvaluator<'l, 'p> { .downcast_ref::() .expect("just allocated ConfigContext"); + // Evaluate config bindings for all tasks (lazy evaluation) + { + let mut eval = Evaluator::new(eval_module); + eval.set_loader(self.loader); + for task_value in ctx.task_values() { + let task = task_value + .downcast_ref::() + .expect("task_values should contain ConfiguredTask"); + task.evaluate_config(&mut eval)?; + } + } + // Evaluate each config file with its associated scope for (scope, path) in &scoped_configs { self.loader.module_stack.borrow_mut().push(scope.clone()); diff --git a/crates/axl-runtime/src/eval/task.rs b/crates/axl-runtime/src/eval/task.rs index 18f4a7476..0cb146c0e 100644 --- a/crates/axl-runtime/src/eval/task.rs +++ b/crates/axl-runtime/src/eval/task.rs @@ -75,9 +75,8 @@ pub fn execute_task( store: AxlStore, args: HashMap, ) -> Result, EvalError> { - // Get config first - it needs to outlive the evaluator - let config = task.get_config(); - let config_value = config.value(); + // Get config value + let config_value = task.get_config(); // Get the task implementation function let task_impl = task @@ -120,9 +119,8 @@ pub fn execute_task_with_args( store: AxlStore, args_builder: impl FnOnce(&Heap) -> TaskArgs, ) -> Result, EvalError> { - // Get config first - it needs to outlive the evaluator - let config = task.get_config(); - let config_value = config.value(); + // Get config value + let config_value = task.get_config(); // Get the task implementation function let task_impl = task From e9e4683ad854811bb8a380ed6157101f43f18a08 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Tue, 27 Jan 2026 15:20:39 -0800 Subject: [PATCH 08/65] use cache --- .buildkite/hooks/pre-command | 12 ++++++++++-- axel-f/config.axl | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index 662c651c3..81bd0af5c 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -3,6 +3,10 @@ set -eu ASPECT_BIN_DIR="$HOME/.aspect/bin" +# Bazel startup options for CI +BAZEL_STARTUP_OPTS="--nohome_rc --output_user_root=/mnt/ephemeral/bazel/aspect-cli/__main__ --output_base=/mnt/ephemeral/output/aspect-cli/__main__" +BAZEL_BUILD_OPTS="--config=workflows --config=ci --show_progress_rate_limit=1" + # Skip if bazel is not installed if ! command -v bazel >/dev/null 2>&1; then exit 0 @@ -18,13 +22,17 @@ if [ -x "$ASPECT_BIN_DIR/aspect" ]; then rm -f "$ASPECT_BIN_DIR/aspect" fi +# Generate workflows bazelrc +rosetta bazelrc > /etc/bazel.bazelrc + + # Build aspect-cli and install echo "--- Building aspect-cli" -bazel build //:cli +bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS //:cli # Create target directory and copy binary mkdir -p "$ASPECT_BIN_DIR" -cp -f "$(bazel cquery --output=files //:cli 2>/dev/null)" "$ASPECT_BIN_DIR/aspect" +cp -f "$(bazel $BAZEL_STARTUP_OPTS cquery $BAZEL_BUILD_OPTS --output=files //:cli 2>/dev/null)" "$ASPECT_BIN_DIR/aspect" chmod 0755 "$ASPECT_BIN_DIR/aspect" # Add to PATH for subsequent commands diff --git a/axel-f/config.axl b/axel-f/config.axl index 50ba44846..9dc378f63 100644 --- a/axel-f/config.axl +++ b/axel-f/config.axl @@ -14,7 +14,7 @@ PLATFORM_DIR = "/etc/aspect/workflows/platform" def config(ctx: ConfigContext): if ctx.std.env.var("BUILDKITE"): - print("--- Configuring Workflows") + print("--- :aspect-build: Configuring Workflows") # Read platform config from disk platform_config = read_platform_config( From cda8b5881615256d555b6e03065ca1a9bed457ba Mon Sep 17 00:00:00 2001 From: thesayyn Date: Tue, 27 Jan 2026 16:59:40 -0800 Subject: [PATCH 09/65] configure Signed-off-by: thesayyn --- .buildkite/hooks/pre-command | 2 +- .buildkite/pipeline.yaml | 75 +---- axel-f/config.axl | 29 +- axel-f/platform-config.axl | 531 ++++++++++------------------------- 4 files changed, 165 insertions(+), 472 deletions(-) diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index 81bd0af5c..2daa2f4dd 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -27,7 +27,7 @@ rosetta bazelrc > /etc/bazel.bazelrc # Build aspect-cli and install -echo "--- Building aspect-cli" +# echo "--- Building aspect-cli" bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS //:cli # Create target directory and copy binary diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index f7d783a12..fa6fc2298 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -3,80 +3,13 @@ # DO NOT EDIT - regenerate with 'aspect workflows migrate' steps: - - key: __main__::lint - label: ":bazel: Lint" + - key: __main__::build + label: ":bazel: Build" agents: queue: aspect-default - timeout_in_minutes: 60 + timeout_in_minutes: 20 command: - - 'echo "--- :bazel: Lint"' - - aspect lint - retry: - automatic: - - exit_status: -1 - limit: 1 - manual: - allowed: true - permit_on_passed: false - - - key: __main__::format - label: ":bazel: Format" - agents: - queue: aspect-default - timeout_in_minutes: 60 - command: - - 'echo "--- :bazel: Format"' - - aspect format - retry: - automatic: - - exit_status: -1 - limit: 1 - manual: - allowed: true - permit_on_passed: false - - - key: __main__::buildifier - label: ":bazel: Buildifier" - agents: - queue: aspect-default - timeout_in_minutes: 60 - command: - - 'echo "--- :bazel: Buildifier"' - - aspect buildifier - retry: - automatic: - - exit_status: -1 - limit: 1 - manual: - allowed: true - permit_on_passed: false - - - key: __main__::gazelle - label: ":bazel: Gazelle" - agents: - queue: aspect-default - timeout_in_minutes: 60 - command: - - 'echo "--- :bazel: Gazelle"' - - aspect gazelle - retry: - automatic: - - exit_status: -1 - limit: 1 - manual: - allowed: true - permit_on_passed: false - - - key: __main__::test - label: ":bazel: Test" - agents: - queue: aspect-default - timeout_in_minutes: 60 - command: - - "vmstat -a -S M -t 5 2>&1 > vmstat.out &" - - 'echo "--- :bazel: Test"' - - aspect test - - "cp /etc/bazel.bazelrc workflows-etc-bazel.bazelrc" + - aspect build artifact_paths: - "vmstat.out" - "workflows-etc-bazel.bazelrc" diff --git a/axel-f/config.axl b/axel-f/config.axl index 9dc378f63..fa7638114 100644 --- a/axel-f/config.axl +++ b/axel-f/config.axl @@ -7,7 +7,7 @@ load("./migrate.axl", "migrate") load("./platform-config.axl", "read_platform_config", "read_host_config", - "get_bazelrc_content", + "get_bazelrc_flags", ) PLATFORM_DIR = "/etc/aspect/workflows/platform" @@ -21,31 +21,38 @@ def config(ctx: ConfigContext): ctx.std.fs, platform_dir = PLATFORM_DIR, ) - print(platform_config) # Read host config from environment host_config = read_host_config(ctx.std.env, ctx.std.io) - print(host_config) - # Generate bazelrc content - content = get_bazelrc_content( + flags = get_bazelrc_flags( platform_config = platform_config, host_config = host_config, bazel_version = "7.0.0", - task_types = ["build"], - workspace = ".", ) - ctx.std.fs.write("/tmp/bazelrc", content) + # Debugging information + print(platform_config) + print(host_config) + print(flags) + + print("~~~ :aspect-build: Configuring Workflows") + + user = ctx.std.env.var("USER") + + def flags(flags, type): + if user != "thesayyn" and type in flags: + flags += flags[type] + return flags for task in ctx.tasks: if task.name == "build" and task.path.endswith("aspect/build.axl"): - task.config.startup_flags = lambda flags: flags + ["--bazelrc=/tmp/bazelrc"] - task.config.flags = lambda flags: flags + task.config.startup_flags = lambda f: flags(f, "startup") + task.config.flags = lambda f: flags(f, "build") task.config.build_start = lambda: print("+++ Building") task.config.build_end = lambda status: print(f"--- Build done {status}") - print(content) + ctx.tasks.add(configure) ctx.tasks.add(gazelle) diff --git a/axel-f/platform-config.axl b/axel-f/platform-config.axl index b0dc3e11c..78dfe221c 100644 --- a/axel-f/platform-config.axl +++ b/axel-f/platform-config.axl @@ -1,123 +1,41 @@ """ -Platform Configuration and Bazelrc Flag Generation Library +Platform Configuration and Bazelrc Generation Library -A pure Starlark library for generating .bazelrc content for Aspect Workflows. -All functions are pure and take explicit parameters - no side effects or implicit -environment reading. - -This is a library, not a task. All configuration is passed as function parameters. - -Usage: - load("@axel-f//platform-config.axl", - "read_platform_config", - "read_host_config", - "get_bazelrc_content", - ) - - # In a task implementation: - platform_config = read_platform_config(ctx.std.fs) - host_config = read_host_config(ctx.std.env, ctx.std.io) - content = get_bazelrc_content(platform_config, host_config) +Pure functions for reading platform/host configuration and generating bazelrc content. +This is the AXL equivalent of rosetta's bazel/flags.ts and related modules. """ -# ============================================================================= # Constants -# ============================================================================= - DEFAULT_STORAGE_PATH = "/mnt/ephemeral" DEFAULT_PLATFORM_DIR = "/etc/aspect/workflows/platform" -# Map of logical config keys to filenames in the platform directory +# Map of logical keys to filenames PLATFORM_CONFIG_KEYS = { "remote_cache_endpoint": "remote_cache_endpoint", "remote_cache_address": "remote_cache_address", "storage_path": "storage_path", } -# All Bazel commands +# Bazel command lists BAZEL_COMMANDS_ALL = [ - "analyze-profile", - "aquery", - "build", - "canonicalize-flags", - "clean", - "config", - "coverage", - "cquery", - "dump", - "fetch", - "help", - "info", - "license", - "mobile-install", - "print_action", - "query", - "run", - "shutdown", - "sync", - "test", - "version", + "analyze-profile", "aquery", "build", "canonicalize-flags", "clean", + "config", "coverage", "cquery", "dump", "fetch", "help", "info", + "license", "mobile-install", "print_action", "query", "run", + "shutdown", "sync", "test", "version", ] -# Commands that involve building BAZEL_COMMANDS_BUILD = [ - "aquery", - "build", - "canonicalize-flags", - "clean", - "config", - "coverage", - "cquery", - "fetch", - "info", - "mobile-install", - "print_action", - "query", - "run", - "sync", - "test", -] - -# Commands for action-related flags -BAZEL_COMMANDS_ACTIONS = [ - "aquery", - "build", - "canonicalize-flags", - "clean", - "config", - "coverage", - "cquery", - "info", - "mobile-install", - "print_action", - "run", - "test", + "aquery", "build", "canonicalize-flags", "clean", "config", "coverage", + "cquery", "fetch", "info", "mobile-install", "print_action", "query", + "run", "sync", "test", ] -# Commands with symlink support -BAZEL_COMMANDS_SYMLINK = [ - "aquery", - "build", - "canonicalize-flags", - "clean", - "config", - "coverage", - "cquery", - "info", - "mobile-install", - "print_action", - "run", - "test", +BAZEL_COMMANDS_BUILD_TEST = [ + "aquery", "build", "canonicalize-flags", "clean", "config", "coverage", + "cquery", "info", "mobile-install", "print_action", "run", "test", ] -# Commands for jobs flag -BAZEL_COMMANDS_JOBS = [ - "build", - "coverage", - "cquery", - "run", - "test", -] +BAZEL_COMMANDS_JOBS = ["build", "coverage", "cquery", "run", "test"] # ============================================================================= # Flag Definitions @@ -131,12 +49,13 @@ STATIC_BOOLEAN_FLAGS = [ {"name": "keep_going", "commands": BAZEL_COMMANDS_BUILD}, {"name": "generate_json_trace_profile", "commands": BAZEL_COMMANDS_ALL}, {"name": "experimental_profile_include_target_label", "commands": BAZEL_COMMANDS_ALL}, - {"name": "incompatible_strict_action_env", "commands": BAZEL_COMMANDS_ACTIONS}, + {"name": "incompatible_strict_action_env", "commands": BAZEL_COMMANDS_BUILD_TEST}, {"name": "experimental_repository_cache_hardlinks", "commands": BAZEL_COMMANDS_ALL}, - {"name": "incompatible_exclusive_test_sandboxed", "commands": BAZEL_COMMANDS_ACTIONS}, - {"name": "experimental_reuse_sandbox_directories", "commands": BAZEL_COMMANDS_ACTIONS}, - {"name": "incompatible_default_to_explicit_init_py", "commands": BAZEL_COMMANDS_ACTIONS}, + {"name": "incompatible_exclusive_test_sandboxed", "commands": BAZEL_COMMANDS_BUILD_TEST}, + {"name": "experimental_reuse_sandbox_directories", "commands": BAZEL_COMMANDS_BUILD_TEST}, + {"name": "incompatible_default_to_explicit_init_py", "commands": BAZEL_COMMANDS_BUILD_TEST}, {"name": "remote_accept_cached", "commands": BAZEL_COMMANDS_BUILD}, + {"name": "incompatible_remote_results_ignore_disk", "commands": BAZEL_COMMANDS_BUILD, "versions": "< 7"}, ] # Static value flags @@ -146,26 +65,20 @@ STATIC_VALUE_FLAGS = [ {"name": "isatty", "value": "0", "commands": BAZEL_COMMANDS_ALL}, {"name": "terminal_columns", "value": "143", "commands": BAZEL_COMMANDS_ALL}, {"name": "disk_cache", "value": "", "commands": BAZEL_COMMANDS_BUILD}, - {"name": "symlink_prefix", "value": "bazel-", "commands": BAZEL_COMMANDS_SYMLINK}, - {"name": "experimental_convenience_symlinks", "value": "normal", "commands": BAZEL_COMMANDS_SYMLINK}, - {"name": "max_config_changes_to_show", "value": "-1", "commands": BAZEL_COMMANDS_ACTIONS}, + {"name": "symlink_prefix", "value": "bazel-", "commands": BAZEL_COMMANDS_BUILD_TEST}, + {"name": "experimental_convenience_symlinks", "value": "normal", "commands": BAZEL_COMMANDS_BUILD_TEST}, + {"name": "max_config_changes_to_show", "value": "-1", "commands": BAZEL_COMMANDS_BUILD_TEST}, {"name": "remote_timeout", "value": "3600", "commands": BAZEL_COMMANDS_BUILD}, {"name": "remote_retries", "value": "360", "commands": BAZEL_COMMANDS_BUILD}, {"name": "grpc_keepalive_timeout", "value": "30s", "commands": BAZEL_COMMANDS_ALL}, - {"name": "bes_upload_mode", "value": "wait_for_upload_complete", "commands": BAZEL_COMMANDS_ALL}, {"name": "experimental_repository_downloader_retries", "value": "2", "commands": BAZEL_COMMANDS_ALL}, -] - -# Version-specific static flags -VERSION_SPECIFIC_FLAGS = [ - # incompatible_remote_results_ignore_disk removed in Bazel 7 - {"name": "incompatible_remote_results_ignore_disk", "commands": BAZEL_COMMANDS_BUILD, "versions": "< 7"}, - # Build event upload flag renamed in Bazel 7 + {"name": "bes_upload_mode", "value": "wait_for_upload_complete", "commands": BAZEL_COMMANDS_ALL}, + # Version-specific flags {"name": "experimental_remote_build_event_upload", "value": "minimal", "commands": BAZEL_COMMANDS_BUILD, "versions": ">= 6 < 7"}, {"name": "remote_build_event_upload", "value": "minimal", "commands": BAZEL_COMMANDS_BUILD, "versions": ">= 7"}, - # Cache compression flag renamed in Bazel 8 - {"name": "noexperimental_remote_cache_compression", "commands": BAZEL_COMMANDS_BUILD, "versions": "< 8"}, - {"name": "noremote_cache_compression", "commands": BAZEL_COMMANDS_BUILD, "versions": ">= 8"}, + # Cache compression flags (BuildBarn doesn't support compression) + {"name": "noexperimental_remote_cache_compression", "value": None, "commands": BAZEL_COMMANDS_BUILD, "versions": "< 8"}, + {"name": "noremote_cache_compression", "value": None, "commands": BAZEL_COMMANDS_BUILD, "versions": ">= 8"}, ] # Dynamic flags - value resolved from config dicts @@ -175,7 +88,7 @@ DYNAMIC_FLAGS = [ {"name": "repository_cache", "value": "dynamic:computed.repository_cache", "commands": BAZEL_COMMANDS_ALL}, {"name": "curses", "value": "dynamic:host.curses", "commands": BAZEL_COMMANDS_ALL}, {"name": "show_progress_rate_limit", "value": "dynamic:host.progress_rate_limit", "commands": BAZEL_COMMANDS_ALL}, - # RBE flags (omit if not configured) + # RBE flags {"name": "remote_executor", "value": "dynamic:rbe.remote_executor", "commands": BAZEL_COMMANDS_BUILD, "omit_if_none": True}, {"name": "jobs", "value": "dynamic:rbe.jobs", "commands": BAZEL_COMMANDS_JOBS, "omit_if_none": True}, ] @@ -186,126 +99,8 @@ STARTUP_FLAGS = [ {"name": "output_base", "value": "dynamic:computed.output_base"}, ] - -# ============================================================================= -# Version Comparison Functions -# ============================================================================= - -def parse_version(version_str): - """ - Parse version string to tuple (major, minor, patch). - - Args: - version_str: Version string like "7.0.0" or "7.1.2-rc1" - - Returns: - Tuple of (major, minor, patch) as integers - """ - if not version_str: - return (0, 0, 0) - - parts = version_str.split(".") - major = int(parts[0]) if len(parts) > 0 and parts[0].isdigit() else 0 - - minor = 0 - if len(parts) > 1: - minor_part = parts[1] - if minor_part.isdigit(): - minor = int(minor_part) - - patch = 0 - if len(parts) > 2: - # Handle versions like "7.0.0-rc1" - patch_part = parts[2].split("-")[0] - if patch_part.isdigit(): - patch = int(patch_part) - - return (major, minor, patch) - - -def _compare_versions(v1, v2): - """ - Compare two version tuples. - - Returns: - -1 if v1 < v2, 0 if v1 == v2, 1 if v1 > v2 - """ - for i in range(3): - if v1[i] < v2[i]: - return -1 - elif v1[i] > v2[i]: - return 1 - return 0 - - -def version_satisfies(version, constraint): - """ - Check if version satisfies semver constraint. - - Args: - version: Version string like "7.0.0" or None - constraint: Semver constraint like "< 7", ">= 6 < 7", ">= 8", or "*" - - Returns: - True if version satisfies constraint, False otherwise - - Examples: - version_satisfies("7.0.0", "< 8") -> True - version_satisfies("7.0.0", ">= 7") -> True - version_satisfies("6.5.0", ">= 7") -> False - version_satisfies("6.5.0", ">= 6 < 7") -> True - version_satisfies(None, "< 7") -> True (no version means include all) - """ - if not version or constraint == "*" or not constraint: - return True - - v = parse_version(version) - - # Parse constraint like "< 7", ">= 6 < 7", ">= 8" - # Tokenize the constraint string - tokens = [] - current = "" - for c in constraint.elems(): - if c == " ": - if current: - tokens.append(current) - current = "" - else: - current += c - if current: - tokens.append(current) - - # Process tokens in pairs (operator, version) - # Tokens are like [">=", "6", "<", "7"] for ">= 6 < 7" - num_pairs = len(tokens) // 2 - for pair_idx in range(num_pairs): - i = pair_idx * 2 - op = tokens[i] - target_str = tokens[i + 1] - target = parse_version(target_str) - cmp = _compare_versions(v, target) - - if op == "<": - if cmp >= 0: - return False - elif op == "<=": - if cmp > 0: - return False - elif op == ">": - if cmp <= 0: - return False - elif op == ">=": - if cmp < 0: - return False - elif op == "=": - if cmp != 0: - return False - - return True - - # ============================================================================= -# Configuration Reader Functions +# Configuration Readers # ============================================================================= def read_platform_config(fs, platform_dir = DEFAULT_PLATFORM_DIR): @@ -317,7 +112,7 @@ def read_platform_config(fs, platform_dir = DEFAULT_PLATFORM_DIR): platform_dir: Path to platform config directory Returns: - dict with keys: remote_cache_endpoint, remote_cache_address, storage_path + dict with keys: remote_cache_endpoint, remote_cache_address, storage_path, etc. """ config = {} @@ -347,95 +142,98 @@ def read_host_config(env, io): dict with keys: supports_curses, scm_repo_name, ci_host """ config = { - "supports_curses": io.stdout.is_tty if hasattr(io, "stdout") else False, + "supports_curses": io.stdout.is_tty, "scm_repo_name": None, "ci_host": None, } # Detect CI host and repo name - # BuildKite - buildkite_repo = env.var("BUILDKITE_REPO") - if buildkite_repo: + if env.var("BUILDKITE_REPO"): config["ci_host"] = "buildkite" - config["scm_repo_name"] = _parse_git_url_name(buildkite_repo) + config["scm_repo_name"] = _parse_git_url_name(env.var("BUILDKITE_REPO")) config["supports_curses"] = True # BuildKite supports curses - return config - - # GitHub Actions - github_repo = env.var("GITHUB_REPOSITORY") - if github_repo: + elif env.var("GITHUB_REPOSITORY"): config["ci_host"] = "github" - if "/" in github_repo: - config["scm_repo_name"] = github_repo.split("/")[-1] - else: - config["scm_repo_name"] = github_repo - return config - - # CircleCI - circle_repo = env.var("CIRCLE_PROJECT_REPONAME") - if circle_repo: + repo = env.var("GITHUB_REPOSITORY") + config["scm_repo_name"] = repo.split("/")[-1] if "/" in repo else repo + elif env.var("CIRCLE_PROJECT_REPONAME"): config["ci_host"] = "circleci" - config["scm_repo_name"] = circle_repo - return config - - # GitLab CI - gitlab_project = env.var("CI_PROJECT_NAME") - if gitlab_project: + config["scm_repo_name"] = env.var("CIRCLE_PROJECT_REPONAME") + elif env.var("CI_PROJECT_NAME"): config["ci_host"] = "gitlab" - config["scm_repo_name"] = gitlab_project - return config + config["scm_repo_name"] = env.var("CI_PROJECT_NAME") return config def _parse_git_url_name(url): - """ - Extract repo name from git URL. - - Args: - url: Git URL like "git@github.com:org/repo.git" or "https://github.com/org/repo" - - Returns: - Repository name or None - """ + """Extract repo name from git URL.""" if not url: return None - name = url.rstrip("/") - - # Remove .git suffix if name.endswith(".git"): name = name[:-4] - - # Handle SSH URLs like git@github.com:org/repo - if ":" in name and "@" in name: - # Split by : and take last part - name = name.split(":")[-1] - - # Handle HTTP URLs - take last path segment - if "/" in name: - name = name.split("/")[-1] - - return name - + return name.split("/")[-1].split(":")[-1] # ============================================================================= -# Dynamic Value Resolution +# Version Comparison # ============================================================================= -def _sanitize_filename(name): +def parse_version(version_str): + """Parse version string to tuple (major, minor, patch).""" + parts = version_str.split(".") + major = int(parts[0]) if len(parts) > 0 else 0 + minor = int(parts[1]) if len(parts) > 1 else 0 + patch_str = parts[2].split("-")[0] if len(parts) > 2 else "0" + patch = int(patch_str) if patch_str else 0 + return (major, minor, patch) + + +def version_satisfies(version, constraint): """ - Sanitize string for use in filesystem paths. + Check if version satisfies semver constraint. Args: - name: Input string + version: Version string like "7.0.0" + constraint: Constraint like "< 7", ">= 6 < 7", ">= 8" Returns: - Sanitized string with only alphanumeric, dash, underscore, and dot + True if version satisfies the constraint """ + if not version or constraint == "*": + return True + + v = parse_version(version) + + # Parse constraint like "< 7", ">= 6 < 7", ">= 8" + parts = constraint.split() + for i in range(0, len(parts), 2): + if i + 1 >= len(parts): + break + op = parts[i] + target = parse_version(parts[i + 1]) + + if op == "<" and not (v < target): + return False + elif op == "<=" and not (v <= target): + return False + elif op == ">" and not (v > target): + return False + elif op == ">=" and not (v >= target): + return False + elif op == "=" and v != target: + return False + + return True + +# ============================================================================= +# Dynamic Value Resolution +# ============================================================================= + +def _sanitize_filename(name): + """Sanitize string for use in filesystem paths.""" if not name: return "" - result = "" for c in name.elems(): if c.isalnum() or c in "-_.": @@ -446,25 +244,11 @@ def _sanitize_filename(name): def _compute_output_path(platform_config, host_config, segment, workspace): - """ - Compute output_base or output_user_root path. - - Args: - platform_config: Platform configuration dict - host_config: Host configuration dict - segment: Path segment ("bazel" or "output") - workspace: Workspace name - - Returns: - Computed path string - """ + """Compute output_base or output_user_root path.""" mount = platform_config.get("storage_path", DEFAULT_STORAGE_PATH) # Normalize workspace name - if workspace == "." or not workspace: - subdir = "__main__" - else: - subdir = workspace.replace("/", "_") + subdir = "__main__" if workspace == "." else workspace.replace("/", "_") # Include repo name if available repo_name = host_config.get("scm_repo_name") @@ -474,7 +258,7 @@ def _compute_output_path(platform_config, host_config, segment, workspace): return mount + "/" + segment + "/" + subdir -def resolve_dynamic_value(key, platform_config, host_config, workspace, rbe_config = None): +def resolve_dynamic_value(key, platform_config, host_config, rbe_config, workspace): """ Resolve a dynamic value from config dicts. @@ -482,8 +266,8 @@ def resolve_dynamic_value(key, platform_config, host_config, workspace, rbe_conf key: Dynamic key like "platform.remote_cache_endpoint" or "computed.repository_cache" platform_config: Platform configuration dict host_config: Host configuration dict + rbe_config: RBE configuration dict (may be None) workspace: Workspace name - rbe_config: Optional RBE configuration dict with "enabled" and "jobs" keys Returns: Resolved value string or None @@ -511,11 +295,11 @@ def resolve_dynamic_value(key, platform_config, host_config, workspace, rbe_conf return _compute_output_path(platform_config, host_config, "output", workspace) elif key.startswith("rbe."): - if not rbe_config or not rbe_config.get("enabled"): + if not rbe_config: return None rbe_key = key[len("rbe."):] if rbe_key == "remote_executor": - # When RBE is enabled, use the remote cache endpoint as the executor + # RBE uses the same endpoint as remote cache return platform_config.get("remote_cache_endpoint") elif rbe_key == "jobs": jobs = rbe_config.get("jobs") @@ -523,12 +307,11 @@ def resolve_dynamic_value(key, platform_config, host_config, workspace, rbe_conf return None - # ============================================================================= -# Flag Resolution Functions +# Flag Resolution # ============================================================================= -def resolve_flag_value(flag_def, platform_config, host_config, workspace, rbe_config = None): +def resolve_flag_value(flag_def, platform_config, host_config, rbe_config, workspace): """ Resolve a flag's value from config dicts. @@ -536,11 +319,11 @@ def resolve_flag_value(flag_def, platform_config, host_config, workspace, rbe_co flag_def: Flag definition dict platform_config: Platform configuration dict host_config: Host configuration dict + rbe_config: RBE configuration dict (may be None) workspace: Workspace name - rbe_config: Optional RBE configuration dict Returns: - Resolved value string or None (for boolean flags) + Resolved value string or None """ value = flag_def.get("value") @@ -549,121 +332,91 @@ def resolve_flag_value(flag_def, platform_config, host_config, workspace, rbe_co if type(value) == "string" and value.startswith("dynamic:"): dynamic_key = value[len("dynamic:"):] - return resolve_dynamic_value(dynamic_key, platform_config, host_config, workspace, rbe_config) + return resolve_dynamic_value(dynamic_key, platform_config, host_config, rbe_config, workspace) return value # Static value def stringify_flag(name, value): - """ - Convert flag name and value to string. - - Args: - name: Flag name - value: Flag value or None for boolean flags - - Returns: - Flag string like "--name=value" or "--name" - """ + """Convert flag name and value to string.""" if value == None: return "--" + name return "--" + name + "=" + str(value) -def should_include_flag(flag_def, version, task_types): +def should_include_flag(flag_def, version): """ - Check if flag should be included based on version and task types. + Check if flag should be included based on version. Args: flag_def: Flag definition dict - version: Bazel version string or None - task_types: List of task type strings + version: Bazel version string (e.g., "7.0.0") or None Returns: - True if flag should be included, False otherwise + True if flag should be included """ - # Check version constraint constraint = flag_def.get("versions", "*") - if not version_satisfies(version, constraint): - return False - - # Check task type requirement - required_types = flag_def.get("task_types") - if required_types: - for t in required_types: - if t in task_types: - return True - return False - - return True - + return version_satisfies(version, constraint) # ============================================================================= -# Main Bazelrc Generation Function +# Bazelrc Generation # ============================================================================= -def get_bazelrc_content( - platform_config, - host_config, - bazel_version = None, - task_types = None, - workspace = ".", - rbe_config = None, -): +def get_bazelrc_flags(platform_config, host_config, bazel_version = None, rbe_config = None, workspace = ".", verbs = None): """ - Generate complete .bazelrc content. + Generate bazelrc flags organized by verb. Args: platform_config: dict from read_platform_config() host_config: dict from read_host_config() bazel_version: str like "7.0.0" or None - task_types: list of task type strings (e.g., ["lint", "test"]) + rbe_config: dict with RBE config (e.g., {"jobs": 50}) or None workspace: workspace name (default ".") - rbe_config: Optional dict with RBE configuration {"enabled": bool, "jobs": int} + verbs: list of verbs to generate flags for (default: all verbs) Returns: - str: Complete .bazelrc file content + dict: Flags organized by verb, e.g.: + { + "build": ["--flag1", "--flag2"], + "test": ["--flag1", "--test_flag"], + "startup": ["--output_base=...", "--output_user_root=..."], + } """ - if task_types == None: - task_types = [] + if verbs == None: + verbs = BAZEL_COMMANDS_ALL - lines = [ - "#### Aspect Workflows", - "#### Generated bazelrc file, do not edit", - "", - "#### Common Flags", - "", - ] + result = {} - # Combine all flag lists - all_flags = STATIC_BOOLEAN_FLAGS + STATIC_VALUE_FLAGS + VERSION_SPECIFIC_FLAGS + DYNAMIC_FLAGS + all_flags = STATIC_BOOLEAN_FLAGS + STATIC_VALUE_FLAGS + DYNAMIC_FLAGS for flag_def in all_flags: - if not should_include_flag(flag_def, bazel_version, task_types): + if not should_include_flag(flag_def, bazel_version): continue - value = resolve_flag_value(flag_def, platform_config, host_config, workspace, rbe_config) + value = resolve_flag_value(flag_def, platform_config, host_config, rbe_config, workspace) - # Skip if omit_if_none and value is None (for dynamic flags) + # Skip if omit_if_none and value is None (for dynamic flags that may not resolve) if flag_def.get("omit_if_none") and value == None: continue - # For boolean flags without explicit value, value will be None which is correct flag_str = stringify_flag(flag_def["name"], value) - # Add for each applicable command + # Add for each applicable command that's in the requested verbs for cmd in flag_def.get("commands", ["build"]): - lines.append(cmd + " " + flag_str) - - # Add startup flags section - lines.append("") - lines.append("#### Startup Flags") - lines.append("") - + if cmd not in verbs: + continue + if cmd not in result: + result[cmd] = [] + result[cmd].append(flag_str) + + # Add startup flags + startup_flags = [] for flag_def in STARTUP_FLAGS: - value = resolve_flag_value(flag_def, platform_config, host_config, workspace, rbe_config) + value = resolve_flag_value(flag_def, platform_config, host_config, rbe_config, workspace) if value: - lines.append("startup " + stringify_flag(flag_def["name"], value)) + startup_flags.append(stringify_flag(flag_def["name"], value)) + + if startup_flags: + result["startup"] = startup_flags - lines.append("") - return "\n".join(lines) + return result From b5d5bdc5dc99d0219c6ee65d932c3ed57cae6d65 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Tue, 27 Jan 2026 17:13:55 -0800 Subject: [PATCH 10/65] Update pre-command Signed-off-by: thesayyn --- .buildkite/hooks/environment | 2 +- .buildkite/hooks/pre-command | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.buildkite/hooks/environment b/.buildkite/hooks/environment index 1912c8600..8512ddafb 100755 --- a/.buildkite/hooks/environment +++ b/.buildkite/hooks/environment @@ -1,3 +1,3 @@ #!/bin/sh export PATH="$HOME/.aspect/bin:$PATH" -export AXL_CONFIG=axel-f/config.axl +export AXL_CONFIG="$(pwd)/axel-f/config.axl" diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index 2daa2f4dd..97c365137 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -27,8 +27,8 @@ rosetta bazelrc > /etc/bazel.bazelrc # Build aspect-cli and install -# echo "--- Building aspect-cli" -bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS //:cli +echo "--- Building aspect-cli" +bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS --remote_download_toplevel //:cli # Create target directory and copy binary mkdir -p "$ASPECT_BIN_DIR" From 806817b78a481f866d50b007dee34207b27bab19 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Tue, 27 Jan 2026 17:22:44 -0800 Subject: [PATCH 11/65] Update pipeline.yaml Signed-off-by: thesayyn --- .buildkite/pipeline.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index fa6fc2298..56819f86f 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -9,7 +9,7 @@ steps: queue: aspect-default timeout_in_minutes: 20 command: - - aspect build + - aspect build ... artifact_paths: - "vmstat.out" - "workflows-etc-bazel.bazelrc" From 32811ff0859f3d867140d41e745a1699b5c3bd5a Mon Sep 17 00:00:00 2001 From: thesayyn Date: Tue, 27 Jan 2026 17:25:08 -0800 Subject: [PATCH 12/65] Update environment Signed-off-by: thesayyn --- .buildkite/hooks/environment | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.buildkite/hooks/environment b/.buildkite/hooks/environment index 8512ddafb..d9a4f76bc 100755 --- a/.buildkite/hooks/environment +++ b/.buildkite/hooks/environment @@ -1,3 +1,7 @@ #!/bin/sh export PATH="$HOME/.aspect/bin:$PATH" export AXL_CONFIG="$(pwd)/axel-f/config.axl" +if [ -z "$AXL_CONFIG" ]; then + echo "AXL_CONFIG is not set" + exit 1 +fi From 64b3a69e3885b0c8415dd0d12e3c438dd2499202 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Tue, 27 Jan 2026 17:32:29 -0800 Subject: [PATCH 13/65] Update pipeline.yaml Signed-off-by: thesayyn --- .buildkite/hooks/environment | 7 ------- .buildkite/hooks/pre-command | 24 ++++++++++++++++++++---- .buildkite/pipeline.yaml | 5 +++++ 3 files changed, 25 insertions(+), 11 deletions(-) delete mode 100755 .buildkite/hooks/environment diff --git a/.buildkite/hooks/environment b/.buildkite/hooks/environment deleted file mode 100755 index d9a4f76bc..000000000 --- a/.buildkite/hooks/environment +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -export PATH="$HOME/.aspect/bin:$PATH" -export AXL_CONFIG="$(pwd)/axel-f/config.axl" -if [ -z "$AXL_CONFIG" ]; then - echo "AXL_CONFIG is not set" - exit 1 -fi diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index 97c365137..3fbb27350 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -7,19 +7,31 @@ ASPECT_BIN_DIR="$HOME/.aspect/bin" BAZEL_STARTUP_OPTS="--nohome_rc --output_user_root=/mnt/ephemeral/bazel/aspect-cli/__main__ --output_base=/mnt/ephemeral/output/aspect-cli/__main__" BAZEL_BUILD_OPTS="--config=workflows --config=ci --show_progress_rate_limit=1" +echo "=== pre-command hook debug ===" +echo "ASPECT_BIN_DIR: $ASPECT_BIN_DIR" +echo "PWD: $(pwd)" + # Skip if bazel is not installed if ! command -v bazel >/dev/null 2>&1; then + echo "DEBUG: bazel not found, skipping" exit 0 fi # Check if aspect binary exists if [ -x "$ASPECT_BIN_DIR/aspect" ]; then + echo "DEBUG: Found existing aspect binary" + echo "DEBUG: Existing version:" + "$ASPECT_BIN_DIR/aspect" --version 2>&1 || true # Skip if it's the new version (contains "programmable" in help) if "$ASPECT_BIN_DIR/aspect" --help 2>&1 | grep -q programmable; then + echo "DEBUG: New version detected (has 'programmable'), skipping build" exit 0 fi + echo "DEBUG: Old version detected, removing" # Remove old version rm -f "$ASPECT_BIN_DIR/aspect" +else + echo "DEBUG: No existing aspect binary at $ASPECT_BIN_DIR/aspect" fi # Generate workflows bazelrc @@ -32,10 +44,14 @@ bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS --remote_download_toplevel //: # Create target directory and copy binary mkdir -p "$ASPECT_BIN_DIR" -cp -f "$(bazel $BAZEL_STARTUP_OPTS cquery $BAZEL_BUILD_OPTS --output=files //:cli 2>/dev/null)" "$ASPECT_BIN_DIR/aspect" +CLI_PATH="$(bazel $BAZEL_STARTUP_OPTS cquery $BAZEL_BUILD_OPTS --output=files //:cli 2>/dev/null)" +echo "DEBUG: cquery returned path: $CLI_PATH" +echo "DEBUG: File exists check:" +ls -la "$CLI_PATH" 2>&1 || echo "DEBUG: File does not exist!" +cp -f "$CLI_PATH" "$ASPECT_BIN_DIR/aspect" chmod 0755 "$ASPECT_BIN_DIR/aspect" -# Add to PATH for subsequent commands -export PATH="$ASPECT_BIN_DIR:$PATH" - +echo "DEBUG: Installed version:" +"$ASPECT_BIN_DIR/aspect" --version 2>&1 || true echo "aspect-cli installed to $ASPECT_BIN_DIR/aspect" +echo "=== end pre-command hook debug ===" diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index 56819f86f..7f30b70dc 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -2,6 +2,10 @@ # Source: .aspect/workflows/config_aws.yaml # DO NOT EDIT - regenerate with 'aspect workflows migrate' +env: + PATH: "$HOME/.aspect/bin:$PATH" + AXL_CONFIG: "$PWD/axel-f/config.axl" + steps: - key: __main__::build label: ":bazel: Build" @@ -9,6 +13,7 @@ steps: queue: aspect-default timeout_in_minutes: 20 command: + - env - aspect build ... artifact_paths: - "vmstat.out" From 8358b4badb51ce4acbcbef3163645f5efa3b3d90 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Tue, 27 Jan 2026 18:06:38 -0800 Subject: [PATCH 14/65] Update pipeline.yaml Signed-off-by: thesayyn --- .buildkite/pipeline.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index 7f30b70dc..338be55a3 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -4,7 +4,6 @@ env: PATH: "$HOME/.aspect/bin:$PATH" - AXL_CONFIG: "$PWD/axel-f/config.axl" steps: - key: __main__::build @@ -14,7 +13,7 @@ steps: timeout_in_minutes: 20 command: - env - - aspect build ... + - AXL_CONFIG="$PWD/axel-f/config.axl" aspect build ... artifact_paths: - "vmstat.out" - "workflows-etc-bazel.bazelrc" From 681b8ad9b33f0466596043496cc31590c40720ba Mon Sep 17 00:00:00 2001 From: thesayyn Date: Tue, 27 Jan 2026 18:11:57 -0800 Subject: [PATCH 15/65] Update pipeline.yaml Signed-off-by: thesayyn --- .buildkite/pipeline.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index 338be55a3..c5351229c 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -4,7 +4,7 @@ env: PATH: "$HOME/.aspect/bin:$PATH" - + ASPECT_DEBUG: "1" steps: - key: __main__::build label: ":bazel: Build" From 19799c0d0e7c2c7546dfe4b893a2f3bc861ea8f2 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Tue, 27 Jan 2026 18:13:58 -0800 Subject: [PATCH 16/65] Update pipeline.yaml Signed-off-by: thesayyn --- .buildkite/pipeline.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index c5351229c..759de8bb8 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -4,6 +4,7 @@ env: PATH: "$HOME/.aspect/bin:$PATH" + AXL_CONFIG: "$PWD/axel-f/config.axl" ASPECT_DEBUG: "1" steps: - key: __main__::build @@ -13,7 +14,8 @@ steps: timeout_in_minutes: 20 command: - env - - AXL_CONFIG="$PWD/axel-f/config.axl" aspect build ... + - stat $AXL_CONFIG + - aspect build ... artifact_paths: - "vmstat.out" - "workflows-etc-bazel.bazelrc" From 9f43706f5ceac11846943fe10ed2fcca4a049945 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Tue, 27 Jan 2026 18:16:14 -0800 Subject: [PATCH 17/65] Update pipeline.yaml Signed-off-by: thesayyn --- .buildkite/pipeline.yaml | 4 +--- axel-f/config.axl | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index 759de8bb8..d3fadd822 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -4,7 +4,7 @@ env: PATH: "$HOME/.aspect/bin:$PATH" - AXL_CONFIG: "$PWD/axel-f/config.axl" + AXL_CONFIG: "/mnt/ephemeral/workdir/aspect-build/aspect-cli/axel-f/config.axl" ASPECT_DEBUG: "1" steps: - key: __main__::build @@ -13,8 +13,6 @@ steps: queue: aspect-default timeout_in_minutes: 20 command: - - env - - stat $AXL_CONFIG - aspect build ... artifact_paths: - "vmstat.out" diff --git a/axel-f/config.axl b/axel-f/config.axl index fa7638114..e67426d05 100644 --- a/axel-f/config.axl +++ b/axel-f/config.axl @@ -37,8 +37,6 @@ def config(ctx: ConfigContext): print(host_config) print(flags) - print("~~~ :aspect-build: Configuring Workflows") - user = ctx.std.env.var("USER") def flags(flags, type): From 5a3c9480d4ae355401a12663a5c666a3c6140c7e Mon Sep 17 00:00:00 2001 From: thesayyn Date: Tue, 27 Jan 2026 18:23:26 -0800 Subject: [PATCH 18/65] Update config.axl Signed-off-by: thesayyn --- axel-f/config.axl | 1 + 1 file changed, 1 insertion(+) diff --git a/axel-f/config.axl b/axel-f/config.axl index e67426d05..b9e72fe4f 100644 --- a/axel-f/config.axl +++ b/axel-f/config.axl @@ -46,6 +46,7 @@ def config(ctx: ConfigContext): for task in ctx.tasks: if task.name == "build" and task.path.endswith("aspect/build.axl"): + print("found build task") task.config.startup_flags = lambda f: flags(f, "startup") task.config.flags = lambda f: flags(f, "build") task.config.build_start = lambda: print("+++ Building") From c13621210b3cc552888d0450bd4d6d27c6dd6221 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Tue, 27 Jan 2026 18:47:28 -0800 Subject: [PATCH 19/65] Update build.axl Signed-off-by: thesayyn --- crates/axl-runtime/src/builtins/aspect/build.axl | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/axl-runtime/src/builtins/aspect/build.axl b/crates/axl-runtime/src/builtins/aspect/build.axl index 8ca1c90bf..a39c9ae8c 100644 --- a/crates/axl-runtime/src/builtins/aspect/build.axl +++ b/crates/axl-runtime/src/builtins/aspect/build.axl @@ -41,6 +41,7 @@ def impl(ctx: TaskContext) -> int: bazel_flags = ctx.config.flags(bazel_flags) bazel_startup_flags = ctx.config.startup_flags(bazel_startup_flags) + print(ctx.config.build_start) ctx.config.build_start() build = ctx.bazel.build( From 8a246fc11b69af7c2bac9be34090a9b98b8ab670 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 09:57:28 -0800 Subject: [PATCH 20/65] Update build.axl Signed-off-by: thesayyn --- crates/axl-runtime/src/builtins/aspect/build.axl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/axl-runtime/src/builtins/aspect/build.axl b/crates/axl-runtime/src/builtins/aspect/build.axl index a39c9ae8c..8bb4c1fb9 100644 --- a/crates/axl-runtime/src/builtins/aspect/build.axl +++ b/crates/axl-runtime/src/builtins/aspect/build.axl @@ -41,9 +41,11 @@ def impl(ctx: TaskContext) -> int: bazel_flags = ctx.config.flags(bazel_flags) bazel_startup_flags = ctx.config.startup_flags(bazel_startup_flags) - print(ctx.config.build_start) + ctx.config.build_start() + print(ctx.config.build_start) + build = ctx.bazel.build( build_events = build_events, flags = bazel_flags, From 3591059fd3fd79bc173b19e12951e28c451e5c76 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 10:07:37 -0800 Subject: [PATCH 21/65] Update build.axl Signed-off-by: thesayyn --- crates/axl-runtime/src/builtins/aspect/build.axl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/axl-runtime/src/builtins/aspect/build.axl b/crates/axl-runtime/src/builtins/aspect/build.axl index 8bb4c1fb9..d1175c909 100644 --- a/crates/axl-runtime/src/builtins/aspect/build.axl +++ b/crates/axl-runtime/src/builtins/aspect/build.axl @@ -46,14 +46,14 @@ def impl(ctx: TaskContext) -> int: print(ctx.config.build_start) - build = ctx.bazel.build( - build_events = build_events, - flags = bazel_flags, - startup_flags = bazel_startup_flags, - *ctx.args.target_pattern - ) + # build = ctx.bazel.build( + # build_events = build_events, + # flags = bazel_flags, + # startup_flags = bazel_startup_flags, + # *ctx.args.target_pattern + # ) - build_status = build.wait() + # build_status = build.wait() ctx.config.build_end(build_status.code) From b7e9065abd4505dfd758c71fa9b3188d0014ac64 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 10:15:21 -0800 Subject: [PATCH 22/65] fix staleness issues Signed-off-by: thesayyn --- .buildkite/hooks/pre-command | 2 +- .../axl-runtime/src/builtins/aspect/build.axl | 14 ++++----- crates/axl-runtime/src/builtins/mod.rs | 30 +++++++++++++------ 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index 3fbb27350..f68c26020 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -1,7 +1,7 @@ #!/bin/sh set -eu -ASPECT_BIN_DIR="$HOME/.aspect/bin" +ASPECT_BIN_DIR="/home/aspect-runner/.aspect/bin" # Bazel startup options for CI BAZEL_STARTUP_OPTS="--nohome_rc --output_user_root=/mnt/ephemeral/bazel/aspect-cli/__main__ --output_base=/mnt/ephemeral/output/aspect-cli/__main__" diff --git a/crates/axl-runtime/src/builtins/aspect/build.axl b/crates/axl-runtime/src/builtins/aspect/build.axl index d1175c909..8bb4c1fb9 100644 --- a/crates/axl-runtime/src/builtins/aspect/build.axl +++ b/crates/axl-runtime/src/builtins/aspect/build.axl @@ -46,14 +46,14 @@ def impl(ctx: TaskContext) -> int: print(ctx.config.build_start) - # build = ctx.bazel.build( - # build_events = build_events, - # flags = bazel_flags, - # startup_flags = bazel_startup_flags, - # *ctx.args.target_pattern - # ) + build = ctx.bazel.build( + build_events = build_events, + flags = bazel_flags, + startup_flags = bazel_startup_flags, + *ctx.args.target_pattern + ) - # build_status = build.wait() + build_status = build.wait() ctx.config.build_end(build_status.code) diff --git a/crates/axl-runtime/src/builtins/mod.rs b/crates/axl-runtime/src/builtins/mod.rs index babd7f65e..f59c18a67 100644 --- a/crates/axl-runtime/src/builtins/mod.rs +++ b/crates/axl-runtime/src/builtins/mod.rs @@ -19,13 +19,9 @@ pub fn expand_builtins( _root_dir: PathBuf, broot: PathBuf, ) -> std::io::Result> { - use aspect_telemetry::cargo_pkg_version; use std::fs; - let builtins_root = broot.join(sha256::digest(cargo_pkg_version())); - fs::create_dir_all(&builtins_root)?; - - let builtins = vec![ + const BUILTINS: &[(&str, &str)] = &[ ("aspect/build.axl", include_str!("./aspect/build.axl")), ("aspect/test.axl", include_str!("./aspect/test.axl")), ("aspect/axl_add.axl", include_str!("./aspect/axl_add.axl")), @@ -35,10 +31,26 @@ pub fn expand_builtins( ), ]; - for (path, content) in builtins { - let out_path = &builtins_root.join(path); - fs::create_dir_all(&out_path.parent().unwrap())?; - fs::write(out_path, content)?; + // Hash content to ensure staleness is detected when files change, + // even without a version bump + let content_hash = { + let mut combined = String::new(); + for (path, content) in BUILTINS { + combined.push_str(path); + combined.push_str(content); + } + sha256::digest(combined) + }; + + let builtins_root = broot.join(content_hash); + + // Only write if directory doesn't exist - content hash guarantees correctness + if !builtins_root.join("aspect").exists() { + for (path, content) in BUILTINS { + let out_path = builtins_root.join(path); + fs::create_dir_all(out_path.parent().unwrap())?; + fs::write(&out_path, content)?; + } } Ok(vec![("aspect".to_string(), builtins_root.join("aspect"))]) From 8c417dc2fb3cd6ec5a936e74ed4b9c05e40a5775 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 10:28:55 -0800 Subject: [PATCH 23/65] Update pipeline.yaml Signed-off-by: thesayyn --- .buildkite/pipeline.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index d3fadd822..e1b4fde52 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -13,6 +13,7 @@ steps: queue: aspect-default timeout_in_minutes: 20 command: + - which aspect - aspect build ... artifact_paths: - "vmstat.out" From 0bb1861baeb6d9f358fcc9ac8a02ffdd32d2d4b4 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 10:31:06 -0800 Subject: [PATCH 24/65] Update pipeline.yaml Signed-off-by: thesayyn --- .buildkite/pipeline.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index e1b4fde52..4fec4fa4c 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -13,6 +13,7 @@ steps: queue: aspect-default timeout_in_minutes: 20 command: + - echo $PATH - which aspect - aspect build ... artifact_paths: From 7ce00ef2380fdd004e10270024487fb1aa77d689 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 10:33:00 -0800 Subject: [PATCH 25/65] Update pre-command Signed-off-by: thesayyn --- .buildkite/hooks/pre-command | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index f68c26020..f566ce812 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -1,7 +1,7 @@ #!/bin/sh set -eu -ASPECT_BIN_DIR="/home/aspect-runner/.aspect/bin" +ASPECT_BIN_DIR="/root/.aspect/bin" # Bazel startup options for CI BAZEL_STARTUP_OPTS="--nohome_rc --output_user_root=/mnt/ephemeral/bazel/aspect-cli/__main__ --output_base=/mnt/ephemeral/output/aspect-cli/__main__" From 52b46c654551613ab325f6df217b5b33e78477b8 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 10:36:20 -0800 Subject: [PATCH 26/65] fix Signed-off-by: thesayyn --- .buildkite/hooks/pre-command | 2 +- .buildkite/pipeline.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index f566ce812..f68c26020 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -1,7 +1,7 @@ #!/bin/sh set -eu -ASPECT_BIN_DIR="/root/.aspect/bin" +ASPECT_BIN_DIR="/home/aspect-runner/.aspect/bin" # Bazel startup options for CI BAZEL_STARTUP_OPTS="--nohome_rc --output_user_root=/mnt/ephemeral/bazel/aspect-cli/__main__ --output_base=/mnt/ephemeral/output/aspect-cli/__main__" diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index 4fec4fa4c..9f5c151c6 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -3,7 +3,7 @@ # DO NOT EDIT - regenerate with 'aspect workflows migrate' env: - PATH: "$HOME/.aspect/bin:$PATH" + PATH: "/home/aspect-runner/.aspect/bin:$PATH" AXL_CONFIG: "/mnt/ephemeral/workdir/aspect-build/aspect-cli/axel-f/config.axl" ASPECT_DEBUG: "1" steps: From ccd98712e42dab0074e81e26da2663288e557d3a Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 10:39:48 -0800 Subject: [PATCH 27/65] Update pipeline.yaml Signed-off-by: thesayyn --- .buildkite/pipeline.yaml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index 9f5c151c6..02d60cc95 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -13,19 +13,4 @@ steps: queue: aspect-default timeout_in_minutes: 20 command: - - echo $PATH - - which aspect - aspect build ... - artifact_paths: - - "vmstat.out" - - "workflows-etc-bazel.bazelrc" - - "bes.pb" - - "bes.json" - - "compact.exec.log" - retry: - automatic: - - exit_status: -1 - limit: 1 - manual: - allowed: true - permit_on_passed: false From 2e614c83eaba1757c5b3b0fbf8d30a00c0a97d34 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 10:42:06 -0800 Subject: [PATCH 28/65] Update config.axl Signed-off-by: thesayyn --- axel-f/config.axl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/axel-f/config.axl b/axel-f/config.axl index b9e72fe4f..f38452358 100644 --- a/axel-f/config.axl +++ b/axel-f/config.axl @@ -13,6 +13,7 @@ load("./platform-config.axl", PLATFORM_DIR = "/etc/aspect/workflows/platform" def config(ctx: ConfigContext): + if ctx.std.env.var("BUILDKITE"): print("--- :aspect-build: Configuring Workflows") @@ -46,11 +47,10 @@ def config(ctx: ConfigContext): for task in ctx.tasks: if task.name == "build" and task.path.endswith("aspect/build.axl"): - print("found build task") task.config.startup_flags = lambda f: flags(f, "startup") task.config.flags = lambda f: flags(f, "build") - task.config.build_start = lambda: print("+++ Building") - task.config.build_end = lambda status: print(f"--- Build done {status}") + task.config.build_start = lambda: print("+++ :bazel: Building") + task.config.build_end = lambda status: print(f"--- :bazel: Done {status}") ctx.tasks.add(configure) From f12dba0d9e0c74c3bd7bbba92ccca50d1e4cb842 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 10:48:12 -0800 Subject: [PATCH 29/65] Update pre-command Signed-off-by: thesayyn --- .buildkite/hooks/pre-command | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index f68c26020..ea1379aed 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -7,37 +7,21 @@ ASPECT_BIN_DIR="/home/aspect-runner/.aspect/bin" BAZEL_STARTUP_OPTS="--nohome_rc --output_user_root=/mnt/ephemeral/bazel/aspect-cli/__main__ --output_base=/mnt/ephemeral/output/aspect-cli/__main__" BAZEL_BUILD_OPTS="--config=workflows --config=ci --show_progress_rate_limit=1" -echo "=== pre-command hook debug ===" -echo "ASPECT_BIN_DIR: $ASPECT_BIN_DIR" -echo "PWD: $(pwd)" - # Skip if bazel is not installed if ! command -v bazel >/dev/null 2>&1; then echo "DEBUG: bazel not found, skipping" exit 0 fi +# Generate workflows bazelrc +rosetta bazelrc > /etc/bazel.bazelrc + # Check if aspect binary exists if [ -x "$ASPECT_BIN_DIR/aspect" ]; then echo "DEBUG: Found existing aspect binary" - echo "DEBUG: Existing version:" - "$ASPECT_BIN_DIR/aspect" --version 2>&1 || true - # Skip if it's the new version (contains "programmable" in help) - if "$ASPECT_BIN_DIR/aspect" --help 2>&1 | grep -q programmable; then - echo "DEBUG: New version detected (has 'programmable'), skipping build" - exit 0 - fi - echo "DEBUG: Old version detected, removing" - # Remove old version - rm -f "$ASPECT_BIN_DIR/aspect" -else - echo "DEBUG: No existing aspect binary at $ASPECT_BIN_DIR/aspect" + exit 0 fi -# Generate workflows bazelrc -rosetta bazelrc > /etc/bazel.bazelrc - - # Build aspect-cli and install echo "--- Building aspect-cli" bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS --remote_download_toplevel //:cli From e9f04ca993490a4a73bfad61d55decd704b49e0f Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 10:48:32 -0800 Subject: [PATCH 30/65] Update pre-command Signed-off-by: thesayyn --- .buildkite/hooks/pre-command | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index ea1379aed..759be7277 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -29,13 +29,10 @@ bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS --remote_download_toplevel //: # Create target directory and copy binary mkdir -p "$ASPECT_BIN_DIR" CLI_PATH="$(bazel $BAZEL_STARTUP_OPTS cquery $BAZEL_BUILD_OPTS --output=files //:cli 2>/dev/null)" -echo "DEBUG: cquery returned path: $CLI_PATH" -echo "DEBUG: File exists check:" ls -la "$CLI_PATH" 2>&1 || echo "DEBUG: File does not exist!" cp -f "$CLI_PATH" "$ASPECT_BIN_DIR/aspect" chmod 0755 "$ASPECT_BIN_DIR/aspect" -echo "DEBUG: Installed version:" + "$ASPECT_BIN_DIR/aspect" --version 2>&1 || true echo "aspect-cli installed to $ASPECT_BIN_DIR/aspect" -echo "=== end pre-command hook debug ===" From 7c25dd66f8f5074413475997ab82106dbc30fb2e Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 10:55:27 -0800 Subject: [PATCH 31/65] cleanup Signed-off-by: thesayyn --- axel-f/config.axl | 1 - crates/aspect-cli/.aspect/config.axl | 1 - crates/axl-runtime/src/builtins/aspect/build.axl | 3 --- crates/axl-runtime/src/engine/bazel/build.rs | 2 +- 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/axel-f/config.axl b/axel-f/config.axl index f38452358..9cb826d37 100644 --- a/axel-f/config.axl +++ b/axel-f/config.axl @@ -50,7 +50,6 @@ def config(ctx: ConfigContext): task.config.startup_flags = lambda f: flags(f, "startup") task.config.flags = lambda f: flags(f, "build") task.config.build_start = lambda: print("+++ :bazel: Building") - task.config.build_end = lambda status: print(f"--- :bazel: Done {status}") ctx.tasks.add(configure) diff --git a/crates/aspect-cli/.aspect/config.axl b/crates/aspect-cli/.aspect/config.axl index 5acc4d7af..417478929 100644 --- a/crates/aspect-cli/.aspect/config.axl +++ b/crates/aspect-cli/.aspect/config.axl @@ -1,3 +1,2 @@ def config(ctx: ConfigContext): - print("running crates/aspect-cli/.aspect/config.axl") pass diff --git a/crates/axl-runtime/src/builtins/aspect/build.axl b/crates/axl-runtime/src/builtins/aspect/build.axl index 8bb4c1fb9..8ca1c90bf 100644 --- a/crates/axl-runtime/src/builtins/aspect/build.axl +++ b/crates/axl-runtime/src/builtins/aspect/build.axl @@ -41,11 +41,8 @@ def impl(ctx: TaskContext) -> int: bazel_flags = ctx.config.flags(bazel_flags) bazel_startup_flags = ctx.config.startup_flags(bazel_startup_flags) - ctx.config.build_start() - print(ctx.config.build_start) - build = ctx.bazel.build( build_events = build_events, flags = bazel_flags, diff --git a/crates/axl-runtime/src/engine/bazel/build.rs b/crates/axl-runtime/src/engine/bazel/build.rs index 87c5b9fe8..9eb726cbd 100644 --- a/crates/axl-runtime/src/engine/bazel/build.rs +++ b/crates/axl-runtime/src/engine/bazel/build.rs @@ -187,7 +187,7 @@ impl Build { if debug_mode() { eprintln!( - "running {}", + "exec: {}", format_bazel_command(&startup_flags, verb, &flags, &targets) ); } From 0692a052df38448a664c254f3fff4f7e080456cc Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 11:07:23 -0800 Subject: [PATCH 32/65] bessie endpoint Signed-off-by: thesayyn --- .buildkite/pipeline.yaml | 1 + axel-f/config.axl | 19 +++++++++++++------ axel-f/platform-config.axl | 1 + .../axl-runtime/src/builtins/aspect/build.axl | 7 +++++++ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index 02d60cc95..5fd5a6a0a 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -13,4 +13,5 @@ steps: queue: aspect-default timeout_in_minutes: 20 command: + - ls /etc/aspect/workflows/platform - aspect build ... diff --git a/axel-f/config.axl b/axel-f/config.axl index 9cb826d37..610191900 100644 --- a/axel-f/config.axl +++ b/axel-f/config.axl @@ -8,20 +8,16 @@ load("./platform-config.axl", "read_platform_config", "read_host_config", "get_bazelrc_flags", + "DEFAULT_PLATFORM_DIR" ) -PLATFORM_DIR = "/etc/aspect/workflows/platform" - def config(ctx: ConfigContext): if ctx.std.env.var("BUILDKITE"): print("--- :aspect-build: Configuring Workflows") # Read platform config from disk - platform_config = read_platform_config( - ctx.std.fs, - platform_dir = PLATFORM_DIR, - ) + platform_config = read_platform_config(ctx.std.fs) # Read host config from environment host_config = read_host_config(ctx.std.env, ctx.std.io) @@ -45,11 +41,22 @@ def config(ctx: ConfigContext): flags += flags[type] return flags + bessie_endpoint = platform_config.get("bessie_endpoint", None) + def build_event_sinks(): + sinks = [] + if user != "thesayyn" and bessie_endpoint: + sinks += bazel.build_events.grpc( + uri = bessie_endpoint, + metadata = {} # TODO: how does bessie authenticate? + ) + return sinks + for task in ctx.tasks: if task.name == "build" and task.path.endswith("aspect/build.axl"): task.config.startup_flags = lambda f: flags(f, "startup") task.config.flags = lambda f: flags(f, "build") task.config.build_start = lambda: print("+++ :bazel: Building") + task.config.build_event_sinks = build_event_sinks ctx.tasks.add(configure) diff --git a/axel-f/platform-config.axl b/axel-f/platform-config.axl index 78dfe221c..426838f27 100644 --- a/axel-f/platform-config.axl +++ b/axel-f/platform-config.axl @@ -14,6 +14,7 @@ PLATFORM_CONFIG_KEYS = { "remote_cache_endpoint": "remote_cache_endpoint", "remote_cache_address": "remote_cache_address", "storage_path": "storage_path", + "bessie_endpoint": "bessie_endpoint", } # Bazel command lists diff --git a/crates/axl-runtime/src/builtins/aspect/build.axl b/crates/axl-runtime/src/builtins/aspect/build.axl index 8ca1c90bf..00fbaeafc 100644 --- a/crates/axl-runtime/src/builtins/aspect/build.axl +++ b/crates/axl-runtime/src/builtins/aspect/build.axl @@ -5,6 +5,7 @@ A default 'build' task that wraps a 'bazel build' command. BuildConfig = spec( startup_flags = attr(typing.Callable[[list[str]], list[str]], lambda flags: flags), flags = attr(typing.Callable[[list[str]], list[str]], lambda flags: flags), + build_event_sinks = attr(typing.Callable[[], list[bazel.build.BuildEventSink]], lambda: []), # TODO: build event sinks configuration # Lifecycle build_start = attr(typing.Callable[[], None], lambda: None), @@ -29,6 +30,12 @@ def impl(ctx: TaskContext) -> int: ) ) + extra_sinks = ctx.config.build_event_sinks() + if extra_sinks: + if type(build_events) != "list": + build_events = [] + build_events.extend(extra_sinks) + bazel_flags = ["--isatty=" + str(int(ctx.std.io.stdout.is_tty))] for bazel_flag in ctx.args.bazel_flag: bazel_flags.append(bazel_flag) From e45800b8a19a0516d2380429ebcccb333cc79795 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 11:17:32 -0800 Subject: [PATCH 33/65] build it in debug mode Signed-off-by: thesayyn --- .buildkite/hooks/pre-command | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index 759be7277..466e2fd58 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -24,11 +24,11 @@ fi # Build aspect-cli and install echo "--- Building aspect-cli" -bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS --remote_download_toplevel //:cli +bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS -c dbg --remote_download_toplevel //:cli # Create target directory and copy binary mkdir -p "$ASPECT_BIN_DIR" -CLI_PATH="$(bazel $BAZEL_STARTUP_OPTS cquery $BAZEL_BUILD_OPTS --output=files //:cli 2>/dev/null)" +CLI_PATH="$(bazel $BAZEL_STARTUP_OPTS cquery $BAZEL_BUILD_OPTS -c dbg --output=files //:cli 2>/dev/null)" ls -la "$CLI_PATH" 2>&1 || echo "DEBUG: File does not exist!" cp -f "$CLI_PATH" "$ASPECT_BIN_DIR/aspect" chmod 0755 "$ASPECT_BIN_DIR/aspect" From 5ea456c0b1463884156f01300f9d29d81adf2bc3 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 11:35:56 -0800 Subject: [PATCH 34/65] Update config.axl Signed-off-by: thesayyn --- axel-f/config.axl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/axel-f/config.axl b/axel-f/config.axl index 610191900..01168a13d 100644 --- a/axel-f/config.axl +++ b/axel-f/config.axl @@ -45,10 +45,10 @@ def config(ctx: ConfigContext): def build_event_sinks(): sinks = [] if user != "thesayyn" and bessie_endpoint: - sinks += bazel.build_events.grpc( + sinks.append(bazel.build_events.grpc( uri = bessie_endpoint, metadata = {} # TODO: how does bessie authenticate? - ) + )) return sinks for task in ctx.tasks: From b108c9b0dd7e67d9b049f1b0284a0c2de6743347 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 11:38:40 -0800 Subject: [PATCH 35/65] Update config.axl Signed-off-by: thesayyn --- axel-f/config.axl | 1 + 1 file changed, 1 insertion(+) diff --git a/axel-f/config.axl b/axel-f/config.axl index 01168a13d..606dc99b4 100644 --- a/axel-f/config.axl +++ b/axel-f/config.axl @@ -53,6 +53,7 @@ def config(ctx: ConfigContext): for task in ctx.tasks: if task.name == "build" and task.path.endswith("aspect/build.axl"): + print(task.config) task.config.startup_flags = lambda f: flags(f, "startup") task.config.flags = lambda f: flags(f, "build") task.config.build_start = lambda: print("+++ :bazel: Building") From 1a88cf533cc8cbaddcd1484af4c9f87c30ed5d95 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 11:45:38 -0800 Subject: [PATCH 36/65] Update platform-config.axl Signed-off-by: thesayyn --- .buildkite/hooks/pre-command | 2 -- axel-f/platform-config.axl | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index 466e2fd58..e76f8090b 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -33,6 +33,4 @@ ls -la "$CLI_PATH" 2>&1 || echo "DEBUG: File does not exist!" cp -f "$CLI_PATH" "$ASPECT_BIN_DIR/aspect" chmod 0755 "$ASPECT_BIN_DIR/aspect" - -"$ASPECT_BIN_DIR/aspect" --version 2>&1 || true echo "aspect-cli installed to $ASPECT_BIN_DIR/aspect" diff --git a/axel-f/platform-config.axl b/axel-f/platform-config.axl index 426838f27..e3a87818b 100644 --- a/axel-f/platform-config.axl +++ b/axel-f/platform-config.axl @@ -15,6 +15,7 @@ PLATFORM_CONFIG_KEYS = { "remote_cache_address": "remote_cache_address", "storage_path": "storage_path", "bessie_endpoint": "bessie_endpoint", + "build_result_ui_base_url": "build_result_ui_base_url" } # Bazel command lists From 808613dd942ecf5526fc78888af2ad94b1287635 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 12:38:31 -0800 Subject: [PATCH 37/65] unix_socket support Signed-off-by: thesayyn --- Cargo.lock | 20 ++++ crates/axl-runtime/Cargo.toml | 5 + crates/axl-runtime/src/engine/http.rs | 128 ++++++++++++++++++++++---- 3 files changed, 134 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1d7ee3788..37e0c57eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -340,6 +340,10 @@ dependencies = [ "galvanize", "getargs", "handlebars", + "http-body-util", + "hyper", + "hyper-util", + "hyperlocal", "liquid", "liquid-core", "minijinja", @@ -359,6 +363,7 @@ dependencies = [ "tokio-stream", "tonic", "tracing", + "url", "uuid", "wasmi", "wasmi_wasi", @@ -1767,6 +1772,21 @@ dependencies = [ "windows-registry", ] +[[package]] +name = "hyperlocal" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "986c5ce3b994526b3cd75578e62554abd09f0899d6206de48b3e96ab34ccc8c7" +dependencies = [ + "hex", + "http-body-util", + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + [[package]] name = "iana-time-zone" version = "0.1.63" diff --git a/crates/axl-runtime/Cargo.toml b/crates/axl-runtime/Cargo.toml index 96d423ddd..c50da0e63 100644 --- a/crates/axl-runtime/Cargo.toml +++ b/crates/axl-runtime/Cargo.toml @@ -24,6 +24,11 @@ thiserror = "2.0.12" prost = "0.14.1" reqwest = { version="0.12.22", features = ["stream", "gzip", "zstd"] } +hyper = "1.6.0" +hyper-util = { version = "0.1.12", features = ["client-legacy", "tokio", "http1"] } +hyperlocal = "0.9.1" +http-body-util = "0.1.3" +url = "2.5.4" zstd = "0.13.3" nix = { version = "0.30.1", features = ["fs"] } diff --git a/crates/axl-runtime/src/engine/http.rs b/crates/axl-runtime/src/engine/http.rs index ed2633e17..9dc9b62c8 100644 --- a/crates/axl-runtime/src/engine/http.rs +++ b/crates/axl-runtime/src/engine/http.rs @@ -2,6 +2,10 @@ use allocative::Allocative; use derive_more::Display; use futures::FutureExt; use futures::TryStreamExt; +use http_body_util::{BodyExt, Empty, Full}; +use hyper::body::Bytes; +use hyper_util::client::legacy::Client as HyperClient; +use hyperlocal::{UnixClientExt, Uri as UnixUri}; use reqwest::redirect::Policy; use ssri::{Integrity, IntegrityChecker}; use starlark::environment::{Methods, MethodsBuilder, MethodsStatic}; @@ -174,17 +178,60 @@ pub(crate) fn http_methods(registry: &mut MethodsBuilder) { #[starlark(require = named)] url: values::StringValue, #[starlark(require = named, default = UnpackDictEntries::default())] headers: UnpackDictEntries, + #[starlark(require = named)] unix_socket: Option, ) -> starlark::Result { - let client = &this.downcast_ref_err::()?.client; - let mut req = client.get(url.as_str().to_string()); - for (key, value) in headers.entries { - req = req.header(key.as_str(), value.as_str()); - } + let url_str = url.as_str().to_string(); + let headers_vec: Vec<(String, String)> = headers + .entries + .into_iter() + .map(|(k, v)| (k.as_str().to_string(), v.as_str().to_string())) + .collect(); - let fut = async { - let res = req.send().await?; - let response = HttpResponse::from_response(res).await?; - Ok(response) + let fut = async move { + let client = HyperClient::unix(); + let uri = match &unix_socket { + Some(socket) => { + let parsed = url::Url::parse(&url_str) + .map_err(|e| anyhow::anyhow!("invalid url: {}", e))?; + UnixUri::new(socket, parsed.path()).into() + } + None => url_str + .parse::() + .map_err(|e| anyhow::anyhow!("invalid url: {}", e))?, + }; + + let mut req = hyper::Request::builder().method("GET").uri(uri); + for (key, value) in &headers_vec { + req = req.header(key.as_str(), value.as_str()); + } + let req = req + .body(Empty::::new()) + .map_err(|e| anyhow::anyhow!("failed to build request: {}", e))?; + + let res = client + .request(req) + .await + .map_err(|e| anyhow::anyhow!("request failed: {}", e))?; + + let status = res.status().as_u16(); + let headers: Vec<(String, String)> = res + .headers() + .iter() + .map(|(n, v)| (n.to_string(), v.to_str().unwrap_or("").to_string())) + .collect(); + let body = res + .into_body() + .collect() + .await + .map_err(|e| anyhow::anyhow!("failed to read body: {}", e))? + .to_bytes(); + let body = String::from_utf8_lossy(&body).to_string(); + + Ok(HttpResponse { + status, + headers, + body, + }) }; Ok(StarlarkFuture::from_future(fut.boxed())) @@ -196,17 +243,60 @@ pub(crate) fn http_methods(registry: &mut MethodsBuilder) { #[starlark(require = named, default = UnpackDictEntries::default())] headers: UnpackDictEntries, data: String, + #[starlark(require = named)] unix_socket: Option, ) -> starlark::Result { - let client = &this.downcast_ref_err::()?.client; - let mut req = client.post(url.as_str().to_string()); - for (key, value) in headers.entries { - req = req.header(key.as_str(), value.as_str()); - } - req = req.body(data); - let fut = async { - let res = req.send().await?; - let response = HttpResponse::from_response(res).await?; - Ok(response) + let url_str = url.as_str().to_string(); + let headers_vec: Vec<(String, String)> = headers + .entries + .into_iter() + .map(|(k, v)| (k.as_str().to_string(), v.as_str().to_string())) + .collect(); + + let fut = async move { + let client = HyperClient::unix(); + let uri = match &unix_socket { + Some(socket) => { + let parsed = url::Url::parse(&url_str) + .map_err(|e| anyhow::anyhow!("invalid url: {}", e))?; + UnixUri::new(socket, parsed.path()).into() + } + None => url_str + .parse::() + .map_err(|e| anyhow::anyhow!("invalid url: {}", e))?, + }; + + let mut req = hyper::Request::builder().method("POST").uri(uri); + for (key, value) in &headers_vec { + req = req.header(key.as_str(), value.as_str()); + } + let req = req + .body(Full::new(Bytes::from(data))) + .map_err(|e| anyhow::anyhow!("failed to build request: {}", e))?; + + let res = client + .request(req) + .await + .map_err(|e| anyhow::anyhow!("request failed: {}", e))?; + + let status = res.status().as_u16(); + let headers: Vec<(String, String)> = res + .headers() + .iter() + .map(|(n, v)| (n.to_string(), v.to_str().unwrap_or("").to_string())) + .collect(); + let body = res + .into_body() + .collect() + .await + .map_err(|e| anyhow::anyhow!("failed to read body: {}", e))? + .to_bytes(); + let body = String::from_utf8_lossy(&body).to_string(); + + Ok(HttpResponse { + status, + headers, + body, + }) }; Ok(StarlarkFuture::from_future(fut)) From aeed333cd58fe98b0d0681279dcd805d6cb116f2 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 12:52:00 -0800 Subject: [PATCH 38/65] fix Signed-off-by: thesayyn --- .aspect/axl.axl | 115 +++++++++++++++++++++++++++++++++ .buildkite/hooks/pre-command | 40 ++++++++---- axel-f/config.axl | 37 +++++++++-- axel-f/platform-config.axl | 3 +- crates/axl-runtime/BUILD.bazel | 5 ++ 5 files changed, 179 insertions(+), 21 deletions(-) diff --git a/.aspect/axl.axl b/.aspect/axl.axl index 6e7ee1641..d26da44e1 100644 --- a/.aspect/axl.axl +++ b/.aspect/axl.axl @@ -377,6 +377,120 @@ def test_http(ctx: TaskContext, tc: int, temp_dir: str) -> int: return tc +def test_http_get_post(ctx: TaskContext, tc: int, temp_dir: str) -> int: + # Test HTTP get and post methods including unix_socket support + test_dir = temp_dir + "/axl_http_get_post_test" + if ctx.std.fs.exists(test_dir): + ctx.std.fs.remove_dir_all(test_dir) + ctx.std.fs.create_dir(test_dir) + + # Test 1: Basic HTTP GET request + url = "https://raw.githubusercontent.com/aspect-build/aspect-cli/refs/heads/main/LICENSE" + resp1 = ctx.http().get(url = url).block() + tc = test_case(tc, resp1.status == 200, "http.get should return status 200") + tc = test_case(tc, "Apache License" in resp1.body, "http.get body should contain Apache License text") + tc = test_case(tc, type(resp1.headers) == "list", "http.get headers should be a list") + tc = test_case(tc, len(resp1.headers) > 0, "http.get headers should not be empty") + + # Test 2: HTTP GET with custom headers + resp2 = ctx.http().get(url = url, headers = {"User-Agent": "AXL-Test"}).block() + tc = test_case(tc, resp2.status == 200, "http.get with custom headers should return status 200") + + # Test 3: HTTP POST to httpbin echo endpoint + post_url = "https://httpbin.org/post" + post_data = '{"test": "data"}' + resp3 = ctx.http().post(post_url, data = post_data, headers = {"Content-Type": "application/json"}).block() + tc = test_case(tc, resp3.status == 200, "http.post should return status 200") + tc = test_case(tc, post_data in resp3.body, "http.post response should echo the posted data") + + # Test 4: Unix socket support using a Python HTTP server + socket_path = test_dir + "/test.sock" + + # Create a simple Python HTTP server script that listens on a Unix socket + server_script = test_dir + "/server.py" + ctx.std.fs.write(server_script, """ +import socket +import os +import sys + +socket_path = sys.argv[1] + +# Remove socket if it exists +if os.path.exists(socket_path): + os.unlink(socket_path) + +# Create Unix socket server +server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) +server.bind(socket_path) +server.listen(1) + +# Signal ready by creating a marker file +open(socket_path + ".ready", "w").close() + +# Handle exactly 2 connections (one GET, one POST) +for i in range(2): + conn, _ = server.accept() + data = conn.recv(4096).decode() + + # Parse the request + lines = data.split("\\r\\n") + method = lines[0].split()[0] if lines else "UNKNOWN" + + # Find body for POST + body = "" + if "\\r\\n\\r\\n" in data: + body = data.split("\\r\\n\\r\\n", 1)[1] + + # Send HTTP response + if method == "GET": + response_body = "Hello from Unix socket GET" + elif method == "POST": + response_body = "Received POST: " + body + else: + response_body = "Unknown method" + + response = "HTTP/1.1 200 OK\\r\\nContent-Length: {}\\r\\nContent-Type: text/plain\\r\\n\\r\\n{}".format( + len(response_body), response_body + ) + conn.sendall(response.encode()) + conn.close() + +server.close() +os.unlink(socket_path) +""") + + # Start the server in background + server_proc = ctx.std.process.command("python3").arg(server_script).arg(socket_path).spawn() + + # Wait for server to be ready (poll for ready file) + ready_file = socket_path + ".ready" + for _ in range(50): # 5 seconds max + if ctx.std.fs.exists(ready_file): + break + ctx.std.process.command("sleep").arg("0.1").output() + + tc = test_case(tc, ctx.std.fs.exists(ready_file), "unix socket server should be ready") + + # Test 5: HTTP GET over Unix socket + resp4 = ctx.http().get(url = "http://localhost/test", unix_socket = socket_path).block() + tc = test_case(tc, resp4.status == 200, "http.get over unix_socket should return status 200") + tc = test_case(tc, resp4.body == "Hello from Unix socket GET", "http.get over unix_socket should return correct body") + + # Test 6: HTTP POST over Unix socket + resp5 = ctx.http().post("http://localhost/test", data = "unix socket data", unix_socket = socket_path).block() + tc = test_case(tc, resp5.status == 200, "http.post over unix_socket should return status 200") + tc = test_case(tc, "Received POST: unix socket data" in resp5.body, "http.post over unix_socket should echo data") + + # Wait for server to finish + server_proc.wait() + + # Cleanup + if ctx.std.fs.exists(ready_file): + ctx.std.fs.remove_file(ready_file) + ctx.std.fs.remove_dir_all(test_dir) + + return tc + def impl(ctx: TaskContext) -> int: tc = 0 @@ -422,6 +536,7 @@ def impl(ctx: TaskContext) -> int: tc = test_build_events(ctx, tc, temp_dir) tc = test_large_bes(ctx, tc, temp_dir) tc = test_http(ctx, tc, temp_dir) + tc = test_http_get_post(ctx, tc, temp_dir) print(tc, "tests passed") return 0 diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index e76f8090b..410b6781d 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -16,21 +16,33 @@ fi # Generate workflows bazelrc rosetta bazelrc > /etc/bazel.bazelrc -# Check if aspect binary exists +# Create target directory +mkdir -p "$ASPECT_BIN_DIR" + +# Build and install aspect-cli if not present if [ -x "$ASPECT_BIN_DIR/aspect" ]; then echo "DEBUG: Found existing aspect binary" - exit 0 +else + echo "--- Building aspect-cli" + bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS -c dbg --remote_download_toplevel //:cli + + CLI_PATH="$(bazel $BAZEL_STARTUP_OPTS cquery $BAZEL_BUILD_OPTS -c dbg --output=files //:cli 2>/dev/null)" + ls -la "$CLI_PATH" 2>&1 || echo "DEBUG: File does not exist!" + cp -f "$CLI_PATH" "$ASPECT_BIN_DIR/aspect" + chmod 0755 "$ASPECT_BIN_DIR/aspect" + echo "aspect-cli installed to $ASPECT_BIN_DIR/aspect" fi -# Build aspect-cli and install -echo "--- Building aspect-cli" -bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS -c dbg --remote_download_toplevel //:cli - -# Create target directory and copy binary -mkdir -p "$ASPECT_BIN_DIR" -CLI_PATH="$(bazel $BAZEL_STARTUP_OPTS cquery $BAZEL_BUILD_OPTS -c dbg --output=files //:cli 2>/dev/null)" -ls -la "$CLI_PATH" 2>&1 || echo "DEBUG: File does not exist!" -cp -f "$CLI_PATH" "$ASPECT_BIN_DIR/aspect" -chmod 0755 "$ASPECT_BIN_DIR/aspect" - -echo "aspect-cli installed to $ASPECT_BIN_DIR/aspect" +# Build and install deliveryd if not present +if [ -x "$ASPECT_BIN_DIR/deliveryd" ]; then + echo "DEBUG: Found existing deliveryd binary" +else + echo "--- Building deliveryd" + bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS -c dbg --remote_download_toplevel //examples/deliveryd + + DELIVERYD_PATH="$(bazel $BAZEL_STARTUP_OPTS cquery $BAZEL_BUILD_OPTS -c dbg --output=files //examples/deliveryd 2>/dev/null)" + ls -la "$DELIVERYD_PATH" 2>&1 || echo "DEBUG: File does not exist!" + cp -f "$DELIVERYD_PATH" "$ASPECT_BIN_DIR/deliveryd" + chmod 0755 "$ASPECT_BIN_DIR/deliveryd" + echo "deliveryd installed to $ASPECT_BIN_DIR/deliveryd" +fi diff --git a/axel-f/config.axl b/axel-f/config.axl index 606dc99b4..0a4b538f6 100644 --- a/axel-f/config.axl +++ b/axel-f/config.axl @@ -4,6 +4,7 @@ load("./configure.axl", "configure") load("./gazelle.axl", "gazelle") load("./buildifier.axl", "buildifier") load("./migrate.axl", "migrate") +load("./delivery.axl", "delivery") load("./platform-config.axl", "read_platform_config", "read_host_config", @@ -11,7 +12,32 @@ load("./platform-config.axl", "DEFAULT_PLATFORM_DIR" ) +def _start_deliveryd(ctx, delivery_db_endpoint, socket_path = "/tmp/deliveryd.sock"): + """ + Start the deliveryd process in the background. + + Args: + ctx: Config context + delivery_db_endpoint: Redis endpoint URL (redis:// or rediss:// for TLS) + socket_path: Unix socket path for deliveryd + """ + cmd = ctx.std.process.command("deliveryd") + cmd.arg("--socket=" + socket_path) + cmd.arg("--redis-endpoint=" + delivery_db_endpoint) + + # Run in background + cmd.stdout("null") + cmd.stderr("null") + cmd.spawn() + + print("Started deliveryd (socket: {}, endpoint: {})".format(socket_path, delivery_db_endpoint)) + def config(ctx: ConfigContext): + ctx.tasks.add(configure) + ctx.tasks.add(gazelle) + ctx.tasks.add(buildifier) + ctx.tasks.add(migrate) + ctx.tasks.add(delivery) if ctx.std.env.var("BUILDKITE"): print("--- :aspect-build: Configuring Workflows") @@ -19,6 +45,11 @@ def config(ctx: ConfigContext): # Read platform config from disk platform_config = read_platform_config(ctx.std.fs) + # Start deliveryd if delivery_db_endpoint is configured + delivery_db_endpoint = platform_config.get("delivery_db_endpoint") + if delivery_db_endpoint: + _start_deliveryd(ctx, delivery_db_endpoint) + # Read host config from environment host_config = read_host_config(ctx.std.env, ctx.std.io) @@ -58,9 +89,3 @@ def config(ctx: ConfigContext): task.config.flags = lambda f: flags(f, "build") task.config.build_start = lambda: print("+++ :bazel: Building") task.config.build_event_sinks = build_event_sinks - - - ctx.tasks.add(configure) - ctx.tasks.add(gazelle) - ctx.tasks.add(buildifier) - ctx.tasks.add(migrate) diff --git a/axel-f/platform-config.axl b/axel-f/platform-config.axl index e3a87818b..48539f57a 100644 --- a/axel-f/platform-config.axl +++ b/axel-f/platform-config.axl @@ -15,7 +15,8 @@ PLATFORM_CONFIG_KEYS = { "remote_cache_address": "remote_cache_address", "storage_path": "storage_path", "bessie_endpoint": "bessie_endpoint", - "build_result_ui_base_url": "build_result_ui_base_url" + "build_result_ui_base_url": "build_result_ui_base_url", + "delivery_db_endpoint": "delivery_db_endpoint" } # Bazel command lists diff --git a/crates/axl-runtime/BUILD.bazel b/crates/axl-runtime/BUILD.bazel index 95c0f570e..aa6d73e65 100644 --- a/crates/axl-runtime/BUILD.bazel +++ b/crates/axl-runtime/BUILD.bazel @@ -17,6 +17,10 @@ rust_library( "@crates//:futures-util", "@crates//:futures", "@crates//:handlebars", + "@crates//:http-body-util", + "@crates//:hyper", + "@crates//:hyper-util", + "@crates//:hyperlocal", "@crates//:liquid-core", "@crates//:liquid", "@crates//:minijinja", @@ -33,6 +37,7 @@ rust_library( "@crates//:tokio-stream", "@crates//:tokio", "@crates//:tracing", + "@crates//:url", "@crates//:uuid", "@crates//:wasmi_wasi", "@crates//:wasmi", From e7c4bdaf50cc8a3f950bf200156467742347d6a9 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 12:53:19 -0800 Subject: [PATCH 39/65] Update pre-command Signed-off-by: thesayyn --- .buildkite/hooks/pre-command | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index 410b6781d..03136d719 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -33,16 +33,20 @@ else echo "aspect-cli installed to $ASPECT_BIN_DIR/aspect" fi -# Build and install deliveryd if not present +# Build and install deliveryd if not present (separate module) if [ -x "$ASPECT_BIN_DIR/deliveryd" ]; then echo "DEBUG: Found existing deliveryd binary" else echo "--- Building deliveryd" - bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS -c dbg --remote_download_toplevel //examples/deliveryd - - DELIVERYD_PATH="$(bazel $BAZEL_STARTUP_OPTS cquery $BAZEL_BUILD_OPTS -c dbg --output=files //examples/deliveryd 2>/dev/null)" - ls -la "$DELIVERYD_PATH" 2>&1 || echo "DEBUG: File does not exist!" - cp -f "$DELIVERYD_PATH" "$ASPECT_BIN_DIR/deliveryd" - chmod 0755 "$ASPECT_BIN_DIR/deliveryd" + DELIVERYD_STARTUP_OPTS="--nohome_rc --output_user_root=/mnt/ephemeral/bazel/deliveryd/__main__ --output_base=/mnt/ephemeral/output/deliveryd/__main__" + + ( + cd examples/deliveryd + bazel $DELIVERYD_STARTUP_OPTS build $BAZEL_BUILD_OPTS -c dbg --remote_download_toplevel //:deliveryd + DELIVERYD_PATH="$(bazel $DELIVERYD_STARTUP_OPTS cquery $BAZEL_BUILD_OPTS -c dbg --output=files //:deliveryd 2>/dev/null)" + ls -la "$DELIVERYD_PATH" 2>&1 || echo "DEBUG: File does not exist!" + cp -f "$DELIVERYD_PATH" "$ASPECT_BIN_DIR/deliveryd" + chmod 0755 "$ASPECT_BIN_DIR/deliveryd" + ) echo "deliveryd installed to $ASPECT_BIN_DIR/deliveryd" fi From cfd631e450bb24be777a20b7635d4c62883d274a Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 12:54:22 -0800 Subject: [PATCH 40/65] deliveryd Signed-off-by: thesayyn --- examples/deliveryd/BUILD.bazel | 22 ++++ examples/deliveryd/MODULE.bazel | 11 ++ examples/deliveryd/go.mod | 10 ++ examples/deliveryd/go.sum | 10 ++ examples/deliveryd/handlers.go | 177 ++++++++++++++++++++++++++++++++ examples/deliveryd/main.go | 53 ++++++++++ examples/deliveryd/redis.go | 139 +++++++++++++++++++++++++ examples/deliveryd/server.go | 46 +++++++++ examples/deliveryd/types.go | 48 +++++++++ 9 files changed, 516 insertions(+) create mode 100644 examples/deliveryd/BUILD.bazel create mode 100644 examples/deliveryd/MODULE.bazel create mode 100644 examples/deliveryd/go.mod create mode 100644 examples/deliveryd/go.sum create mode 100644 examples/deliveryd/handlers.go create mode 100644 examples/deliveryd/main.go create mode 100644 examples/deliveryd/redis.go create mode 100644 examples/deliveryd/server.go create mode 100644 examples/deliveryd/types.go diff --git a/examples/deliveryd/BUILD.bazel b/examples/deliveryd/BUILD.bazel new file mode 100644 index 000000000..82873d27f --- /dev/null +++ b/examples/deliveryd/BUILD.bazel @@ -0,0 +1,22 @@ +load("@rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( + name = "deliveryd_lib", + srcs = [ + "handlers.go", + "main.go", + "redis.go", + "server.go", + "types.go", + ], + importpath = "github.com/aspect-build/deliveryd", + deps = [ + "@com_github_redis_go_redis_v9//:go-redis", + ], +) + +go_binary( + name = "deliveryd", + embed = [":deliveryd_lib"], + visibility = ["//visibility:public"], +) diff --git a/examples/deliveryd/MODULE.bazel b/examples/deliveryd/MODULE.bazel new file mode 100644 index 000000000..c40259e22 --- /dev/null +++ b/examples/deliveryd/MODULE.bazel @@ -0,0 +1,11 @@ +module( + name = "deliveryd", + version = "0.0.0", +) + +bazel_dep(name = "rules_go", version = "0.50.1") +bazel_dep(name = "gazelle", version = "0.39.1") + +go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps") +go_deps.from_file(go_mod = "//:go.mod") +use_repo(go_deps, "com_github_redis_go_redis_v9") diff --git a/examples/deliveryd/go.mod b/examples/deliveryd/go.mod new file mode 100644 index 000000000..38ab0799f --- /dev/null +++ b/examples/deliveryd/go.mod @@ -0,0 +1,10 @@ +module github.com/aspect-build/deliveryd + +go 1.22 + +require github.com/redis/go-redis/v9 v9.7.0 + +require ( + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect +) diff --git a/examples/deliveryd/go.sum b/examples/deliveryd/go.sum new file mode 100644 index 000000000..f11d99f08 --- /dev/null +++ b/examples/deliveryd/go.sum @@ -0,0 +1,10 @@ +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E= +github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw= diff --git a/examples/deliveryd/handlers.go b/examples/deliveryd/handlers.go new file mode 100644 index 000000000..da0367fd5 --- /dev/null +++ b/examples/deliveryd/handlers.go @@ -0,0 +1,177 @@ +package main + +import ( + "encoding/json" + "net/http" +) + +// Handler holds the HTTP handlers and their dependencies. +type Handler struct { + redis *RedisClient +} + +// NewHandler creates a new Handler with the given Redis client. +func NewHandler(redis *RedisClient) *Handler { + return &Handler{redis: redis} +} + +// HandleQuery handles POST /query requests. +func (h *Handler) HandleQuery(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + + var req QueryRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "Invalid JSON: "+err.Error(), http.StatusBadRequest) + return + } + + if req.CIHost == "" || req.CommitSHA == "" || req.Workspace == "" { + http.Error(w, "Missing required fields: ci_host, commit_sha, workspace", http.StatusBadRequest) + return + } + + ctx := r.Context() + + entries, err := h.redis.GetOutputSHAsForCommit(ctx, req.CIHost, req.CommitSHA, req.Workspace) + if err != nil { + http.Error(w, "Redis error: "+err.Error(), http.StatusInternalServerError) + return + } + + var targets []TargetStatus + for _, entry := range entries { + signature, err := h.redis.GetDeliverySignature(ctx, req.CIHost, entry.OutputSHA, req.Workspace) + if err != nil { + http.Error(w, "Redis error: "+err.Error(), http.StatusInternalServerError) + return + } + + target := TargetStatus{ + Label: entry.Label, + OutputSHA: entry.OutputSHA, + Delivered: signature != "", + } + if signature != "" { + target.DeliveredBy = &signature + } + targets = append(targets, target) + } + + resp := QueryResponse{ + CIHost: req.CIHost, + CommitSHA: req.CommitSHA, + Workspace: req.Workspace, + Targets: targets, + } + + w.Header().Set("Content-Type", "application/json") + if err := json.NewEncoder(w).Encode(resp); err != nil { + http.Error(w, "Failed to encode response", http.StatusInternalServerError) + return + } +} + +// HandleHealth handles GET /health requests. +func (h *Handler) HandleHealth(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + + ctx := r.Context() + if err := h.redis.Ping(ctx); err != nil { + w.WriteHeader(http.StatusServiceUnavailable) + w.Write([]byte("unhealthy: redis connection failed")) + return + } + + w.WriteHeader(http.StatusOK) + w.Write([]byte("ok")) +} + +// HandleRecord handles POST /record requests to record an output SHA for a target. +func (h *Handler) HandleRecord(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + + var req RecordRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "Invalid JSON: "+err.Error(), http.StatusBadRequest) + return + } + + if req.CIHost == "" || req.CommitSHA == "" || req.Workspace == "" || req.Label == "" || req.OutputSHA == "" { + http.Error(w, "Missing required fields: ci_host, commit_sha, workspace, label, output_sha", http.StatusBadRequest) + return + } + + ctx := r.Context() + if err := h.redis.SetOutputSHA(ctx, req.CIHost, req.CommitSHA, req.Workspace, req.Label, req.OutputSHA); err != nil { + http.Error(w, "Redis error: "+err.Error(), http.StatusInternalServerError) + return + } + + w.WriteHeader(http.StatusOK) + w.Write([]byte("ok")) +} + +// HandleDeliver handles POST /deliver requests to mark a target as delivered. +func (h *Handler) HandleDeliver(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + + var req DeliverRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "Invalid JSON: "+err.Error(), http.StatusBadRequest) + return + } + + if req.CIHost == "" || req.OutputSHA == "" || req.Workspace == "" || req.Signature == "" { + http.Error(w, "Missing required fields: ci_host, output_sha, workspace, signature", http.StatusBadRequest) + return + } + + ctx := r.Context() + if err := h.redis.SetDeliverySignature(ctx, req.CIHost, req.OutputSHA, req.Workspace, req.Signature); err != nil { + http.Error(w, "Redis error: "+err.Error(), http.StatusInternalServerError) + return + } + + w.WriteHeader(http.StatusOK) + w.Write([]byte("ok")) +} + +// HandleDeleteArtifact handles POST /artifact/delete requests to delete artifact metadata. +func (h *Handler) HandleDeleteArtifact(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + + var req DeleteArtifactRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "Invalid JSON: "+err.Error(), http.StatusBadRequest) + return + } + + if req.CIHost == "" || req.OutputSHA == "" || req.Workspace == "" { + http.Error(w, "Missing required fields: ci_host, output_sha, workspace", http.StatusBadRequest) + return + } + + ctx := r.Context() + if err := h.redis.DeleteArtifactMetadata(ctx, req.CIHost, req.OutputSHA, req.Workspace); err != nil { + http.Error(w, "Redis error: "+err.Error(), http.StatusInternalServerError) + return + } + + w.WriteHeader(http.StatusOK) + w.Write([]byte("ok")) +} diff --git a/examples/deliveryd/main.go b/examples/deliveryd/main.go new file mode 100644 index 000000000..9c55601aa --- /dev/null +++ b/examples/deliveryd/main.go @@ -0,0 +1,53 @@ +package main + +import ( + "context" + "flag" + "log" + "net/http" + "os" + "os/signal" + "syscall" +) + +func main() { + socketPath := flag.String("socket", "/tmp/deliveryd.sock", "Unix socket path") + redisEndpoint := flag.String("redis-endpoint", "redis://localhost:6379", "Redis endpoint URL (redis:// or rediss:// for TLS)") + flag.Parse() + + redisClient, err := NewRedisClientFromEndpoint(*redisEndpoint) + if err != nil { + log.Fatalf("Failed to parse Redis endpoint: %v", err) + } + defer redisClient.Close() + + handler := NewHandler(redisClient) + + mux := http.NewServeMux() + mux.HandleFunc("/query", handler.HandleQuery) + mux.HandleFunc("/health", handler.HandleHealth) + mux.HandleFunc("/record", handler.HandleRecord) + mux.HandleFunc("/deliver", handler.HandleDeliver) + mux.HandleFunc("/artifact/delete", handler.HandleDeleteArtifact) + + server, err := NewServer(*socketPath, mux) + if err != nil { + log.Fatalf("Failed to create server: %v", err) + } + + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) + + go func() { + <-sigChan + log.Println("Shutting down...") + if err := server.Shutdown(context.Background()); err != nil { + log.Printf("Shutdown error: %v", err) + } + }() + + log.Printf("Listening on %s", *socketPath) + if err := server.Serve(); err != nil && err != http.ErrServerClosed { + log.Fatalf("Server error: %v", err) + } +} diff --git a/examples/deliveryd/redis.go b/examples/deliveryd/redis.go new file mode 100644 index 000000000..fd417f351 --- /dev/null +++ b/examples/deliveryd/redis.go @@ -0,0 +1,139 @@ +package main + +import ( + "context" + "crypto/tls" + "fmt" + "strings" + + "github.com/redis/go-redis/v9" +) + +// RedisClient wraps the Redis client for delivery state queries. +type RedisClient struct { + client *redis.Client +} + +// NewRedisClientFromEndpoint creates a new Redis client from an endpoint URL. +// Supports formats: +// - redis://host:port +// - rediss://host:port (TLS) +// - host:port +func NewRedisClientFromEndpoint(endpoint string) (*RedisClient, error) { + useTLS := false + addr := endpoint + + // Parse protocol prefix + if strings.HasPrefix(endpoint, "rediss://") { + useTLS = true + addr = strings.TrimPrefix(endpoint, "rediss://") + } else if strings.HasPrefix(endpoint, "redis://") { + addr = strings.TrimPrefix(endpoint, "redis://") + } + + // Default port if not specified + if !strings.Contains(addr, ":") { + addr = addr + ":6379" + } + + opts := &redis.Options{ + Addr: addr, + } + if useTLS { + opts.TLSConfig = &tls.Config{ + MinVersion: tls.VersionTLS12, + } + } + + return &RedisClient{ + client: redis.NewClient(opts), + }, nil +} + +// Close closes the Redis connection. +func (r *RedisClient) Close() error { + return r.client.Close() +} + +// Ping checks the Redis connection. +func (r *RedisClient) Ping(ctx context.Context) error { + return r.client.Ping(ctx).Err() +} + +// OutputSHAEntry represents a target's output SHA from Redis. +type OutputSHAEntry struct { + Label string + OutputSHA string +} + +// GetOutputSHAsForCommit scans Redis for all output-sha keys for a given commit. +// Key format: output-sha:{ci_host}:{commit_sha}:{workspace}:{label} +func (r *RedisClient) GetOutputSHAsForCommit(ctx context.Context, ciHost, commitSHA, workspace string) ([]OutputSHAEntry, error) { + pattern := fmt.Sprintf("output-sha:%s:%s:%s:*", ciHost, commitSHA, workspace) + var entries []OutputSHAEntry + + iter := r.client.Scan(ctx, 0, pattern, 0).Iterator() + for iter.Next(ctx) { + key := iter.Val() + outputSHA, err := r.client.Get(ctx, key).Result() + if err != nil { + if err == redis.Nil { + continue + } + return nil, fmt.Errorf("failed to get value for key %s: %w", key, err) + } + + label := extractLabelFromKey(key, ciHost, commitSHA, workspace) + entries = append(entries, OutputSHAEntry{ + Label: label, + OutputSHA: outputSHA, + }) + } + if err := iter.Err(); err != nil { + return nil, fmt.Errorf("scan error: %w", err) + } + + return entries, nil +} + +// GetDeliverySignature gets the delivery signature for an output SHA. +// Key format: delivery-signature:{ci_host}:{output_sha}:{workspace} +// Returns the build URL if delivered, empty string if not. +func (r *RedisClient) GetDeliverySignature(ctx context.Context, ciHost, outputSHA, workspace string) (string, error) { + key := fmt.Sprintf("delivery-signature:%s:%s:%s", ciHost, outputSHA, workspace) + val, err := r.client.Get(ctx, key).Result() + if err != nil { + if err == redis.Nil { + return "", nil + } + return "", fmt.Errorf("failed to get delivery signature: %w", err) + } + return val, nil +} + +// extractLabelFromKey extracts the label from an output-sha key. +func extractLabelFromKey(key, ciHost, commitSHA, workspace string) string { + prefix := fmt.Sprintf("output-sha:%s:%s:%s:", ciHost, commitSHA, workspace) + return strings.TrimPrefix(key, prefix) +} + +// SetOutputSHA records an output SHA for a target. +// Key format: output-sha:{ci_host}:{commit_sha}:{workspace}:{label} +func (r *RedisClient) SetOutputSHA(ctx context.Context, ciHost, commitSHA, workspace, label, outputSHA string) error { + key := fmt.Sprintf("output-sha:%s:%s:%s:%s", ciHost, commitSHA, workspace, label) + return r.client.Set(ctx, key, outputSHA, 0).Err() +} + +// SetDeliverySignature marks an output SHA as delivered. +// Key format: delivery-signature:{ci_host}:{output_sha}:{workspace} +func (r *RedisClient) SetDeliverySignature(ctx context.Context, ciHost, outputSHA, workspace, signature string) error { + key := fmt.Sprintf("delivery-signature:%s:%s:%s", ciHost, outputSHA, workspace) + return r.client.Set(ctx, key, signature, 0).Err() +} + +// DeleteArtifactMetadata deletes artifact metadata for an output SHA. +// Key format: {ci_host}:{output_sha}:{workspace} +func (r *RedisClient) DeleteArtifactMetadata(ctx context.Context, ciHost, outputSHA, workspace string) error { + key := fmt.Sprintf("%s:%s:%s", ciHost, outputSHA, workspace) + return r.client.Del(ctx, key).Err() +} diff --git a/examples/deliveryd/server.go b/examples/deliveryd/server.go new file mode 100644 index 000000000..ce2843602 --- /dev/null +++ b/examples/deliveryd/server.go @@ -0,0 +1,46 @@ +package main + +import ( + "context" + "net" + "net/http" + "os" +) + +// Server wraps the HTTP server and Unix socket listener. +type Server struct { + httpServer *http.Server + listener net.Listener + socketPath string +} + +// NewServer creates a new server that listens on a Unix socket. +func NewServer(socketPath string, handler http.Handler) (*Server, error) { + // Remove existing socket file if it exists + if err := os.Remove(socketPath); err != nil && !os.IsNotExist(err) { + return nil, err + } + + listener, err := net.Listen("unix", socketPath) + if err != nil { + return nil, err + } + + return &Server{ + httpServer: &http.Server{Handler: handler}, + listener: listener, + socketPath: socketPath, + }, nil +} + +// Serve starts serving HTTP requests. +func (s *Server) Serve() error { + return s.httpServer.Serve(s.listener) +} + +// Shutdown gracefully shuts down the server. +func (s *Server) Shutdown(ctx context.Context) error { + err := s.httpServer.Shutdown(ctx) + os.Remove(s.socketPath) + return err +} diff --git a/examples/deliveryd/types.go b/examples/deliveryd/types.go new file mode 100644 index 000000000..7bead82f3 --- /dev/null +++ b/examples/deliveryd/types.go @@ -0,0 +1,48 @@ +package main + +// QueryRequest represents a request to query delivery state for a commit. +type QueryRequest struct { + CIHost string `json:"ci_host"` + CommitSHA string `json:"commit_sha"` + Workspace string `json:"workspace"` +} + +// TargetStatus represents the delivery status of a single target. +type TargetStatus struct { + Label string `json:"label"` + OutputSHA string `json:"output_sha"` + Delivered bool `json:"delivered"` + DeliveredBy *string `json:"delivered_by,omitempty"` +} + +// QueryResponse contains the delivery state for all targets in a commit. +type QueryResponse struct { + CIHost string `json:"ci_host"` + CommitSHA string `json:"commit_sha"` + Workspace string `json:"workspace"` + Targets []TargetStatus `json:"targets"` +} + +// RecordRequest represents a request to record an output SHA for a target. +type RecordRequest struct { + CIHost string `json:"ci_host"` + CommitSHA string `json:"commit_sha"` + Workspace string `json:"workspace"` + Label string `json:"label"` + OutputSHA string `json:"output_sha"` +} + +// DeliverRequest represents a request to mark a target as delivered. +type DeliverRequest struct { + CIHost string `json:"ci_host"` + OutputSHA string `json:"output_sha"` + Workspace string `json:"workspace"` + Signature string `json:"signature"` // e.g., build URL that performed the delivery +} + +// DeleteArtifactRequest represents a request to delete artifact metadata. +type DeleteArtifactRequest struct { + CIHost string `json:"ci_host"` + OutputSHA string `json:"output_sha"` + Workspace string `json:"workspace"` +} From 8bf39e33695fcba958dbb856170467c9aba1df64 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 12:56:04 -0800 Subject: [PATCH 41/65] Update pre-command Signed-off-by: thesayyn --- .buildkite/hooks/pre-command | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index 03136d719..bd8497d2d 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -38,12 +38,13 @@ if [ -x "$ASPECT_BIN_DIR/deliveryd" ]; then echo "DEBUG: Found existing deliveryd binary" else echo "--- Building deliveryd" - DELIVERYD_STARTUP_OPTS="--nohome_rc --output_user_root=/mnt/ephemeral/bazel/deliveryd/__main__ --output_base=/mnt/ephemeral/output/deliveryd/__main__" + DELIVERYD_STARTUP_OPTS="--nohome_rc --bazelrc=/etc/bazel.bazelrc --output_user_root=/mnt/ephemeral/bazel/deliveryd/__main__ --output_base=/mnt/ephemeral/output/deliveryd/__main__" + DELIVERYD_BUILD_OPTS="--show_progress_rate_limit=1" ( cd examples/deliveryd - bazel $DELIVERYD_STARTUP_OPTS build $BAZEL_BUILD_OPTS -c dbg --remote_download_toplevel //:deliveryd - DELIVERYD_PATH="$(bazel $DELIVERYD_STARTUP_OPTS cquery $BAZEL_BUILD_OPTS -c dbg --output=files //:deliveryd 2>/dev/null)" + bazel $DELIVERYD_STARTUP_OPTS build $DELIVERYD_BUILD_OPTS -c dbg --remote_download_toplevel //:deliveryd + DELIVERYD_PATH="$(bazel $DELIVERYD_STARTUP_OPTS cquery $DELIVERYD_BUILD_OPTS -c dbg --output=files //:deliveryd 2>/dev/null)" ls -la "$DELIVERYD_PATH" 2>&1 || echo "DEBUG: File does not exist!" cp -f "$DELIVERYD_PATH" "$ASPECT_BIN_DIR/deliveryd" chmod 0755 "$ASPECT_BIN_DIR/deliveryd" From ba66c71a7f8216c99b11e8a25ad71eb821b3e77e Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 12:58:25 -0800 Subject: [PATCH 42/65] Update pre-command Signed-off-by: thesayyn --- .buildkite/hooks/pre-command | 8 ++------ examples/deliveryd/.bazelversion | 1 + 2 files changed, 3 insertions(+), 6 deletions(-) create mode 100644 examples/deliveryd/.bazelversion diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index bd8497d2d..ff4846980 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -38,14 +38,10 @@ if [ -x "$ASPECT_BIN_DIR/deliveryd" ]; then echo "DEBUG: Found existing deliveryd binary" else echo "--- Building deliveryd" - DELIVERYD_STARTUP_OPTS="--nohome_rc --bazelrc=/etc/bazel.bazelrc --output_user_root=/mnt/ephemeral/bazel/deliveryd/__main__ --output_base=/mnt/ephemeral/output/deliveryd/__main__" - DELIVERYD_BUILD_OPTS="--show_progress_rate_limit=1" - ( cd examples/deliveryd - bazel $DELIVERYD_STARTUP_OPTS build $DELIVERYD_BUILD_OPTS -c dbg --remote_download_toplevel //:deliveryd - DELIVERYD_PATH="$(bazel $DELIVERYD_STARTUP_OPTS cquery $DELIVERYD_BUILD_OPTS -c dbg --output=files //:deliveryd 2>/dev/null)" - ls -la "$DELIVERYD_PATH" 2>&1 || echo "DEBUG: File does not exist!" + bazel build //:deliveryd + DELIVERYD_PATH="$(bazel cquery --output=files //:deliveryd 2>/dev/null)" cp -f "$DELIVERYD_PATH" "$ASPECT_BIN_DIR/deliveryd" chmod 0755 "$ASPECT_BIN_DIR/deliveryd" ) diff --git a/examples/deliveryd/.bazelversion b/examples/deliveryd/.bazelversion new file mode 100644 index 000000000..f7ee06693 --- /dev/null +++ b/examples/deliveryd/.bazelversion @@ -0,0 +1 @@ +9.0.0 From 8992f20ecbc7d1d7de36fa6cb9393daa97b57568 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 13:31:49 -0800 Subject: [PATCH 43/65] Update pre-command Signed-off-by: thesayyn --- .buildkite/hooks/pre-command | 15 +- MODULE.bazel | 6 + axel-f/delivery.axl | 312 ++++++++++++++++++++++++++ crates/axl-runtime/src/engine/http.rs | 207 +++++++++-------- 4 files changed, 438 insertions(+), 102 deletions(-) create mode 100644 axel-f/delivery.axl diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index ff4846980..cc65e5549 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -33,17 +33,16 @@ else echo "aspect-cli installed to $ASPECT_BIN_DIR/aspect" fi -# Build and install deliveryd if not present (separate module) +# Build and install deliveryd if not present (local_path_override in root module) if [ -x "$ASPECT_BIN_DIR/deliveryd" ]; then echo "DEBUG: Found existing deliveryd binary" else echo "--- Building deliveryd" - ( - cd examples/deliveryd - bazel build //:deliveryd - DELIVERYD_PATH="$(bazel cquery --output=files //:deliveryd 2>/dev/null)" - cp -f "$DELIVERYD_PATH" "$ASPECT_BIN_DIR/deliveryd" - chmod 0755 "$ASPECT_BIN_DIR/deliveryd" - ) + bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS -c dbg --remote_download_toplevel @deliveryd//:deliveryd + + DELIVERYD_PATH="$(bazel $BAZEL_STARTUP_OPTS cquery $BAZEL_BUILD_OPTS -c dbg --output=files @deliveryd//:deliveryd 2>/dev/null)" + ls -la "$DELIVERYD_PATH" 2>&1 || echo "DEBUG: File does not exist!" + cp -f "$DELIVERYD_PATH" "$ASPECT_BIN_DIR/deliveryd" + chmod 0755 "$ASPECT_BIN_DIR/deliveryd" echo "deliveryd installed to $ASPECT_BIN_DIR/deliveryd" fi diff --git a/MODULE.bazel b/MODULE.bazel index dd094a17f..d2368a026 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -16,6 +16,12 @@ bazel_dep(name = "rules_pkg", version = "1.1.0") bazel_dep(name = "rules_shell", version = "0.6.1") bazel_dep(name = "with_cfg.bzl", version = "0.12.0") bazel_dep(name = "toolchains_llvm_bootstrapped", version = "0.5.2") +bazel_dep(name = "deliveryd", version = "0.0.0") + +local_path_override( + module_name = "deliveryd", + path = "./examples/deliveryd" +) register_toolchains("@toolchains_llvm_bootstrapped//toolchain:all") diff --git a/axel-f/delivery.axl b/axel-f/delivery.axl new file mode 100644 index 000000000..f1c735ef3 --- /dev/null +++ b/axel-f/delivery.axl @@ -0,0 +1,312 @@ +""" +Delivery task that coordinates artifact delivery via deliveryd. + +Delivers each target via bazel run with stamping enabled, and signs artifacts +to prevent re-delivery. + +Uses deliveryd (Unix socket HTTP server) for all delivery state operations. +""" + +# deliveryd client helpers + +def _deliveryd_query(ctx, socket_path, ci_host, commit_sha, workspace): + """ + Query deliveryd for delivery state of all targets in a commit. + Returns a dict mapping label -> {output_sha, delivered, delivered_by}. + """ + http = ctx.http() + response = http.post( + "http://localhost/query", + unix_socket=socket_path, + json={ + "ci_host": ci_host, + "commit_sha": commit_sha, + "workspace": workspace, + }, + ) + + if not response.ok: + fail("deliveryd query failed: " + response.text) + + data = response.json() + + # Build lookup dict by label + result = {} + for target in data.get("targets", []): + result[target["label"]] = { + "output_sha": target["output_sha"], + "delivered": target["delivered"], + "delivered_by": target.get("delivered_by"), + } + return result + +def _deliveryd_deliver(ctx, socket_path, ci_host, output_sha, workspace, signature): + """ + Mark a target as delivered by setting its delivery signature. + """ + http = ctx.http() + response = http.post( + "http://localhost/deliver", + unix_socket=socket_path, + json={ + "ci_host": ci_host, + "output_sha": output_sha, + "workspace": workspace, + "signature": signature, + }, + ) + + if not response.ok: + fail("deliveryd deliver failed: " + response.text) + +def _deliveryd_delete_artifact(ctx, socket_path, ci_host, output_sha, workspace): + """ + Delete artifact metadata (used for cleanup on failed deliveries). + """ + http = ctx.http() + response = http.post( + "http://localhost/artifact/delete", + unix_socket=socket_path, + json={ + "ci_host": ci_host, + "output_sha": output_sha, + "workspace": workspace, + }, + ) + + if not response.ok: + fail("deliveryd artifact delete failed: " + response.text) + +# Delivery implementation + +def _get_override_targets(ctx): + """ + Check for override targets from environment variables. + ASPECT_WORKFLOWS_DELIVERY_TARGETS or DELIVERY_TARGETS (legacy). + Returns a set of target labels, or empty set if none. + """ + targets_str = ctx.std.env.var("ASPECT_WORKFLOWS_DELIVERY_TARGETS") + if not targets_str: + targets_str = ctx.std.env.var("DELIVERY_TARGETS") + if not targets_str: + return set() + + # Split on whitespace and filter valid labels + targets = [] + for t in targets_str.split(): + t = t.strip() + if t.startswith("//") or t.startswith("@"): + targets.append(t) + return set(targets) + +def _get_commit_sha(ctx, args_commit_sha): + """ + Get commit SHA from env vars or args. + Priority: ASPECT_WORKFLOWS_DELIVERY_COMMIT > DELIVERY_COMMIT > args. + """ + commit = ctx.std.env.var("ASPECT_WORKFLOWS_DELIVERY_COMMIT") + if commit: + return commit + commit = ctx.std.env.var("DELIVERY_COMMIT") + if commit: + return commit + return args_commit_sha + +def _run_bazel(ctx, verb, target, flags): + """ + Run a bazel command and return the exit code. + TODO: Implement ctx.bazel.run() when available. + """ + print(" [TODO] bazel {} {} {}".format(verb, " ".join(flags), target)) + return 0 # Simulate success + +def _deliver_target(ctx, socket_path, ci_host, workspace, build_url, bazel_flags, label, is_forced, target_state): + """ + Deliver a single target. + + Args: + is_forced: If True, skip signature check and always deliver. + target_state: Dict with {output_sha, delivered, delivered_by} from deliveryd, or None. + + Returns (status: str, message: str) where status is one of: + - "success": Successfully delivered + - "skipped": Already delivered (only for non-forced) + - "build_failed": Bazel build failed + - "run_failed": Bazel run failed + """ + output_sha = target_state.get("output_sha") if target_state else None + can_sign = False + + # For non-forced targets, check if already delivered + if not is_forced: + if target_state: + if target_state.get("delivered"): + return ("skipped", "Already delivered by {}".format(target_state.get("delivered_by"))) + # Have output SHA, can sign after delivery + can_sign = True + else: + # No state found - target may have been added before signatures + # were introduced. Proceed with delivery. + print(" Warning: No delivery state found for {}, bypassing signature check".format(label)) + + # Run bazel to deliver the target with stamping + print(" Delivering {}...".format(label)) + exit_code = _run_bazel(ctx, "run", label, bazel_flags) + + if exit_code != 0: + # Delivery failed - delete artifact metadata so it can be retried + # (only for non-forced targets with known output SHA) + if output_sha and not is_forced: + _deliveryd_delete_artifact(ctx, socket_path, ci_host, output_sha, workspace) + return ("run_failed", "Delivery failed with exit code {}".format(exit_code)) + + # Sign the artifact to mark as delivered (only for non-forced with output SHA) + if can_sign and output_sha: + _deliveryd_deliver(ctx, socket_path, ci_host, output_sha, workspace, build_url) + + return ("success", "Delivered successfully") + +def _delivery_impl(ctx): + # deliveryd socket path + socket_path = ctx.args.socket + + # Delivery context + ci_host = ctx.args.ci_host + workspace = ctx.args.workspace + build_url = ctx.args.build_url + + # Get commit SHA (env vars take precedence) + commit_sha = _get_commit_sha(ctx, ctx.args.commit_sha) + if not commit_sha: + fail("commit_sha is required (via --commit_sha or ASPECT_WORKFLOWS_DELIVERY_COMMIT env var)") + + # Build bazel flags for delivery + # Default: --stamp --noremote_upload_local_results --remote_download_outputs=toplevel + stamp_flags_str = ctx.args.stamp_flags + if stamp_flags_str: + bazel_flags = stamp_flags_str.split(",") + else: + bazel_flags = ["--stamp"] + + # Add flags that Workflows forces during delivery + bazel_flags.append("--noremote_upload_local_results") + bazel_flags.append("--remote_download_outputs=toplevel") + + print("Delivery task starting") + print(" deliveryd: {}".format(socket_path)) + print(" CI: {} commit: {} workspace: {}".format(ci_host, commit_sha, workspace)) + print(" Build URL: {}".format(build_url)) + print(" Bazel flags: {}".format(bazel_flags)) + + # Check for override targets (manual delivery / break the glass) + override_targets = _get_override_targets(ctx) + forced_targets = set() + + if override_targets: + print("") + print("Found {} override target(s) from ASPECT_WORKFLOWS_DELIVERY_TARGETS".format(len(override_targets))) + targets = list(override_targets) + # All override targets are forced (bypass signature check) + forced_targets = override_targets + else: + # Get targets from args (manifest generated on demand by caller) + targets_str = ctx.args.targets + if targets_str: + targets = [t.strip() for t in targets_str.split(",") if t.strip()] + else: + targets = [] + + if not targets: + print("No targets to deliver") + return 0 + + print("Found {} target(s) to deliver:".format(len(targets))) + for t in targets: + forced_marker = " (forced)" if t in forced_targets else "" + print(" - {}{}".format(t, forced_marker)) + print("") + + # Query deliveryd for delivery state of all targets + print("Querying deliveryd for delivery state...") + delivery_state = _deliveryd_query(ctx, socket_path, ci_host, commit_sha, workspace) + print(" Found state for {} target(s)".format(len(delivery_state))) + print("") + + # Track results + success = [] + skipped = [] + build_failed = [] + run_failed = [] + + for label in targets: + is_forced = label in forced_targets + target_state = delivery_state.get(label) + status, message = _deliver_target( + ctx, socket_path, ci_host, workspace, build_url, + bazel_flags, label, is_forced, target_state + ) + + if status == "success": + success.append(label) + print(" [OK] {}: {}".format(label, message)) + elif status == "skipped": + skipped.append(label) + print(" [SKIP] {}: {}".format(label, message)) + elif status == "build_failed": + build_failed.append(label) + print(" [FAIL] {}: {}".format(label, message)) + else: # run_failed + run_failed.append(label) + print(" [FAIL] {}: {}".format(label, message)) + + # Summary + print("") + print("=" * 50) + print("Delivery Summary") + print("=" * 50) + print(" Delivered: {}".format(len(success))) + print(" Skipped: {}".format(len(skipped))) + print(" Failed: {} ({} build, {} run)".format( + len(build_failed) + len(run_failed), + len(build_failed), + len(run_failed) + )) + + if success: + print("") + print("Successfully delivered:") + for t in success: + print(" - {}".format(t)) + + if skipped: + print("") + print("Skipped (already delivered):") + for t in skipped: + print(" - {}".format(t)) + + if build_failed or run_failed: + print("") + print("Failed:") + for t in build_failed: + print(" - {} (build failed)".format(t)) + for t in run_failed: + print(" - {} (run failed)".format(t)) + return 1 + + return 0 + + + +delivery = task( + name = "delivery", + implementation = _delivery_impl, + args = { + "socket": args.string(default = "/tmp/deliveryd.sock"), + "ci_host": args.string(default = "bk"), + "commit_sha": args.string(), + "workspace": args.string(default = "."), + "build_url": args.string(), + "stamp_flags": args.string(default = "--stamp"), + "targets": args.string(), # Comma-separated list of targets to deliver + }, +) diff --git a/crates/axl-runtime/src/engine/http.rs b/crates/axl-runtime/src/engine/http.rs index 9dc9b62c8..07747f4bc 100644 --- a/crates/axl-runtime/src/engine/http.rs +++ b/crates/axl-runtime/src/engine/http.rs @@ -174,11 +174,11 @@ pub(crate) fn http_methods(registry: &mut MethodsBuilder) { } fn get<'v>( - #[allow(unused)] this: values::Value<'v>, + this: values::Value<'v>, #[starlark(require = named)] url: values::StringValue, #[starlark(require = named, default = UnpackDictEntries::default())] headers: UnpackDictEntries, - #[starlark(require = named)] unix_socket: Option, + #[starlark(require = named, default = None)] unix_socket: Option, ) -> starlark::Result { let url_str = url.as_str().to_string(); let headers_vec: Vec<(String, String)> = headers @@ -187,63 +187,72 @@ pub(crate) fn http_methods(registry: &mut MethodsBuilder) { .map(|(k, v)| (k.as_str().to_string(), v.as_str().to_string())) .collect(); - let fut = async move { - let client = HyperClient::unix(); - let uri = match &unix_socket { - Some(socket) => { + match unix_socket { + Some(socket) => { + let fut = async move { + let client = HyperClient::unix(); let parsed = url::Url::parse(&url_str) .map_err(|e| anyhow::anyhow!("invalid url: {}", e))?; - UnixUri::new(socket, parsed.path()).into() - } - None => url_str - .parse::() - .map_err(|e| anyhow::anyhow!("invalid url: {}", e))?, - }; - - let mut req = hyper::Request::builder().method("GET").uri(uri); - for (key, value) in &headers_vec { - req = req.header(key.as_str(), value.as_str()); + let uri: hyper::Uri = UnixUri::new(&socket, parsed.path()).into(); + + let mut req = hyper::Request::builder().method("GET").uri(uri); + for (key, value) in &headers_vec { + req = req.header(key.as_str(), value.as_str()); + } + let req = req + .body(Empty::::new()) + .map_err(|e| anyhow::anyhow!("failed to build request: {}", e))?; + + let res = client + .request(req) + .await + .map_err(|e| anyhow::anyhow!("request failed: {}", e))?; + + let status = res.status().as_u16(); + let resp_headers: Vec<(String, String)> = res + .headers() + .iter() + .map(|(n, v)| (n.to_string(), v.to_str().unwrap_or("").to_string())) + .collect(); + let body = res + .into_body() + .collect() + .await + .map_err(|e| anyhow::anyhow!("failed to read body: {}", e))? + .to_bytes(); + let body = String::from_utf8_lossy(&body).to_string(); + + Ok(HttpResponse { + status, + headers: resp_headers, + body, + }) + }; + Ok(StarlarkFuture::from_future(fut.boxed())) } - let req = req - .body(Empty::::new()) - .map_err(|e| anyhow::anyhow!("failed to build request: {}", e))?; - - let res = client - .request(req) - .await - .map_err(|e| anyhow::anyhow!("request failed: {}", e))?; - - let status = res.status().as_u16(); - let headers: Vec<(String, String)> = res - .headers() - .iter() - .map(|(n, v)| (n.to_string(), v.to_str().unwrap_or("").to_string())) - .collect(); - let body = res - .into_body() - .collect() - .await - .map_err(|e| anyhow::anyhow!("failed to read body: {}", e))? - .to_bytes(); - let body = String::from_utf8_lossy(&body).to_string(); - - Ok(HttpResponse { - status, - headers, - body, - }) - }; - - Ok(StarlarkFuture::from_future(fut.boxed())) + None => { + let client = this.downcast_ref_err::()?.client.clone(); + let fut = async move { + let mut req = client.get(&url_str); + for (key, value) in &headers_vec { + req = req.header(key.as_str(), value.as_str()); + } + let res = req.send().await?; + let response = HttpResponse::from_response(res).await?; + Ok(response) + }; + Ok(StarlarkFuture::from_future(fut.boxed())) + } + } } fn post<'v>( - #[allow(unused)] this: values::Value<'v>, + this: values::Value<'v>, url: values::StringValue, #[starlark(require = named, default = UnpackDictEntries::default())] headers: UnpackDictEntries, data: String, - #[starlark(require = named)] unix_socket: Option, + #[starlark(require = named, default = None)] unix_socket: Option, ) -> starlark::Result { let url_str = url.as_str().to_string(); let headers_vec: Vec<(String, String)> = headers @@ -252,54 +261,64 @@ pub(crate) fn http_methods(registry: &mut MethodsBuilder) { .map(|(k, v)| (k.as_str().to_string(), v.as_str().to_string())) .collect(); - let fut = async move { - let client = HyperClient::unix(); - let uri = match &unix_socket { - Some(socket) => { + match unix_socket { + Some(socket) => { + let fut = async move { + let client = HyperClient::unix(); let parsed = url::Url::parse(&url_str) .map_err(|e| anyhow::anyhow!("invalid url: {}", e))?; - UnixUri::new(socket, parsed.path()).into() - } - None => url_str - .parse::() - .map_err(|e| anyhow::anyhow!("invalid url: {}", e))?, - }; - - let mut req = hyper::Request::builder().method("POST").uri(uri); - for (key, value) in &headers_vec { - req = req.header(key.as_str(), value.as_str()); + let uri: hyper::Uri = UnixUri::new(&socket, parsed.path()).into(); + + let mut req = hyper::Request::builder().method("POST").uri(uri); + for (key, value) in &headers_vec { + req = req.header(key.as_str(), value.as_str()); + } + let req = req + .body(Full::new(Bytes::from(data))) + .map_err(|e| anyhow::anyhow!("failed to build request: {}", e))?; + + let res = client + .request(req) + .await + .map_err(|e| anyhow::anyhow!("request failed: {}", e))?; + + let status = res.status().as_u16(); + let resp_headers: Vec<(String, String)> = res + .headers() + .iter() + .map(|(n, v)| (n.to_string(), v.to_str().unwrap_or("").to_string())) + .collect(); + let body = res + .into_body() + .collect() + .await + .map_err(|e| anyhow::anyhow!("failed to read body: {}", e))? + .to_bytes(); + let body = String::from_utf8_lossy(&body).to_string(); + + Ok(HttpResponse { + status, + headers: resp_headers, + body, + }) + }; + Ok(StarlarkFuture::from_future(fut)) } - let req = req - .body(Full::new(Bytes::from(data))) - .map_err(|e| anyhow::anyhow!("failed to build request: {}", e))?; - - let res = client - .request(req) - .await - .map_err(|e| anyhow::anyhow!("request failed: {}", e))?; - - let status = res.status().as_u16(); - let headers: Vec<(String, String)> = res - .headers() - .iter() - .map(|(n, v)| (n.to_string(), v.to_str().unwrap_or("").to_string())) - .collect(); - let body = res - .into_body() - .collect() - .await - .map_err(|e| anyhow::anyhow!("failed to read body: {}", e))? - .to_bytes(); - let body = String::from_utf8_lossy(&body).to_string(); - - Ok(HttpResponse { - status, - headers, - body, - }) - }; - - Ok(StarlarkFuture::from_future(fut)) + None => { + let client = this.downcast_ref_err::()?.client.clone(); + let fut = async move { + let mut req = client.post(&url_str); + for (key, value) in &headers_vec { + req = req.header(key.as_str(), value.as_str()); + } + req = req.body(data); + let res = req.send().await?; + let response = HttpResponse::from_response(res).await?; + Ok(response) + }; + Ok(StarlarkFuture::from_future(fut)) + } + } } } From 6f81331866a06f40a2eb3e3efbcc2e4100d07653 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 28 Jan 2026 14:33:56 -0800 Subject: [PATCH 44/65] fix Signed-off-by: thesayyn --- .aspect/axl.axl | 99 +-------------------------- .bazelignore | 3 +- .buildkite/hooks/pre-command | 40 ++++++++--- .buildkite/pipeline.yaml | 8 +++ axel-f/config.axl | 7 +- axel-f/delivery.axl | 76 ++++++++++++++------ crates/axl-runtime/src/engine/http.rs | 9 +-- examples/deliveryd/MODULE.bazel | 5 +- 8 files changed, 113 insertions(+), 134 deletions(-) diff --git a/.aspect/axl.axl b/.aspect/axl.axl index d26da44e1..a0c377c89 100644 --- a/.aspect/axl.axl +++ b/.aspect/axl.axl @@ -379,12 +379,8 @@ def test_http(ctx: TaskContext, tc: int, temp_dir: str) -> int: def test_http_get_post(ctx: TaskContext, tc: int, temp_dir: str) -> int: # Test HTTP get and post methods including unix_socket support - test_dir = temp_dir + "/axl_http_get_post_test" - if ctx.std.fs.exists(test_dir): - ctx.std.fs.remove_dir_all(test_dir) - ctx.std.fs.create_dir(test_dir) - # Test 1: Basic HTTP GET request + # Test 1: Basic HTTP GET request (reuse same URL as download test) url = "https://raw.githubusercontent.com/aspect-build/aspect-cli/refs/heads/main/LICENSE" resp1 = ctx.http().get(url = url).block() tc = test_case(tc, resp1.status == 200, "http.get should return status 200") @@ -396,99 +392,6 @@ def test_http_get_post(ctx: TaskContext, tc: int, temp_dir: str) -> int: resp2 = ctx.http().get(url = url, headers = {"User-Agent": "AXL-Test"}).block() tc = test_case(tc, resp2.status == 200, "http.get with custom headers should return status 200") - # Test 3: HTTP POST to httpbin echo endpoint - post_url = "https://httpbin.org/post" - post_data = '{"test": "data"}' - resp3 = ctx.http().post(post_url, data = post_data, headers = {"Content-Type": "application/json"}).block() - tc = test_case(tc, resp3.status == 200, "http.post should return status 200") - tc = test_case(tc, post_data in resp3.body, "http.post response should echo the posted data") - - # Test 4: Unix socket support using a Python HTTP server - socket_path = test_dir + "/test.sock" - - # Create a simple Python HTTP server script that listens on a Unix socket - server_script = test_dir + "/server.py" - ctx.std.fs.write(server_script, """ -import socket -import os -import sys - -socket_path = sys.argv[1] - -# Remove socket if it exists -if os.path.exists(socket_path): - os.unlink(socket_path) - -# Create Unix socket server -server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) -server.bind(socket_path) -server.listen(1) - -# Signal ready by creating a marker file -open(socket_path + ".ready", "w").close() - -# Handle exactly 2 connections (one GET, one POST) -for i in range(2): - conn, _ = server.accept() - data = conn.recv(4096).decode() - - # Parse the request - lines = data.split("\\r\\n") - method = lines[0].split()[0] if lines else "UNKNOWN" - - # Find body for POST - body = "" - if "\\r\\n\\r\\n" in data: - body = data.split("\\r\\n\\r\\n", 1)[1] - - # Send HTTP response - if method == "GET": - response_body = "Hello from Unix socket GET" - elif method == "POST": - response_body = "Received POST: " + body - else: - response_body = "Unknown method" - - response = "HTTP/1.1 200 OK\\r\\nContent-Length: {}\\r\\nContent-Type: text/plain\\r\\n\\r\\n{}".format( - len(response_body), response_body - ) - conn.sendall(response.encode()) - conn.close() - -server.close() -os.unlink(socket_path) -""") - - # Start the server in background - server_proc = ctx.std.process.command("python3").arg(server_script).arg(socket_path).spawn() - - # Wait for server to be ready (poll for ready file) - ready_file = socket_path + ".ready" - for _ in range(50): # 5 seconds max - if ctx.std.fs.exists(ready_file): - break - ctx.std.process.command("sleep").arg("0.1").output() - - tc = test_case(tc, ctx.std.fs.exists(ready_file), "unix socket server should be ready") - - # Test 5: HTTP GET over Unix socket - resp4 = ctx.http().get(url = "http://localhost/test", unix_socket = socket_path).block() - tc = test_case(tc, resp4.status == 200, "http.get over unix_socket should return status 200") - tc = test_case(tc, resp4.body == "Hello from Unix socket GET", "http.get over unix_socket should return correct body") - - # Test 6: HTTP POST over Unix socket - resp5 = ctx.http().post("http://localhost/test", data = "unix socket data", unix_socket = socket_path).block() - tc = test_case(tc, resp5.status == 200, "http.post over unix_socket should return status 200") - tc = test_case(tc, "Received POST: unix socket data" in resp5.body, "http.post over unix_socket should echo data") - - # Wait for server to finish - server_proc.wait() - - # Cleanup - if ctx.std.fs.exists(ready_file): - ctx.std.fs.remove_file(ready_file) - ctx.std.fs.remove_dir_all(test_dir) - return tc def impl(ctx: TaskContext) -> int: diff --git a/.bazelignore b/.bazelignore index f41c42fd7..b2b72506d 100644 --- a/.bazelignore +++ b/.bazelignore @@ -1,3 +1,4 @@ # Cargo output directory target/ -bazel/proto/ \ No newline at end of file +bazel/proto/ +examples/ diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index cc65e5549..1a4a3ad99 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -19,9 +19,25 @@ rosetta bazelrc > /etc/bazel.bazelrc # Create target directory mkdir -p "$ASPECT_BIN_DIR" -# Build and install aspect-cli if not present -if [ -x "$ASPECT_BIN_DIR/aspect" ]; then - echo "DEBUG: Found existing aspect binary" +# Get current commit +CURRENT_COMMIT="$(git rev-parse HEAD)" + +# Check if crates/ changed between two commits +crates_changed() { + local old_commit="$1" + local new_commit="$2" + git diff --name-only "$old_commit" "$new_commit" -- crates/ | grep -q . +} + +# Build and install aspect-cli if not present or crates/ changed +ASPECT_COMMIT_FILE="$ASPECT_BIN_DIR/aspect.commit" +CACHED_COMMIT="" +if [ -f "$ASPECT_COMMIT_FILE" ]; then + CACHED_COMMIT="$(cat "$ASPECT_COMMIT_FILE")" +fi + +if [ -x "$ASPECT_BIN_DIR/aspect" ] && [ -n "$CACHED_COMMIT" ] && ! crates_changed "$CACHED_COMMIT" "$CURRENT_COMMIT"; then + echo "DEBUG: Found existing aspect binary (no crates/ changes since $CACHED_COMMIT)" else echo "--- Building aspect-cli" bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS -c dbg --remote_download_toplevel //:cli @@ -30,12 +46,19 @@ else ls -la "$CLI_PATH" 2>&1 || echo "DEBUG: File does not exist!" cp -f "$CLI_PATH" "$ASPECT_BIN_DIR/aspect" chmod 0755 "$ASPECT_BIN_DIR/aspect" - echo "aspect-cli installed to $ASPECT_BIN_DIR/aspect" + echo "$CURRENT_COMMIT" > "$ASPECT_COMMIT_FILE" + echo "aspect-cli installed to $ASPECT_BIN_DIR/aspect (commit: $CURRENT_COMMIT)" +fi + +# Build and install deliveryd if not present or crates/ changed (local_path_override in root module) +DELIVERYD_COMMIT_FILE="$ASPECT_BIN_DIR/deliveryd.commit" +CACHED_DELIVERYD_COMMIT="" +if [ -f "$DELIVERYD_COMMIT_FILE" ]; then + CACHED_DELIVERYD_COMMIT="$(cat "$DELIVERYD_COMMIT_FILE")" fi -# Build and install deliveryd if not present (local_path_override in root module) -if [ -x "$ASPECT_BIN_DIR/deliveryd" ]; then - echo "DEBUG: Found existing deliveryd binary" +if [ -x "$ASPECT_BIN_DIR/deliveryd" ] && [ -n "$CACHED_DELIVERYD_COMMIT" ] && ! crates_changed "$CACHED_DELIVERYD_COMMIT" "$CURRENT_COMMIT"; then + echo "DEBUG: Found existing deliveryd binary (no crates/ changes since $CACHED_DELIVERYD_COMMIT)" else echo "--- Building deliveryd" bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS -c dbg --remote_download_toplevel @deliveryd//:deliveryd @@ -44,5 +67,6 @@ else ls -la "$DELIVERYD_PATH" 2>&1 || echo "DEBUG: File does not exist!" cp -f "$DELIVERYD_PATH" "$ASPECT_BIN_DIR/deliveryd" chmod 0755 "$ASPECT_BIN_DIR/deliveryd" - echo "deliveryd installed to $ASPECT_BIN_DIR/deliveryd" + echo "$CURRENT_COMMIT" > "$DELIVERYD_COMMIT_FILE" + echo "deliveryd installed to $ASPECT_BIN_DIR/deliveryd (commit: $CURRENT_COMMIT)" fi diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index 5fd5a6a0a..5c1588d2e 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -15,3 +15,11 @@ steps: command: - ls /etc/aspect/workflows/platform - aspect build ... + - key: __main__::delivery + label: ":bazel: Delivery" + agents: + queue: aspect-default + timeout_in_minutes: 20 + command: + - ls /tmp + - aspect delivery --commit_sha deadbeef --targets hello diff --git a/axel-f/config.axl b/axel-f/config.axl index 0a4b538f6..3655e97ab 100644 --- a/axel-f/config.axl +++ b/axel-f/config.axl @@ -14,13 +14,18 @@ load("./platform-config.axl", def _start_deliveryd(ctx, delivery_db_endpoint, socket_path = "/tmp/deliveryd.sock"): """ - Start the deliveryd process in the background. + Start the deliveryd process in the background if not already running. Args: ctx: Config context delivery_db_endpoint: Redis endpoint URL (redis:// or rediss:// for TLS) socket_path: Unix socket path for deliveryd """ + # Check if deliveryd is already running by checking for the socket + if ctx.std.fs.exists(socket_path): + print("deliveryd already running (socket: {})".format(socket_path)) + return + cmd = ctx.std.process.command("deliveryd") cmd.arg("--socket=" + socket_path) cmd.arg("--redis-endpoint=" + delivery_db_endpoint) diff --git a/axel-f/delivery.axl b/axel-f/delivery.axl index f1c735ef3..9c24e143a 100644 --- a/axel-f/delivery.axl +++ b/axel-f/delivery.axl @@ -17,22 +17,25 @@ def _deliveryd_query(ctx, socket_path, ci_host, commit_sha, workspace): http = ctx.http() response = http.post( "http://localhost/query", - unix_socket=socket_path, - json={ + headers={"Content-Type": "application/json"}, + data=json.encode({ "ci_host": ci_host, "commit_sha": commit_sha, "workspace": workspace, - }, - ) + }), + unix_socket=socket_path, + ).block() + - if not response.ok: - fail("deliveryd query failed: " + response.text) + if response.status < 200 or response.status >= 300: + fail("deliveryd query failed: " + response.body) - data = response.json() + data = json.decode(response.body) + targets = data.get("targets", []) or [] # Build lookup dict by label result = {} - for target in data.get("targets", []): + for target in targets: result[target["label"]] = { "output_sha": target["output_sha"], "delivered": target["delivered"], @@ -47,17 +50,40 @@ def _deliveryd_deliver(ctx, socket_path, ci_host, output_sha, workspace, signatu http = ctx.http() response = http.post( "http://localhost/deliver", - unix_socket=socket_path, - json={ + headers={"Content-Type": "application/json"}, + data=json.encode({ "ci_host": ci_host, "output_sha": output_sha, "workspace": workspace, "signature": signature, - }, - ) + }), + unix_socket=socket_path, + ).block() - if not response.ok: - fail("deliveryd deliver failed: " + response.text) + if response.status < 200 or response.status >= 300: + fail("deliveryd deliver failed: " + response.body) + +def _deliveryd_record(ctx, socket_path, ci_host, commit_sha, workspace, label, output_sha): + """ + Record a target's output SHA with deliveryd. + This must be called before the target can be queried or delivered. + """ + http = ctx.http() + response = http.post( + "http://localhost/record", + headers={"Content-Type": "application/json"}, + data=json.encode({ + "ci_host": ci_host, + "commit_sha": commit_sha, + "workspace": workspace, + "label": label, + "output_sha": output_sha, + }), + unix_socket=socket_path, + ).block() + + if response.status < 200 or response.status >= 300: + fail("deliveryd record failed: " + response.body) def _deliveryd_delete_artifact(ctx, socket_path, ci_host, output_sha, workspace): """ @@ -66,16 +92,17 @@ def _deliveryd_delete_artifact(ctx, socket_path, ci_host, output_sha, workspace) http = ctx.http() response = http.post( "http://localhost/artifact/delete", - unix_socket=socket_path, - json={ + headers={"Content-Type": "application/json"}, + data=json.encode({ "ci_host": ci_host, "output_sha": output_sha, "workspace": workspace, - }, - ) + }), + unix_socket=socket_path, + ).block() - if not response.ok: - fail("deliveryd artifact delete failed: " + response.text) + if response.status < 200 or response.status >= 300: + fail("deliveryd artifact delete failed: " + response.body) # Delivery implementation @@ -226,6 +253,15 @@ def _delivery_impl(ctx): print(" - {}{}".format(t, forced_marker)) print("") + # Record each target with deliveryd (so they can be queried/signed) + print("Recording targets with deliveryd...") + for label in targets: + # Use hash of commit_sha + label as output_sha + output_sha = hash(commit_sha + label) + _deliveryd_record(ctx, socket_path, ci_host, commit_sha, workspace, label, str(output_sha)) + print(" Recorded {} target(s)".format(len(targets))) + print("") + # Query deliveryd for delivery state of all targets print("Querying deliveryd for delivery state...") delivery_state = _deliveryd_query(ctx, socket_path, ci_host, commit_sha, workspace) diff --git a/crates/axl-runtime/src/engine/http.rs b/crates/axl-runtime/src/engine/http.rs index 07747f4bc..2ee384367 100644 --- a/crates/axl-runtime/src/engine/http.rs +++ b/crates/axl-runtime/src/engine/http.rs @@ -11,6 +11,7 @@ use ssri::{Integrity, IntegrityChecker}; use starlark::environment::{Methods, MethodsBuilder, MethodsStatic}; use starlark::values::AllocValue; use starlark::values::dict::UnpackDictEntries; +use starlark::values::none::NoneOr; use starlark::values::{Heap, NoSerialize, ProvidesStaticType, ValueLike}; use starlark::values::{StarlarkValue, starlark_value}; use starlark::{starlark_module, starlark_simple_value, values}; @@ -178,7 +179,7 @@ pub(crate) fn http_methods(registry: &mut MethodsBuilder) { #[starlark(require = named)] url: values::StringValue, #[starlark(require = named, default = UnpackDictEntries::default())] headers: UnpackDictEntries, - #[starlark(require = named, default = None)] unix_socket: Option, + #[starlark(require = named, default = NoneOr::None)] unix_socket: NoneOr, ) -> starlark::Result { let url_str = url.as_str().to_string(); let headers_vec: Vec<(String, String)> = headers @@ -187,7 +188,7 @@ pub(crate) fn http_methods(registry: &mut MethodsBuilder) { .map(|(k, v)| (k.as_str().to_string(), v.as_str().to_string())) .collect(); - match unix_socket { + match unix_socket.into_option() { Some(socket) => { let fut = async move { let client = HyperClient::unix(); @@ -252,7 +253,7 @@ pub(crate) fn http_methods(registry: &mut MethodsBuilder) { #[starlark(require = named, default = UnpackDictEntries::default())] headers: UnpackDictEntries, data: String, - #[starlark(require = named, default = None)] unix_socket: Option, + #[starlark(require = named, default = NoneOr::None)] unix_socket: NoneOr, ) -> starlark::Result { let url_str = url.as_str().to_string(); let headers_vec: Vec<(String, String)> = headers @@ -261,7 +262,7 @@ pub(crate) fn http_methods(registry: &mut MethodsBuilder) { .map(|(k, v)| (k.as_str().to_string(), v.as_str().to_string())) .collect(); - match unix_socket { + match unix_socket.into_option() { Some(socket) => { let fut = async move { let client = HyperClient::unix(); diff --git a/examples/deliveryd/MODULE.bazel b/examples/deliveryd/MODULE.bazel index c40259e22..3a2489622 100644 --- a/examples/deliveryd/MODULE.bazel +++ b/examples/deliveryd/MODULE.bazel @@ -3,8 +3,9 @@ module( version = "0.0.0", ) -bazel_dep(name = "rules_go", version = "0.50.1") -bazel_dep(name = "gazelle", version = "0.39.1") +bazel_dep(name = "platforms", version = "0.0.10") +bazel_dep(name = "rules_go", version = "0.59.0") +bazel_dep(name = "gazelle", version = "0.47.0") go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps") go_deps.from_file(go_mod = "//:go.mod") From 7111e57a1dbde745b381f79fe554a3fc1516806d Mon Sep 17 00:00:00 2001 From: thesayyn Date: Thu, 29 Jan 2026 19:10:47 -0800 Subject: [PATCH 45/65] working Signed-off-by: thesayyn --- .buildkite/hooks/pre-command | 6 +- .buildkite/pipeline.yaml | 4 +- axel-f/config.axl | 40 +- axel-f/delivery.axl | 345 ++++++------------ axel-f/deliveryd.axl | 104 ++++++ crates/axl-runtime/src/engine/async/future.rs | 123 ++++++- crates/axl-runtime/src/engine/http.rs | 6 +- examples/deliveryd/main.go | 2 +- examples/deliveryd/redis.go | 16 +- 9 files changed, 381 insertions(+), 265 deletions(-) create mode 100644 axel-f/deliveryd.axl diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index 1a4a3ad99..796e047dd 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -22,11 +22,11 @@ mkdir -p "$ASPECT_BIN_DIR" # Get current commit CURRENT_COMMIT="$(git rev-parse HEAD)" -# Check if crates/ changed between two commits +# Check if crates/ or examples/deliveryd/ changed between two commits crates_changed() { local old_commit="$1" local new_commit="$2" - git diff --name-only "$old_commit" "$new_commit" -- crates/ | grep -q . + git diff --name-only "$old_commit" "$new_commit" -- crates/ examples/deliveryd/ | grep -q . } # Build and install aspect-cli if not present or crates/ changed @@ -61,6 +61,8 @@ if [ -x "$ASPECT_BIN_DIR/deliveryd" ] && [ -n "$CACHED_DELIVERYD_COMMIT" ] && ! echo "DEBUG: Found existing deliveryd binary (no crates/ changes since $CACHED_DELIVERYD_COMMIT)" else echo "--- Building deliveryd" + # Kill any running deliveryd instances before rebuilding + pkill -9 deliveryd 2>/dev/null || true bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS -c dbg --remote_download_toplevel @deliveryd//:deliveryd DELIVERYD_PATH="$(bazel $BAZEL_STARTUP_OPTS cquery $BAZEL_BUILD_OPTS -c dbg --output=files @deliveryd//:deliveryd 2>/dev/null)" diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index 5c1588d2e..2b6bc30fc 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -16,10 +16,10 @@ steps: - ls /etc/aspect/workflows/platform - aspect build ... - key: __main__::delivery - label: ":bazel: Delivery" + label: ":ship: :package: :bazel: Delivery" agents: queue: aspect-default timeout_in_minutes: 20 command: - ls /tmp - - aspect delivery --commit_sha deadbeef --targets hello + - aspect delivery --build_url $BUILDKITE_BUILD_URL --commit_sha $BUILDKITE_COMMIT --force_target //:hello -- //:hello //:hello2 diff --git a/axel-f/config.axl b/axel-f/config.axl index 3655e97ab..bcfd63662 100644 --- a/axel-f/config.axl +++ b/axel-f/config.axl @@ -12,6 +12,24 @@ load("./platform-config.axl", "DEFAULT_PLATFORM_DIR" ) +def _check_deliveryd_health(ctx, socket_path): + """ + Check if deliveryd is healthy by calling the /health endpoint. + + Returns: + True if healthy, False otherwise + """ + http = ctx.http() + response = http.get( + url="http://localhost/health", + unix_socket=socket_path, + ) + + result = response.map_err(lambda e: str(e)).block() + if type(result) == "string": + return False + return result.status >= 200 and result.status < 300 + def _start_deliveryd(ctx, delivery_db_endpoint, socket_path = "/tmp/deliveryd.sock"): """ Start the deliveryd process in the background if not already running. @@ -23,8 +41,14 @@ def _start_deliveryd(ctx, delivery_db_endpoint, socket_path = "/tmp/deliveryd.so """ # Check if deliveryd is already running by checking for the socket if ctx.std.fs.exists(socket_path): - print("deliveryd already running (socket: {})".format(socket_path)) - return + # Socket exists, check if the instance is healthy + if _check_deliveryd_health(ctx, socket_path): + print("deliveryd already running and healthy (socket: {})".format(socket_path)) + return + else: + # Stale socket, remove it + print("deliveryd socket exists but instance is unhealthy, removing stale socket") + ctx.std.fs.remove_file(socket_path) cmd = ctx.std.process.command("deliveryd") cmd.arg("--socket=" + socket_path) @@ -44,7 +68,9 @@ def config(ctx: ConfigContext): ctx.tasks.add(migrate) ctx.tasks.add(delivery) - if ctx.std.env.var("BUILDKITE"): + CI = ctx.std.env.var("BUILDKITE") + + if CI: print("--- :aspect-build: Configuring Workflows") # Read platform config from disk @@ -66,9 +92,10 @@ def config(ctx: ConfigContext): ) # Debugging information - print(platform_config) - print(host_config) - print(flags) + if CI: + print(platform_config) + print(host_config) + print(flags) user = ctx.std.env.var("USER") @@ -89,7 +116,6 @@ def config(ctx: ConfigContext): for task in ctx.tasks: if task.name == "build" and task.path.endswith("aspect/build.axl"): - print(task.config) task.config.startup_flags = lambda f: flags(f, "startup") task.config.flags = lambda f: flags(f, "build") task.config.build_start = lambda: print("+++ :bazel: Building") diff --git a/axel-f/delivery.axl b/axel-f/delivery.axl index 9c24e143a..15e626acb 100644 --- a/axel-f/delivery.axl +++ b/axel-f/delivery.axl @@ -7,137 +7,26 @@ to prevent re-delivery. Uses deliveryd (Unix socket HTTP server) for all delivery state operations. """ -# deliveryd client helpers +load( + "./deliveryd.axl", + deliveryd_query = "query", + deliveryd_deliver = "deliver", + deliveryd_record = "record", + deliveryd_delete_artifact = "delete_artifact", +) -def _deliveryd_query(ctx, socket_path, ci_host, commit_sha, workspace): - """ - Query deliveryd for delivery state of all targets in a commit. - Returns a dict mapping label -> {output_sha, delivered, delivered_by}. - """ - http = ctx.http() - response = http.post( - "http://localhost/query", - headers={"Content-Type": "application/json"}, - data=json.encode({ - "ci_host": ci_host, - "commit_sha": commit_sha, - "workspace": workspace, - }), - unix_socket=socket_path, - ).block() - - - if response.status < 200 or response.status >= 300: - fail("deliveryd query failed: " + response.body) - - data = json.decode(response.body) - - targets = data.get("targets", []) or [] - # Build lookup dict by label - result = {} - for target in targets: - result[target["label"]] = { - "output_sha": target["output_sha"], - "delivered": target["delivered"], - "delivered_by": target.get("delivered_by"), - } - return result - -def _deliveryd_deliver(ctx, socket_path, ci_host, output_sha, workspace, signature): - """ - Mark a target as delivered by setting its delivery signature. - """ - http = ctx.http() - response = http.post( - "http://localhost/deliver", - headers={"Content-Type": "application/json"}, - data=json.encode({ - "ci_host": ci_host, - "output_sha": output_sha, - "workspace": workspace, - "signature": signature, - }), - unix_socket=socket_path, - ).block() - - if response.status < 200 or response.status >= 300: - fail("deliveryd deliver failed: " + response.body) - -def _deliveryd_record(ctx, socket_path, ci_host, commit_sha, workspace, label, output_sha): - """ - Record a target's output SHA with deliveryd. - This must be called before the target can be queried or delivered. - """ - http = ctx.http() - response = http.post( - "http://localhost/record", - headers={"Content-Type": "application/json"}, - data=json.encode({ - "ci_host": ci_host, - "commit_sha": commit_sha, - "workspace": workspace, - "label": label, - "output_sha": output_sha, - }), - unix_socket=socket_path, - ).block() - - if response.status < 200 or response.status >= 300: - fail("deliveryd record failed: " + response.body) - -def _deliveryd_delete_artifact(ctx, socket_path, ci_host, output_sha, workspace): - """ - Delete artifact metadata (used for cleanup on failed deliveries). - """ - http = ctx.http() - response = http.post( - "http://localhost/artifact/delete", - headers={"Content-Type": "application/json"}, - data=json.encode({ - "ci_host": ci_host, - "output_sha": output_sha, - "workspace": workspace, - }), - unix_socket=socket_path, - ).block() - - if response.status < 200 or response.status >= 300: - fail("deliveryd artifact delete failed: " + response.body) - -# Delivery implementation - -def _get_override_targets(ctx): - """ - Check for override targets from environment variables. - ASPECT_WORKFLOWS_DELIVERY_TARGETS or DELIVERY_TARGETS (legacy). - Returns a set of target labels, or empty set if none. - """ - targets_str = ctx.std.env.var("ASPECT_WORKFLOWS_DELIVERY_TARGETS") - if not targets_str: - targets_str = ctx.std.env.var("DELIVERY_TARGETS") - if not targets_str: - return set() - - # Split on whitespace and filter valid labels - targets = [] - for t in targets_str.split(): - t = t.strip() - if t.startswith("//") or t.startswith("@"): - targets.append(t) - return set(targets) - -def _get_commit_sha(ctx, args_commit_sha): - """ - Get commit SHA from env vars or args. - Priority: ASPECT_WORKFLOWS_DELIVERY_COMMIT > DELIVERY_COMMIT > args. - """ - commit = ctx.std.env.var("ASPECT_WORKFLOWS_DELIVERY_COMMIT") - if commit: - return commit - commit = ctx.std.env.var("DELIVERY_COMMIT") - if commit: - return commit - return args_commit_sha +# ANSI codes +_BOLD = "\033[1m" +_GREEN = "\033[32m" +_YELLOW = "\033[33m" +_RED = "\033[31m" +_RESET = "\033[0m" + +def _style(text, codes, is_tty): + """Wrap text in ANSI codes if terminal is TTY.""" + if is_tty: + return codes + text + _RESET + return text def _run_bazel(ctx, verb, target, flags): """ @@ -147,13 +36,14 @@ def _run_bazel(ctx, verb, target, flags): print(" [TODO] bazel {} {} {}".format(verb, " ".join(flags), target)) return 0 # Simulate success -def _deliver_target(ctx, socket_path, ci_host, workspace, build_url, bazel_flags, label, is_forced, target_state): +def _deliver_target(ctx, socket_path, ci_host, workspace, build_url, bazel_flags, label, is_forced, target_state, is_tty): """ Deliver a single target. Args: is_forced: If True, skip signature check and always deliver. target_state: Dict with {output_sha, delivered, delivered_by} from deliveryd, or None. + is_tty: Whether terminal supports colors. Returns (status: str, message: str) where status is one of: - "success": Successfully delivered @@ -162,38 +52,38 @@ def _deliver_target(ctx, socket_path, ci_host, workspace, build_url, bazel_flags - "run_failed": Bazel run failed """ output_sha = target_state.get("output_sha") if target_state else None - can_sign = False # For non-forced targets, check if already delivered if not is_forced: if target_state: if target_state.get("delivered"): return ("skipped", "Already delivered by {}".format(target_state.get("delivered_by"))) - # Have output SHA, can sign after delivery - can_sign = True else: # No state found - target may have been added before signatures # were introduced. Proceed with delivery. - print(" Warning: No delivery state found for {}, bypassing signature check".format(label)) + print(" {}: No delivery state found for {}, bypassing signature check".format( + _style("Warning", _BOLD + _YELLOW, is_tty), label)) # Run bazel to deliver the target with stamping - print(" Delivering {}...".format(label)) + print(" {} {}...".format(_style("Delivering", _BOLD, is_tty), label)) exit_code = _run_bazel(ctx, "run", label, bazel_flags) if exit_code != 0: # Delivery failed - delete artifact metadata so it can be retried - # (only for non-forced targets with known output SHA) - if output_sha and not is_forced: - _deliveryd_delete_artifact(ctx, socket_path, ci_host, output_sha, workspace) + if output_sha: + deliveryd_delete_artifact(ctx, socket_path, ci_host, output_sha, workspace) return ("run_failed", "Delivery failed with exit code {}".format(exit_code)) - # Sign the artifact to mark as delivered (only for non-forced with output SHA) - if can_sign and output_sha: - _deliveryd_deliver(ctx, socket_path, ci_host, output_sha, workspace, build_url) + # Sign the artifact to mark as delivered + if output_sha: + deliveryd_deliver(ctx, socket_path, ci_host, output_sha, workspace, build_url) return ("success", "Delivered successfully") def _delivery_impl(ctx): + # Check if terminal supports colors + is_tty = ctx.std.io.stdout.is_tty + # deliveryd socket path socket_path = ctx.args.socket @@ -201,132 +91,116 @@ def _delivery_impl(ctx): ci_host = ctx.args.ci_host workspace = ctx.args.workspace build_url = ctx.args.build_url - - # Get commit SHA (env vars take precedence) - commit_sha = _get_commit_sha(ctx, ctx.args.commit_sha) - if not commit_sha: - fail("commit_sha is required (via --commit_sha or ASPECT_WORKFLOWS_DELIVERY_COMMIT env var)") + commit_sha = ctx.args.commit_sha # Build bazel flags for delivery # Default: --stamp --noremote_upload_local_results --remote_download_outputs=toplevel - stamp_flags_str = ctx.args.stamp_flags - if stamp_flags_str: - bazel_flags = stamp_flags_str.split(",") - else: + bazel_flags = ctx.args.bazel_flag + if not bazel_flags: bazel_flags = ["--stamp"] # Add flags that Workflows forces during delivery bazel_flags.append("--noremote_upload_local_results") bazel_flags.append("--remote_download_outputs=toplevel") - print("Delivery task starting") - print(" deliveryd: {}".format(socket_path)) - print(" CI: {} commit: {} workspace: {}".format(ci_host, commit_sha, workspace)) - print(" Build URL: {}".format(build_url)) - print(" Bazel flags: {}".format(bazel_flags)) - - # Check for override targets (manual delivery / break the glass) - override_targets = _get_override_targets(ctx) - forced_targets = set() - - if override_targets: - print("") - print("Found {} override target(s) from ASPECT_WORKFLOWS_DELIVERY_TARGETS".format(len(override_targets))) - targets = list(override_targets) - # All override targets are forced (bypass signature check) - forced_targets = override_targets - else: - # Get targets from args (manifest generated on demand by caller) - targets_str = ctx.args.targets - if targets_str: - targets = [t.strip() for t in targets_str.split(",") if t.strip()] - else: - targets = [] + print(_style("Delivery:", _BOLD, is_tty)) + print(" {}: {}".format(_style("deliveryd", _BOLD, is_tty), socket_path)) + print(" {}: {}".format(_style("Host", _BOLD, is_tty), ci_host)) + print(" {}: {}".format(_style("Commit", _BOLD, is_tty), commit_sha)) + print(" {}: {}".format(_style("Workspace", _BOLD, is_tty), workspace)) + print(" {}: {}".format(_style("URL", _BOLD, is_tty), build_url)) + print(" {}: {}".format(_style("Flags", _BOLD, is_tty), bazel_flags)) + print() + + + targets = ctx.args.targets + forced_targets = ctx.args.force_target if not targets: - print("No targets to deliver") + print(_style("No targets to deliver", _BOLD + _YELLOW, is_tty)) return 0 - print("Found {} target(s) to deliver:".format(len(targets))) + print(_style("Found {} target(s) to deliver:".format(len(targets)), _BOLD, is_tty)) for t in targets: - forced_marker = " (forced)" if t in forced_targets else "" + forced_marker = _style(" (forced)", _YELLOW, is_tty) if t in forced_targets else "" print(" - {}{}".format(t, forced_marker)) print("") # Record each target with deliveryd (so they can be queried/signed) - print("Recording targets with deliveryd...") for label in targets: # Use hash of commit_sha + label as output_sha + # TODO: query remote-cache action key to determine target hash. output_sha = hash(commit_sha + label) - _deliveryd_record(ctx, socket_path, ci_host, commit_sha, workspace, label, str(output_sha)) - print(" Recorded {} target(s)".format(len(targets))) - print("") + deliveryd_record(ctx, socket_path, ci_host, commit_sha, workspace, label, str(output_sha)) # Query deliveryd for delivery state of all targets - print("Querying deliveryd for delivery state...") - delivery_state = _deliveryd_query(ctx, socket_path, ci_host, commit_sha, workspace) - print(" Found state for {} target(s)".format(len(delivery_state))) - print("") + delivery_state = deliveryd_query(ctx, socket_path, ci_host, commit_sha, workspace) # Track results - success = [] - skipped = [] - build_failed = [] - run_failed = [] + results = [] # List of (label, status, delivered_by) + success_count = 0 + skipped_count = 0 + failed_count = 0 for label in targets: is_forced = label in forced_targets target_state = delivery_state.get(label) status, message = _deliver_target( ctx, socket_path, ci_host, workspace, build_url, - bazel_flags, label, is_forced, target_state + bazel_flags, label, is_forced, target_state, is_tty ) + forced_marker = " (FORCED)" if is_forced else "" if status == "success": - success.append(label) - print(" [OK] {}: {}".format(label, message)) + success_count += 1 + results.append((label, "OK" + forced_marker, "ok", "-")) elif status == "skipped": - skipped.append(label) - print(" [SKIP] {}: {}".format(label, message)) - elif status == "build_failed": - build_failed.append(label) - print(" [FAIL] {}: {}".format(label, message)) - else: # run_failed - run_failed.append(label) - print(" [FAIL] {}: {}".format(label, message)) - - # Summary + skipped_count += 1 + delivered_by = target_state.get("delivered_by") if target_state else "-" + results.append((label, "SKIP", "skip", delivered_by or "-")) + else: # build_failed or run_failed + failed_count += 1 + results.append((label, "FAIL" + forced_marker, "fail", "-")) + + # Calculate column width for alignment + max_label_width = len("TARGET") + for label, _, _, _ in results: + if len(label) > max_label_width: + max_label_width = len(label) + + # Helper to pad string to width + def pad(s, width): + return s + " " * (width - len(s)) + + # Calculate status column width + max_status_width = len("STATUS") + for _, status_text, _, _ in results: + if len(status_text) > max_status_width: + max_status_width = len(status_text) + + # Style mapping for status types (bold + color) + status_styles = {"ok": _BOLD + _GREEN, "skip": _BOLD + _YELLOW, "fail": _BOLD + _RED} + + # Print table header (bold) + print("") + header = " {} {} {}".format(pad("TARGET", max_label_width), pad("STATUS", max_status_width), "DELIVERED BY") + print(_style(header, _BOLD, is_tty)) + for label, status_text, status_type, delivered_by in results: + styled_status = _style(status_text, status_styles[status_type], is_tty) + # Pad based on original text length, then apply style + padding = " " * (max_status_width - len(status_text)) + print(" {} {}{} {}".format(pad(label, max_label_width), styled_status, padding, delivered_by)) + + # Summary (single line with bold colors) print("") - print("=" * 50) - print("Delivery Summary") - print("=" * 50) - print(" Delivered: {}".format(len(success))) - print(" Skipped: {}".format(len(skipped))) - print(" Failed: {} ({} build, {} run)".format( - len(build_failed) + len(run_failed), - len(build_failed), - len(run_failed) - )) - - if success: - print("") - print("Successfully delivered:") - for t in success: - print(" - {}".format(t)) - - if skipped: - print("") - print("Skipped (already delivered):") - for t in skipped: - print(" - {}".format(t)) - - if build_failed or run_failed: - print("") - print("Failed:") - for t in build_failed: - print(" - {} (build failed)".format(t)) - for t in run_failed: - print(" - {} (run failed)".format(t)) + summary_parts = [ + _style("{} delivered".format(success_count), _BOLD + _GREEN, is_tty), + _style("{} skipped".format(skipped_count), _BOLD + _YELLOW, is_tty), + _style("{} failed".format(failed_count), _BOLD + _RED, is_tty), + ] + print("{} {}".format(_style("Summary:", _BOLD, is_tty), ", ".join(summary_parts))) + + if failed_count > 0: return 1 return 0 @@ -341,8 +215,9 @@ delivery = task( "ci_host": args.string(default = "bk"), "commit_sha": args.string(), "workspace": args.string(default = "."), - "build_url": args.string(), - "stamp_flags": args.string(default = "--stamp"), - "targets": args.string(), # Comma-separated list of targets to deliver + "build_url": args.string(default = "-"), + "bazel_flag": args.string(), + "force_target": args.string_list(default = []), + "targets": args.trailing_var_args(), # Comma-separated list of targets to deliver }, ) diff --git a/axel-f/deliveryd.axl b/axel-f/deliveryd.axl new file mode 100644 index 000000000..2abd33dfb --- /dev/null +++ b/axel-f/deliveryd.axl @@ -0,0 +1,104 @@ +""" +Client library for communicating with deliveryd. + +deliveryd is a Unix socket HTTP server that manages delivery state, +tracking which artifacts have been delivered and preventing re-delivery. +""" + +def query(ctx, socket_path, ci_host, commit_sha, workspace): + """ + Query deliveryd for delivery state of all targets in a commit. + Returns a dict mapping label -> {output_sha, delivered, delivered_by}. + """ + http = ctx.http() + response = http.post( + "http://localhost/query", + headers={"Content-Type": "application/json"}, + data=json.encode({ + "ci_host": ci_host, + "commit_sha": commit_sha, + "workspace": workspace, + }), + unix_socket=socket_path, + ).block() + + + if response.status < 200 or response.status >= 300: + fail("deliveryd query failed: " + response.body) + + data = json.decode(response.body) + + targets = data.get("targets", []) or [] + # Build lookup dict by label + result = {} + for target in targets: + result[target["label"]] = { + "output_sha": target["output_sha"], + "delivered": target["delivered"], + "delivered_by": target.get("delivered_by"), + } + return result + +def deliver(ctx, socket_path, ci_host, output_sha, workspace, signature): + """ + Mark a target as delivered by setting its delivery signature. + """ + http = ctx.http() + response = http.post( + "http://localhost/deliver", + headers={"Content-Type": "application/json"}, + data=json.encode({ + "ci_host": ci_host, + "output_sha": output_sha, + "workspace": workspace, + "signature": signature, + }), + unix_socket=socket_path, + ).block() + + if response.status < 200 or response.status >= 300: + fail("deliveryd deliver failed: " + response.body) + +def record(ctx, socket_path, ci_host, commit_sha, workspace, label, output_sha): + """ + Record a target's output SHA with deliveryd. + This must be called before the target can be queried or delivered. + """ + http = ctx.http() + response = http.post( + "http://localhost/record", + headers={"Content-Type": "application/json"}, + data=json.encode({ + "ci_host": ci_host, + "commit_sha": commit_sha, + "workspace": workspace, + "label": label, + "output_sha": output_sha, + }), + unix_socket=socket_path, + ).map_err(lambda e: e).block() + + if type(response) == "string": + fail("deliveryd record failed: " + response) + + if response.status < 200 or response.status >= 300: + fail("deliveryd record failed: " + response.body) + +def delete_artifact(ctx, socket_path, ci_host, output_sha, workspace): + """ + Delete artifact metadata (used for cleanup on failed deliveries). + """ + http = ctx.http() + response = http.post( + "http://localhost/artifact/delete", + headers={"Content-Type": "application/json"}, + data=json.encode({ + "ci_host": ci_host, + "output_sha": output_sha, + "workspace": workspace, + }), + unix_socket=socket_path, + ).block() + + if response.status < 200 or response.status >= 300: + fail("deliveryd artifact delete failed: " + response.body) diff --git a/crates/axl-runtime/src/engine/async/future.rs b/crates/axl-runtime/src/engine/async/future.rs index a2140d2da..a464a8e6d 100644 --- a/crates/axl-runtime/src/engine/async/future.rs +++ b/crates/axl-runtime/src/engine/async/future.rs @@ -35,14 +35,26 @@ impl<'v> AllocValue<'v> for Box { } pub type FutOutput = Result, anyhow::Error>; +#[derive(Clone, Copy)] +pub enum Transform<'v> { + MapOk(values::Value<'v>), + MapErr(values::Value<'v>), + MapOkOrElse { + map_ok: values::Value<'v>, + map_err: values::Value<'v>, + }, +} + #[derive(Display, Allocative, ProvidesStaticType, NoSerialize)] #[display("Future")] -pub struct StarlarkFuture { +pub struct StarlarkFuture<'v> { #[allocative(skip)] inner: Rc>>>, + #[allocative(skip)] + transforms: Rc>>>, } -impl StarlarkFuture { +impl<'v> StarlarkFuture<'v> { pub fn from_future( fut: impl Future> + Send + 'static, ) -> Self { @@ -52,6 +64,7 @@ impl StarlarkFuture { fut.map_ok_or_else(|e| Err(e), |r| Ok(Box::new(r) as Box)) .boxed(), ))), + transforms: Rc::new(RefCell::new(Vec::new())), } } @@ -63,9 +76,18 @@ impl StarlarkFuture { r.into_future() } + + fn with_transform(&self, transform: Transform<'v>) -> Self { + let mut new_transforms = self.transforms.borrow().clone(); + new_transforms.push(transform); + Self { + inner: self.inner.clone(), + transforms: Rc::new(RefCell::new(new_transforms)), + } + } } -impl Future for StarlarkFuture { +impl<'v> Future for StarlarkFuture<'v> { type Output = FutOutput; fn poll( @@ -76,54 +98,131 @@ impl Future for StarlarkFuture { } } -unsafe impl<'v> Trace<'v> for StarlarkFuture { - fn trace(&mut self, _tracer: &Tracer<'v>) {} +unsafe impl<'v> Trace<'v> for StarlarkFuture<'v> { + fn trace(&mut self, tracer: &Tracer<'v>) { + for transform in self.transforms.borrow_mut().iter_mut() { + match transform { + Transform::MapOk(v) => v.trace(tracer), + Transform::MapErr(v) => v.trace(tracer), + Transform::MapOkOrElse { map_ok, map_err } => { + map_ok.trace(tracer); + map_err.trace(tracer); + } + } + } + } } -impl Debug for StarlarkFuture { +impl<'v> Debug for StarlarkFuture<'v> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("Future").finish() } } -impl<'v> AllocValue<'v> for StarlarkFuture { +impl<'v> AllocValue<'v> for StarlarkFuture<'v> { fn alloc_value(self, heap: &'v Heap) -> values::Value<'v> { heap.alloc_complex_no_freeze(self) } } -impl<'v> UnpackValue<'v> for StarlarkFuture { +impl<'v> UnpackValue<'v> for StarlarkFuture<'v> { type Error = anyhow::Error; fn unpack_value_impl(value: values::Value<'v>) -> Result, Self::Error> { let fut = value.downcast_ref_err::()?; Ok(Some(Self { inner: fut.inner.clone(), + transforms: fut.transforms.clone(), })) } } #[starlark_value(type = "Future")] -impl<'v> values::StarlarkValue<'v> for StarlarkFuture { +impl<'v> values::StarlarkValue<'v> for StarlarkFuture<'v> { fn get_methods() -> Option<&'static Methods> { static RES: MethodsStatic = MethodsStatic::new(); RES.methods(future_methods) } } +fn apply_transforms<'v>( + result: FutOutput, + transforms: &[Transform<'v>], + eval: &mut Evaluator<'v, '_, '_>, +) -> starlark::Result> { + let heap = eval.heap(); + let mut current: Result, anyhow::Error> = + result.map(|boxed| boxed.alloc_value_fut(heap)); + + for transform in transforms { + current = match (current, transform) { + (Ok(val), Transform::MapOk(f)) => eval + .eval_function(*f, &[val], &[]) + .map_err(|e| anyhow::anyhow!("{}", e)), + (Err(e), Transform::MapOk(_)) => Err(e), + + (Err(e), Transform::MapErr(f)) => { + let err_str = heap.alloc_str(&e.to_string()).to_value(); + eval.eval_function(*f, &[err_str], &[]) + .map_err(|e| anyhow::anyhow!("{}", e)) + } + (Ok(v), Transform::MapErr(_)) => Ok(v), + + (Ok(val), Transform::MapOkOrElse { map_ok, .. }) => eval + .eval_function(*map_ok, &[val], &[]) + .map_err(|e| anyhow::anyhow!("{}", e)), + (Err(e), Transform::MapOkOrElse { map_err, .. }) => { + let err_str = heap.alloc_str(&e.to_string()).to_value(); + eval.eval_function(*map_err, &[err_str], &[]) + .map_err(|e| anyhow::anyhow!("{}", e)) + } + }; + } + + current.map_err(|e| starlark::Error::from(anyhow::anyhow!("{}", e))) +} + #[starlark_module] pub(crate) fn future_methods(registry: &mut MethodsBuilder) { fn block<'v>( - #[allow(unused)] this: values::Value<'v>, + this: values::Value<'v>, eval: &mut Evaluator<'v, '_, '_>, ) -> starlark::Result> { let store = AxlStore::from_eval(eval)?; let this = this.downcast_ref_err::()?; + let fut = this .inner .replace(None) .ok_or(anyhow::anyhow!("future has already been awaited"))?; - let value = store.rt.block_on(fut)?; - Ok(value.alloc_value_fut(eval.heap())) + let transforms = this.transforms.borrow().clone(); + + let result = store.rt.block_on(fut); + apply_transforms(result, &transforms, eval) + } + + fn map_ok<'v>( + this: values::Value<'v>, + callable: values::Value<'v>, + ) -> starlark::Result> { + let this_fut = this.downcast_ref_err::()?; + Ok(this_fut.with_transform(Transform::MapOk(callable))) + } + + fn map_err<'v>( + this: values::Value<'v>, + callable: values::Value<'v>, + ) -> starlark::Result> { + let this_fut = this.downcast_ref_err::()?; + Ok(this_fut.with_transform(Transform::MapErr(callable))) + } + + fn map_ok_or_else<'v>( + this: values::Value<'v>, + #[starlark(require = named)] map_ok: values::Value<'v>, + #[starlark(require = named)] map_err: values::Value<'v>, + ) -> starlark::Result> { + let this_fut = this.downcast_ref_err::()?; + Ok(this_fut.with_transform(Transform::MapOkOrElse { map_ok, map_err })) } } diff --git a/crates/axl-runtime/src/engine/http.rs b/crates/axl-runtime/src/engine/http.rs index 2ee384367..0a48777b7 100644 --- a/crates/axl-runtime/src/engine/http.rs +++ b/crates/axl-runtime/src/engine/http.rs @@ -122,7 +122,7 @@ pub(crate) fn http_methods(registry: &mut MethodsBuilder) { headers: UnpackDictEntries, #[starlark(require = named)] integrity: Option, #[starlark(require = named)] sha256: Option, - ) -> starlark::Result { + ) -> starlark::Result> { let client = &this.downcast_ref_err::()?.client; let mut req = client.get(url.as_str().to_string()); for (key, value) in headers.entries { @@ -180,7 +180,7 @@ pub(crate) fn http_methods(registry: &mut MethodsBuilder) { #[starlark(require = named, default = UnpackDictEntries::default())] headers: UnpackDictEntries, #[starlark(require = named, default = NoneOr::None)] unix_socket: NoneOr, - ) -> starlark::Result { + ) -> starlark::Result> { let url_str = url.as_str().to_string(); let headers_vec: Vec<(String, String)> = headers .entries @@ -254,7 +254,7 @@ pub(crate) fn http_methods(registry: &mut MethodsBuilder) { headers: UnpackDictEntries, data: String, #[starlark(require = named, default = NoneOr::None)] unix_socket: NoneOr, - ) -> starlark::Result { + ) -> starlark::Result> { let url_str = url.as_str().to_string(); let headers_vec: Vec<(String, String)> = headers .entries diff --git a/examples/deliveryd/main.go b/examples/deliveryd/main.go index 9c55601aa..ffdd3a7ef 100644 --- a/examples/deliveryd/main.go +++ b/examples/deliveryd/main.go @@ -17,7 +17,7 @@ func main() { redisClient, err := NewRedisClientFromEndpoint(*redisEndpoint) if err != nil { - log.Fatalf("Failed to parse Redis endpoint: %v", err) + log.Fatalf("Failed to parse Rediss endpoint: %v", err) } defer redisClient.Close() diff --git a/examples/deliveryd/redis.go b/examples/deliveryd/redis.go index fd417f351..417f3e01d 100644 --- a/examples/deliveryd/redis.go +++ b/examples/deliveryd/redis.go @@ -5,6 +5,7 @@ import ( "crypto/tls" "fmt" "strings" + "time" "github.com/redis/go-redis/v9" ) @@ -20,13 +21,19 @@ type RedisClient struct { // - rediss://host:port (TLS) // - host:port func NewRedisClientFromEndpoint(endpoint string) (*RedisClient, error) { - useTLS := false + // TLS is enabled by default (matches the old TypeScript behavior) + useTLS := true addr := endpoint // Parse protocol prefix + // - rediss:// explicitly enables TLS (default) + // - redis+insecure:// explicitly disables TLS (for local development) + // - redis:// uses TLS by default (AWS MemoryDB requires TLS) if strings.HasPrefix(endpoint, "rediss://") { - useTLS = true addr = strings.TrimPrefix(endpoint, "rediss://") + } else if strings.HasPrefix(endpoint, "redis+insecure://") { + useTLS = false + addr = strings.TrimPrefix(endpoint, "redis+insecure://") } else if strings.HasPrefix(endpoint, "redis://") { addr = strings.TrimPrefix(endpoint, "redis://") } @@ -37,7 +44,10 @@ func NewRedisClientFromEndpoint(endpoint string) (*RedisClient, error) { } opts := &redis.Options{ - Addr: addr, + Addr: addr, + DialTimeout: 2 * time.Second, + ReadTimeout: 3 * time.Second, + WriteTimeout: 3 * time.Second, } if useTLS { opts.TLSConfig = &tls.Config{ From 2b7d58268b6566714b896c51f63216bc17d3611a Mon Sep 17 00:00:00 2001 From: thesayyn Date: Thu, 29 Jan 2026 21:26:40 -0800 Subject: [PATCH 46/65] Update delivery.axl Signed-off-by: thesayyn --- axel-f/delivery.axl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/axel-f/delivery.axl b/axel-f/delivery.axl index 15e626acb..062059de0 100644 --- a/axel-f/delivery.axl +++ b/axel-f/delivery.axl @@ -84,6 +84,11 @@ def _delivery_impl(ctx): # Check if terminal supports colors is_tty = ctx.std.io.stdout.is_tty + is_ci = ctx.std.env.var("BUILDKITE") + + if is_ci: + print("--- :bazel: Delivery") + # deliveryd socket path socket_path = ctx.args.socket From 0c601ac124e432b85d5699cbdf816e2765ba012d Mon Sep 17 00:00:00 2001 From: thesayyn Date: Fri, 30 Jan 2026 11:16:03 -0800 Subject: [PATCH 47/65] healthcheck and information Signed-off-by: thesayyn --- .buildkite/pipeline.yaml | 10 ++++++++++ axel-f/config.axl | 2 ++ axel-f/delivery.axl | 29 ++++++++++++++++++++--------- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index 2b6bc30fc..50355679e 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -13,6 +13,11 @@ steps: queue: aspect-default timeout_in_minutes: 20 command: + - | + echo "--- :aspect-build: Workflows environment" + /etc/aspect/workflows/bin/configure_workflows_env + echo "--- :stethoscope: Agent health check" + /etc/aspect/workflows/bin/agent_health_check - ls /etc/aspect/workflows/platform - aspect build ... - key: __main__::delivery @@ -21,5 +26,10 @@ steps: queue: aspect-default timeout_in_minutes: 20 command: + - | + echo "--- :aspect-build: Workflows environment" + /etc/aspect/workflows/bin/configure_workflows_env + echo "--- :stethoscope: Agent health check" + /etc/aspect/workflows/bin/agent_health_check - ls /tmp - aspect delivery --build_url $BUILDKITE_BUILD_URL --commit_sha $BUILDKITE_COMMIT --force_target //:hello -- //:hello //:hello2 diff --git a/axel-f/config.axl b/axel-f/config.axl index bcfd63662..c938dd2a2 100644 --- a/axel-f/config.axl +++ b/axel-f/config.axl @@ -120,3 +120,5 @@ def config(ctx: ConfigContext): task.config.flags = lambda f: flags(f, "build") task.config.build_start = lambda: print("+++ :bazel: Building") task.config.build_event_sinks = build_event_sinks + if task.name == "delivery": + task.config.delivery_start = lambda: print("--- :bazel: Delivery") diff --git a/axel-f/delivery.axl b/axel-f/delivery.axl index 062059de0..ce863ef00 100644 --- a/axel-f/delivery.axl +++ b/axel-f/delivery.axl @@ -15,6 +15,7 @@ load( deliveryd_delete_artifact = "delete_artifact", ) + # ANSI codes _BOLD = "\033[1m" _GREEN = "\033[32m" @@ -36,6 +37,11 @@ def _run_bazel(ctx, verb, target, flags): print(" [TODO] bazel {} {} {}".format(verb, " ".join(flags), target)) return 0 # Simulate success +# Helper to pad string to width +def pad(s, width): + return s + " " * (width - len(s)) + + def _deliver_target(ctx, socket_path, ci_host, workspace, build_url, bazel_flags, label, is_forced, target_state, is_tty): """ Deliver a single target. @@ -81,14 +87,11 @@ def _deliver_target(ctx, socket_path, ci_host, workspace, build_url, bazel_flags return ("success", "Delivered successfully") def _delivery_impl(ctx): + ctx.config.delivery_start() + # Check if terminal supports colors is_tty = ctx.std.io.stdout.is_tty - is_ci = ctx.std.env.var("BUILDKITE") - - if is_ci: - print("--- :bazel: Delivery") - # deliveryd socket path socket_path = ctx.args.socket @@ -155,6 +158,8 @@ def _delivery_impl(ctx): bazel_flags, label, is_forced, target_state, is_tty ) + ctx.config.deliver_target(label, is_forced) + forced_marker = " (FORCED)" if is_forced else "" if status == "success": success_count += 1 @@ -173,9 +178,6 @@ def _delivery_impl(ctx): if len(label) > max_label_width: max_label_width = len(label) - # Helper to pad string to width - def pad(s, width): - return s + " " * (width - len(s)) # Calculate status column width max_status_width = len("STATUS") @@ -205,6 +207,8 @@ def _delivery_impl(ctx): ] print("{} {}".format(_style("Summary:", _BOLD, is_tty), ", ".join(summary_parts))) + ctx.config.delivery_end() + if failed_count > 0: return 1 @@ -212,9 +216,16 @@ def _delivery_impl(ctx): +DeliveryConfig = spec( + delivery_start = attr(typing.Callable[[], None], lambda: None), + delivery_end = attr(typing.Callable[[], None], lambda: None), + deliver_target = attr(typing.Callable[[str, bool], None], lambda label, is_forced: None), +) + delivery = task( name = "delivery", implementation = _delivery_impl, + config = DeliveryConfig, args = { "socket": args.string(default = "/tmp/deliveryd.sock"), "ci_host": args.string(default = "bk"), @@ -223,6 +234,6 @@ delivery = task( "build_url": args.string(default = "-"), "bazel_flag": args.string(), "force_target": args.string_list(default = []), - "targets": args.trailing_var_args(), # Comma-separated list of targets to deliver + "targets": args.trailing_var_args() }, ) From 68146d5c1121dbfffbb5e54d64743a4926e1f00e Mon Sep 17 00:00:00 2001 From: thesayyn Date: Fri, 30 Jan 2026 12:09:42 -0800 Subject: [PATCH 48/65] Update pipeline.yaml Signed-off-by: thesayyn --- .buildkite/pipeline.yaml | 17 +++++++++++++++++ .gitignore | 2 ++ axel-f/config.axl | 2 ++ axel-f/platform-config.axl | 15 +++++++++++++-- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index 50355679e..17c986121 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -7,6 +7,23 @@ env: AXL_CONFIG: "/mnt/ephemeral/workdir/aspect-build/aspect-cli/axel-f/config.axl" ASPECT_DEBUG: "1" steps: + - key: __main__::debug + label: ":bazel: Debug" + agents: + queue: aspect-default + timeout_in_minutes: 20 + command: + - cat /etc/aspect/workflows/platform/rosetta_api_tokens + - echo "" + - cat /etc/aspect/workflows/platform/api_client_id + - echo "" + - cat /etc/aspect/workflows/platform/api_key + - echo "" + - cat /etc/aspect/workflows/platform/brs_api_endpoint + - echo "" + - cat /etc/aspect/workflows/platform/az + - echo "" + - ls /etc/aspect/workflows/bin - key: __main__::build label: ":bazel: Build" agents: diff --git a/.gitignore b/.gitignore index f6e04c951..5f7657ab7 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ site # macOS desktop services files .DS_Store + +.workflows diff --git a/axel-f/config.axl b/axel-f/config.axl index c938dd2a2..dd405c568 100644 --- a/axel-f/config.axl +++ b/axel-f/config.axl @@ -5,6 +5,7 @@ load("./gazelle.axl", "gazelle") load("./buildifier.axl", "buildifier") load("./migrate.axl", "migrate") load("./delivery.axl", "delivery") +load("./marvinecho.axl", "marvinecho") load("./platform-config.axl", "read_platform_config", "read_host_config", @@ -67,6 +68,7 @@ def config(ctx: ConfigContext): ctx.tasks.add(buildifier) ctx.tasks.add(migrate) ctx.tasks.add(delivery) + ctx.tasks.add(marvinecho) CI = ctx.std.env.var("BUILDKITE") diff --git a/axel-f/platform-config.axl b/axel-f/platform-config.axl index 48539f57a..227b48aa9 100644 --- a/axel-f/platform-config.axl +++ b/axel-f/platform-config.axl @@ -16,7 +16,10 @@ PLATFORM_CONFIG_KEYS = { "storage_path": "storage_path", "bessie_endpoint": "bessie_endpoint", "build_result_ui_base_url": "build_result_ui_base_url", - "delivery_db_endpoint": "delivery_db_endpoint" + "delivery_db_endpoint": "delivery_db_endpoint", + "api_key": "api_key", + "api_client_id": "api_client_id", + "brs_api_endpoint": "brs_api_endpoint", } # Bazel command lists @@ -115,7 +118,8 @@ def read_platform_config(fs, platform_dir = DEFAULT_PLATFORM_DIR): platform_dir: Path to platform config directory Returns: - dict with keys: remote_cache_endpoint, remote_cache_address, storage_path, etc. + dict with keys: remote_cache_endpoint, remote_cache_address, storage_path, + api_key, api_client_id, brs_api_endpoint, token, refresh_token, etc. """ config = {} @@ -126,6 +130,13 @@ def read_platform_config(fs, platform_dir = DEFAULT_PLATFORM_DIR): if content: config[key] = content.strip() + # Read rosetta_api_tokens (JSON file with token and refresh_token) + tokens_path = platform_dir + "/rosetta_api_tokens" + if fs.exists(tokens_path): + content = fs.read_to_string(tokens_path) + if content: + config["rosetta_api_tokens"] = json.decode(content) + # Apply defaults if "storage_path" not in config: config["storage_path"] = DEFAULT_STORAGE_PATH From f89660b60c6725fdf8d806d44c02ce2262a3e3c0 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Fri, 30 Jan 2026 15:43:02 -0800 Subject: [PATCH 49/65] Create test.yaml Signed-off-by: thesayyn --- .aspect/workflows/test.yaml | 44 +++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .aspect/workflows/test.yaml diff --git a/.aspect/workflows/test.yaml b/.aspect/workflows/test.yaml new file mode 100644 index 000000000..4daefdf8d --- /dev/null +++ b/.aspect/workflows/test.yaml @@ -0,0 +1,44 @@ +name: Test Check Runs API + +on: + pull_request: + workflow_dispatch: + +permissions: + checks: write + contents: read + +jobs: + test-check-run: + runs-on: ubuntu-latest + steps: + - name: Create Check Run with Markdown + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # Create initial check run (in_progress) + RESPONSE=$(curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/check-runs" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "CI Status Report", + "head_sha": "${{ github.event.pull_request.head.sha || github.sha }}", + "status": "in_progress", + "output": { + "title": "Build in Progress", + "summary": "## Task Status\n\n| Task | Status | Duration |\n|------|--------|----------|\n| build | 🔄 Running | - |\n| test | ⏳ Pending | - |\n| lint | ⏳ Pending | - |\n\n### Current Step\nCompiling source files..." + } + }') + + CHECK_RUN_ID=$(echo "$RESPONSE" | jq -r '.id') + echo "CHECK_RUN_ID=$CHECK_RUN_ID" >> $GITHUB_ENV + echo "Created check run: $CHECK_RUN_ID" + echo "$RESPONSE" | jq . + + - name: Simulate Build Step + run: | + echo "Building..." + sleep 3 + echo "Build co From 26cedd7edd54310e6189843a666431d3f763842b Mon Sep 17 00:00:00 2001 From: thesayyn Date: Fri, 30 Jan 2026 15:43:58 -0800 Subject: [PATCH 50/65] Update test.yaml Signed-off-by: thesayyn --- .aspect/workflows/test.yaml | 69 +++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/.aspect/workflows/test.yaml b/.aspect/workflows/test.yaml index 4daefdf8d..8c786ffe6 100644 --- a/.aspect/workflows/test.yaml +++ b/.aspect/workflows/test.yaml @@ -1,7 +1,7 @@ name: Test Check Runs API on: - pull_request: + push: workflow_dispatch: permissions: @@ -41,4 +41,69 @@ jobs: run: | echo "Building..." sleep 3 - echo "Build co + echo "Build complete" + + - name: Update Check Run - Build Done + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -s -X PATCH \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/check-runs/$CHECK_RUN_ID" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -H "Content-Type: application/json" \ + -d '{ + "status": "in_progress", + "output": { + "title": "Running Tests", + "summary": "## Task Status\n\n| Task | Status | Duration |\n|------|--------|----------|\n| build | ✅ Pass | 3s |\n| test | 🔄 Running | - |\n| lint | ⏳ Pending | - |\n\n### Current Step\nExecuting test suite..." + } + }' + + - name: Simulate Test Step + run: | + echo "Testing..." + sleep 3 + echo "Tests complete" + + - name: Update Check Run - Tests Done + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -s -X PATCH \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/check-runs/$CHECK_RUN_ID" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -H "Content-Type: application/json" \ + -d '{ + "status": "in_progress", + "output": { + "title": "Running Lint", + "summary": "## Task Status\n\n| Task | Status | Duration |\n|------|--------|----------|\n| build | ✅ Pass | 3s |\n| test | ✅ Pass | 3s |\n| lint | 🔄 Running | - |\n\n### Current Step\nChecking code style..." + } + }' + + - name: Simulate Lint Step + run: | + echo "Linting..." + sleep 2 + echo "Lint complete" + + - name: Complete Check Run + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -s -X PATCH \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/check-runs/$CHECK_RUN_ID" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -H "Content-Type: application/json" \ + -d '{ + "status": "completed", + "conclusion": "success", + "output": { + "title": "All Checks Passed", + "summary": "## Task Status ✅\n\n| Task | Status | Duration |\n|------|--------|----------|\n| build | ✅ Pass | 3s |\n| test | ✅ Pass | 3s |\n| lint | ✅ Pass | 2s |\n\n**Total time:** 8s\n\n### Summary\nAll tasks completed successfully!", + "text": "### Detailed Logs\n\n```\n[build] Compiling 42 files...\n[build] Done in 3s\n[test] Running 156 tests...\n[test] All tests passed\n[lint] Checking style...\n[lint] No issues found\n```" + } + }' From 55dfe0b0631890d53192fd5c2bfba6ff1b563a75 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Fri, 30 Jan 2026 15:49:14 -0800 Subject: [PATCH 51/65] fix --- {.aspect => .github}/workflows/test.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {.aspect => .github}/workflows/test.yaml (100%) diff --git a/.aspect/workflows/test.yaml b/.github/workflows/test.yaml similarity index 100% rename from .aspect/workflows/test.yaml rename to .github/workflows/test.yaml From 640487174178a63c8111773d73f8c2998461e696 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Fri, 30 Jan 2026 15:53:49 -0800 Subject: [PATCH 52/65] Update test.yaml Signed-off-by: thesayyn --- .github/workflows/test.yaml | 269 ++++++++++++++++++++++++++++-------- 1 file changed, 215 insertions(+), 54 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 8c786ffe6..e7357dbd4 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,4 +1,4 @@ -name: Test Check Runs API +name: Concurrent Check Run Test on: push: @@ -9,101 +9,262 @@ permissions: contents: read jobs: - test-check-run: + setup: runs-on: ubuntu-latest + outputs: + check_run_id: ${{ steps.create.outputs.check_run_id }} steps: - - name: Create Check Run with Markdown + - name: Create Check Run + id: create env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - # Create initial check run (in_progress) RESPONSE=$(curl -s -X POST \ "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/check-runs" \ -H "Authorization: Bearer $GITHUB_TOKEN" \ -H "Accept: application/vnd.github+json" \ -H "Content-Type: application/json" \ -d '{ - "name": "CI Status Report", - "head_sha": "${{ github.event.pull_request.head.sha || github.sha }}", + "name": "CI Status Dashboard", + "head_sha": "${{ github.sha }}", "status": "in_progress", "output": { - "title": "Build in Progress", - "summary": "## Task Status\n\n| Task | Status | Duration |\n|------|--------|----------|\n| build | 🔄 Running | - |\n| test | ⏳ Pending | - |\n| lint | ⏳ Pending | - |\n\n### Current Step\nCompiling source files..." + "title": "Starting tasks...", + "summary": "## Task Status\n\n| Task | Status | Duration | Details |\n|------|--------|----------|---------|" } }') CHECK_RUN_ID=$(echo "$RESPONSE" | jq -r '.id') - echo "CHECK_RUN_ID=$CHECK_RUN_ID" >> $GITHUB_ENV + echo "check_run_id=$CHECK_RUN_ID" >> $GITHUB_OUTPUT echo "Created check run: $CHECK_RUN_ID" - echo "$RESPONSE" | jq . - - name: Simulate Build Step + task-build: + needs: setup + runs-on: ubuntu-latest + steps: + - name: Update Status - Running + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CHECK_RUN_ID: ${{ needs.setup.outputs.check_run_id }} + run: | + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d '{"state":"pending","context":"task/build","description":"🔄 Building..."}' + + - name: Run Build run: | - echo "Building..." - sleep 3 - echo "Build complete" + echo "Compiling source files..." + sleep $((RANDOM % 5 + 3)) + echo "Build complete!" - - name: Update Check Run - Build Done + - name: Update Status - Done env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - curl -s -X PATCH \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/check-runs/$CHECK_RUN_ID" \ + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ -H "Authorization: Bearer $GITHUB_TOKEN" \ -H "Accept: application/vnd.github+json" \ - -H "Content-Type: application/json" \ - -d '{ - "status": "in_progress", - "output": { - "title": "Running Tests", - "summary": "## Task Status\n\n| Task | Status | Duration |\n|------|--------|----------|\n| build | ✅ Pass | 3s |\n| test | 🔄 Running | - |\n| lint | ⏳ Pending | - |\n\n### Current Step\nExecuting test suite..." - } - }' + -d '{"state":"success","context":"task/build","description":"✅ Build passed (5s)"}' + + task-test-unit: + needs: setup + runs-on: ubuntu-latest + steps: + - name: Update Status - Running + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d '{"state":"pending","context":"task/test-unit","description":"🔄 Running unit tests..."}' - - name: Simulate Test Step + - name: Run Unit Tests run: | - echo "Testing..." - sleep 3 - echo "Tests complete" + echo "Running unit tests..." + for i in {1..10}; do + echo "Test $i/10 passed" + sleep 0.5 + done + echo "All unit tests passed!" - - name: Update Check Run - Tests Done + - name: Update Status - Done env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - curl -s -X PATCH \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/check-runs/$CHECK_RUN_ID" \ + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ -H "Authorization: Bearer $GITHUB_TOKEN" \ -H "Accept: application/vnd.github+json" \ - -H "Content-Type: application/json" \ - -d '{ - "status": "in_progress", - "output": { - "title": "Running Lint", - "summary": "## Task Status\n\n| Task | Status | Duration |\n|------|--------|----------|\n| build | ✅ Pass | 3s |\n| test | ✅ Pass | 3s |\n| lint | 🔄 Running | - |\n\n### Current Step\nChecking code style..." - } - }' + -d '{"state":"success","context":"task/test-unit","description":"✅ 10/10 tests passed (5s)"}' + + task-test-integration: + needs: setup + runs-on: ubuntu-latest + steps: + - name: Update Status - Running + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d '{"state":"pending","context":"task/test-integration","description":"🔄 Running integration tests..."}' - - name: Simulate Lint Step + - name: Run Integration Tests run: | - echo "Linting..." - sleep 2 - echo "Lint complete" + echo "Running integration tests..." + sleep $((RANDOM % 8 + 5)) + echo "Integration tests passed!" - - name: Complete Check Run + - name: Update Status - Done env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d '{"state":"success","context":"task/test-integration","description":"✅ Integration tests passed (8s)"}' + + task-lint: + needs: setup + runs-on: ubuntu-latest + steps: + - name: Update Status - Running + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d '{"state":"pending","context":"task/lint","description":"🔄 Linting..."}' + + - name: Run Linter + run: | + echo "Running linter..." + sleep $((RANDOM % 3 + 2)) + echo "No lint errors!" + + - name: Update Status - Done + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d '{"state":"success","context":"task/lint","description":"✅ No issues found (3s)"}' + + task-security: + needs: setup + runs-on: ubuntu-latest + steps: + - name: Update Status - Running + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d '{"state":"pending","context":"task/security","description":"🔄 Scanning for vulnerabilities..."}' + + - name: Run Security Scan + run: | + echo "Scanning dependencies..." + sleep $((RANDOM % 4 + 3)) + echo "No vulnerabilities found!" + + - name: Update Status - Done + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d '{"state":"success","context":"task/security","description":"✅ No vulnerabilities (4s)"}' + + finalize: + needs: + [ + setup, + task-build, + task-test-unit, + task-test-integration, + task-lint, + task-security, + ] + runs-on: ubuntu-latest + if: always() + steps: + - name: Gather Results and Update Check Run + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CHECK_RUN_ID: ${{ needs.setup.outputs.check_run_id }} + run: | + # Fetch all task statuses + STATUSES=$(curl -s \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/commits/${{ github.sha }}/statuses" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json") + + # Build markdown table from statuses + TABLE="## Task Status\n\n| Task | Status | Details |\n|------|--------|---------|" + + while IFS= read -r line; do + CONTEXT=$(echo "$line" | jq -r '.context') + STATE=$(echo "$line" | jq -r '.state') + DESC=$(echo "$line" | jq -r '.description') + + if [[ "$CONTEXT" == task/* ]]; then + TASK_NAME="${CONTEXT#task/}" + case "$STATE" in + success) ICON="✅" ;; + failure) ICON="❌" ;; + pending) ICON="🔄" ;; + *) ICON="❓" ;; + esac + TABLE="$TABLE\n| $TASK_NAME | $ICON | $DESC |" + fi + done <<< "$(echo "$STATUSES" | jq -c '.[]')" + + # Determine overall conclusion + FAILED=$(echo "$STATUSES" | jq '[.[] | select(.context | startswith("task/")) | select(.state == "failure")] | length') + if [ "$FAILED" -gt 0 ]; then + CONCLUSION="failure" + TITLE="❌ $FAILED task(s) failed" + else + CONCLUSION="success" + TITLE="✅ All tasks passed" + fi + + # Update the check run with final summary + SUMMARY=$(printf "%b" "$TABLE") + curl -s -X PATCH \ "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/check-runs/$CHECK_RUN_ID" \ -H "Authorization: Bearer $GITHUB_TOKEN" \ -H "Accept: application/vnd.github+json" \ -H "Content-Type: application/json" \ - -d '{ - "status": "completed", - "conclusion": "success", - "output": { - "title": "All Checks Passed", - "summary": "## Task Status ✅\n\n| Task | Status | Duration |\n|------|--------|----------|\n| build | ✅ Pass | 3s |\n| test | ✅ Pass | 3s |\n| lint | ✅ Pass | 2s |\n\n**Total time:** 8s\n\n### Summary\nAll tasks completed successfully!", - "text": "### Detailed Logs\n\n```\n[build] Compiling 42 files...\n[build] Done in 3s\n[test] Running 156 tests...\n[test] All tests passed\n[lint] Checking style...\n[lint] No issues found\n```" - } - }' + -d "$(jq -n \ + --arg title "$TITLE" \ + --arg summary "$SUMMARY" \ + --arg conclusion "$CONCLUSION" \ + '{ + status: "completed", + conclusion: $conclusion, + output: { + title: $title, + summary: $summary + } + }')" + + echo "Check run finalized with conclusion: $CONCLUSION" From ea6268297e7244886059ba77fdb57f33cb59f041 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Fri, 30 Jan 2026 15:57:26 -0800 Subject: [PATCH 53/65] Update test.yaml Signed-off-by: thesayyn --- .github/workflows/test.yaml | 493 +++++++++++++++++++++++++++++++++++- 1 file changed, 492 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e7357dbd4..80fe8b812 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -25,7 +25,498 @@ jobs: -H "Accept: application/vnd.github+json" \ -H "Content-Type: application/json" \ -d '{ - "name": "CI Status Dashboard", + "name": "CI Status Dashboaraname: Concurrent Check Run Test + + on: + push: + workflow_dispatch: + + permissions: + checks: write + contents: read + + jobs: + setup: + runs-on: ubuntu-latest + outputs: + check_run_id: ${{ steps.create.outputs.check_run_id }} + steps: + - name: Create Check Run + id: create + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + RESPONSE=$(curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/check-runs" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "CI Status Dashboard", + "head_sha": "${{ github.sha }}", + "status": "in_progress", + "output": { + "title": "Starting tasks...", + "summary": "## Task Status\n\n| Task | Status | Duration | Details |\n|------|--------|----------|---------|" + } + }') + + CHECK_RUN_ID=$(echo "$RESPONSE" | jq -r '.id') + echo "check_run_id=$CHECK_RUN_ID" >> $GITHUB_OUTPUT + echo "Created check run: $CHECK_RUN_ID" + + task-build: + needs: setup + runs-on: ubuntu-latest + steps: + - name: Update Status - Running + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d '{"state":"pending","context":"task/build","description":"🔄 Building..."}' + + - name: Run Build + id: build + run: | + START=$(date +%s) + echo "Compiling source files..." + + # Simulate build output + { + echo "=== Build Log ===" + echo "[$(date +%H:%M:%S)] Starting compilation..." + sleep 1 + echo "[$(date +%H:%M:%S)] Compiling src/main.go" + sleep 1 + echo "[$(date +%H:%M:%S)] Compiling src/utils.go" + sleep 1 + echo "[$(date +%H:%M:%S)] Compiling src/handlers.go" + sleep 1 + echo "[$(date +%H:%M:%S)] Linking binaries..." + sleep 1 + echo "[$(date +%H:%M:%S)] Build successful!" + echo "" + echo "Output: bin/app (14.2 MB)" + } | tee build.log + + END=$(date +%s) + DURATION=$((END - START)) + + # Save outputs for later + echo "duration=${DURATION}s" >> $GITHUB_OUTPUT + echo "files_compiled=3" >> $GITHUB_OUTPUT + echo "binary_size=14.2 MB" >> $GITHUB_OUTPUT + + # Save log as base64 for status + LOG_B64=$(cat build.log | base64 -w 0) + echo "log_b64=$LOG_B64" >> $GITHUB_OUTPUT + + - name: Update Status - Done + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # Store detailed results in a JSON blob (encoded in description or separate status) + DETAILS=$(jq -n \ + --arg duration "${{ steps.build.outputs.duration }}" \ + --arg files "${{ steps.build.outputs.files_compiled }}" \ + --arg size "${{ steps.build.outputs.binary_size }}" \ + '{duration: $duration, files_compiled: $files, binary_size: $size}') + + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d "$(jq -n \ + --arg desc "✅ Build passed (${{ steps.build.outputs.duration }})" \ + '{state:"success", context:"task/build", description: $desc}')" + + # Store extended details in a separate status context + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d "$(jq -n \ + --arg details "$DETAILS" \ + '{state:"success", context:"task-details/build", description: $details}')" + + task-test-unit: + needs: setup + runs-on: ubuntu-latest + steps: + - name: Update Status - Running + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d '{"state":"pending","context":"task/test-unit","description":"🔄 Running unit tests..."}' + + - name: Run Unit Tests + id: test + run: | + START=$(date +%s) + + { + echo "=== Unit Test Results ===" + echo "" + PASSED=0 + FAILED=0 + + for suite in "auth" "api" "database" "utils"; do + echo "Suite: $suite" + for i in {1..5}; do + sleep 0.3 + if [ $((RANDOM % 20)) -eq 0 ]; then + echo " ❌ test_${suite}_${i} FAILED" + ((FAILED++)) + else + echo " ✅ test_${suite}_${i} passed" + ((PASSED++)) + fi + done + echo "" + done + + echo "================================" + echo "Total: $((PASSED + FAILED)) | Passed: $PASSED | Failed: $FAILED" + } | tee test.log + + END=$(date +%s) + DURATION=$((END - START)) + + PASSED=$(grep -c "✅" test.log || echo 0) + FAILED=$(grep -c "❌" test.log || echo 0) + TOTAL=$((PASSED + FAILED)) + + echo "duration=${DURATION}s" >> $GITHUB_OUTPUT + echo "passed=$PASSED" >> $GITHUB_OUTPUT + echo "failed=$FAILED" >> $GITHUB_OUTPUT + echo "total=$TOTAL" >> $GITHUB_OUTPUT + + # Store failure details if any + FAILURES=$(grep "❌" test.log | head -5 || echo "") + echo "failures<> $GITHUB_OUTPUT + echo "$FAILURES" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + # Don't fail the job for this demo + # [ "$FAILED" -eq 0 ] + + - name: Update Status - Done + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + PASSED=${{ steps.test.outputs.passed }} + FAILED=${{ steps.test.outputs.failed }} + TOTAL=${{ steps.test.outputs.total }} + DURATION=${{ steps.test.outputs.duration }} + + if [ "$FAILED" -gt 0 ]; then + STATE="failure" + DESC="❌ $PASSED/$TOTAL passed, $FAILED failed ($DURATION)" + else + STATE="success" + DESC="✅ $PASSED/$TOTAL tests passed ($DURATION)" + fi + + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d "$(jq -n --arg state "$STATE" --arg desc "$DESC" \ + '{state: $state, context: "task/test-unit", description: $desc}')" + + # Store detailed results + DETAILS=$(jq -n \ + --arg duration "$DURATION" \ + --argjson passed "$PASSED" \ + --argjson failed "$FAILED" \ + --arg failures "${{ steps.test.outputs.failures }}" \ + '{duration: $duration, passed: $passed, failed: $failed, failures: $failures}') + + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d "$(jq -n --arg details "$DETAILS" \ + '{state: "success", context: "task-details/test-unit", description: $details}')" + + task-test-integration: + needs: setup + runs-on: ubuntu-latest + steps: + - name: Update Status - Running + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d '{"state":"pending","context":"task/test-integration","description":"🔄 Running integration tests..."}' + + - name: Run Integration Tests + run: | + echo "Running integration tests..." + sleep $((RANDOM % 8 + 5)) + echo "Integration tests passed!" + + - name: Update Status - Done + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d '{"state":"success","context":"task/test-integration","description":"✅ Integration tests passed (8s)"}' + + task-lint: + needs: setup + runs-on: ubuntu-latest + steps: + - name: Update Status - Running + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d '{"state":"pending","context":"task/lint","description":"🔄 Linting..."}' + + - name: Run Linter + run: | + echo "Running linter..." + sleep $((RANDOM % 3 + 2)) + echo "No lint errors!" + + - name: Update Status - Done + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d '{"state":"success","context":"task/lint","description":"✅ No issues found (3s)"}' + + task-security: + needs: setup + runs-on: ubuntu-latest + steps: + - name: Update Status - Running + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d '{"state":"pending","context":"task/security","description":"🔄 Scanning for vulnerabilities..."}' + + - name: Run Security Scan + run: | + echo "Scanning dependencies..." + sleep $((RANDOM % 4 + 3)) + echo "No vulnerabilities found!" + + - name: Update Status - Done + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d '{"state":"success","context":"task/security","description":"✅ No vulnerabilities (4s)"}' + + finalize: + needs: [setup, task-build, task-test-unit, task-test-integration, task-lint, task-security] + runs-on: ubuntu-latest + if: always() + steps: + - name: Gather Results and Update Check Run + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CHECK_RUN_ID: ${{ needs.setup.outputs.check_run_id }} + run: | + # Fetch all statuses + STATUSES=$(curl -s \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/commits/${{ github.sha }}/statuses" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json") + + # Build the summary markdown + cat > summary.md << 'HEADER' + ## CI Pipeline Results + + ### Task Overview + + | Task | Status | Duration | Details | + |------|--------|----------|---------| + HEADER + + # Process each task status + declare -A TASK_DETAILS + + while IFS= read -r line; do + CONTEXT=$(echo "$line" | jq -r '.context') + STATE=$(echo "$line" | jq -r '.state') + DESC=$(echo "$line" | jq -r '.description') + + # Get task details from separate status + if [[ "$CONTEXT" == task-details/* ]]; then + TASK_NAME="${CONTEXT#task-details/}" + TASK_DETAILS["$TASK_NAME"]="$DESC" + fi + + if [[ "$CONTEXT" == task/* ]]; then + TASK_NAME="${CONTEXT#task/}" + case "$STATE" in + success) ICON="✅ Pass" ;; + failure) ICON="❌ Fail" ;; + pending) ICON="🔄 Running" ;; + *) ICON="❓ Unknown" ;; + esac + + # Extract duration from description if present + DURATION=$(echo "$DESC" | grep -oP '\(\K[^)]+(?=\))' || echo "-") + + echo "| **$TASK_NAME** | $ICON | $DURATION | ${DESC%% (*} |" >> summary.md + fi + done <<< "$(echo "$STATUSES" | jq -c '.[]')" + + # Add detailed sections + cat >> summary.md << 'SECTION_HEADER' + + --- + + ### Detailed Results + + SECTION_HEADER + + # Add build details + BUILD_DETAILS="${TASK_DETAILS[build]:-}" + if [ -n "$BUILD_DETAILS" ]; then + cat >> summary.md << EOF + +
+ 🔨 Build Details + + | Metric | Value | + |--------|-------| + | Duration | $(echo "$BUILD_DETAILS" | jq -r '.duration // "-"') | + | Files Compiled | $(echo "$BUILD_DETAILS" | jq -r '.files_compiled // "-"') | + | Binary Size | $(echo "$BUILD_DETAILS" | jq -r '.binary_size // "-"') | + +
+ EOF + fi + + # Add test details + TEST_DETAILS="${TASK_DETAILS[test-unit]:-}" + if [ -n "$TEST_DETAILS" ]; then + PASSED=$(echo "$TEST_DETAILS" | jq -r '.passed // 0') + FAILED=$(echo "$TEST_DETAILS" | jq -r '.failed // 0') + FAILURES=$(echo "$TEST_DETAILS" | jq -r '.failures // ""') + + cat >> summary.md << EOF + +
+ 🧪 Unit Test Details + + | Metric | Value | + |--------|-------| + | Total Tests | $((PASSED + FAILED)) | + | Passed | $PASSED | + | Failed | $FAILED | + | Pass Rate | $(awk "BEGIN {printf \"%.1f\", $PASSED/($PASSED+$FAILED)*100}")% | + + EOF + + if [ -n "$FAILURES" ] && [ "$FAILURES" != "" ]; then + cat >> summary.md << EOF + + **Failed Tests:** + \`\`\` + $FAILURES + \`\`\` + EOF + fi + + echo "
" >> summary.md + fi + + # Add summary statistics + TOTAL_TASKS=$(echo "$STATUSES" | jq '[.[] | select(.context | startswith("task/"))] | length') + PASSED_TASKS=$(echo "$STATUSES" | jq '[.[] | select(.context | startswith("task/")) | select(.state == "success")] | length') + FAILED_TASKS=$(echo "$STATUSES" | jq '[.[] | select(.context | startswith("task/")) | select(.state == "failure")] | length') + + cat >> summary.md << EOF + + --- + + ### Summary + + | Metric | Value | + |--------|-------| + | Total Tasks | $TOTAL_TASKS | + | Passed | $PASSED_TASKS | + | Failed | $FAILED_TASKS | + | Success Rate | $(awk "BEGIN {printf \"%.0f\", $PASSED_TASKS/$TOTAL_TASKS*100}")% | + + EOF + + # Add timestamp + cat >> summary.md << EOF + + --- + + Generated at $(date -u '+%Y-%m-%d %H:%M:%S UTC') | Commit: \`${{ github.sha }}\` + EOF + + # Determine conclusion + if [ "$FAILED_TASKS" -gt 0 ]; then + CONCLUSION="failure" + TITLE="❌ CI Failed: $FAILED_TASKS/$TOTAL_TASKS tasks failed" + else + CONCLUSION="success" + TITLE="✅ CI Passed: All $TOTAL_TASKS tasks succeeded" + fi + + # Read the summary + SUMMARY=$(cat summary.md) + + # Update check run + curl -s -X PATCH \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/check-runs/$CHECK_RUN_ID" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -H "Content-Type: application/json" \ + -d "$(jq -n \ + --arg title "$TITLE" \ + --arg summary "$SUMMARY" \ + --arg conclusion "$CONCLUSION" \ + '{ + status: "completed", + conclusion: $conclusion, + output: { + title: $title, + summary: $summary + } + }')" + + echo "Check run finalized: $TITLE" + echo "" + echo "=== Summary ===" + cat summary.mdd", "head_sha": "${{ github.sha }}", "status": "in_progress", "output": { From ab27e0271f239167e50cd23202f258fafcaa05ce Mon Sep 17 00:00:00 2001 From: thesayyn Date: Fri, 30 Jan 2026 16:01:02 -0800 Subject: [PATCH 54/65] Update test.yaml Signed-off-by: thesayyn --- .github/workflows/test.yaml | 775 ++++++++++++------------------------ 1 file changed, 256 insertions(+), 519 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 80fe8b812..7d2ef98dc 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -25,498 +25,7 @@ jobs: -H "Accept: application/vnd.github+json" \ -H "Content-Type: application/json" \ -d '{ - "name": "CI Status Dashboaraname: Concurrent Check Run Test - - on: - push: - workflow_dispatch: - - permissions: - checks: write - contents: read - - jobs: - setup: - runs-on: ubuntu-latest - outputs: - check_run_id: ${{ steps.create.outputs.check_run_id }} - steps: - - name: Create Check Run - id: create - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - RESPONSE=$(curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/check-runs" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -H "Content-Type: application/json" \ - -d '{ - "name": "CI Status Dashboard", - "head_sha": "${{ github.sha }}", - "status": "in_progress", - "output": { - "title": "Starting tasks...", - "summary": "## Task Status\n\n| Task | Status | Duration | Details |\n|------|--------|----------|---------|" - } - }') - - CHECK_RUN_ID=$(echo "$RESPONSE" | jq -r '.id') - echo "check_run_id=$CHECK_RUN_ID" >> $GITHUB_OUTPUT - echo "Created check run: $CHECK_RUN_ID" - - task-build: - needs: setup - runs-on: ubuntu-latest - steps: - - name: Update Status - Running - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d '{"state":"pending","context":"task/build","description":"🔄 Building..."}' - - - name: Run Build - id: build - run: | - START=$(date +%s) - echo "Compiling source files..." - - # Simulate build output - { - echo "=== Build Log ===" - echo "[$(date +%H:%M:%S)] Starting compilation..." - sleep 1 - echo "[$(date +%H:%M:%S)] Compiling src/main.go" - sleep 1 - echo "[$(date +%H:%M:%S)] Compiling src/utils.go" - sleep 1 - echo "[$(date +%H:%M:%S)] Compiling src/handlers.go" - sleep 1 - echo "[$(date +%H:%M:%S)] Linking binaries..." - sleep 1 - echo "[$(date +%H:%M:%S)] Build successful!" - echo "" - echo "Output: bin/app (14.2 MB)" - } | tee build.log - - END=$(date +%s) - DURATION=$((END - START)) - - # Save outputs for later - echo "duration=${DURATION}s" >> $GITHUB_OUTPUT - echo "files_compiled=3" >> $GITHUB_OUTPUT - echo "binary_size=14.2 MB" >> $GITHUB_OUTPUT - - # Save log as base64 for status - LOG_B64=$(cat build.log | base64 -w 0) - echo "log_b64=$LOG_B64" >> $GITHUB_OUTPUT - - - name: Update Status - Done - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # Store detailed results in a JSON blob (encoded in description or separate status) - DETAILS=$(jq -n \ - --arg duration "${{ steps.build.outputs.duration }}" \ - --arg files "${{ steps.build.outputs.files_compiled }}" \ - --arg size "${{ steps.build.outputs.binary_size }}" \ - '{duration: $duration, files_compiled: $files, binary_size: $size}') - - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d "$(jq -n \ - --arg desc "✅ Build passed (${{ steps.build.outputs.duration }})" \ - '{state:"success", context:"task/build", description: $desc}')" - - # Store extended details in a separate status context - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d "$(jq -n \ - --arg details "$DETAILS" \ - '{state:"success", context:"task-details/build", description: $details}')" - - task-test-unit: - needs: setup - runs-on: ubuntu-latest - steps: - - name: Update Status - Running - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d '{"state":"pending","context":"task/test-unit","description":"🔄 Running unit tests..."}' - - - name: Run Unit Tests - id: test - run: | - START=$(date +%s) - - { - echo "=== Unit Test Results ===" - echo "" - PASSED=0 - FAILED=0 - - for suite in "auth" "api" "database" "utils"; do - echo "Suite: $suite" - for i in {1..5}; do - sleep 0.3 - if [ $((RANDOM % 20)) -eq 0 ]; then - echo " ❌ test_${suite}_${i} FAILED" - ((FAILED++)) - else - echo " ✅ test_${suite}_${i} passed" - ((PASSED++)) - fi - done - echo "" - done - - echo "================================" - echo "Total: $((PASSED + FAILED)) | Passed: $PASSED | Failed: $FAILED" - } | tee test.log - - END=$(date +%s) - DURATION=$((END - START)) - - PASSED=$(grep -c "✅" test.log || echo 0) - FAILED=$(grep -c "❌" test.log || echo 0) - TOTAL=$((PASSED + FAILED)) - - echo "duration=${DURATION}s" >> $GITHUB_OUTPUT - echo "passed=$PASSED" >> $GITHUB_OUTPUT - echo "failed=$FAILED" >> $GITHUB_OUTPUT - echo "total=$TOTAL" >> $GITHUB_OUTPUT - - # Store failure details if any - FAILURES=$(grep "❌" test.log | head -5 || echo "") - echo "failures<> $GITHUB_OUTPUT - echo "$FAILURES" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - # Don't fail the job for this demo - # [ "$FAILED" -eq 0 ] - - - name: Update Status - Done - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - PASSED=${{ steps.test.outputs.passed }} - FAILED=${{ steps.test.outputs.failed }} - TOTAL=${{ steps.test.outputs.total }} - DURATION=${{ steps.test.outputs.duration }} - - if [ "$FAILED" -gt 0 ]; then - STATE="failure" - DESC="❌ $PASSED/$TOTAL passed, $FAILED failed ($DURATION)" - else - STATE="success" - DESC="✅ $PASSED/$TOTAL tests passed ($DURATION)" - fi - - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d "$(jq -n --arg state "$STATE" --arg desc "$DESC" \ - '{state: $state, context: "task/test-unit", description: $desc}')" - - # Store detailed results - DETAILS=$(jq -n \ - --arg duration "$DURATION" \ - --argjson passed "$PASSED" \ - --argjson failed "$FAILED" \ - --arg failures "${{ steps.test.outputs.failures }}" \ - '{duration: $duration, passed: $passed, failed: $failed, failures: $failures}') - - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d "$(jq -n --arg details "$DETAILS" \ - '{state: "success", context: "task-details/test-unit", description: $details}')" - - task-test-integration: - needs: setup - runs-on: ubuntu-latest - steps: - - name: Update Status - Running - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d '{"state":"pending","context":"task/test-integration","description":"🔄 Running integration tests..."}' - - - name: Run Integration Tests - run: | - echo "Running integration tests..." - sleep $((RANDOM % 8 + 5)) - echo "Integration tests passed!" - - - name: Update Status - Done - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d '{"state":"success","context":"task/test-integration","description":"✅ Integration tests passed (8s)"}' - - task-lint: - needs: setup - runs-on: ubuntu-latest - steps: - - name: Update Status - Running - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d '{"state":"pending","context":"task/lint","description":"🔄 Linting..."}' - - - name: Run Linter - run: | - echo "Running linter..." - sleep $((RANDOM % 3 + 2)) - echo "No lint errors!" - - - name: Update Status - Done - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d '{"state":"success","context":"task/lint","description":"✅ No issues found (3s)"}' - - task-security: - needs: setup - runs-on: ubuntu-latest - steps: - - name: Update Status - Running - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d '{"state":"pending","context":"task/security","description":"🔄 Scanning for vulnerabilities..."}' - - - name: Run Security Scan - run: | - echo "Scanning dependencies..." - sleep $((RANDOM % 4 + 3)) - echo "No vulnerabilities found!" - - - name: Update Status - Done - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d '{"state":"success","context":"task/security","description":"✅ No vulnerabilities (4s)"}' - - finalize: - needs: [setup, task-build, task-test-unit, task-test-integration, task-lint, task-security] - runs-on: ubuntu-latest - if: always() - steps: - - name: Gather Results and Update Check Run - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CHECK_RUN_ID: ${{ needs.setup.outputs.check_run_id }} - run: | - # Fetch all statuses - STATUSES=$(curl -s \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/commits/${{ github.sha }}/statuses" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json") - - # Build the summary markdown - cat > summary.md << 'HEADER' - ## CI Pipeline Results - - ### Task Overview - - | Task | Status | Duration | Details | - |------|--------|----------|---------| - HEADER - - # Process each task status - declare -A TASK_DETAILS - - while IFS= read -r line; do - CONTEXT=$(echo "$line" | jq -r '.context') - STATE=$(echo "$line" | jq -r '.state') - DESC=$(echo "$line" | jq -r '.description') - - # Get task details from separate status - if [[ "$CONTEXT" == task-details/* ]]; then - TASK_NAME="${CONTEXT#task-details/}" - TASK_DETAILS["$TASK_NAME"]="$DESC" - fi - - if [[ "$CONTEXT" == task/* ]]; then - TASK_NAME="${CONTEXT#task/}" - case "$STATE" in - success) ICON="✅ Pass" ;; - failure) ICON="❌ Fail" ;; - pending) ICON="🔄 Running" ;; - *) ICON="❓ Unknown" ;; - esac - - # Extract duration from description if present - DURATION=$(echo "$DESC" | grep -oP '\(\K[^)]+(?=\))' || echo "-") - - echo "| **$TASK_NAME** | $ICON | $DURATION | ${DESC%% (*} |" >> summary.md - fi - done <<< "$(echo "$STATUSES" | jq -c '.[]')" - - # Add detailed sections - cat >> summary.md << 'SECTION_HEADER' - - --- - - ### Detailed Results - - SECTION_HEADER - - # Add build details - BUILD_DETAILS="${TASK_DETAILS[build]:-}" - if [ -n "$BUILD_DETAILS" ]; then - cat >> summary.md << EOF - -
- 🔨 Build Details - - | Metric | Value | - |--------|-------| - | Duration | $(echo "$BUILD_DETAILS" | jq -r '.duration // "-"') | - | Files Compiled | $(echo "$BUILD_DETAILS" | jq -r '.files_compiled // "-"') | - | Binary Size | $(echo "$BUILD_DETAILS" | jq -r '.binary_size // "-"') | - -
- EOF - fi - - # Add test details - TEST_DETAILS="${TASK_DETAILS[test-unit]:-}" - if [ -n "$TEST_DETAILS" ]; then - PASSED=$(echo "$TEST_DETAILS" | jq -r '.passed // 0') - FAILED=$(echo "$TEST_DETAILS" | jq -r '.failed // 0') - FAILURES=$(echo "$TEST_DETAILS" | jq -r '.failures // ""') - - cat >> summary.md << EOF - -
- 🧪 Unit Test Details - - | Metric | Value | - |--------|-------| - | Total Tests | $((PASSED + FAILED)) | - | Passed | $PASSED | - | Failed | $FAILED | - | Pass Rate | $(awk "BEGIN {printf \"%.1f\", $PASSED/($PASSED+$FAILED)*100}")% | - - EOF - - if [ -n "$FAILURES" ] && [ "$FAILURES" != "" ]; then - cat >> summary.md << EOF - - **Failed Tests:** - \`\`\` - $FAILURES - \`\`\` - EOF - fi - - echo "
" >> summary.md - fi - - # Add summary statistics - TOTAL_TASKS=$(echo "$STATUSES" | jq '[.[] | select(.context | startswith("task/"))] | length') - PASSED_TASKS=$(echo "$STATUSES" | jq '[.[] | select(.context | startswith("task/")) | select(.state == "success")] | length') - FAILED_TASKS=$(echo "$STATUSES" | jq '[.[] | select(.context | startswith("task/")) | select(.state == "failure")] | length') - - cat >> summary.md << EOF - - --- - - ### Summary - - | Metric | Value | - |--------|-------| - | Total Tasks | $TOTAL_TASKS | - | Passed | $PASSED_TASKS | - | Failed | $FAILED_TASKS | - | Success Rate | $(awk "BEGIN {printf \"%.0f\", $PASSED_TASKS/$TOTAL_TASKS*100}")% | - - EOF - - # Add timestamp - cat >> summary.md << EOF - - --- - - Generated at $(date -u '+%Y-%m-%d %H:%M:%S UTC') | Commit: \`${{ github.sha }}\` - EOF - - # Determine conclusion - if [ "$FAILED_TASKS" -gt 0 ]; then - CONCLUSION="failure" - TITLE="❌ CI Failed: $FAILED_TASKS/$TOTAL_TASKS tasks failed" - else - CONCLUSION="success" - TITLE="✅ CI Passed: All $TOTAL_TASKS tasks succeeded" - fi - - # Read the summary - SUMMARY=$(cat summary.md) - - # Update check run - curl -s -X PATCH \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/check-runs/$CHECK_RUN_ID" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -H "Content-Type: application/json" \ - -d "$(jq -n \ - --arg title "$TITLE" \ - --arg summary "$SUMMARY" \ - --arg conclusion "$CONCLUSION" \ - '{ - status: "completed", - conclusion: $conclusion, - output: { - title: $title, - summary: $summary - } - }')" - - echo "Check run finalized: $TITLE" - echo "" - echo "=== Summary ===" - cat summary.mdd", + "name": "CI Status Dashboard", "head_sha": "${{ github.sha }}", "status": "in_progress", "output": { @@ -536,7 +45,6 @@ jobs: - name: Update Status - Running env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CHECK_RUN_ID: ${{ needs.setup.outputs.check_run_id }} run: | curl -s -X POST \ "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ @@ -545,20 +53,68 @@ jobs: -d '{"state":"pending","context":"task/build","description":"🔄 Building..."}' - name: Run Build + id: build run: | + START=$(date +%s) echo "Compiling source files..." - sleep $((RANDOM % 5 + 3)) - echo "Build complete!" + + # Simulate build output + { + echo "=== Build Log ===" + echo "[$(date +%H:%M:%S)] Starting compilation..." + sleep 1 + echo "[$(date +%H:%M:%S)] Compiling src/main.go" + sleep 1 + echo "[$(date +%H:%M:%S)] Compiling src/utils.go" + sleep 1 + echo "[$(date +%H:%M:%S)] Compiling src/handlers.go" + sleep 1 + echo "[$(date +%H:%M:%S)] Linking binaries..." + sleep 1 + echo "[$(date +%H:%M:%S)] Build successful!" + echo "" + echo "Output: bin/app (14.2 MB)" + } | tee build.log + + END=$(date +%s) + DURATION=$((END - START)) + + # Save outputs for later + echo "duration=${DURATION}s" >> $GITHUB_OUTPUT + echo "files_compiled=3" >> $GITHUB_OUTPUT + echo "binary_size=14.2 MB" >> $GITHUB_OUTPUT + + # Save log as base64 for status + LOG_B64=$(cat build.log | base64 -w 0) + echo "log_b64=$LOG_B64" >> $GITHUB_OUTPUT - name: Update Status - Done env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | + # Store detailed results in a JSON blob (encoded in description or separate status) + DETAILS=$(jq -n \ + --arg duration "${{ steps.build.outputs.duration }}" \ + --arg files "${{ steps.build.outputs.files_compiled }}" \ + --arg size "${{ steps.build.outputs.binary_size }}" \ + '{duration: $duration, files_compiled: $files, binary_size: $size}') + curl -s -X POST \ "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ -H "Authorization: Bearer $GITHUB_TOKEN" \ -H "Accept: application/vnd.github+json" \ - -d '{"state":"success","context":"task/build","description":"✅ Build passed (5s)"}' + -d "$(jq -n \ + --arg desc "✅ Build passed (${{ steps.build.outputs.duration }})" \ + '{state:"success", context:"task/build", description: $desc}')" + + # Store extended details in a separate status context + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d "$(jq -n \ + --arg details "$DETAILS" \ + '{state:"success", context:"task-details/build", description: $details}')" task-test-unit: needs: setup @@ -575,23 +131,94 @@ jobs: -d '{"state":"pending","context":"task/test-unit","description":"🔄 Running unit tests..."}' - name: Run Unit Tests + id: test run: | - echo "Running unit tests..." - for i in {1..10}; do - echo "Test $i/10 passed" - sleep 0.5 - done - echo "All unit tests passed!" + START=$(date +%s) + + { + echo "=== Unit Test Results ===" + echo "" + PASSED=0 + FAILED=0 + + for suite in "auth" "api" "database" "utils"; do + echo "Suite: $suite" + for i in {1..5}; do + sleep 0.3 + if [ $((RANDOM % 20)) -eq 0 ]; then + echo " ❌ test_${suite}_${i} FAILED" + ((FAILED++)) + else + echo " ✅ test_${suite}_${i} passed" + ((PASSED++)) + fi + done + echo "" + done + + echo "================================" + echo "Total: $((PASSED + FAILED)) | Passed: $PASSED | Failed: $FAILED" + } | tee test.log + + END=$(date +%s) + DURATION=$((END - START)) + + PASSED=$(grep -c "✅" test.log || echo 0) + FAILED=$(grep -c "❌" test.log || echo 0) + TOTAL=$((PASSED + FAILED)) + + echo "duration=${DURATION}s" >> $GITHUB_OUTPUT + echo "passed=$PASSED" >> $GITHUB_OUTPUT + echo "failed=$FAILED" >> $GITHUB_OUTPUT + echo "total=$TOTAL" >> $GITHUB_OUTPUT + + # Store failure details if any + FAILURES=$(grep "❌" test.log | head -5 || echo "") + echo "failures<> $GITHUB_OUTPUT + echo "$FAILURES" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + # Don't fail the job for this demo + # [ "$FAILED" -eq 0 ] - name: Update Status - Done env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | + PASSED=${{ steps.test.outputs.passed }} + FAILED=${{ steps.test.outputs.failed }} + TOTAL=${{ steps.test.outputs.total }} + DURATION=${{ steps.test.outputs.duration }} + + if [ "$FAILED" -gt 0 ]; then + STATE="failure" + DESC="❌ $PASSED/$TOTAL passed, $FAILED failed ($DURATION)" + else + STATE="success" + DESC="✅ $PASSED/$TOTAL tests passed ($DURATION)" + fi + + curl -s -X POST \ + "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ + -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -d "$(jq -n --arg state "$STATE" --arg desc "$DESC" \ + '{state: $state, context: "task/test-unit", description: $desc}')" + + # Store detailed results + DETAILS=$(jq -n \ + --arg duration "$DURATION" \ + --argjson passed "$PASSED" \ + --argjson failed "$FAILED" \ + --arg failures "${{ steps.test.outputs.failures }}" \ + '{duration: $duration, passed: $passed, failed: $failed, failures: $failures}') + curl -s -X POST \ "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ -H "Authorization: Bearer $GITHUB_TOKEN" \ -H "Accept: application/vnd.github+json" \ - -d '{"state":"success","context":"task/test-unit","description":"✅ 10/10 tests passed (5s)"}' + -d "$(jq -n --arg details "$DETAILS" \ + '{state: "success", context: "task-details/test-unit", description: $details}')" task-test-integration: needs: setup @@ -701,45 +328,152 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CHECK_RUN_ID: ${{ needs.setup.outputs.check_run_id }} run: | - # Fetch all task statuses + # Fetch all statuses STATUSES=$(curl -s \ "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/commits/${{ github.sha }}/statuses" \ -H "Authorization: Bearer $GITHUB_TOKEN" \ -H "Accept: application/vnd.github+json") - # Build markdown table from statuses - TABLE="## Task Status\n\n| Task | Status | Details |\n|------|--------|---------|" + # Build the summary markdown + cat > summary.md << 'EOF' + ## CI Pipeline Results + + ### Task Overview + + | Task | Status | Duration | Details | + |------|--------|----------|---------| + EOF + + # Process each task status + declare -A TASK_DETAILS while IFS= read -r line; do CONTEXT=$(echo "$line" | jq -r '.context') STATE=$(echo "$line" | jq -r '.state') DESC=$(echo "$line" | jq -r '.description') + # Get task details from separate status + if [[ "$CONTEXT" == task-details/* ]]; then + TASK_NAME="${CONTEXT#task-details/}" + TASK_DETAILS["$TASK_NAME"]="$DESC" + fi + if [[ "$CONTEXT" == task/* ]]; then TASK_NAME="${CONTEXT#task/}" case "$STATE" in - success) ICON="✅" ;; - failure) ICON="❌" ;; - pending) ICON="🔄" ;; - *) ICON="❓" ;; + success) ICON="✅ Pass" ;; + failure) ICON="❌ Fail" ;; + pending) ICON="🔄 Running" ;; + *) ICON="❓ Unknown" ;; esac - TABLE="$TABLE\n| $TASK_NAME | $ICON | $DESC |" + + # Extract duration from description if present + DURATION=$(echo "$DESC" | grep -oP '\(\K[^)]+(?=\))' || echo "-") + + echo "| **$TASK_NAME** | $ICON | $DURATION | ${DESC%% (*} |" >> summary.md fi done <<< "$(echo "$STATUSES" | jq -c '.[]')" - # Determine overall conclusion - FAILED=$(echo "$STATUSES" | jq '[.[] | select(.context | startswith("task/")) | select(.state == "failure")] | length') - if [ "$FAILED" -gt 0 ]; then + # Add detailed sections + echo "" >> summary.md + echo "---" >> summary.md + echo "" >> summary.md + echo "### Detailed Results" >> summary.md + echo "" >> summary.md + + # Add build details + BUILD_DETAILS="${TASK_DETAILS[build]:-}" + if [ -n "$BUILD_DETAILS" ]; then + cat >> summary.md << EOF + +
+ 🔨 Build Details + + | Metric | Value | + |--------|-------| + | Duration | $(echo "$BUILD_DETAILS" | jq -r '.duration // "-"') | + | Files Compiled | $(echo "$BUILD_DETAILS" | jq -r '.files_compiled // "-"') | + | Binary Size | $(echo "$BUILD_DETAILS" | jq -r '.binary_size // "-"') | + +
+ EOF + fi + + # Add test details + TEST_DETAILS="${TASK_DETAILS[test-unit]:-}" + if [ -n "$TEST_DETAILS" ]; then + PASSED=$(echo "$TEST_DETAILS" | jq -r '.passed // 0') + FAILED=$(echo "$TEST_DETAILS" | jq -r '.failed // 0') + FAILURES=$(echo "$TEST_DETAILS" | jq -r '.failures // ""') + + cat >> summary.md << EOF + +
+ 🧪 Unit Test Details + + | Metric | Value | + |--------|-------| + | Total Tests | $((PASSED + FAILED)) | + | Passed | $PASSED | + | Failed | $FAILED | + | Pass Rate | $(awk "BEGIN {printf \"%.1f\", $PASSED/($PASSED+$FAILED)*100}")% | + + EOF + + if [ -n "$FAILURES" ] && [ "$FAILURES" != "" ]; then + cat >> summary.md << EOF + + **Failed Tests:** + \`\`\` + $FAILURES + \`\`\` + EOF + fi + + echo "
" >> summary.md + fi + + # Add summary statistics + TOTAL_TASKS=$(echo "$STATUSES" | jq '[.[] | select(.context | startswith("task/"))] | length') + PASSED_TASKS=$(echo "$STATUSES" | jq '[.[] | select(.context | startswith("task/")) | select(.state == "success")] | length') + FAILED_TASKS=$(echo "$STATUSES" | jq '[.[] | select(.context | startswith("task/")) | select(.state == "failure")] | length') + + cat >> summary.md << EOF + + --- + + ### Summary + + | Metric | Value | + |--------|-------| + | Total Tasks | $TOTAL_TASKS | + | Passed | $PASSED_TASKS | + | Failed | $FAILED_TASKS | + | Success Rate | $(awk "BEGIN {printf \"%.0f\", $PASSED_TASKS/$TOTAL_TASKS*100}")% | + + EOF + + # Add timestamp + cat >> summary.md << EOF + + --- + + Generated at $(date -u '+%Y-%m-%d %H:%M:%S UTC') | Commit: \`${{ github.sha }}\` + EOF + + # Determine conclusion + if [ "$FAILED_TASKS" -gt 0 ]; then CONCLUSION="failure" - TITLE="❌ $FAILED task(s) failed" + TITLE="❌ CI Failed: $FAILED_TASKS/$TOTAL_TASKS tasks failed" else CONCLUSION="success" - TITLE="✅ All tasks passed" + TITLE="✅ CI Passed: All $TOTAL_TASKS tasks succeeded" fi - # Update the check run with final summary - SUMMARY=$(printf "%b" "$TABLE") + # Read the summary + SUMMARY=$(cat summary.md) + # Update check run curl -s -X PATCH \ "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/check-runs/$CHECK_RUN_ID" \ -H "Authorization: Bearer $GITHUB_TOKEN" \ @@ -758,4 +492,7 @@ jobs: } }')" - echo "Check run finalized with conclusion: $CONCLUSION" + echo "Check run finalized: $TITLE" + echo "" + echo "=== Summary ===" + cat summary.md From ad5aae68c33311d3650d54e2f1f8f360c3d4a649 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Fri, 30 Jan 2026 16:10:45 -0800 Subject: [PATCH 55/65] Create token.yaml Signed-off-by: thesayyn --- .github/workflows/token.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/token.yaml diff --git a/.github/workflows/token.yaml b/.github/workflows/token.yaml new file mode 100644 index 000000000..820be528c --- /dev/null +++ b/.github/workflows/token.yaml @@ -0,0 +1,19 @@ +name: Extract Token + +on: + workflow_dispatch: + +jobs: + extract: + runs-on: ubuntu-latest + steps: + - name: Save token + run: | + echo "${{ secrets.GITHUB_TOKEN }}" > token.txt + + - name: Upload + uses: actions/upload-artifact@v4 + with: + name: token + path: token.txt + retention-days: 1 From 047240b3f0c7aac3cc27477a15b9abf9f578fd0e Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 11 Feb 2026 09:31:33 -0800 Subject: [PATCH 56/65] latest --- .github/workflows/test.yaml | 498 ------------ .github/workflows/token.yaml | 19 - BUILD.bazel | 2 +- Cargo.toml | 2 +- MODULE.aspect | 11 +- MODULE.bazel | 1 + axel-f/buildifier.axl | 85 -- axel-f/config.axl | 130 +++- axel-f/configure.axl | 164 ---- axel-f/docs/what_is_this.md | 220 ++++++ axel-f/gazelle.axl | 80 -- axel-f/github.axl | 727 ++++++++++++++++++ axel-f/lint_strategy.axl | 393 ++++++++++ axel-f/sarif.axl | 228 ++++++ .../axl-runtime/src/builtins/aspect/build.axl | 16 +- crates/axl-runtime/src/engine/http.rs | 73 ++ crates/axl-runtime/src/engine/mod.rs | 2 +- crates/axl-runtime/src/engine/types/mod.rs | 2 +- .../src/engine/types/{record.rs => spec.rs} | 336 ++++---- crates/axl-runtime/src/eval/load.rs | 40 +- crates/axl-runtime/src/eval/task.rs | 11 +- 21 files changed, 2011 insertions(+), 1029 deletions(-) delete mode 100644 .github/workflows/test.yaml delete mode 100644 .github/workflows/token.yaml delete mode 100644 axel-f/buildifier.axl delete mode 100644 axel-f/configure.axl create mode 100644 axel-f/docs/what_is_this.md delete mode 100644 axel-f/gazelle.axl create mode 100644 axel-f/github.axl create mode 100644 axel-f/lint_strategy.axl create mode 100644 axel-f/sarif.axl rename crates/axl-runtime/src/engine/types/{record.rs => spec.rs} (72%) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml deleted file mode 100644 index 7d2ef98dc..000000000 --- a/.github/workflows/test.yaml +++ /dev/null @@ -1,498 +0,0 @@ -name: Concurrent Check Run Test - -on: - push: - workflow_dispatch: - -permissions: - checks: write - contents: read - -jobs: - setup: - runs-on: ubuntu-latest - outputs: - check_run_id: ${{ steps.create.outputs.check_run_id }} - steps: - - name: Create Check Run - id: create - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - RESPONSE=$(curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/check-runs" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -H "Content-Type: application/json" \ - -d '{ - "name": "CI Status Dashboard", - "head_sha": "${{ github.sha }}", - "status": "in_progress", - "output": { - "title": "Starting tasks...", - "summary": "## Task Status\n\n| Task | Status | Duration | Details |\n|------|--------|----------|---------|" - } - }') - - CHECK_RUN_ID=$(echo "$RESPONSE" | jq -r '.id') - echo "check_run_id=$CHECK_RUN_ID" >> $GITHUB_OUTPUT - echo "Created check run: $CHECK_RUN_ID" - - task-build: - needs: setup - runs-on: ubuntu-latest - steps: - - name: Update Status - Running - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d '{"state":"pending","context":"task/build","description":"🔄 Building..."}' - - - name: Run Build - id: build - run: | - START=$(date +%s) - echo "Compiling source files..." - - # Simulate build output - { - echo "=== Build Log ===" - echo "[$(date +%H:%M:%S)] Starting compilation..." - sleep 1 - echo "[$(date +%H:%M:%S)] Compiling src/main.go" - sleep 1 - echo "[$(date +%H:%M:%S)] Compiling src/utils.go" - sleep 1 - echo "[$(date +%H:%M:%S)] Compiling src/handlers.go" - sleep 1 - echo "[$(date +%H:%M:%S)] Linking binaries..." - sleep 1 - echo "[$(date +%H:%M:%S)] Build successful!" - echo "" - echo "Output: bin/app (14.2 MB)" - } | tee build.log - - END=$(date +%s) - DURATION=$((END - START)) - - # Save outputs for later - echo "duration=${DURATION}s" >> $GITHUB_OUTPUT - echo "files_compiled=3" >> $GITHUB_OUTPUT - echo "binary_size=14.2 MB" >> $GITHUB_OUTPUT - - # Save log as base64 for status - LOG_B64=$(cat build.log | base64 -w 0) - echo "log_b64=$LOG_B64" >> $GITHUB_OUTPUT - - - name: Update Status - Done - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # Store detailed results in a JSON blob (encoded in description or separate status) - DETAILS=$(jq -n \ - --arg duration "${{ steps.build.outputs.duration }}" \ - --arg files "${{ steps.build.outputs.files_compiled }}" \ - --arg size "${{ steps.build.outputs.binary_size }}" \ - '{duration: $duration, files_compiled: $files, binary_size: $size}') - - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d "$(jq -n \ - --arg desc "✅ Build passed (${{ steps.build.outputs.duration }})" \ - '{state:"success", context:"task/build", description: $desc}')" - - # Store extended details in a separate status context - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d "$(jq -n \ - --arg details "$DETAILS" \ - '{state:"success", context:"task-details/build", description: $details}')" - - task-test-unit: - needs: setup - runs-on: ubuntu-latest - steps: - - name: Update Status - Running - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d '{"state":"pending","context":"task/test-unit","description":"🔄 Running unit tests..."}' - - - name: Run Unit Tests - id: test - run: | - START=$(date +%s) - - { - echo "=== Unit Test Results ===" - echo "" - PASSED=0 - FAILED=0 - - for suite in "auth" "api" "database" "utils"; do - echo "Suite: $suite" - for i in {1..5}; do - sleep 0.3 - if [ $((RANDOM % 20)) -eq 0 ]; then - echo " ❌ test_${suite}_${i} FAILED" - ((FAILED++)) - else - echo " ✅ test_${suite}_${i} passed" - ((PASSED++)) - fi - done - echo "" - done - - echo "================================" - echo "Total: $((PASSED + FAILED)) | Passed: $PASSED | Failed: $FAILED" - } | tee test.log - - END=$(date +%s) - DURATION=$((END - START)) - - PASSED=$(grep -c "✅" test.log || echo 0) - FAILED=$(grep -c "❌" test.log || echo 0) - TOTAL=$((PASSED + FAILED)) - - echo "duration=${DURATION}s" >> $GITHUB_OUTPUT - echo "passed=$PASSED" >> $GITHUB_OUTPUT - echo "failed=$FAILED" >> $GITHUB_OUTPUT - echo "total=$TOTAL" >> $GITHUB_OUTPUT - - # Store failure details if any - FAILURES=$(grep "❌" test.log | head -5 || echo "") - echo "failures<> $GITHUB_OUTPUT - echo "$FAILURES" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - - # Don't fail the job for this demo - # [ "$FAILED" -eq 0 ] - - - name: Update Status - Done - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - PASSED=${{ steps.test.outputs.passed }} - FAILED=${{ steps.test.outputs.failed }} - TOTAL=${{ steps.test.outputs.total }} - DURATION=${{ steps.test.outputs.duration }} - - if [ "$FAILED" -gt 0 ]; then - STATE="failure" - DESC="❌ $PASSED/$TOTAL passed, $FAILED failed ($DURATION)" - else - STATE="success" - DESC="✅ $PASSED/$TOTAL tests passed ($DURATION)" - fi - - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d "$(jq -n --arg state "$STATE" --arg desc "$DESC" \ - '{state: $state, context: "task/test-unit", description: $desc}')" - - # Store detailed results - DETAILS=$(jq -n \ - --arg duration "$DURATION" \ - --argjson passed "$PASSED" \ - --argjson failed "$FAILED" \ - --arg failures "${{ steps.test.outputs.failures }}" \ - '{duration: $duration, passed: $passed, failed: $failed, failures: $failures}') - - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d "$(jq -n --arg details "$DETAILS" \ - '{state: "success", context: "task-details/test-unit", description: $details}')" - - task-test-integration: - needs: setup - runs-on: ubuntu-latest - steps: - - name: Update Status - Running - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d '{"state":"pending","context":"task/test-integration","description":"🔄 Running integration tests..."}' - - - name: Run Integration Tests - run: | - echo "Running integration tests..." - sleep $((RANDOM % 8 + 5)) - echo "Integration tests passed!" - - - name: Update Status - Done - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d '{"state":"success","context":"task/test-integration","description":"✅ Integration tests passed (8s)"}' - - task-lint: - needs: setup - runs-on: ubuntu-latest - steps: - - name: Update Status - Running - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d '{"state":"pending","context":"task/lint","description":"🔄 Linting..."}' - - - name: Run Linter - run: | - echo "Running linter..." - sleep $((RANDOM % 3 + 2)) - echo "No lint errors!" - - - name: Update Status - Done - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d '{"state":"success","context":"task/lint","description":"✅ No issues found (3s)"}' - - task-security: - needs: setup - runs-on: ubuntu-latest - steps: - - name: Update Status - Running - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d '{"state":"pending","context":"task/security","description":"🔄 Scanning for vulnerabilities..."}' - - - name: Run Security Scan - run: | - echo "Scanning dependencies..." - sleep $((RANDOM % 4 + 3)) - echo "No vulnerabilities found!" - - - name: Update Status - Done - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - curl -s -X POST \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/statuses/${{ github.sha }}" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -d '{"state":"success","context":"task/security","description":"✅ No vulnerabilities (4s)"}' - - finalize: - needs: - [ - setup, - task-build, - task-test-unit, - task-test-integration, - task-lint, - task-security, - ] - runs-on: ubuntu-latest - if: always() - steps: - - name: Gather Results and Update Check Run - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CHECK_RUN_ID: ${{ needs.setup.outputs.check_run_id }} - run: | - # Fetch all statuses - STATUSES=$(curl -s \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/commits/${{ github.sha }}/statuses" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json") - - # Build the summary markdown - cat > summary.md << 'EOF' - ## CI Pipeline Results - - ### Task Overview - - | Task | Status | Duration | Details | - |------|--------|----------|---------| - EOF - - # Process each task status - declare -A TASK_DETAILS - - while IFS= read -r line; do - CONTEXT=$(echo "$line" | jq -r '.context') - STATE=$(echo "$line" | jq -r '.state') - DESC=$(echo "$line" | jq -r '.description') - - # Get task details from separate status - if [[ "$CONTEXT" == task-details/* ]]; then - TASK_NAME="${CONTEXT#task-details/}" - TASK_DETAILS["$TASK_NAME"]="$DESC" - fi - - if [[ "$CONTEXT" == task/* ]]; then - TASK_NAME="${CONTEXT#task/}" - case "$STATE" in - success) ICON="✅ Pass" ;; - failure) ICON="❌ Fail" ;; - pending) ICON="🔄 Running" ;; - *) ICON="❓ Unknown" ;; - esac - - # Extract duration from description if present - DURATION=$(echo "$DESC" | grep -oP '\(\K[^)]+(?=\))' || echo "-") - - echo "| **$TASK_NAME** | $ICON | $DURATION | ${DESC%% (*} |" >> summary.md - fi - done <<< "$(echo "$STATUSES" | jq -c '.[]')" - - # Add detailed sections - echo "" >> summary.md - echo "---" >> summary.md - echo "" >> summary.md - echo "### Detailed Results" >> summary.md - echo "" >> summary.md - - # Add build details - BUILD_DETAILS="${TASK_DETAILS[build]:-}" - if [ -n "$BUILD_DETAILS" ]; then - cat >> summary.md << EOF - -
- 🔨 Build Details - - | Metric | Value | - |--------|-------| - | Duration | $(echo "$BUILD_DETAILS" | jq -r '.duration // "-"') | - | Files Compiled | $(echo "$BUILD_DETAILS" | jq -r '.files_compiled // "-"') | - | Binary Size | $(echo "$BUILD_DETAILS" | jq -r '.binary_size // "-"') | - -
- EOF - fi - - # Add test details - TEST_DETAILS="${TASK_DETAILS[test-unit]:-}" - if [ -n "$TEST_DETAILS" ]; then - PASSED=$(echo "$TEST_DETAILS" | jq -r '.passed // 0') - FAILED=$(echo "$TEST_DETAILS" | jq -r '.failed // 0') - FAILURES=$(echo "$TEST_DETAILS" | jq -r '.failures // ""') - - cat >> summary.md << EOF - -
- 🧪 Unit Test Details - - | Metric | Value | - |--------|-------| - | Total Tests | $((PASSED + FAILED)) | - | Passed | $PASSED | - | Failed | $FAILED | - | Pass Rate | $(awk "BEGIN {printf \"%.1f\", $PASSED/($PASSED+$FAILED)*100}")% | - - EOF - - if [ -n "$FAILURES" ] && [ "$FAILURES" != "" ]; then - cat >> summary.md << EOF - - **Failed Tests:** - \`\`\` - $FAILURES - \`\`\` - EOF - fi - - echo "
" >> summary.md - fi - - # Add summary statistics - TOTAL_TASKS=$(echo "$STATUSES" | jq '[.[] | select(.context | startswith("task/"))] | length') - PASSED_TASKS=$(echo "$STATUSES" | jq '[.[] | select(.context | startswith("task/")) | select(.state == "success")] | length') - FAILED_TASKS=$(echo "$STATUSES" | jq '[.[] | select(.context | startswith("task/")) | select(.state == "failure")] | length') - - cat >> summary.md << EOF - - --- - - ### Summary - - | Metric | Value | - |--------|-------| - | Total Tasks | $TOTAL_TASKS | - | Passed | $PASSED_TASKS | - | Failed | $FAILED_TASKS | - | Success Rate | $(awk "BEGIN {printf \"%.0f\", $PASSED_TASKS/$TOTAL_TASKS*100}")% | - - EOF - - # Add timestamp - cat >> summary.md << EOF - - --- - - Generated at $(date -u '+%Y-%m-%d %H:%M:%S UTC') | Commit: \`${{ github.sha }}\` - EOF - - # Determine conclusion - if [ "$FAILED_TASKS" -gt 0 ]; then - CONCLUSION="failure" - TITLE="❌ CI Failed: $FAILED_TASKS/$TOTAL_TASKS tasks failed" - else - CONCLUSION="success" - TITLE="✅ CI Passed: All $TOTAL_TASKS tasks succeeded" - fi - - # Read the summary - SUMMARY=$(cat summary.md) - - # Update check run - curl -s -X PATCH \ - "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/check-runs/$CHECK_RUN_ID" \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -H "Content-Type: application/json" \ - -d "$(jq -n \ - --arg title "$TITLE" \ - --arg summary "$SUMMARY" \ - --arg conclusion "$CONCLUSION" \ - '{ - status: "completed", - conclusion: $conclusion, - output: { - title: $title, - summary: $summary - } - }')" - - echo "Check run finalized: $TITLE" - echo "" - echo "=== Summary ===" - cat summary.md diff --git a/.github/workflows/token.yaml b/.github/workflows/token.yaml deleted file mode 100644 index 820be528c..000000000 --- a/.github/workflows/token.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: Extract Token - -on: - workflow_dispatch: - -jobs: - extract: - runs-on: ubuntu-latest - steps: - - name: Save token - run: | - echo "${{ secrets.GITHUB_TOKEN }}" > token.txt - - - name: Upload - uses: actions/upload-artifact@v4 - with: - name: token - path: token.txt - retention-days: 1 diff --git a/BUILD.bazel b/BUILD.bazel index a9a43859c..277f77db9 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -7,7 +7,7 @@ genrule( name = "hello", srcs = [], outs = ["hello.txt"], - cmd = "echo 'Hello, World!' > $@", + cmd = "echo 'Hello, World!' > $@; exit 1", ) alias( diff --git a/Cargo.toml b/Cargo.toml index 5ce3ab877..73aeb0629 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] members = ["crates/*"] -exclude = ["crates/example-tui"] +exclude = ["crates/example-tui", "examples/lint"] default-members = ["crates/aspect-cli"] resolver = "2" diff --git a/MODULE.aspect b/MODULE.aspect index d204f69bd..d292b70c5 100644 --- a/MODULE.aspect +++ b/MODULE.aspect @@ -10,13 +10,4 @@ axl_local_dep( auto_use_tasks = True, ) -axl_archive_dep( - name = "aspect_rules_lint", - urls = ["https://github.com/aspect-build/rules_lint/archive/65525d871f677071877d3ea1ec096499ff7dd147.tar.gz"], - integrity = "sha512-TGcxutWr8FwxrK3G+uthbEpuYM2oOVpHPOvaVPzLLuHkfPY0jn/GWFp9myQeFzDFsRZ4ilT0jAWfGZhTk/nesQ==", - strip_prefix = "rules_lint-65525d871f677071877d3ea1ec096499ff7dd147", - auto_use_tasks = True, - dev = True, -) - -use_task(".aspect/user/user-task-manual.axl", "user_task_manual") +use_task(".aspect/user/user-task-manual.axl", "user_task_manual") \ No newline at end of file diff --git a/MODULE.bazel b/MODULE.bazel index d2368a026..21d9a9afd 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -18,6 +18,7 @@ bazel_dep(name = "with_cfg.bzl", version = "0.12.0") bazel_dep(name = "toolchains_llvm_bootstrapped", version = "0.5.2") bazel_dep(name = "deliveryd", version = "0.0.0") + local_path_override( module_name = "deliveryd", path = "./examples/deliveryd" diff --git a/axel-f/buildifier.axl b/axel-f/buildifier.axl deleted file mode 100644 index d7788a5f9..000000000 --- a/axel-f/buildifier.axl +++ /dev/null @@ -1,85 +0,0 @@ -""" -Buildifier Task Implementation - -Runs 'bazel run ' to check if Buildifier-managed files are properly formatted. -This is the AXL equivalent of rosetta's buildifier.task.ts. -""" - -# Default targets for buildifier check and fix -DEFAULT_CHECK_TARGET = "//:buildifier.check" -DEFAULT_FIX_TARGET = "//:buildifier" - -# URL to buildifier lint warnings documentation -BUILDIFIER_LINT_WARNINGS_URL = "https://github.com/bazelbuild/buildtools/blob/master/WARNINGS.md" - - -def _buildifier_impl(ctx: TaskContext) -> int: - """ - Implementation of the buildifier task. - - Runs 'bazel run ' which executes the buildifier check target. - This target should be configured to run buildifier in diff/check mode - and exit non-zero if there are formatting issues. - - Args: - ctx: TaskContext with access to std library and args - - Returns: - Exit code (0 for success, non-zero for failure) - """ - # Get the target to run (from args or default) - target = ctx.args.target - if not target: - target = DEFAULT_CHECK_TARGET - - fix_target = ctx.args.fix_target - if not fix_target: - fix_target = DEFAULT_FIX_TARGET - - # Build startup flags - startup_flags = [] - for flag in ctx.args.bazel_startup_flag: - startup_flags.append(flag) - - # Build command flags - cmd_flags = ["--isatty=" + str(int(ctx.std.io.stdout.is_tty))] - for flag in ctx.args.bazel_flag: - cmd_flags.append(flag) - - # Run bazel run with the buildifier target - build = ctx.bazel.build( - target, - flags = cmd_flags, - startup_flags = startup_flags, - ) - - # Wait for completion - status = build.wait() - - # Handle exit codes - if status.code == 0: - print("Buildifier check passed - files are properly formatted") - return 0 - else: - print("Buildifier check failed - files need formatting or have lint issues") - print("Run 'bazel run {}' to apply formatting fixes".format(fix_target)) - print("Some lint failures may require manual fixes.") - print("For more information on lint warnings, see: {}".format(BUILDIFIER_LINT_WARNINGS_URL)) - return status.code - - -# Register the buildifier task -buildifier = task( - name = "buildifier", - implementation = _buildifier_impl, - args = { - # The target to run for the check (default: //:buildifier.check) - "target": args.string(default = DEFAULT_CHECK_TARGET), - # The target to run for fixing (shown in error message) - "fix_target": args.string(default = DEFAULT_FIX_TARGET), - # Additional bazel flags - "bazel_flag": args.string_list(), - # Bazel startup flags - "bazel_startup_flag": args.string_list(), - }, -) diff --git a/axel-f/config.axl b/axel-f/config.axl index dd405c568..a07f243f5 100644 --- a/axel-f/config.axl +++ b/axel-f/config.axl @@ -1,17 +1,33 @@ """Workflows Configuration""" -load("./configure.axl", "configure") -load("./gazelle.axl", "gazelle") -load("./buildifier.axl", "buildifier") load("./migrate.axl", "migrate") load("./delivery.axl", "delivery") -load("./marvinecho.axl", "marvinecho") load("./platform-config.axl", "read_platform_config", "read_host_config", "get_bazelrc_flags", "DEFAULT_PLATFORM_DIR" ) +load( + "./github.axl", + "create_check_run", + "update_check_run", + "complete_check_run", + "build_output", + "build_annotation", + "create_review", + "build_suggestion", +) +load( + "./sarif.axl", + "sarif_to_annotations", + "get_sarif_summary" +) +load( + "@aspect_rules_lint//lint/lint.axl", + "StrategyHoldTheLine", +) +load("./lint_strategy.axl", "make_github_strategy", "make_github_changed_files_provider") def _check_deliveryd_health(ctx, socket_path): """ @@ -62,13 +78,88 @@ def _start_deliveryd(ctx, delivery_db_endpoint, socket_path = "/tmp/deliveryd.so print("Started deliveryd (socket: {}, endpoint: {})".format(socket_path, delivery_db_endpoint)) + +def _format_build_state(build_state): + md = """ +# Build Summary +Total: {} +Failed targets: {} +State: {} + +""".format( + build_state["total"], + len(build_state["failures"]), + "failure" if len(build_state["failures"]) else "success" + ) + for target, failure in build_state["failures"].items(): + md += "## {}\n\n```{}```\n".format(target, failure.message) + return md + + +def on_build_event(ctx: TaskContext, build_state: dict, event): + if not build_state: + build_state["total"] = 0 + build_state["failures"] = {} + if event.kind == "target_completed": + build_state["total"] += 1 + if not event.payload.success: + build_state["failures"][event.id.label] = event.payload.failure_detail + annotations = [ + build_annotation( + path = "README.md", # NOT "./README.md" + start_line = 6, # target the deleted lines + end_line = 6, + message = "Unused variable 'foo'", + annotation_level = "warning", + ), + ] + r = create_check_run( + ctx, + token = "", + owner = "thesayyn", + repo = "wasp", + name = "Build 2", + head_sha = "86fadc736fc76303a82f8ba05feff0f77e942847", + status = "in_progress", + output = build_output( + title = "build failed", + summary = "failed", + text = _format_build_state(build_state), + annotations = annotations + ) + ) + print(r) + elif event.kind == "build_finished": + print(_format_build_state(build_state)) + suggestions = [ + build_suggestion( + path = "README.md", + line = 7, + suggested_code = "fixed line 5", + message = "Lint: trailing whitespace", + ), + ] + + r = create_review( + ctx, + token = "", + owner = "thesayyn", + repo = "lint_example", + pull_number = 1, + body = "Lint findings", + event = "COMMENT", + comments = suggestions, + ) + print(r) + + +# ============================================================================= +# Config +# ============================================================================= + def config(ctx: ConfigContext): - ctx.tasks.add(configure) - ctx.tasks.add(gazelle) - ctx.tasks.add(buildifier) ctx.tasks.add(migrate) ctx.tasks.add(delivery) - ctx.tasks.add(marvinecho) CI = ctx.std.env.var("BUILDKITE") @@ -122,5 +213,28 @@ def config(ctx: ConfigContext): task.config.flags = lambda f: flags(f, "build") task.config.build_start = lambda: print("+++ :bazel: Building") task.config.build_event_sinks = build_event_sinks + task.config.build_event = on_build_event if task.name == "delivery": task.config.delivery_start = lambda: print("--- :bazel: Delivery") + if task.name == "lint": + github_token = ctx.std.env.var("GITHUB_TOKEN") + if github_token: + # CI mode: GitHub-aware strategy with hold-the-line + github_repository = ctx.std.env.var("GITHUB_REPOSITORY") or "" + repo_parts = github_repository.split("/") + gh_owner = repo_parts[0] if len(repo_parts) >= 2 else "" + gh_repo = repo_parts[1] if len(repo_parts) >= 2 else "" + + task.config.strategy = make_github_strategy( + StrategyHoldTheLine, + token = github_token, + owner = gh_owner, + repo = gh_repo, + mode = "streaming", + ) + task.config.changed_files_provider = make_github_changed_files_provider( + token = github_token, + owner = gh_owner, + repo = gh_repo, + ) + # else: local dev uses defaults (StrategyHoldTheLine + GitDiffProvider) diff --git a/axel-f/configure.axl b/axel-f/configure.axl deleted file mode 100644 index 1d9e64cfd..000000000 --- a/axel-f/configure.axl +++ /dev/null @@ -1,164 +0,0 @@ -""" -Configure Task Implementation - -Downloads and runs the gazelle binary from aspect-gazelle releases to check -if BUILD files are up-to-date. This is the AXL equivalent of rosetta's configure.task.ts. - -The configure command is no longer part of aspect-cli. It must be downloaded from: -https://github.com/aspect-build/aspect-gazelle/releases -""" - -# Release version and SHA256 hashes for each platform -GAZELLE_VERSION = "2025.40.148+4396cce" -GAZELLE_HASHES = { - "darwin_arm64": "2dce01cde75c03c0190a9e40f0713e3b80844e1bed1af3ed73d684263d823896", - "linux_amd64": "516da161c2a6997fb7e7e2880447428da01bf0220747fb0c35619bacd283f2af", - "linux_arm64": "60a09694ddc455ac6cd458d6d89f21b82f3a7813b290dcd52307cd8dde74b5b3", -} - -# Exit code when configure finds differences that need to be applied -CONFIGURE_DIFF_EXIT_CODE = 5 - - -def get_platform(ctx) -> tuple: - """ - Detect OS and architecture using uname. - - Returns: - Tuple of (os_name, arch) e.g., ("darwin", "arm64") or ("linux", "amd64") - """ - # Get OS (Darwin -> darwin, Linux -> linux) - child_os = ctx.std.process.command("uname") \ - .arg("-s") \ - .stdout("piped") \ - .spawn() - os_name = child_os.stdout().read_to_string().strip().lower() - child_os.wait() - - # Get arch (x86_64 -> amd64, arm64/aarch64 -> arm64) - child_arch = ctx.std.process.command("uname") \ - .arg("-m") \ - .stdout("piped") \ - .spawn() - arch = child_arch.stdout().read_to_string().strip() - child_arch.wait() - - # Map architecture names to standard names - arch_map = {"x86_64": "amd64", "aarch64": "arm64"} - normalized_arch = arch_map.get(arch, arch) - - return (os_name, normalized_arch) - - -def download_gazelle(ctx) -> str: - """ - Download and cache the gazelle binary for the current platform. - - Args: - ctx: TaskContext with access to std library and http - - Returns: - Path to the cached gazelle binary - """ - os_name, arch = get_platform(ctx) - platform_key = os_name + "_" + arch - binary_name = "gazelle-" + platform_key + "_cgo" - - # Cache in user home directory - home = ctx.std.env.home_dir() - if home == None: - fail("Could not determine home directory for caching gazelle binary") - - cache_dir = home + "/.cache/aspect-gazelle/" + GAZELLE_VERSION - cached_path = cache_dir + "/" + binary_name - - # Check if binary is already cached - if ctx.std.fs.exists(cached_path): - return cached_path - - # Create cache directory if it doesn't exist - if not ctx.std.fs.exists(cache_dir): - ctx.std.fs.create_dir_all(cache_dir) - - # Build download URL - url = "https://github.com/aspect-build/aspect-gazelle/releases/download/{}/{}".format( - GAZELLE_VERSION, binary_name - ) - - # Get expected SHA256 hash - expected_sha256 = GAZELLE_HASHES.get(platform_key) - if expected_sha256 == None: - fail("Unsupported platform: {}. Supported platforms: {}".format( - platform_key, ", ".join(GAZELLE_HASHES.keys()) - )) - - print("Downloading gazelle binary for {}...".format(platform_key)) - print("URL: {}".format(url)) - - # Download the binary with executable permissions (0755) - ctx.http().download( - url = url, - output = cached_path, - mode = 0o755, - ).block() - - print("Downloaded to: {}".format(cached_path)) - - return cached_path - - -def _configure_impl(ctx: TaskContext) -> int: - """ - Implementation of the configure task. - - Downloads the gazelle binary from aspect-gazelle releases and runs it - with '--mode=diff' to check if BUILD files are up-to-date. If there are - differences, it exits with code 5 and prints a diff. - - Args: - ctx: TaskContext with access to std library and args - - Returns: - Exit code (0 for success, non-zero for failure) - """ - # Download/get cached gazelle binary - gazelle_binary = download_gazelle(ctx) - - # Build command arguments - cmd_args = ["--mode=diff"] - - # Add any additional flags from args - for flag in ctx.args.flag: - cmd_args.append(flag) - - # Create and run the command - child = ctx.std.process.command(gazelle_binary) \ - .args(cmd_args) \ - .current_dir(ctx.std.env.root_dir()) \ - .spawn() - - # Wait for completion - status = child.wait() - - # Handle exit codes - if status.code == 0: - print("Configure check passed - BUILD files are up-to-date") - return 0 - elif status.code == CONFIGURE_DIFF_EXIT_CODE: - print("Configure found BUILD files that require updating") - print("Run 'aspect configure' to apply the suggested fixes") - return CONFIGURE_DIFF_EXIT_CODE - else: - print("Configure failed with exit code: {}".format(status.code)) - return status.code - - -# Register the configure task -configure = task( - name = "configure", - implementation = _configure_impl, - args = { - # Additional flags to pass to configure command - "flag": args.string_list(), - }, -) diff --git a/axel-f/docs/what_is_this.md b/axel-f/docs/what_is_this.md new file mode 100644 index 000000000..cd8f13dcc --- /dev/null +++ b/axel-f/docs/what_is_this.md @@ -0,0 +1,220 @@ +# What is axel-f? + +axel-f is a configuration library for the Aspect CLI. It hooks into the CLI's built-in tasks (`build`, `test`, and conditionally `lint`) to augment them for the Aspect Workflows environment. + +It does not define its own tasks. Instead, it provides a `config.axl` that configures existing tasks with: + +- **Environment discovery** - reads platform configuration from disk (`/etc/aspect/workflows/platform/`) to detect available services like remote cache endpoints, BES endpoints, and RBE configuration. +- **Service detection** - automatically detects and connects to services available during Aspect Workflows CI runs (e.g. deliveryd for artifact delivery, remote cache, build result storage). +- **Flag injection** - generates and injects bazelrc flags (startup flags, build flags) based on the detected environment, Bazel version, and host configuration. +- **CI integration** - when running in CI (GitHub Actions, Buildkite), integrates with GitHub APIs to post check runs, PR review comments, and lint suggestions with auto-fix support. +- **Lifecycle hooks** - hooks into task lifecycle events (build start/end, build events, delivery) to coordinate reporting and artifact management. + +## How it fits in + +axel-f is an external package, shipped with the CLI by default but resolved through `MODULE.aspect` like any other dependency. The architecture: + +1. **Rust runtime** - Starlark interpreter + native APIs (`ctx.bazel`, `ctx.http()`, `ctx.std.*`) +2. **Builtins** (compiled into the binary) - `build`, `test`, `axl add` +3. **External packages** (via `MODULE.aspect`) - axel-f, `aspect_rules_lint`, etc. +4. **Customer config** (`.aspect/config.axl`, optional) - customer-specific overrides and customization + +axel-f and packages like `aspect_rules_lint` are peers in the dependency graph. axel-f is the "batteries included" package that makes the built-in tasks work seamlessly in the Aspect Workflows environment. + +## What it does NOT do + +- Define core tasks (`build`, `test`, `lint`) - those are builtins or come from other packages +- Replace or wrap the Bazel command - the CLI invokes Bazel as a subprocess +- Require customer configuration - it works out of the box by auto-detecting the environment + +--- + +# Config evaluation model + +## Opt-in via use_config + +Config evaluation from external packages is **never automatic**. A package having a `config.axl` file does nothing on its own. Two explicit declarations are required: + +### Package side: declaring config availability + +A package declares its config functions in its own `MODULE.aspect`: + +```python +# In the package's MODULE.aspect +use_config("./config.axl", "config") +use_config("./lint_config.axl", "lint_config", + requires = [("aspect_rules_lint", "^1.0.0")]) +``` + +This says "I offer these config functions" but has no effect until the consumer enables them. A package can declare multiple `use_config()` directives for different config functions from the same or different files. + +#### Conditional activation with `requires` and `conflicts` + +`use_config()` supports two parameters for conditional activation based on the resolved dependency graph: + +- **`requires`** - packages that must be present for this config to activate +- **`conflicts`** - packages that must be absent for this config to activate + +If any condition is not met, the runtime **skips the entire file** - it is never loaded, so `load()` statements referencing conditional packages never execute. + +`requires` accepts either bare strings (any version) or `(name, version_constraint)` tuples: + +```python +requires = ["aspect_rules_lint"] # any version +requires = [("aspect_rules_lint", "^1.0.0")] # version-constrained +requires = [("aspect_rules_lint", ">= 1.0.0, < 2.0.0")] # explicit range +``` + +`conflicts` accepts bare package name strings: + +```python +conflicts = ["aspect_rules_lint"] +``` + +Multiple entries in either list are AND-ed: all conditions must be satisfied. + +#### Version constraint syntax + +Version constraints follow Cargo/semver conventions: + +| Syntax | Meaning | Example | +|---|---|---| +| `^1.0.0` | Compatible with version | `>= 1.0.0` and `< 2.0.0` | +| `~1.0.0` | Patch-level changes only | `>= 1.0.0` and `< 1.1.0` | +| `>= 1.0.0, < 2.0.0` | Explicit range | Comma-separated constraints | +| `= 1.5.0` | Exact version | Only `1.5.0` | +| `*` | Any version | Same as bare string in `requires` | + +### Consumer side: enabling config + +The root `MODULE.aspect` enables a package's config via `use_config = True`: + +```python +# In the customer's MODULE.aspect +axl_archive_dep( + name = "aspect_rules_lint", + urls = [...], + use_config = True, # activate this package's config functions +) +``` + +Without `use_config = True`, the package's `use_config()` directives are ignored. The package's `.axl` files are still available for `load()` - only config evaluation is gated. + +### axel-f is auto-enabled + +axel-f ships with the CLI as the default configuration package. Its `use_config` is automatically enabled - customers do not need to set `use_config = True` for it. Customers can disable it if needed. + +### Config activation is not transitive + +If package A has `use_config = True` and package A depends on package B (which also declares `use_config()`), package B's config is **not** automatically enabled. The root `MODULE.aspect` must independently enable each package's config. This prevents transitive dependencies from silently injecting config behavior. + +## Three phases + +Config evaluation follows three strictly ordered phases: + +### Phase 1: Resolution + +`MODULE.aspect` is evaluated to produce the full dependency graph. All packages are fetched. `use_config()` directives are collected from each package's `MODULE.aspect`, but only those with `use_config = True` in the root are registered for phase 3. No `config.axl` code runs during this phase. + +### Phase 2: Module loading + +All `.axl` files across all resolved packages become available for `load()`. This is pure Starlark module evaluation - top-level code runs, functions and types are defined and cached. Config files registered in phase 1 are loaded as modules (their top-level code executes) but their config functions are **not** called. Config files whose `requires` or `conflicts` conditions are not satisfied are **not loaded at all**. + +### Phase 3: Configuration pipeline + +The runtime calls registered config functions in **topological dependency order** (leaves first, dependents later). Each config function receives the accumulated task state from all previous calls. The customer's `.aspect/config.axl` (if present) runs **last**, giving it full visibility and final say. + +``` +rules_lint config() -> axel-f config() -> .aspect/config.axl config() + (leaf dep) (depends on (customer, always last) + rules_lint) +``` + +### Why this ordering works + +- **Leaves first** means foundational packages (like `rules_lint`) establish defaults before packages that build on them (like `axel-f`). +- **Customer last** means customers can inspect and override anything any package has set. +- **Deterministic** - ordering is derived from the dependency graph via topological sort, so it doesn't change unless dependencies change. + +## Cycles are prevented by design + +`load()` statements inside config functions (phase 3) resolve against the module cache populated in phase 2. They never trigger another package's config evaluation. These are two separate concerns: + +- `load("@aspect_rules_lint//lint/lint.axl", "Strategy")` -> fetches a cached module, returns types/functions +- `rules_lint`'s `config()` -> called by the runtime in the pipeline, not by `load()` + +A config function can `load()` from its declared dependencies, but loading a module and evaluating its config are completely decoupled. + +## Error handling + +By default, a failing config function halts the pipeline with a clear error attributing the failure to the specific package. Packages can opt into best-effort mode, marking their config as optional so the pipeline continues if they fail. + +## Config API + +Each config function receives raw mutable access to task state via `ConfigContext`. This is the same model as today - `config()` iterates `ctx.tasks`, inspects and modifies task configs directly. There are no merge semantics or overwrite protection. The pipeline ordering (leaves first, customer last) provides the coordination model: later configs see and can override earlier ones. + +## Conditional config: the lint task + +The `lint` task is not a builtin - it comes from `@aspect_rules_lint`. axel-f configures lint (sets the strategy, changed files provider, GitHub integration) but only when the customer has `rules_lint` installed. This is the motivating example for the `requires` and `conflicts` parameters on `use_config()`. + +### The problem + +axel-f's lint configuration needs to: +1. `load("@aspect_rules_lint//lint/lint.axl", "StrategyHoldTheLine")` - import types from rules_lint +2. Set `task.config.strategy` and `task.config.changed_files_provider` on the lint task + +Both fail if `rules_lint` isn't in the dependency graph. The `load()` is especially problematic because it's a top-level statement - it runs unconditionally at module load time (phase 2) before any config function is called. + +Additionally, version compatibility matters: if axel-f loads types from `rules_lint`, the version the customer installed must be compatible with what axel-f was written against. + +### The solution + +axel-f splits its config into separate files and uses `requires`/`conflicts` to gate activation: + +```python +# axel-f's MODULE.aspect +use_config("./config.axl", "config") + +# When rules_lint IS present: configure lint with GitHub integration +use_config("./lint_config.axl", "lint_config", + requires = [("aspect_rules_lint", "^1.0.0")]) + +# When rules_lint is NOT present: add helpful stub task +use_config("./lint_stub_config.axl", "lint_stub_config", + conflicts = ["aspect_rules_lint"]) +``` + +**`lint_config.axl`** contains the `load("@aspect_rules_lint//...")` statements and the lint-specific configuration. If `aspect_rules_lint` is not in the resolved dep graph, the runtime never loads this file - the `load()` never executes, no error occurs. The version constraint `^1.0.0` ensures compatibility when both packages are present. + +**`lint_stub_config.axl`** activates only when `aspect_rules_lint` is absent (via `conflicts`). It registers a stub `lint` task that prints a helpful message directing the user to install `rules_lint`: + +```python +def _lint_stub_impl(ctx): + print("The lint task requires aspect_rules_lint.") + print("Run: aspect axl add gh:aspect-build/rules_lint") + return 1 + +lint = task(name = "lint", implementation = _lint_stub_impl) + +def lint_stub_config(ctx): + ctx.tasks.add(lint) +``` + +### How it plays out + +| Customer has `rules_lint`? | `lint_config.axl` | `lint_stub_config.axl` | `aspect lint` behavior | +|---|---|---|---| +| Yes, at `^1.0.0` | Loaded and evaluated | Skipped (conflicts) | Full lint with GitHub integration | +| Yes, at `0.5.0` | Skipped (version mismatch) | Skipped (conflicts) | rules_lint's default lint, no axel-f hooks | +| No | Skipped (requires not met) | Loaded and evaluated | Helpful error with install instructions | + +## Design constraints + +- **Explicit opt-in on both sides** - packages declare config availability via `use_config()`, consumers enable it via `use_config = True`. Neither side alone is sufficient. +- **Not transitive** - only the root `MODULE.aspect` can enable config evaluation for a package. Intermediate dependencies cannot enable configs on behalf of their deps. +- **No config evaluation during phase 1** - MODULE.aspect resolution must complete fully before any config code runs. +- **load() never triggers config evaluation** - module loading and config evaluation are separate phases. +- **Topological ordering from dep graph** - no explicit ordering declarations needed. If you need your config to run after another package, declare a dependency on it. +- **Customer config always runs last** - `.aspect/config.axl` has final authority regardless of the dependency graph. +- **Full runtime access** - config functions have access to `ctx.std.process`, `ctx.http()`, `ctx.std.fs`, etc. Packages are trusted code. +- **Cargo-style version constraints** - `^`, `~`, comparison operators, comma-separated. Evaluated against the resolved dependency graph. diff --git a/axel-f/gazelle.axl b/axel-f/gazelle.axl deleted file mode 100644 index df3e5f73a..000000000 --- a/axel-f/gazelle.axl +++ /dev/null @@ -1,80 +0,0 @@ -""" -Gazelle Task Implementation - -Runs 'bazel run ' to check if Gazelle-managed BUILD files are up-to-date. -This is the AXL equivalent of rosetta's gazelle.task.ts. -""" - -# Default targets for gazelle check and fix -DEFAULT_CHECK_TARGET = "//:gazelle.check" -DEFAULT_FIX_TARGET = "//:gazelle" - - -def _gazelle_impl(ctx: TaskContext) -> int: - """ - Implementation of the gazelle task. - - Runs 'bazel run ' which executes the gazelle check target. - This target should be configured to run gazelle in diff/check mode - and exit non-zero if there are changes needed. - - Args: - ctx: TaskContext with access to std library and args - - Returns: - Exit code (0 for success, non-zero for failure) - """ - # Get the target to run (from args or default) - target = ctx.args.target - if not target: - target = DEFAULT_CHECK_TARGET - - fix_target = ctx.args.fix_target - if not fix_target: - fix_target = DEFAULT_FIX_TARGET - - # Build startup flags - startup_flags = [] - for flag in ctx.args.bazel_startup_flag: - startup_flags.append(flag) - - # Build command flags - cmd_flags = ["--isatty=" + str(int(ctx.std.io.stdout.is_tty))] - for flag in ctx.args.bazel_flag: - cmd_flags.append(flag) - - # Run bazel run with the gazelle target - build = ctx.bazel.build( - target, - flags = cmd_flags, - startup_flags = startup_flags, - ) - - # Wait for completion - status = build.wait() - - # Handle exit codes - if status.code == 0: - print("Gazelle check passed - BUILD files are up-to-date") - return 0 - else: - print("Gazelle check failed - BUILD files need updating") - print("Run 'bazel run {}' to apply the suggested fixes".format(fix_target)) - return status.code - - -# Register the gazelle task -gazelle = task( - name = "gazelle", - implementation = _gazelle_impl, - args = { - # The target to run for the check (default: //:gazelle.check) - "target": args.string(default = DEFAULT_CHECK_TARGET), - # The target to run for fixing (shown in error message) - "fix_target": args.string(default = DEFAULT_FIX_TARGET), - # Additional bazel flags - "bazel_flag": args.string_list(), - # Bazel startup flags - "bazel_startup_flag": args.string_list(), - }, -) diff --git a/axel-f/github.axl b/axel-f/github.axl new file mode 100644 index 000000000..bdd16dcd2 --- /dev/null +++ b/axel-f/github.axl @@ -0,0 +1,727 @@ +""" +GitHub Check Runs Client Library + +Client for creating and updating GitHub Check Runs via the GitHub API. +""" + +DEFAULT_GITHUB_API = "https://api.github.com" + + +def _normalize_output(output): + """ + Normalize output parameter to the required dict format. + + If output is a string, wraps it in a dict with title and summary. + If output is already a dict, returns it as-is. + """ + if output == None: + return None + if type(output) == "string": + return { + "title": "Check Run Output", + "summary": output, + } + return output + + +def _do_request(ctx, method, url, token, payload = None): + """ + Make an HTTP request to GitHub API. + + Args: + ctx: Context with http() + method: HTTP method ("POST" or "PATCH") + url: Full URL to request + token: GitHub token (PAT or Actions token) + payload: Optional dict to send as JSON body + + Returns: + (success: bool, status: int, body: dict or str) + """ + http = ctx.http() + + headers = { + "Authorization": "Bearer " + token, + "Accept": "application/vnd.github+json", + "Content-Type": "application/json", + "X-GitHub-Api-Version": "2022-11-28", + } + + if method == "POST": + response = http.post( + url, + headers = headers, + data = json.encode(payload) if payload else None, + ).block() + elif method == "PATCH": + response = http.patch( + url, + headers = headers, + data = json.encode(payload) if payload else None, + ).block() + else: + return (False, 0, "unsupported method: " + method) + + success = response.status >= 200 and response.status < 300 + + # Try to parse response as JSON + body = response.body + if body: + body = json.decode(body) + + return (success, response.status, body) + + +def _do_get_request(ctx, url, token): + """ + Make a GET request to GitHub API. + + Args: + ctx: Context with http() + url: Full URL to request + token: GitHub token (PAT or Actions token) + + Returns: + (success: bool, status: int, body: dict or str) + """ + http = ctx.http() + + headers = { + "Authorization": "Bearer " + token, + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28", + } + + response = http.get( + url = url, + headers = headers, + ).block() + + success = response.status >= 200 and response.status < 300 + + body = response.body + if body: + body = json.decode(body) + + return (success, response.status, body) + + +def _do_delete_request(ctx, url, token): + """ + Make a DELETE request to GitHub API. + + Args: + ctx: Context with http() + url: Full URL to request + token: GitHub token (PAT or Actions token) + + Returns: + (success: bool, status: int, body: str or None) + """ + http = ctx.http() + + headers = { + "Authorization": "Bearer " + token, + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28", + } + + response = http.delete( + url = url, + headers = headers, + ).block() + + success = response.status >= 200 and response.status < 300 + + return (success, response.status, response.body) + + +def get_pull_request(ctx, token, owner, repo, pull_number, api_base = DEFAULT_GITHUB_API): + """ + Get a pull request by number. + + Args: + ctx: Context with http() + token: GitHub token + owner: Repository owner + repo: Repository name + pull_number: The PR number + api_base: GitHub API base URL + + Returns: + dict with "success" (bool), "pull_request" (dict) on success + dict with "success" (False), "error" (str), "status" (int) on failure + """ + url = api_base + "/repos/" + owner + "/" + repo + "/pulls/" + str(pull_number) + + success, status_code, body = _do_get_request(ctx, url, token) + + if success: + return { + "success": True, + "pull_request": body, + } + + error_msg = "request failed: " + str(status_code) + if body and type(body) == "dict" and body.get("message"): + error_msg = error_msg + " - " + body["message"] + + return {"success": False, "error": error_msg, "status": status_code} + + +def list_review_comments(ctx, token, owner, repo, pull_number, api_base = DEFAULT_GITHUB_API): + """ + List all review comments on a pull request. + + Handles pagination to retrieve all comments. + + Args: + ctx: Context with http() + token: GitHub token + owner: Repository owner + repo: Repository name + pull_number: The PR number + api_base: GitHub API base URL + + Returns: + dict with "success" (bool), "comments" (list) on success + dict with "success" (False), "error" (str), "status" (int) on failure + """ + all_comments = [] + + for page in range(1, 101): # max 100 pages (10,000 comments) + url = api_base + "/repos/" + owner + "/" + repo + "/pulls/" + str(pull_number) + "/comments?per_page=100&page=" + str(page) + + success, status_code, body = _do_get_request(ctx, url, token) + + if not success: + error_msg = "request failed: " + str(status_code) + if body and type(body) == "dict" and body.get("message"): + error_msg = error_msg + " - " + body["message"] + return {"success": False, "error": error_msg, "status": status_code} + + if not body or len(body) == 0: + break + + all_comments.extend(body) + + if len(body) < 100: + break + + return { + "success": True, + "comments": all_comments, + } + + +def delete_review_comment(ctx, token, owner, repo, comment_id, api_base = DEFAULT_GITHUB_API): + """ + Delete a review comment on a pull request. + + Args: + ctx: Context with http() + token: GitHub token + owner: Repository owner + repo: Repository name + comment_id: The comment ID to delete + api_base: GitHub API base URL + + Returns: + dict with "success" (bool) on success + dict with "success" (False), "error" (str), "status" (int) on failure + """ + url = api_base + "/repos/" + owner + "/" + repo + "/pulls/comments/" + str(comment_id) + + success, status_code, body = _do_delete_request(ctx, url, token) + + if success: + return {"success": True} + + error_msg = "request failed: " + str(status_code) + return {"success": False, "error": error_msg, "status": status_code} + + +def list_pull_request_files(ctx, token, owner, repo, pull_number, api_base = DEFAULT_GITHUB_API): + """ + List files changed in a pull request. + + Handles pagination to retrieve all files. + + Args: + ctx: Context with http() + token: GitHub token + owner: Repository owner + repo: Repository name + pull_number: The PR number + api_base: GitHub API base URL + + Returns: + dict with "success" (bool), "files" (list) on success + dict with "success" (False), "error" (str), "status" (int) on failure + """ + all_files = [] + + for page in range(1, 101): # max 100 pages (10,000 files) + url = api_base + "/repos/" + owner + "/" + repo + "/pulls/" + str(pull_number) + "/files?per_page=100&page=" + str(page) + + success, status_code, body = _do_get_request(ctx, url, token) + + if not success: + error_msg = "request failed: " + str(status_code) + if body and type(body) == "dict" and body.get("message"): + error_msg = error_msg + " - " + body["message"] + return {"success": False, "error": error_msg, "status": status_code} + + if not body or len(body) == 0: + break + + all_files.extend(body) + + if len(body) < 100: + break + + return { + "success": True, + "files": all_files, + } + + +def create_check_run(ctx, token, owner, repo, name, head_sha, status = None, output = None, details_url = None, external_id = None, started_at = None, api_base = DEFAULT_GITHUB_API): + """ + Create a new check run on a commit. + + Args: + ctx: Context with http() + token: GitHub token (PAT or GITHUB_TOKEN from Actions) + owner: Repository owner + repo: Repository name + name: Name of the check run + head_sha: The SHA of the commit to create the check on + status: Optional status ("queued", "in_progress", "completed") + output: Optional dict with "title", "summary", and optionally "text", "annotations" + details_url: Optional URL for more details + external_id: Optional external identifier + started_at: Optional ISO 8601 timestamp + api_base: GitHub API base URL (default: https://api.github.com) + + Returns: + dict with "success" (bool), "check_run_id" (int), "html_url" (str) on success + dict with "success" (False), "error" (str), "status" (int) on failure + """ + url = api_base + "/repos/" + owner + "/" + repo + "/check-runs" + + payload = { + "name": name, + "head_sha": head_sha, + } + + if status: + payload["status"] = status + if output: + payload["output"] = output + if details_url: + payload["details_url"] = details_url + if external_id: + payload["external_id"] = external_id + if started_at: + payload["started_at"] = started_at + + success, status_code, body = _do_request(ctx, "POST", url, token, payload) + + if success: + return { + "success": True, + "check_run_id": body.get("id"), + "html_url": body.get("html_url"), + "response": body, + } + + error_msg = "request failed: " + str(status_code) + if body and type(body) == "dict" and body.get("message"): + error_msg = error_msg + " - " + body["message"] + + return {"success": False, "error": error_msg, "status": status_code} + + +def update_check_run(ctx, token, owner, repo, check_run_id, status = None, conclusion = None, output = None, details_url = None, completed_at = None, api_base = DEFAULT_GITHUB_API): + """ + Update an existing check run. + + Args: + ctx: Context with http() + token: GitHub token + owner: Repository owner + repo: Repository name + check_run_id: The ID of the check run to update + status: Optional new status ("queued", "in_progress", "completed") + conclusion: Required if status is "completed". One of: + "action_required", "cancelled", "failure", "neutral", + "success", "skipped", "stale", "timed_out" + output: Optional dict with "title", "summary", and optionally "text", "annotations" + details_url: Optional URL for more details + completed_at: Optional ISO 8601 timestamp (required if conclusion is set) + api_base: GitHub API base URL + + Returns: + dict with "success" (bool), "check_run_id" (int) on success + dict with "success" (False), "error" (str), "status" (int) on failure + """ + url = api_base + "/repos/" + owner + "/" + repo + "/check-runs/" + str(check_run_id) + + payload = {} + + if status: + payload["status"] = status + if conclusion: + payload["conclusion"] = conclusion + if output: + payload["output"] = output + if details_url: + payload["details_url"] = details_url + if completed_at: + payload["completed_at"] = completed_at + + success, status_code, body = _do_request(ctx, "PATCH", url, token, payload) + + if success: + return { + "success": True, + "check_run_id": body.get("id"), + "html_url": body.get("html_url"), + "response": body, + } + + error_msg = "request failed: " + str(status_code) + if body and type(body) == "dict" and body.get("message"): + error_msg = error_msg + " - " + body["message"] + + return {"success": False, "error": error_msg, "status": status_code} + + +def complete_check_run(ctx, token, owner, repo, check_run_id, conclusion, output = None, api_base = DEFAULT_GITHUB_API): + """ + Complete a check run with a conclusion. + + Convenience wrapper around update_check_run for completing checks. + + Args: + ctx: Context with http() + token: GitHub token + owner: Repository owner + repo: Repository name + check_run_id: The ID of the check run to complete + conclusion: One of: "action_required", "cancelled", "failure", + "neutral", "success", "skipped", "stale", "timed_out" + output: Optional dict with "title", "summary" + api_base: GitHub API base URL + + Returns: + dict with "success" (bool), "check_run_id" (int) on success + dict with "success" (False), "error" (str), "status" (int) on failure + """ + return update_check_run( + ctx, + token, + owner, + repo, + check_run_id, + status = "completed", + conclusion = conclusion, + output = output, + api_base = api_base, + ) + + +def build_output(title, summary, text = None, annotations = None): + """ + Helper to build an output object for check runs. + + Args: + title: Title of the check run output + summary: Summary (supports markdown) + text: Optional detailed text (supports markdown) + annotations: Optional list of annotation dicts + + Returns: + dict suitable for the "output" parameter + """ + output = { + "title": title, + "summary": summary, + } + if text: + output["text"] = text + if annotations: + output["annotations"] = annotations + return output + + +def build_annotation(path, start_line, end_line, message, annotation_level = "warning", start_column = None, end_column = None, title = None, raw_details = None): + """ + Helper to build an annotation for check run output. + + Args: + path: Path of the file to annotate (relative to repo root) + start_line: Start line of the annotation + end_line: End line of the annotation + message: Short description of the feedback + annotation_level: "notice", "warning", or "failure" (default: "warning") + start_column: Optional start column + end_column: Optional end column + title: Optional title for the annotation + raw_details: Optional raw details string + + Returns: + dict suitable for the "annotations" list + """ + annotation = { + "path": path, + "start_line": start_line, + "end_line": end_line, + "annotation_level": annotation_level, + "message": message, + } + if start_column: + annotation["start_column"] = start_column + if end_column: + annotation["end_column"] = end_column + if title: + annotation["title"] = title + if raw_details: + annotation["raw_details"] = raw_details + return annotation + + +# ============================================================================= +# Pull Request Review Comments API +# ============================================================================= + +def create_review(ctx, token, owner, repo, pull_number, body = None, event = "COMMENT", comments = None, commit_id = None, api_base = DEFAULT_GITHUB_API): + """ + Create a pull request review with optional comments. + + This creates comments that appear directly on the PR diff page. + + Args: + ctx: Context with http() + token: GitHub token + owner: Repository owner + repo: Repository name + pull_number: The PR number + body: Optional review body text (shown at top of review) + event: Review action - "APPROVE", "REQUEST_CHANGES", or "COMMENT" (default) + comments: Optional list of review comment dicts (use build_review_comment) + commit_id: Optional commit SHA to review (defaults to PR head) + api_base: GitHub API base URL + + Returns: + dict with "success" (bool), "review_id" (int) on success + dict with "success" (False), "error" (str), "status" (int) on failure + """ + url = api_base + "/repos/" + owner + "/" + repo + "/pulls/" + str(pull_number) + "/reviews" + + payload = { + "event": event, + } + + if body: + payload["body"] = body + if comments: + payload["comments"] = comments + if commit_id: + payload["commit_id"] = commit_id + + success, status_code, response_body = _do_request(ctx, "POST", url, token, payload) + + if success: + return { + "success": True, + "review_id": response_body.get("id"), + "html_url": response_body.get("html_url"), + "response": response_body, + } + + error_msg = "request failed: " + str(status_code) + if response_body and type(response_body) == "dict" and response_body.get("message"): + error_msg = error_msg + " - " + response_body["message"] + + return {"success": False, "error": error_msg, "status": status_code} + + +def create_review_comment(ctx, token, owner, repo, pull_number, body, path, line = None, commit_id = None, side = "RIGHT", start_line = None, start_side = None, subject_type = None, api_base = DEFAULT_GITHUB_API): + """ + Create a single review comment on a PR diff. + + Args: + ctx: Context with http() + token: GitHub token + owner: Repository owner + repo: Repository name + pull_number: The PR number + body: The comment text (supports markdown) + path: File path relative to repo root + line: Line number in the diff to comment on (required unless using subject_type="file") + commit_id: Optional commit SHA (defaults to PR head) + side: "LEFT" (deletion) or "RIGHT" (addition, default) + start_line: For multi-line comments, the first line + start_side: Side for start_line ("LEFT" or "RIGHT") + subject_type: "line" (default) or "file" for file-level comments + api_base: GitHub API base URL + + Returns: + dict with "success" (bool), "comment_id" (int) on success + dict with "success" (False), "error" (str), "status" (int) on failure + """ + url = api_base + "/repos/" + owner + "/" + repo + "/pulls/" + str(pull_number) + "/comments" + + payload = { + "body": body, + "path": path, + } + + if subject_type: + payload["subject_type"] = subject_type + if line: + payload["line"] = line + payload["side"] = side + if commit_id: + payload["commit_id"] = commit_id + if start_line: + payload["start_line"] = start_line + if start_side: + payload["start_side"] = start_side + + success, status_code, response_body = _do_request(ctx, "POST", url, token, payload) + + if success: + return { + "success": True, + "comment_id": response_body.get("id"), + "html_url": response_body.get("html_url"), + "response": response_body, + } + + error_msg = "request failed: " + str(status_code) + if response_body and type(response_body) == "dict" and response_body.get("message"): + error_msg = error_msg + " - " + response_body["message"] + + return {"success": False, "error": error_msg, "status": status_code} + + +def build_review_comment(path, body, line = None, side = "RIGHT", start_line = None, start_side = None): + """ + Helper to build a review comment for use with create_review. + + Args: + path: File path relative to repo root + body: Comment text (supports markdown) + line: Line number in the diff (the ending line for multi-line) + side: "LEFT" (deletion) or "RIGHT" (addition, default) + start_line: For multi-line comments, the starting line + start_side: Side for start_line + + Returns: + dict suitable for the "comments" list in create_review + """ + comment = { + "path": path, + "body": body, + } + if line: + comment["line"] = line + comment["side"] = side + if start_line: + comment["start_line"] = start_line + if start_side: + comment["start_side"] = start_side + return comment + + +def build_suggestion(path, line, suggested_code, message = None, start_line = None): + """ + Helper to build a code suggestion comment that shows "Apply suggestion" button. + + Args: + path: File path relative to repo root + line: Line number to suggest replacement for (end line if multi-line) + suggested_code: The replacement code (what the line(s) should become) + message: Optional message to show above the suggestion + start_line: For multi-line suggestions, the starting line + + Returns: + dict suitable for the "comments" list in create_review + + Example: + # Single line suggestion + build_suggestion( + path = "src/main.py", + line = 42, + suggested_code = "const FOO = 'bar'", + message = "Use const instead of let for constants", + ) + + # Multi-line suggestion (replace lines 10-12 with new code) + build_suggestion( + path = "src/main.py", + start_line = 10, + line = 12, + suggested_code = "function foo() {\\n return bar\\n}", + ) + """ + body = "" + if message: + body = message + "\n\n" + body = body + "```suggestion\n" + suggested_code + "\n```" + + comment = { + "path": path, + "body": body, + "line": line, + "side": "RIGHT", + } + if start_line: + comment["start_line"] = start_line + comment["start_side"] = "RIGHT" + return comment + + +def create_suggestion(ctx, token, owner, repo, pull_number, path, line, suggested_code, message = None, start_line = None, commit_id = None, api_base = DEFAULT_GITHUB_API): + """ + Create a single code suggestion on a PR. + + This creates an "Apply suggestion" button on the PR diff. + + Args: + ctx: Context with http() + token: GitHub token + owner: Repository owner + repo: Repository name + pull_number: The PR number + path: File path relative to repo root + line: Line number to suggest replacement for + suggested_code: The replacement code + message: Optional message above the suggestion + start_line: For multi-line suggestions, the starting line + commit_id: Optional commit SHA (defaults to PR head) + api_base: GitHub API base URL + + Returns: + dict with "success" (bool), "comment_id" (int) on success + dict with "success" (False), "error" (str), "status" (int) on failure + """ + body = "" + if message: + body = message + "\n\n" + body = body + "```suggestion\n" + suggested_code + "\n```" + + return create_review_comment( + ctx, token, owner, repo, pull_number, + body = body, + path = path, + line = line, + commit_id = commit_id, + side = "RIGHT", + start_line = start_line, + start_side = "RIGHT" if start_line else None, + api_base = api_base, + ) diff --git a/axel-f/lint_strategy.axl b/axel-f/lint_strategy.axl new file mode 100644 index 000000000..155810725 --- /dev/null +++ b/axel-f/lint_strategy.axl @@ -0,0 +1,393 @@ +"""GitHub-aware lint strategy and changed files provider.""" + +load("./github.axl", "create_review", "create_review_comment", "get_pull_request", "list_review_comments", "delete_review_comment", "list_pull_request_files") +load("./sarif.axl", "parse_sarif", "sarif_to_review_comments") +load("@aspect_rules_lint//lint/lint.axl", "Strategy", "ChangedFilesProvider") + + +def _parse_github_diff_patch(patch): + """ + Parse a GitHub file patch string to extract added line numbers. + + Args: + patch: The patch string from GitHub's files API + + Returns: + List of 0-based line numbers of added lines + """ + if not patch: + return [] + + lines = [] + current_line = 0 + for line in patch.split("\n"): + if line.startswith("@@"): + # Parse hunk header: @@ -old,count +new,count @@ + parts = line.split(" ") + for part in parts: + if part.startswith("+") and part != "+++": + plus = part.removeprefix("+") + if "," in plus: + current_line = int(plus.split(",")[0]) + else: + current_line = int(plus) + break + elif line.startswith("+"): + # Added line (0-based) + lines.append(current_line - 1) + current_line += 1 + elif line.startswith("-"): + # Deleted line, don't increment current_line + pass + else: + # Context line + current_line += 1 + + return lines + + +def make_github_changed_files_provider(token, owner, repo): + """ + Create a ChangedFilesProvider that fetches changed files from the GitHub API. + + Args: + token: GitHub token + owner: Repository owner + repo: Repository name + + Returns: + ChangedFilesProvider instance + """ + def get_changed_files(ctx, state): + ref = ctx.std.env.var("GITHUB_REF") or "" + if not (ref.startswith("refs/pull/") and ref.endswith("/merge")): + return [] # not a PR build + + pr_number = int(ref.removeprefix("refs/pull/").removesuffix("/merge")) + state["pr_number"] = pr_number + + # Fetch changed files from GitHub API + result = list_pull_request_files(ctx, token, owner, repo, pr_number) + if not result["success"]: + return [] + + all_files = [] + for f in result["files"]: + if f.get("status", "") == "removed": + continue + filename = f.get("filename", "") + patch = f.get("patch", "") + added_lines = _parse_github_diff_patch(patch) + all_files.append({"file": filename, "lines": added_lines}) + + state["changed_lines"] = {f["file"]: f["lines"] for f in all_files} + return all_files + + return ChangedFilesProvider(get_changed_files = get_changed_files) + + +def _enrich_with_suggestions(ctx, comments): + """Read source files and append suggestion blocks for fixable comments.""" + file_cache = {} + for comment in comments: + fixes = comment.get("_fixes") + if not fixes: + continue + + path = comment["path"] + if path not in file_cache: + file_cache[path] = ctx.std.fs.read_to_string(path) + content = file_cache[path] + if not content: + continue + + lines = content.split("\n") + line_num = comment["line"] + if line_num < 1 or line_num > len(lines): + continue + + # Calculate byte offset of the target line start + line_byte_start = 0 + for i in range(line_num - 1): + line_byte_start += len(lines[i]) + 1 # +1 for \n + + original_line = lines[line_num - 1] + + # Convert absolute byte offsets to line-relative, filter to this line + applicable = [] + for f in fixes: + rel_start = f["byteOffset"] - line_byte_start + rel_end = rel_start + f["byteLength"] + if 0 <= rel_start and rel_end <= len(original_line): + applicable.append({ + "start": rel_start, + "end": rel_end, + "replacement": f["replacement"], + }) + + if not applicable: + continue + + # Apply in reverse position order to preserve earlier offsets + applicable = sorted(applicable, key = lambda f: f["start"], reverse = True) + fixed = original_line + for f in applicable: + fixed = fixed[:f["start"]] + f["replacement"] + fixed[f["end"]:] + + if fixed != original_line: + comment["body"] += "\n\n```suggestion\n" + fixed + "\n```" + + # Clean up internal metadata + comment.pop("_fixes", None) + + +# ============================================================================= +# GitHub Strategy Wrapper +# ============================================================================= + +def _build_comment_marker(tool, file, line, rule_id): + """Build a hidden HTML comment marker for identifying lint comments.""" + return "".format(tool, file, line, rule_id) + + +def _extract_comment_marker(body): + """Extract the aspect-lint marker from a comment body, or None.""" + prefix = "" + if not body: + return None + idx = body.find(prefix) + if idx < 0: + return None + end = body.find(suffix, idx) + if end < 0: + return None + return body[idx:end + len(suffix)] + + +def _check_staleness(ctx, state): + """ + Check if the current run is stale (PR HEAD has moved past our commit). + + Returns True if stale, False otherwise. + On API failure, assumes NOT stale. + """ + gh = state["github"] + pr_number = state.get("pr_number") + if not pr_number: + return False + + result = get_pull_request( + ctx, + token = gh["token"], + owner = gh["owner"], + repo = gh["repo"], + pull_number = pr_number, + ) + + if not result["success"]: + # API failure: assume not stale (better to post stale comments than lose results) + return False + + pr = result["pull_request"] + head_sha = pr.get("head", {}).get("sha", "") + return head_sha != gh["head_sha"] + + +def _filter_by_diff(comments, changed_lines): + """Keep only comments that target lines within the PR diff.""" + if not changed_lines: + return list(comments) + return [ + c for c in comments + if (c.get("line", 0) - 1) in (changed_lines.get(c.get("path", "")) or []) + ] + + +def _get_existing_markers(ctx, gh, pr_number): + """Fetch all aspect-lint markers currently on the PR. Returns {marker: True}.""" + result = list_review_comments( + ctx, token = gh["token"], owner = gh["owner"], + repo = gh["repo"], pull_number = pr_number, + ) + if not result["success"]: + return {} + markers = {} + for c in result["comments"]: + marker = _extract_comment_marker(c.get("body", "")) + if marker: + markers[marker] = True + return markers + + +def _post_as_review(ctx, gh, pr_number, comments, existing_markers): + """Post comments as a single grouped review, skipping duplicates.""" + to_post = [ + c for c in comments + if _extract_comment_marker(c.get("body", "")) not in existing_markers + ] + if not to_post: + return + create_review( + ctx, token = gh["token"], owner = gh["owner"], + repo = gh["repo"], pull_number = pr_number, + body = "Lint findings", event = "COMMENT", + comments = to_post, commit_id = gh["head_sha"], + ) + + +def _post_individually(ctx, gh, pr_number, comments, existing_markers): + """Post comments one at a time, skipping duplicates.""" + for c in comments: + marker = _extract_comment_marker(c.get("body", "")) + if marker and marker in existing_markers: + continue + result = create_review_comment( + ctx, token = gh["token"], owner = gh["owner"], + repo = gh["repo"], pull_number = pr_number, + body = c["body"], path = c["path"], + line = c.get("line"), commit_id = gh["head_sha"], + side = c.get("side", "RIGHT"), + start_line = c.get("start_line"), + start_side = c.get("start_side"), + ) + if result["success"] and marker: + existing_markers[marker] = True + + +def _cleanup_comments(ctx, state): + """Delete stale comments and deduplicate.""" + gh = state["github"] + pr_number = state.get("pr_number") + if not pr_number: + return + + # Desired markers: diagnostics that are within the diff + changed_lines = state.get("changed_lines", {}) + desired = {} + for diag in state.get("diagnostics", []): + lines = changed_lines.get(diag["file"]) + if lines and (diag["line"] - 1) in lines: + marker = _build_comment_marker(diag["tool"], diag["file"], diag["line"], diag["rule_id"]) + desired[marker] = True + + # Fetch fresh state of comments on PR + result = list_review_comments( + ctx, token = gh["token"], owner = gh["owner"], + repo = gh["repo"], pull_number = pr_number, + ) + if not result["success"]: + return + + # Group by marker + by_marker = {} + for c in result["comments"]: + marker = _extract_comment_marker(c.get("body", "")) + if not marker: + continue + if marker not in by_marker: + by_marker[marker] = [] + by_marker[marker].append(c) + + # Delete stale (not desired) and duplicates (keep newest) + for marker, comments in by_marker.items(): + if marker not in desired: + for c in comments: + delete_review_comment( + ctx, token = gh["token"], owner = gh["owner"], + repo = gh["repo"], comment_id = c["id"], + ) + elif len(comments) > 1: + by_id = sorted(comments, key = lambda c: c["id"]) + for c in by_id[:-1]: + delete_review_comment( + ctx, token = gh["token"], owner = gh["owner"], + repo = gh["repo"], comment_id = c["id"], + ) + + +def make_github_strategy(base_strategy, token, owner, repo, mode = "grouped"): + """ + Create a GitHub-aware strategy that wraps a base strategy with GitHub reporting. + + Args: + base_strategy: The underlying Strategy to delegate to + token: GitHub token + owner: Repository owner + repo: Repository name + mode: "grouped" posts one review at the end, + "streaming" posts comments individually as linters finish + + Returns: + Strategy instance with GitHub integration + """ + def setup(ctx, state): + base_strategy.setup(ctx, state) + state["github"] = { + "token": token, + "owner": owner, + "repo": repo, + "head_sha": ctx.std.env.var("GITHUB_SHA") or "", + "pending_comments": [], + "stale": False, + } + + def process(ctx, state, filepath): + # Accumulate diagnostics and build review comments + diag_count_before = len(state.get("diagnostics", [])) + base_strategy.process(ctx, state, filepath) + + gh = state["github"] + if gh["stale"]: + return + + content = ctx.std.fs.read_to_string(filepath) + sarif = parse_sarif(content) + comments = sarif_to_review_comments(sarif) + _enrich_with_suggestions(ctx, comments) + + # Stamp each comment with a hidden marker for identity tracking + new_diagnostics = state.get("diagnostics", [])[diag_count_before:] + for i, comment in enumerate(comments): + if i < len(new_diagnostics): + diag = new_diagnostics[i] + marker = _build_comment_marker( + diag["tool"], diag["file"], diag["line"], diag["rule_id"]) + comment["body"] = marker + "\n" + comment["body"] + + gh["pending_comments"].extend(comments) + + # In streaming mode, post comments as they arrive + if mode == "streaming": + pr_number = state.get("pr_number") + if not pr_number: + return + if "existing_markers" not in gh: + gh["existing_markers"] = _get_existing_markers(ctx, gh, pr_number) + ready = _filter_by_diff(gh["pending_comments"], state.get("changed_lines", {})) + _post_individually(ctx, gh, pr_number, ready, gh["existing_markers"]) + gh["pending_comments"] = [] + + def finish(ctx, state): + gh = state["github"] + + if gh["stale"] or _check_staleness(ctx, state): + gh["stale"] = True + return base_strategy.finish(ctx, state) + + pr_number = state.get("pr_number") + if pr_number: + if mode == "grouped": + existing = _get_existing_markers(ctx, gh, pr_number) + ready = _filter_by_diff(gh["pending_comments"], state.get("changed_lines", {})) + _post_as_review(ctx, gh, pr_number, ready, existing) + _cleanup_comments(ctx, state) + + return base_strategy.finish(ctx, state) + + return Strategy( + needs_machine = base_strategy.needs_machine, + setup = setup, + process = process, + finish = finish, + ) diff --git a/axel-f/sarif.axl b/axel-f/sarif.axl new file mode 100644 index 000000000..2acdb2941 --- /dev/null +++ b/axel-f/sarif.axl @@ -0,0 +1,228 @@ +""" +SARIF (Static Analysis Results Interchange Format) GitHub Translation + +Converts SARIF output from linters into GitHub PR review comments and annotations. +Base parsing utilities (parse_sarif, get_sarif_summary) are loaded from rules_lint. +""" + +load("@aspect_rules_lint//lint/sarif.axl", "parse_sarif", "get_sarif_summary") + + +def _get_level_emoji(level): + """Map SARIF level to display text.""" + if level == "error": + return "error" + elif level == "warning": + return "warning" + elif level == "note": + return "note" + return level or "warning" + + +def sarif_result_to_comment(result, tool_name): + """ + Convert a single SARIF result to a GitHub review comment dict. + + Args: + result: A single result from runs[].results[] + tool_name: Name of the tool (from runs[].tool.driver.name) + + Returns: + dict suitable for create_review comments list, or None if invalid + """ + locations = result.get("locations", []) + if not locations: + return None + + location = locations[0] + physical = location.get("physicalLocation") + if not physical: + return None + + artifact = physical.get("artifactLocation", {}) + path = artifact.get("uri") + if not path: + return None + + region = physical.get("region", {}) + start_line = region.get("startLine") + end_line = region.get("endLine", start_line) + + if not start_line: + return None + + # Build comment body + level = _get_level_emoji(result.get("level", "warning")) + message_obj = result.get("message", {}) + message = message_obj.get("text", "") + + body = "**{}** ({})".format(tool_name, level) + if message: + body = body + "\n\n" + message + + comment = { + "path": path, + "line": end_line, + "side": "RIGHT", + "body": body, + } + + # Multi-line comment if start != end + if start_line != end_line: + comment["start_line"] = start_line + comment["start_side"] = "RIGHT" + + # Extract fix hints from relatedLocations + related = result.get("relatedLocations", []) + fixes = [] + for loc in related: + msg = loc.get("message", {}).get("text", "") + if not msg.startswith("try"): + continue + region = loc.get("physicalLocation", {}).get("region", {}) + byte_offset = region.get("byteOffset") + byte_length = region.get("byteLength") + if byte_offset == None or byte_length == None: + continue + # Parse replacement text from "try" message + if msg == "try": + replacement = "" + else: + text = msg[4:] # strip "try " + # Strip decorative outer quotes (clippy wraps replacements in quotes) + if len(text) >= 2 and text[0] == '"' and text[-1] == '"': + text = text[1:-1] + replacement = text + fixes.append({ + "byteOffset": byte_offset, + "byteLength": byte_length, + "replacement": replacement, + }) + if fixes: + comment["_fixes"] = fixes + + return comment + + +def sarif_to_review_comments(sarif): + """ + Convert SARIF output to GitHub review comments. + + Args: + sarif: Parsed SARIF dict (or JSON string) + + Returns: + List of comment dicts suitable for create_review + """ + if type(sarif) == "string": + sarif = json.decode(sarif) + + comments = [] + runs = sarif.get("runs", []) + + for run in runs: + tool = run.get("tool", {}) + driver = tool.get("driver", {}) + tool_name = driver.get("name", "Linter") + + results = run.get("results", []) + for result in results: + comment = sarif_result_to_comment(result, tool_name) + if comment: + comments.append(comment) + + return comments + + +def sarif_to_annotations(sarif): + """ + Convert SARIF output to GitHub Check Run annotations. + + Args: + sarif: Parsed SARIF dict (or JSON string) + + Returns: + List of annotation dicts suitable for build_output + """ + if type(sarif) == "string": + sarif = json.decode(sarif) + + annotations = [] + runs = sarif.get("runs", []) + + for run in runs: + tool = run.get("tool", {}) + driver = tool.get("driver", {}) + tool_name = driver.get("name", "Linter") + + results = run.get("results", []) + for result in results: + annotation = sarif_result_to_annotation(result, tool_name) + if annotation: + annotations.append(annotation) + + return annotations + + +def sarif_result_to_annotation(result, tool_name): + """ + Convert a single SARIF result to a GitHub Check Run annotation. + + Args: + result: A single result from runs[].results[] + tool_name: Name of the tool + + Returns: + dict suitable for check run annotations list, or None if invalid + """ + locations = result.get("locations", []) + if not locations: + return None + + location = locations[0] + physical = location.get("physicalLocation") + if not physical: + return None + + artifact = physical.get("artifactLocation", {}) + path = artifact.get("uri") + if not path: + return None + + region = physical.get("region", {}) + start_line = region.get("startLine") + end_line = region.get("endLine", start_line) + + if not start_line: + return None + + # Map SARIF level to GitHub annotation level + sarif_level = result.get("level", "warning") + if sarif_level == "error": + annotation_level = "failure" + elif sarif_level == "warning": + annotation_level = "warning" + else: + annotation_level = "notice" + + message_obj = result.get("message", {}) + message = message_obj.get("text", "") + + annotation = { + "path": path, + "start_line": start_line, + "end_line": end_line, + "annotation_level": annotation_level, + "message": message, + "title": tool_name, + } + + # Add column info if available + start_column = region.get("startColumn") + end_column = region.get("endColumn") + if start_column: + annotation["start_column"] = start_column + if end_column: + annotation["end_column"] = end_column + + return annotation diff --git a/crates/axl-runtime/src/builtins/aspect/build.axl b/crates/axl-runtime/src/builtins/aspect/build.axl index 00fbaeafc..f7a5e7a54 100644 --- a/crates/axl-runtime/src/builtins/aspect/build.axl +++ b/crates/axl-runtime/src/builtins/aspect/build.axl @@ -6,9 +6,10 @@ BuildConfig = spec( startup_flags = attr(typing.Callable[[list[str]], list[str]], lambda flags: flags), flags = attr(typing.Callable[[list[str]], list[str]], lambda flags: flags), build_event_sinks = attr(typing.Callable[[], list[bazel.build.BuildEventSink]], lambda: []), - # TODO: build event sinks configuration + # Lifecycle build_start = attr(typing.Callable[[], None], lambda: None), + build_event = attr(typing.Callable[[dict, str, str], None] | None, None), build_end = attr(typing.Callable[[int], None], lambda status: None) ) @@ -36,6 +37,13 @@ def impl(ctx: TaskContext) -> int: build_events = [] build_events.extend(extra_sinks) + if ctx.config.build_event: + # flip build_events to true + # when its a list, it is automatically enabled. + if type(build_events) == "bool": + build_events = True + + bazel_flags = ["--isatty=" + str(int(ctx.std.io.stdout.is_tty))] for bazel_flag in ctx.args.bazel_flag: bazel_flags.append(bazel_flag) @@ -57,6 +65,12 @@ def impl(ctx: TaskContext) -> int: *ctx.args.target_pattern ) + if ctx.config.build_event: + build_event = ctx.config.build_event + state = dict() + for event in build.build_events(): + build_event(ctx, state, event) + build_status = build.wait() ctx.config.build_end(build_status.code) diff --git a/crates/axl-runtime/src/engine/http.rs b/crates/axl-runtime/src/engine/http.rs index 0a48777b7..c36295c01 100644 --- a/crates/axl-runtime/src/engine/http.rs +++ b/crates/axl-runtime/src/engine/http.rs @@ -247,6 +247,79 @@ pub(crate) fn http_methods(registry: &mut MethodsBuilder) { } } + fn delete<'v>( + this: values::Value<'v>, + #[starlark(require = named)] url: values::StringValue, + #[starlark(require = named, default = UnpackDictEntries::default())] + headers: UnpackDictEntries, + #[starlark(require = named, default = NoneOr::None)] unix_socket: NoneOr, + ) -> starlark::Result> { + let url_str = url.as_str().to_string(); + let headers_vec: Vec<(String, String)> = headers + .entries + .into_iter() + .map(|(k, v)| (k.as_str().to_string(), v.as_str().to_string())) + .collect(); + + match unix_socket.into_option() { + Some(socket) => { + let fut = async move { + let client = HyperClient::unix(); + let parsed = url::Url::parse(&url_str) + .map_err(|e| anyhow::anyhow!("invalid url: {}", e))?; + let uri: hyper::Uri = UnixUri::new(&socket, parsed.path()).into(); + + let mut req = hyper::Request::builder().method("DELETE").uri(uri); + for (key, value) in &headers_vec { + req = req.header(key.as_str(), value.as_str()); + } + let req = req + .body(Empty::::new()) + .map_err(|e| anyhow::anyhow!("failed to build request: {}", e))?; + + let res = client + .request(req) + .await + .map_err(|e| anyhow::anyhow!("request failed: {}", e))?; + + let status = res.status().as_u16(); + let resp_headers: Vec<(String, String)> = res + .headers() + .iter() + .map(|(n, v)| (n.to_string(), v.to_str().unwrap_or("").to_string())) + .collect(); + let body = res + .into_body() + .collect() + .await + .map_err(|e| anyhow::anyhow!("failed to read body: {}", e))? + .to_bytes(); + let body = String::from_utf8_lossy(&body).to_string(); + + Ok(HttpResponse { + status, + headers: resp_headers, + body, + }) + }; + Ok(StarlarkFuture::from_future(fut.boxed())) + } + None => { + let client = this.downcast_ref_err::()?.client.clone(); + let fut = async move { + let mut req = client.delete(&url_str); + for (key, value) in &headers_vec { + req = req.header(key.as_str(), value.as_str()); + } + let res = req.send().await?; + let response = HttpResponse::from_response(res).await?; + Ok(response) + }; + Ok(StarlarkFuture::from_future(fut.boxed())) + } + } + } + fn post<'v>( this: values::Value<'v>, url: values::StringValue, diff --git a/crates/axl-runtime/src/engine/mod.rs b/crates/axl-runtime/src/engine/mod.rs index 3952eb93c..da8b8ab20 100644 --- a/crates/axl-runtime/src/engine/mod.rs +++ b/crates/axl-runtime/src/engine/mod.rs @@ -37,7 +37,7 @@ pub fn register_globals(globals: &mut GlobalsBuilder) { globals::register_globals(globals); r#async::register_globals(globals); task::register_globals(globals); - types::record::register_globals(globals); + types::spec::register_globals(globals); globals.namespace("args", task_arg::register_globals); globals.namespace("bazel", bazel::register_globals); diff --git a/crates/axl-runtime/src/engine/types/mod.rs b/crates/axl-runtime/src/engine/types/mod.rs index 9afd7fe17..e244e2bc9 100644 --- a/crates/axl-runtime/src/engine/types/mod.rs +++ b/crates/axl-runtime/src/engine/types/mod.rs @@ -1,2 +1,2 @@ pub mod bytes; -pub mod record; +pub mod spec; diff --git a/crates/axl-runtime/src/engine/types/record.rs b/crates/axl-runtime/src/engine/types/spec.rs similarity index 72% rename from crates/axl-runtime/src/engine/types/record.rs rename to crates/axl-runtime/src/engine/types/spec.rs index 021a68d3c..e3ebfbb40 100644 --- a/crates/axl-runtime/src/engine/types/record.rs +++ b/crates/axl-runtime/src/engine/types/spec.rs @@ -14,20 +14,21 @@ use starlark::values::{ }; use starlark_map::small_map::SmallMap; -static RECORD_TYPE_ID: AtomicU64 = AtomicU64::new(0); +static SPEC_TYPE_ID: AtomicU64 = AtomicU64::new(0); -fn next_record_type_id() -> u64 { - RECORD_TYPE_ID.fetch_add(1, Ordering::SeqCst) +fn next_spec_type_id() -> u64 { + SPEC_TYPE_ID.fetch_add(1, Ordering::SeqCst) } // ----------------------------------------------------------------------------- // Field // ----------------------------------------------------------------------------- -/// A field definition for a record, containing a type and optional default value. +/// A field definition for a spec, containing a type and optional default value. #[derive(Debug, Clone, ProvidesStaticType, Allocative)] pub struct Field<'v> { pub(crate) typ: TypeCompiled>, + pub(crate) typ_value: Value<'v>, pub(crate) default: Option>, } @@ -43,6 +44,7 @@ impl<'v> Display for Field<'v> { unsafe impl<'v> Trace<'v> for Field<'v> { fn trace(&mut self, tracer: &Tracer<'v>) { self.typ.trace(tracer); + self.typ_value.trace(tracer); if let Some(ref mut d) = self.default { d.trace(tracer); } @@ -53,6 +55,7 @@ impl<'v> Field<'v> { pub fn freeze(self, freezer: &Freezer) -> Result { Ok(FrozenField { typ: self.typ.freeze(freezer)?, + typ_value: self.typ_value.freeze(freezer)?, default: self.default.map(|d| d.freeze(freezer)).transpose()?, }) } @@ -62,6 +65,7 @@ impl<'v> Field<'v> { #[derive(Debug, Clone, ProvidesStaticType, Allocative)] pub struct FrozenField { pub(crate) typ: TypeCompiled, + pub(crate) typ_value: FrozenValue, pub(crate) default: Option, } @@ -81,6 +85,7 @@ impl Display for FrozenField { #[derive(Debug, ProvidesStaticType, NoSerialize, Allocative)] pub struct FieldValue<'v> { pub(crate) typ: TypeCompiled>, + pub(crate) typ_value: Value<'v>, pub(crate) default: Option>, } @@ -96,6 +101,7 @@ impl<'v> Display for FieldValue<'v> { unsafe impl<'v> Trace<'v> for FieldValue<'v> { fn trace(&mut self, tracer: &Tracer<'v>) { self.typ.trace(tracer); + self.typ_value.trace(tracer); if let Some(ref mut d) = self.default { d.trace(tracer); } @@ -119,6 +125,7 @@ impl<'v> StarlarkValue<'v> for FieldValue<'v> { #[derive(Debug, ProvidesStaticType, NoSerialize, Allocative)] pub struct FrozenFieldValue { pub(crate) typ: TypeCompiled, + pub(crate) typ_value: FrozenValue, pub(crate) default: Option, } @@ -158,37 +165,50 @@ impl Freeze for FieldValue<'_> { fn freeze(self, freezer: &Freezer) -> Result { Ok(FrozenFieldValue { typ: self.typ.freeze(freezer)?, + typ_value: self.typ_value.freeze(freezer)?, default: self.default.map(|d| d.freeze(freezer)).transpose()?, }) } } +/// Create fresh TypeCompiled values from field type values at runtime. +/// This ensures type checking works correctly for types like starlark Records +/// whose frozen TypeCompiled matchers may not function properly. +fn build_type_checkers<'v>( + fields: impl Iterator>, + heap: &'v Heap, +) -> starlark::Result>>> { + fields + .map(|typ_value| TypeCompiled::new(typ_value, heap).map_err(starlark::Error::new_other)) + .collect() +} + // ----------------------------------------------------------------------------- -// RecordType +// SpecType // ----------------------------------------------------------------------------- -/// The type of a record, created by `record(field1=type1, field2=type2, ...)`. -/// Calling this type creates a `Record` instance. +/// The type of a spec, created by `spec(field1=type1, field2=type2, ...)`. +/// Calling this type creates a `Spec` instance. #[derive(Debug, ProvidesStaticType, NoSerialize, Allocative)] -pub struct RecordType<'v> { - /// Unique identifier for this record type +pub struct SpecType<'v> { + /// Unique identifier for this spec type pub(crate) id: u64, - /// Name of the record type (set when assigned to a variable) + /// Name of the spec type (set when assigned to a variable) pub(crate) name: Option, /// Fields with their types and optional defaults pub(crate) fields: SmallMap>, } -impl<'v> Display for RecordType<'v> { +impl<'v> Display for SpecType<'v> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self.name { - Some(name) => write!(f, "record[{}]", name), - None => write!(f, "record[anon]"), + Some(name) => write!(f, "spec[{}]", name), + None => write!(f, "spec[anon]"), } } } -unsafe impl<'v> Trace<'v> for RecordType<'v> { +unsafe impl<'v> Trace<'v> for SpecType<'v> { fn trace(&mut self, tracer: &Tracer<'v>) { for (_, field) in self.fields.iter_mut() { field.trace(tracer); @@ -196,14 +216,14 @@ unsafe impl<'v> Trace<'v> for RecordType<'v> { } } -impl<'v> AllocValue<'v> for RecordType<'v> { +impl<'v> AllocValue<'v> for SpecType<'v> { fn alloc_value(self, heap: &'v Heap) -> Value<'v> { heap.alloc_complex(self) } } -#[starlark_value(type = "record_type")] -impl<'v> StarlarkValue<'v> for RecordType<'v> { +#[starlark_value(type = "spec")] +impl<'v> StarlarkValue<'v> for SpecType<'v> { fn collect_repr(&self, collector: &mut String) { write!(collector, "{}", self).unwrap(); } @@ -213,7 +233,7 @@ impl<'v> StarlarkValue<'v> for RecordType<'v> { variable_name: &str, _eval: &mut starlark::eval::Evaluator<'v, '_, '_>, ) -> starlark::Result<()> { - // This is called when the record type is assigned to a variable. + // This is called when the spec type is assigned to a variable. // We use unsafe to mutate the name, which is safe because this is only // called during module loading. let this = self as *const Self as *mut Self; @@ -229,6 +249,10 @@ impl<'v> StarlarkValue<'v> for RecordType<'v> { args: &starlark::eval::Arguments<'v, '_>, eval: &mut starlark::eval::Evaluator<'v, '_, '_>, ) -> starlark::Result> { + // Build fresh type checkers from the original type values + let type_checkers = + build_type_checkers(self.fields.values().map(|f| f.typ_value), eval.heap())?; + // Parse the arguments according to our field definitions let mut values: Vec>> = Vec::with_capacity(self.fields.len()); @@ -237,7 +261,7 @@ impl<'v> StarlarkValue<'v> for RecordType<'v> { let kwargs = args.names_map()?; // Build values in field order - for (field_name, field) in self.fields.iter() { + for ((field_name, field), tc) in self.fields.iter().zip(type_checkers.iter()) { let value = if let Some(v) = kwargs.get(field_name.as_str()) { *v } else if let Some(default) = field.default { @@ -250,12 +274,12 @@ impl<'v> StarlarkValue<'v> for RecordType<'v> { ))); }; - // Type check the value - if !field.typ.matches(value) { + // Type check the value using the fresh TypeCompiled + if !tc.matches(value) { return Err(starlark::Error::new_other(anyhow::anyhow!( "Field `{}` expected type `{}`, got `{}`", field_name, - field.typ, + tc, value.get_type() ))); } @@ -274,58 +298,59 @@ impl<'v> StarlarkValue<'v> for RecordType<'v> { } } - let record = Record { + let spec = Spec { typ: _me, values: values.into_boxed_slice(), + type_checkers: type_checkers.into_boxed_slice(), }; - Ok(eval.heap().alloc(record)) + Ok(eval.heap().alloc(spec)) } fn get_methods() -> Option<&'static Methods> { static RES: MethodsStatic = MethodsStatic::new(); - RES.methods(record_type_methods) + RES.methods(spec_type_methods) } } #[starlark_module] -fn record_type_methods(_builder: &mut MethodsBuilder) {} +fn spec_type_methods(_builder: &mut MethodsBuilder) {} // ----------------------------------------------------------------------------- -// FrozenRecordType +// FrozenSpecType // ----------------------------------------------------------------------------- -/// Frozen version of RecordType. +/// Frozen version of SpecType. #[derive(Debug, ProvidesStaticType, NoSerialize, Allocative)] -pub struct FrozenRecordType { +pub struct FrozenSpecType { pub(crate) id: u64, pub(crate) name: Option, pub(crate) fields: SmallMap, } -impl Display for FrozenRecordType { +impl Display for FrozenSpecType { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self.name { - Some(name) => write!(f, "record[{}]", name), - None => write!(f, "record[anon]"), + Some(name) => write!(f, "spec[{}]", name), + None => write!(f, "spec[anon]"), } } } -unsafe impl<'v> Trace<'v> for FrozenRecordType { +unsafe impl<'v> Trace<'v> for FrozenSpecType { fn trace(&mut self, _tracer: &Tracer<'v>) { // Frozen values don't need tracing } } -impl AllocFrozenValue for FrozenRecordType { +impl AllocFrozenValue for FrozenSpecType { fn alloc_frozen_value(self, heap: &FrozenHeap) -> FrozenValue { heap.alloc_simple(self) } } -#[starlark_value(type = "record_type")] -impl<'v> StarlarkValue<'v> for FrozenRecordType { - type Canonical = RecordType<'v>; +#[starlark_value(type = "spec")] +impl<'v> StarlarkValue<'v> for FrozenSpecType { + type Canonical = SpecType<'v>; fn collect_repr(&self, collector: &mut String) { write!(collector, "{}", self).unwrap(); @@ -337,12 +362,18 @@ impl<'v> StarlarkValue<'v> for FrozenRecordType { args: &starlark::eval::Arguments<'v, '_>, eval: &mut starlark::eval::Evaluator<'v, '_, '_>, ) -> starlark::Result> { + // Build fresh type checkers from the original type values + let type_checkers = build_type_checkers( + self.fields.values().map(|f| f.typ_value.to_value()), + eval.heap(), + )?; + let mut values: Vec>> = Vec::with_capacity(self.fields.len()); args.no_positional_args(eval.heap())?; let kwargs = args.names_map()?; - for (field_name, field) in self.fields.iter() { + for ((field_name, field), tc) in self.fields.iter().zip(type_checkers.iter()) { let value = if let Some(v) = kwargs.get(field_name.as_str()) { *v } else if let Some(default) = field.default { @@ -355,12 +386,12 @@ impl<'v> StarlarkValue<'v> for FrozenRecordType { ))); }; - // Type check using matches on the value representation - if !field.typ.matches(value) { + // Type check using the fresh TypeCompiled + if !tc.matches(value) { return Err(starlark::Error::new_other(anyhow::anyhow!( "Field `{}` expected type `{}`, got `{}`", field_name, - field.typ, + tc, value.get_type() ))); } @@ -378,28 +409,29 @@ impl<'v> StarlarkValue<'v> for FrozenRecordType { } } - let record = Record { + let spec = Spec { typ: _me, values: values.into_boxed_slice(), + type_checkers: type_checkers.into_boxed_slice(), }; - Ok(eval.heap().alloc(record)) + Ok(eval.heap().alloc(spec)) } fn get_methods() -> Option<&'static Methods> { static RES: MethodsStatic = MethodsStatic::new(); - RES.methods(record_type_methods) + RES.methods(spec_type_methods) } } -impl Freeze for RecordType<'_> { - type Frozen = FrozenRecordType; +impl Freeze for SpecType<'_> { + type Frozen = FrozenSpecType; fn freeze(self, freezer: &Freezer) -> Result { let mut frozen_fields = SmallMap::with_capacity(self.fields.len()); for (name, field) in self.fields.into_iter() { frozen_fields.insert(name, field.freeze(freezer)?); } - Ok(FrozenRecordType { + Ok(FrozenSpecType { id: self.id, name: self.name, fields: frozen_fields, @@ -408,32 +440,36 @@ impl Freeze for RecordType<'_> { } // ----------------------------------------------------------------------------- -// Record +// Spec // ----------------------------------------------------------------------------- -/// An instance of a record type, containing field values. +/// An instance of a spec type, containing field values. #[derive(Debug, ProvidesStaticType, NoSerialize, Allocative)] -pub struct Record<'v> { - /// The record type this instance belongs to +pub struct Spec<'v> { + /// The spec type this instance belongs to pub(crate) typ: Value<'v>, /// Field values in the same order as the type's field definitions (mutable via Cell) #[allocative(skip)] pub(crate) values: Box<[Cell>]>, + /// Fresh type checkers created at construction time for runtime type checking. + /// These are re-derived from the field type values to avoid issues with frozen TypeCompiled. + #[allocative(skip)] + pub(crate) type_checkers: Box<[TypeCompiled>]>, } -impl<'v> Display for Record<'v> { +impl<'v> Display for Spec<'v> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}(", self.typ)?; - if let Some(record_type) = self.typ.downcast_ref::() { + if let Some(spec_type) = self.typ.downcast_ref::() { let mut first = true; - for ((name, _), value) in record_type.fields.iter().zip(self.values.iter()) { + for ((name, _), value) in spec_type.fields.iter().zip(self.values.iter()) { if !first { write!(f, ", ")?; } first = false; write!(f, "{}={}", name, value.get())?; } - } else if let Some(frozen_type) = self.typ.downcast_ref::() { + } else if let Some(frozen_type) = self.typ.downcast_ref::() { let mut first = true; for ((name, _), value) in frozen_type.fields.iter().zip(self.values.iter()) { if !first { @@ -447,7 +483,7 @@ impl<'v> Display for Record<'v> { } } -unsafe impl<'v> Trace<'v> for Record<'v> { +unsafe impl<'v> Trace<'v> for Spec<'v> { fn trace(&mut self, tracer: &Tracer<'v>) { self.typ.trace(tracer); for cell in self.values.iter() { @@ -455,20 +491,23 @@ unsafe impl<'v> Trace<'v> for Record<'v> { v.trace(tracer); cell.set(v); } + for tc in self.type_checkers.iter_mut() { + tc.trace(tracer); + } } } -impl<'v> AllocValue<'v> for Record<'v> { +impl<'v> AllocValue<'v> for Spec<'v> { fn alloc_value(self, heap: &'v Heap) -> Value<'v> { heap.alloc_complex(self) } } -impl<'v> Record<'v> { +impl<'v> Spec<'v> { fn get_field_names(&self) -> Vec<&str> { - if let Some(record_type) = self.typ.downcast_ref::() { - record_type.fields.keys().map(|s| s.as_str()).collect() - } else if let Some(frozen_type) = self.typ.downcast_ref::() { + if let Some(spec_type) = self.typ.downcast_ref::() { + spec_type.fields.keys().map(|s| s.as_str()).collect() + } else if let Some(frozen_type) = self.typ.downcast_ref::() { frozen_type.fields.keys().map(|s| s.as_str()).collect() } else { vec![] @@ -476,18 +515,18 @@ impl<'v> Record<'v> { } } -#[starlark_value(type = "record")] -impl<'v> StarlarkValue<'v> for Record<'v> { +#[starlark_value(type = "spec")] +impl<'v> StarlarkValue<'v> for Spec<'v> { fn collect_repr(&self, collector: &mut String) { write!(collector, "{}", self).unwrap(); } fn get_attr(&self, attribute: &str, _heap: &'v Heap) -> Option> { - if let Some(record_type) = self.typ.downcast_ref::() { - if let Some(idx) = record_type.fields.get_index_of(attribute) { + if let Some(spec_type) = self.typ.downcast_ref::() { + if let Some(idx) = spec_type.fields.get_index_of(attribute) { return Some(self.values[idx].get()); } - } else if let Some(frozen_type) = self.typ.downcast_ref::() { + } else if let Some(frozen_type) = self.typ.downcast_ref::() { if let Some(idx) = frozen_type.fields.get_index_of(attribute) { return Some(self.values[idx].get()); } @@ -496,50 +535,35 @@ impl<'v> StarlarkValue<'v> for Record<'v> { } fn set_attr(&self, attribute: &str, value: Value<'v>) -> starlark::Result<()> { - // Get field info and index - let (idx, field_typ) = if let Some(record_type) = self.typ.downcast_ref::() { - if let Some(idx) = record_type.fields.get_index_of(attribute) { - (idx, &record_type.fields.get_index(idx).unwrap().1.typ) - } else { - return Err(starlark::Error::new_other(anyhow::anyhow!( - "Record {} has no field `{}`", - self.typ, - attribute - ))); - } - } else if let Some(frozen_type) = self.typ.downcast_ref::() { - if let Some(idx) = frozen_type.fields.get_index_of(attribute) { - // For frozen types, we need to check against the frozen field's type - let field = frozen_type.fields.get_index(idx).unwrap().1; - if !field.typ.matches(value) { - return Err(starlark::Error::new_other(anyhow::anyhow!( - "Field `{}` expected type `{}`, got `{}`", - attribute, - field.typ, - value.get_type() - ))); - } - self.values[idx].set(value); - return Ok(()); - } else { + // Get field index + let idx = if let Some(spec_type) = self.typ.downcast_ref::() { + spec_type.fields.get_index_of(attribute) + } else if let Some(frozen_type) = self.typ.downcast_ref::() { + frozen_type.fields.get_index_of(attribute) + } else { + return Err(starlark::Error::new_other(anyhow::anyhow!( + "Invalid spec type" + ))); + }; + + let idx = match idx { + Some(idx) => idx, + None => { return Err(starlark::Error::new_other(anyhow::anyhow!( - "Record {} has no field `{}`", + "Spec {} has no field `{}`", self.typ, attribute ))); } - } else { - return Err(starlark::Error::new_other(anyhow::anyhow!( - "Invalid record type" - ))); }; - // Type check the value - if !field_typ.matches(value) { + // Type check using the fresh type checker created at construction time + let tc = &self.type_checkers[idx]; + if !tc.matches(value) { return Err(starlark::Error::new_other(anyhow::anyhow!( "Field `{}` expected type `{}`, got `{}`", attribute, - field_typ, + tc, value.get_type() ))); } @@ -550,9 +574,9 @@ impl<'v> StarlarkValue<'v> for Record<'v> { } fn has_attr(&self, attribute: &str, _heap: &'v Heap) -> bool { - if let Some(record_type) = self.typ.downcast_ref::() { - record_type.fields.contains_key(attribute) - } else if let Some(frozen_type) = self.typ.downcast_ref::() { + if let Some(spec_type) = self.typ.downcast_ref::() { + spec_type.fields.contains_key(attribute) + } else if let Some(frozen_type) = self.typ.downcast_ref::() { frozen_type.fields.contains_key(attribute) } else { false @@ -567,21 +591,21 @@ impl<'v> StarlarkValue<'v> for Record<'v> { } fn equals(&self, other: Value<'v>) -> starlark::Result { - if let Some(other_record) = other.downcast_ref::() { - // Check that they have the same record type + if let Some(other_spec) = other.downcast_ref::() { + // Check that they have the same spec type let self_id = self .typ - .downcast_ref::() + .downcast_ref::() .map(|t| t.id) - .or_else(|| self.typ.downcast_ref::().map(|t| t.id)); - let other_id = other_record + .or_else(|| self.typ.downcast_ref::().map(|t| t.id)); + let other_id = other_spec .typ - .downcast_ref::() + .downcast_ref::() .map(|t| t.id) .or_else(|| { - other_record + other_spec .typ - .downcast_ref::() + .downcast_ref::() .map(|t| t.id) }); @@ -590,24 +614,24 @@ impl<'v> StarlarkValue<'v> for Record<'v> { } // Compare all values - if self.values.len() != other_record.values.len() { + if self.values.len() != other_spec.values.len() { return Ok(false); } - for (a, b) in self.values.iter().zip(other_record.values.iter()) { + for (a, b) in self.values.iter().zip(other_spec.values.iter()) { if !a.get().equals(b.get())? { return Ok(false); } } Ok(true) - } else if let Some(other_frozen) = other.downcast_ref::() { + } else if let Some(other_frozen) = other.downcast_ref::() { let self_id = self .typ - .downcast_ref::() + .downcast_ref::() .map(|t| t.id) - .or_else(|| self.typ.downcast_ref::().map(|t| t.id)); + .or_else(|| self.typ.downcast_ref::().map(|t| t.id)); let other_id = other_frozen .typ - .downcast_ref::() + .downcast_ref::() .map(|t| t.id); if self_id != other_id { @@ -630,20 +654,20 @@ impl<'v> StarlarkValue<'v> for Record<'v> { } // ----------------------------------------------------------------------------- -// FrozenRecord +// FrozenSpec // ----------------------------------------------------------------------------- -/// Frozen version of Record. +/// Frozen version of Spec. #[derive(Debug, ProvidesStaticType, NoSerialize, Allocative)] -pub struct FrozenRecord { +pub struct FrozenSpec { pub(crate) typ: FrozenValue, pub(crate) values: Box<[FrozenValue]>, } -impl Display for FrozenRecord { +impl Display for FrozenSpec { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}(", self.typ)?; - if let Some(frozen_type) = self.typ.downcast_ref::() { + if let Some(frozen_type) = self.typ.downcast_ref::() { let mut first = true; for ((name, _), value) in frozen_type.fields.iter().zip(self.values.iter()) { if !first { @@ -657,28 +681,28 @@ impl Display for FrozenRecord { } } -unsafe impl<'v> Trace<'v> for FrozenRecord { +unsafe impl<'v> Trace<'v> for FrozenSpec { fn trace(&mut self, _tracer: &Tracer<'v>) { // Frozen values don't need tracing } } -impl AllocFrozenValue for FrozenRecord { +impl AllocFrozenValue for FrozenSpec { fn alloc_frozen_value(self, heap: &FrozenHeap) -> FrozenValue { heap.alloc_simple(self) } } -#[starlark_value(type = "record")] -impl<'v> StarlarkValue<'v> for FrozenRecord { - type Canonical = Record<'v>; +#[starlark_value(type = "spec")] +impl<'v> StarlarkValue<'v> for FrozenSpec { + type Canonical = Spec<'v>; fn collect_repr(&self, collector: &mut String) { write!(collector, "{}", self).unwrap(); } fn get_attr(&self, attribute: &str, _heap: &'v Heap) -> Option> { - if let Some(frozen_type) = self.typ.downcast_ref::() { + if let Some(frozen_type) = self.typ.downcast_ref::() { if let Some(idx) = frozen_type.fields.get_index_of(attribute) { return Some(self.values[idx].to_value()); } @@ -687,7 +711,7 @@ impl<'v> StarlarkValue<'v> for FrozenRecord { } fn has_attr(&self, attribute: &str, _heap: &'v Heap) -> bool { - if let Some(frozen_type) = self.typ.downcast_ref::() { + if let Some(frozen_type) = self.typ.downcast_ref::() { frozen_type.fields.contains_key(attribute) } else { false @@ -695,7 +719,7 @@ impl<'v> StarlarkValue<'v> for FrozenRecord { } fn dir_attr(&self) -> Vec { - if let Some(frozen_type) = self.typ.downcast_ref::() { + if let Some(frozen_type) = self.typ.downcast_ref::() { frozen_type.fields.keys().map(|s| s.to_string()).collect() } else { vec![] @@ -703,11 +727,11 @@ impl<'v> StarlarkValue<'v> for FrozenRecord { } fn equals(&self, other: Value<'v>) -> starlark::Result { - if let Some(other_frozen) = other.downcast_ref::() { - let self_id = self.typ.downcast_ref::().map(|t| t.id); + if let Some(other_frozen) = other.downcast_ref::() { + let self_id = self.typ.downcast_ref::().map(|t| t.id); let other_id = other_frozen .typ - .downcast_ref::() + .downcast_ref::() .map(|t| t.id); if self_id != other_id { @@ -723,16 +747,16 @@ impl<'v> StarlarkValue<'v> for FrozenRecord { } } Ok(true) - } else if let Some(other_record) = other.downcast_ref::() { - let self_id = self.typ.downcast_ref::().map(|t| t.id); - let other_id = other_record + } else if let Some(other_spec) = other.downcast_ref::() { + let self_id = self.typ.downcast_ref::().map(|t| t.id); + let other_id = other_spec .typ - .downcast_ref::() + .downcast_ref::() .map(|t| t.id) .or_else(|| { - other_record + other_spec .typ - .downcast_ref::() + .downcast_ref::() .map(|t| t.id) }); @@ -740,10 +764,10 @@ impl<'v> StarlarkValue<'v> for FrozenRecord { return Ok(false); } - if self.values.len() != other_record.values.len() { + if self.values.len() != other_spec.values.len() { return Ok(false); } - for (a, b) in self.values.iter().zip(other_record.values.iter()) { + for (a, b) in self.values.iter().zip(other_spec.values.iter()) { if !a.to_value().equals(b.get())? { return Ok(false); } @@ -755,8 +779,8 @@ impl<'v> StarlarkValue<'v> for FrozenRecord { } } -impl Freeze for Record<'_> { - type Frozen = FrozenRecord; +impl Freeze for Spec<'_> { + type Frozen = FrozenSpec; fn freeze(self, freezer: &Freezer) -> Result { let typ = self.typ.freeze(freezer)?; @@ -765,7 +789,7 @@ impl Freeze for Record<'_> { .iter() .map(|v| v.get().freeze(freezer)) .collect(); - Ok(FrozenRecord { + Ok(FrozenSpec { typ, values: values?.into_boxed_slice(), }) @@ -778,19 +802,19 @@ impl Freeze for Record<'_> { #[starlark_module] pub fn register_globals(globals: &mut GlobalsBuilder) { - /// Creates a record type with the given fields. + /// Creates a spec type with the given fields. /// /// Example: /// ```starlark - /// MyRecord = spec(host=str, port=int) - /// r = MyRecord(host="localhost", port=80) + /// MySpec = spec(host=str, port=int) + /// r = MySpec(host="localhost", port=80) /// print(r.host) # "localhost" /// print(r.port) # 80 /// ``` fn spec<'v>( #[starlark(kwargs)] kwargs: SmallMap<&str, Value<'v>>, eval: &mut starlark::eval::Evaluator<'v, '_, '_>, - ) -> starlark::Result> { + ) -> starlark::Result> { let mut fields = SmallMap::with_capacity(kwargs.len()); for (name, value) in kwargs.into_iter() { @@ -798,18 +822,23 @@ pub fn register_globals(globals: &mut GlobalsBuilder) { // It's already a field() definition Field { typ: field_value.typ.dupe(), + typ_value: field_value.typ_value, default: field_value.default, } } else { // It's a type, convert to a field without default let typ = TypeCompiled::new(value, eval.heap())?; - Field { typ, default: None } + Field { + typ, + typ_value: value, + default: None, + } }; fields.insert(name.to_string(), field); } - Ok(RecordType { - id: next_record_type_id(), + Ok(SpecType { + id: next_spec_type_id(), name: None, fields, }) @@ -819,8 +848,8 @@ pub fn register_globals(globals: &mut GlobalsBuilder) { /// /// Example: /// ```starlark - /// MyRecord = spec(host=str, port=attr(int, 80)) - /// r = MyRecord(host="localhost") # port defaults to 80 + /// MySpec = spec(host=str, port=attr(int, 80)) + /// r = MySpec(host="localhost") # port defaults to 80 /// ``` fn attr<'v>( #[starlark(require = pos)] typ: Value<'v>, @@ -842,6 +871,7 @@ pub fn register_globals(globals: &mut GlobalsBuilder) { Ok(FieldValue { typ: compiled_type, + typ_value: typ, default, }) } diff --git a/crates/axl-runtime/src/eval/load.rs b/crates/axl-runtime/src/eval/load.rs index aadecb26f..8d6873a65 100644 --- a/crates/axl-runtime/src/eval/load.rs +++ b/crates/axl-runtime/src/eval/load.rs @@ -58,6 +58,12 @@ impl<'p> AxlLoader<'p> { AxlStore::new(self.cli_version.clone(), self.repo_root.clone(), path) } + /// Caches a frozen module by its absolute path so that subsequent `load()` calls + /// for the same path return the cached module instead of re-evaluating. + pub fn cache_module(&self, path: PathBuf, module: FrozenModule) { + self.loaded_modules.borrow_mut().insert(path, module); + } + pub(super) fn eval_module(&self, path: &Path) -> Result { assert!(path.is_absolute()); @@ -124,15 +130,29 @@ impl<'p> FileLoader for AxlLoader<'p> { .last() .expect("module name stack should not be empty"); + // Track whether we need to push/pop a new module scope for dependency loads. + let new_module_scope = match &load_path { + LoadPath::ModuleSpecifier { module, .. } => Some(ModuleScope { + name: module.clone(), + path: self.deps_root.join(module), + }), + _ => None, + }; + let resolved_script_path = match &load_path { LoadPath::ModuleSpecifier { module, subpath } => { self.resolve_in_deps_root(&module, &subpath)? } LoadPath::ModuleSubpath(subpath) => self.resolve(&module_info.path, subpath)?, LoadPath::RelativePath(relpath) => { - let parent = parent_script_path - .strip_prefix(&module_info.path) - .expect("parent script path should have same prefix as current module"); + let parent = parent_script_path.strip_prefix(&module_info.path).expect( + format!( + "parent script path {} should have same prefix as current module {}", + parent_script_path.display(), + module_info.path.display(), + ) + .as_str(), + ); if let Some(parent) = parent.parent() { self.resolve(&module_info.path, &parent.join(relpath))? } else { @@ -167,8 +187,13 @@ impl<'p> FileLoader for AxlLoader<'p> { drop(load_stack); - // Push the resolved path to the stack so that relative imports from the file still works. - // load_stack.push(resolved_script_path.clone()); + // If loading a dependency module, push its scope so relative imports resolve correctly. + if let Some(scope) = &new_module_scope { + drop(module_stack); + self.module_stack.borrow_mut().push(scope.clone()); + } else { + drop(module_stack); + } // Read and parse the file content into an AST. let frozen_module = self @@ -176,6 +201,11 @@ impl<'p> FileLoader for AxlLoader<'p> { .map_err(|e| Into::::into(e))? .freeze()?; + // Pop the dependency module scope if we pushed one. + if new_module_scope.is_some() { + self.module_stack.borrow_mut().pop(); + } + // Pop the load stack after successful load // self.load_stack.borrow_mut().pop(); diff --git a/crates/axl-runtime/src/eval/task.rs b/crates/axl-runtime/src/eval/task.rs index 0cb146c0e..1da0ff89c 100644 --- a/crates/axl-runtime/src/eval/task.rs +++ b/crates/axl-runtime/src/eval/task.rs @@ -190,8 +190,15 @@ impl<'l, 'p> TaskEvaluator<'l, 'p> { .expect("just pushed a scope"); // Freeze immediately - module + let frozen = module .freeze() - .map_err(|e| EvalError::UnknownError(anyhow!(e))) + .map_err(|e| EvalError::UnknownError(anyhow!(e)))?; + + // Cache the frozen module so that subsequent load() calls for the same + // path (e.g., from config files) return this module instead of + // re-evaluating and creating new type instances with different IDs. + self.loader.cache_module(abs_path, frozen.clone()); + + Ok(frozen) } } From 4665091e0b7dcce2e8a06e380db1768925463a7e Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 11 Feb 2026 11:11:52 -0800 Subject: [PATCH 57/65] Working --- Cargo.lock | 12 ++ Cargo.toml | 2 +- axel-f/BUILD.bazel | 14 ++ axel-f/Cargo.toml | 4 + axel-f/MODULE.aspect | 18 ++ axel-f/{config.axl => config/builtins.axl} | 113 +--------- axel-f/config/delivery.axl | 97 +++++++++ axel-f/config/lint.axl | 132 ++++++++++++ axel-f/config/nolint.axl | 8 + axel-f/docs/lint-task.md | 199 ++++++++++++++++++ axel-f/docs/sarif-translation.md | 178 ++++++++++++++++ axel-f/docs/what_is_this.md | 71 ++++++- axel-f/{ => lib}/deliveryd.axl | 0 axel-f/{ => lib}/github.axl | 0 axel-f/{lint_strategy.axl => lib/linting.axl} | 0 .../{platform-config.axl => lib/platform.axl} | 0 axel-f/{ => lib}/sarif.axl | 0 axel-f/src/lib.rs | 31 +++ axel-f/{ => tasks}/delivery.axl | 2 +- axel-f/tasks/dummy_format.axl | 22 ++ axel-f/tasks/dummy_lint.axl | 22 ++ axel-f/{ => tasks}/migrate.axl | 0 crates/aspect-cli/src/main.rs | 98 +++++++-- crates/axl-runtime/BUILD.bazel | 1 + crates/axl-runtime/Cargo.toml | 2 + crates/axl-runtime/src/builtins/mod.rs | 82 +++++--- crates/axl-runtime/src/eval/config.rs | 8 +- crates/axl-runtime/src/module/disk_store.rs | 11 +- crates/axl-runtime/src/module/eval.rs | 59 +++++- crates/axl-runtime/src/module/mod.rs | 2 +- crates/axl-runtime/src/module/store.rs | 20 ++ 31 files changed, 1041 insertions(+), 167 deletions(-) create mode 100644 axel-f/BUILD.bazel create mode 100644 axel-f/Cargo.toml create mode 100644 axel-f/MODULE.aspect rename axel-f/{config.axl => config/builtins.axl} (51%) create mode 100644 axel-f/config/delivery.axl create mode 100644 axel-f/config/lint.axl create mode 100644 axel-f/config/nolint.axl create mode 100644 axel-f/docs/lint-task.md create mode 100644 axel-f/docs/sarif-translation.md rename axel-f/{ => lib}/deliveryd.axl (100%) rename axel-f/{ => lib}/github.axl (100%) rename axel-f/{lint_strategy.axl => lib/linting.axl} (100%) rename axel-f/{platform-config.axl => lib/platform.axl} (100%) rename axel-f/{ => lib}/sarif.axl (100%) create mode 100644 axel-f/src/lib.rs rename axel-f/{ => tasks}/delivery.axl (99%) create mode 100644 axel-f/tasks/dummy_format.axl create mode 100644 axel-f/tasks/dummy_lint.axl rename axel-f/{ => tasks}/migrate.axl (100%) diff --git a/Cargo.lock b/Cargo.lock index 37e0c57eb..a3a9b7604 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -271,6 +271,10 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "axel-f" +version = "0.0.1" + [[package]] name = "axl-docgen" version = "0.0.0-dev" @@ -324,6 +328,7 @@ dependencies = [ "anyhow", "arc-slice", "aspect-telemetry", + "axel-f", "axl-proto", "base64 0.22.1", "build-event-stream", @@ -351,6 +356,7 @@ dependencies = [ "prost", "rand 0.8.5", "reqwest", + "semver", "serde_json", "sha256", "ssri", @@ -3703,6 +3709,12 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + [[package]] name = "serde" version = "1.0.227" diff --git a/Cargo.toml b/Cargo.toml index 73aeb0629..bf3db772c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["crates/*"] +members = ["crates/*", "axel-f"] exclude = ["crates/example-tui", "examples/lint"] default-members = ["crates/aspect-cli"] resolver = "2" diff --git a/axel-f/BUILD.bazel b/axel-f/BUILD.bazel new file mode 100644 index 000000000..05df07ffd --- /dev/null +++ b/axel-f/BUILD.bazel @@ -0,0 +1,14 @@ +load("//bazel/rust:defs.bzl", "rust_library") + +rust_library( + name = "axel-f", + srcs = glob(["src/**/*.rs"]), + compile_data = glob([ + "**/*.axl", + "**/*.aspect", + ]), + visibility = [ + "//crates/axl-runtime:__pkg__", + "//crates/aspect-cli:__pkg__", + ], +) diff --git a/axel-f/Cargo.toml b/axel-f/Cargo.toml new file mode 100644 index 000000000..a332e24f1 --- /dev/null +++ b/axel-f/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "axel-f" +version = "0.0.1" +edition.workspace = true diff --git a/axel-f/MODULE.aspect b/axel-f/MODULE.aspect new file mode 100644 index 000000000..409d5bc8c --- /dev/null +++ b/axel-f/MODULE.aspect @@ -0,0 +1,18 @@ +# Configure delivery task +use_config("config/delivery.axl", "configure_delivery") + +# Configure builtins for Workflows environment +use_config("config/builtins.axl", "configure_builtins") + +# Configure rules_lint if its declared by user +use_config( + "config/lint.axl", + "configure_rules_lint", + requires = ["aspect_rules_lint"] +) + +use_config( + "config/nolint.axl", + "configure_dummy_lint", + conflicts = ["aspect_rules_lint"] +) diff --git a/axel-f/config.axl b/axel-f/config/builtins.axl similarity index 51% rename from axel-f/config.axl rename to axel-f/config/builtins.axl index a07f243f5..2dc9391ce 100644 --- a/axel-f/config.axl +++ b/axel-f/config/builtins.axl @@ -1,15 +1,16 @@ -"""Workflows Configuration""" +"""Configures builtin tasks for Workflows""" -load("./migrate.axl", "migrate") -load("./delivery.axl", "delivery") -load("./platform-config.axl", +load("../tasks/migrate.axl", "migrate") + +load("../lib/platform.axl", "read_platform_config", "read_host_config", "get_bazelrc_flags", "DEFAULT_PLATFORM_DIR" ) + load( - "./github.axl", + "../lib/github.axl", "create_check_run", "update_check_run", "complete_check_run", @@ -18,66 +19,6 @@ load( "create_review", "build_suggestion", ) -load( - "./sarif.axl", - "sarif_to_annotations", - "get_sarif_summary" -) -load( - "@aspect_rules_lint//lint/lint.axl", - "StrategyHoldTheLine", -) -load("./lint_strategy.axl", "make_github_strategy", "make_github_changed_files_provider") - -def _check_deliveryd_health(ctx, socket_path): - """ - Check if deliveryd is healthy by calling the /health endpoint. - - Returns: - True if healthy, False otherwise - """ - http = ctx.http() - response = http.get( - url="http://localhost/health", - unix_socket=socket_path, - ) - - result = response.map_err(lambda e: str(e)).block() - if type(result) == "string": - return False - return result.status >= 200 and result.status < 300 - -def _start_deliveryd(ctx, delivery_db_endpoint, socket_path = "/tmp/deliveryd.sock"): - """ - Start the deliveryd process in the background if not already running. - - Args: - ctx: Config context - delivery_db_endpoint: Redis endpoint URL (redis:// or rediss:// for TLS) - socket_path: Unix socket path for deliveryd - """ - # Check if deliveryd is already running by checking for the socket - if ctx.std.fs.exists(socket_path): - # Socket exists, check if the instance is healthy - if _check_deliveryd_health(ctx, socket_path): - print("deliveryd already running and healthy (socket: {})".format(socket_path)) - return - else: - # Stale socket, remove it - print("deliveryd socket exists but instance is unhealthy, removing stale socket") - ctx.std.fs.remove_file(socket_path) - - cmd = ctx.std.process.command("deliveryd") - cmd.arg("--socket=" + socket_path) - cmd.arg("--redis-endpoint=" + delivery_db_endpoint) - - # Run in background - cmd.stdout("null") - cmd.stderr("null") - cmd.spawn() - - print("Started deliveryd (socket: {}, endpoint: {})".format(socket_path, delivery_db_endpoint)) - def _format_build_state(build_state): md = """ @@ -153,27 +94,13 @@ def on_build_event(ctx: TaskContext, build_state: dict, event): print(r) -# ============================================================================= -# Config -# ============================================================================= - -def config(ctx: ConfigContext): +def configure_builtins(ctx: ConfigContext): ctx.tasks.add(migrate) - ctx.tasks.add(delivery) CI = ctx.std.env.var("BUILDKITE") - if CI: - print("--- :aspect-build: Configuring Workflows") - # Read platform config from disk platform_config = read_platform_config(ctx.std.fs) - - # Start deliveryd if delivery_db_endpoint is configured - delivery_db_endpoint = platform_config.get("delivery_db_endpoint") - if delivery_db_endpoint: - _start_deliveryd(ctx, delivery_db_endpoint) - # Read host config from environment host_config = read_host_config(ctx.std.env, ctx.std.io) @@ -213,28 +140,4 @@ def config(ctx: ConfigContext): task.config.flags = lambda f: flags(f, "build") task.config.build_start = lambda: print("+++ :bazel: Building") task.config.build_event_sinks = build_event_sinks - task.config.build_event = on_build_event - if task.name == "delivery": - task.config.delivery_start = lambda: print("--- :bazel: Delivery") - if task.name == "lint": - github_token = ctx.std.env.var("GITHUB_TOKEN") - if github_token: - # CI mode: GitHub-aware strategy with hold-the-line - github_repository = ctx.std.env.var("GITHUB_REPOSITORY") or "" - repo_parts = github_repository.split("/") - gh_owner = repo_parts[0] if len(repo_parts) >= 2 else "" - gh_repo = repo_parts[1] if len(repo_parts) >= 2 else "" - - task.config.strategy = make_github_strategy( - StrategyHoldTheLine, - token = github_token, - owner = gh_owner, - repo = gh_repo, - mode = "streaming", - ) - task.config.changed_files_provider = make_github_changed_files_provider( - token = github_token, - owner = gh_owner, - repo = gh_repo, - ) - # else: local dev uses defaults (StrategyHoldTheLine + GitDiffProvider) + task.config.build_event = on_build_event \ No newline at end of file diff --git a/axel-f/config/delivery.axl b/axel-f/config/delivery.axl new file mode 100644 index 000000000..69da960ad --- /dev/null +++ b/axel-f/config/delivery.axl @@ -0,0 +1,97 @@ +"""Configures delivery task for Workflows""" + +load("../tasks/delivery.axl", "delivery") +load("../lib/platform.axl", + "read_platform_config", + "read_host_config", + "get_bazelrc_flags", + "DEFAULT_PLATFORM_DIR" +) + +def _check_deliveryd_health(ctx, socket_path): + """ + Check if deliveryd is healthy by calling the /health endpoint. + + Returns: + True if healthy, False otherwise + """ + http = ctx.http() + response = http.get( + url="http://localhost/health", + unix_socket=socket_path, + ) + + result = response.map_err(lambda e: str(e)).block() + if type(result) == "string": + return False + return result.status >= 200 and result.status < 300 + +def _start_deliveryd(ctx, delivery_db_endpoint, socket_path = "/tmp/deliveryd.sock"): + """ + Start the deliveryd process in the background if not already running. + + Args: + ctx: Config context + delivery_db_endpoint: Redis endpoint URL (redis:// or rediss:// for TLS) + socket_path: Unix socket path for deliveryd + """ + # Check if deliveryd is already running by checking for the socket + if ctx.std.fs.exists(socket_path): + # Socket exists, check if the instance is healthy + if _check_deliveryd_health(ctx, socket_path): + print("deliveryd already running and healthy (socket: {})".format(socket_path)) + return + else: + # Stale socket, remove it + print("deliveryd socket exists but instance is unhealthy, removing stale socket") + ctx.std.fs.remove_file(socket_path) + + cmd = ctx.std.process.command("deliveryd") + cmd.arg("--socket=" + socket_path) + cmd.arg("--redis-endpoint=" + delivery_db_endpoint) + + # Run in background + cmd.stdout("null") + cmd.stderr("null") + cmd.spawn() + + print("Started deliveryd (socket: {}, endpoint: {})".format(socket_path, delivery_db_endpoint)) + +def configure_delivery(ctx: ConfigContext): + # Add a delivery verb + ctx.tasks.add(delivery) + + CI = ctx.std.env.var("BUILDKITE") + + if CI: + print("--- :aspect-build: Configuring Workflows") + + # Read platform config from disk + platform_config = read_platform_config(ctx.std.fs) + + # Start deliveryd if delivery_db_endpoint is configured + delivery_db_endpoint = platform_config.get("delivery_db_endpoint") + if delivery_db_endpoint: + _start_deliveryd(ctx, delivery_db_endpoint) + + # Read host config from environment + host_config = read_host_config(ctx.std.env, ctx.std.io) + + # Generate bazelrc content + # TODO: use these flags? + flags = get_bazelrc_flags( + platform_config = platform_config, + host_config = host_config, + bazel_version = "7.0.0", + ) + + # Debugging information + if CI: + print(platform_config) + print(host_config) + print(flags) + + + for task in ctx.tasks: + if task.name == "delivery": + task.config.delivery_start = lambda: print("--- :bazel: Delivery") diff --git a/axel-f/config/lint.axl b/axel-f/config/lint.axl new file mode 100644 index 000000000..380f774f5 --- /dev/null +++ b/axel-f/config/lint.axl @@ -0,0 +1,132 @@ +"""Configures rules_lint if its available""" + +load("../lib/platform.axl", + "read_platform_config", + "read_host_config", + "get_bazelrc_flags", + "DEFAULT_PLATFORM_DIR" +) +load( + "../lib/github.axl", + "create_check_run", + "update_check_run", + "complete_check_run", + "build_output", + "build_annotation", + "create_review", + "build_suggestion", +) +load( + "../lib/sarif.axl", + "sarif_to_annotations", + "get_sarif_summary" +) +load( + "@aspect_rules_lint//lint/lint.axl", + "StrategyHoldTheLine", +) +load("../lib/linting.axl", "make_github_strategy", "make_github_changed_files_provider") + + + +def _check_deliveryd_health(ctx, socket_path): + """ + Check if deliveryd is healthy by calling the /health endpoint. + + Returns: + True if healthy, False otherwise + """ + http = ctx.http() + response = http.get( + url="http://localhost/health", + unix_socket=socket_path, + ) + + result = response.map_err(lambda e: str(e)).block() + if type(result) == "string": + return False + return result.status >= 200 and result.status < 300 + +def _start_deliveryd(ctx, delivery_db_endpoint, socket_path = "/tmp/deliveryd.sock"): + """ + Start the deliveryd process in the background if not already running. + + Args: + ctx: Config context + delivery_db_endpoint: Redis endpoint URL (redis:// or rediss:// for TLS) + socket_path: Unix socket path for deliveryd + """ + # Check if deliveryd is already running by checking for the socket + if ctx.std.fs.exists(socket_path): + # Socket exists, check if the instance is healthy + if _check_deliveryd_health(ctx, socket_path): + print("deliveryd already running and healthy (socket: {})".format(socket_path)) + return + else: + # Stale socket, remove it + print("deliveryd socket exists but instance is unhealthy, removing stale socket") + ctx.std.fs.remove_file(socket_path) + + cmd = ctx.std.process.command("deliveryd") + cmd.arg("--socket=" + socket_path) + cmd.arg("--redis-endpoint=" + delivery_db_endpoint) + + # Run in background + cmd.stdout("null") + cmd.stderr("null") + cmd.spawn() + + print("Started deliveryd (socket: {}, endpoint: {})".format(socket_path, delivery_db_endpoint)) + + +def configure_rules_lint(ctx: ConfigContext): + CI = ctx.std.env.var("BUILDKITE") + + # Read platform config from disk + platform_config = read_platform_config(ctx.std.fs) + + # Start deliveryd if delivery_db_endpoint is configured + delivery_db_endpoint = platform_config.get("delivery_db_endpoint") + if delivery_db_endpoint: + _start_deliveryd(ctx, delivery_db_endpoint) + + # Read host config from environment + host_config = read_host_config(ctx.std.env, ctx.std.io) + + # Generate bazelrc content + flags = get_bazelrc_flags( + platform_config = platform_config, + host_config = host_config, + bazel_version = "7.0.0", + ) + + # Debugging information + if CI: + print(platform_config) + print(host_config) + print(flags) + + + for task in ctx.tasks: + if task.name == "lint": + github_token = ctx.std.env.var("GITHUB_TOKEN") + if github_token: + # CI mode: GitHub-aware strategy with hold-the-line + github_repository = ctx.std.env.var("GITHUB_REPOSITORY") or "" + repo_parts = github_repository.split("/") + gh_owner = repo_parts[0] if len(repo_parts) >= 2 else "" + gh_repo = repo_parts[1] if len(repo_parts) >= 2 else "" + + task.config.strategy = make_github_strategy( + StrategyHoldTheLine, + token = github_token, + owner = gh_owner, + repo = gh_repo, + mode = "streaming", + ) + task.config.changed_files_provider = make_github_changed_files_provider( + token = github_token, + owner = gh_owner, + repo = gh_repo, + ) + # else: local dev uses defaults (StrategyHoldTheLine + GitDiffProvider) diff --git a/axel-f/config/nolint.axl b/axel-f/config/nolint.axl new file mode 100644 index 000000000..bf7ae89df --- /dev/null +++ b/axel-f/config/nolint.axl @@ -0,0 +1,8 @@ +"""Configures a dummy lint verb for migration.""" + +load("../tasks/dummy_lint.axl", "lint") +load("../tasks/dummy_format.axl", "format") + +def configure_dummy_lint(ctx: ConfigContext): + ctx.tasks.add(lint) + ctx.tasks.add(format) \ No newline at end of file diff --git a/axel-f/docs/lint-task.md b/axel-f/docs/lint-task.md new file mode 100644 index 000000000..458d2ded3 --- /dev/null +++ b/axel-f/docs/lint-task.md @@ -0,0 +1,199 @@ +# Lint Task + +This document describes how the lint task works within the Rosetta workflow system. It is aimed at internal engineers who maintain or extend the task. + +## Overview + +The lint task wraps `aspect lint` — a Bazel-native linting command — and adds CI-aware behavior on top of it. Its primary job is to: + +1. Run `aspect lint` against a set of Bazel targets. +2. Parse the structured lint output (a JSON diagnostics file produced from SARIF). +3. Decide which diagnostics are relevant to the current change. +4. Determine whether the task should pass or fail. +5. Surface results as GitHub check annotations and PR review suggestions. + +## Configuration + +The lint task is configured through a schema that extends the base Bazel task configuration. The lint-specific fields are: + +| Field | Type | Default | Description | +|---|---|---|---| +| `targets` | `string[]` | `['//...']` | Bazel target patterns to lint. | +| `failure_strategy` | `'soft' \| 'hard' \| 'hold_the_line'` | `'hold_the_line'` | Controls when a lint failure causes the task to go red. See [Failure Strategies](#failure-strategies). | +| `only_annotate_changed_regions` | `boolean` | `true` | When true, GitHub annotations are scoped to files changed in the current PR. When false, all lint issues are annotated. | +| `icon` | `string` | `'broom'` | Emoji used in the task label. | + +## Failure Strategies + +### The problem + +Large codebases accumulate lint violations over time. Turning on a new linter — or tightening rules — would flag thousands of pre-existing issues. If the build went red for all of them, the lint task would be unusable until every legacy violation was cleaned up. That is rarely practical. + +At the same time, purely advisory linting ("soft" mode) is easy to ignore, and violations continue to pile up. + +### Hold the line + +The default strategy, `hold_the_line`, is a middle ground. It answers the question: *"Did this PR make things worse?"* + +- On a PR build, the task compares lint errors against the set of files changed in the PR. If any error-severity diagnostics come from changed files, the task fails. +- On a non-PR build (e.g. a post-merge CI run on `main`), the task never fails, because there is no meaningful "changed file" set to compare against. + +This lets teams adopt new linters immediately. Existing violations are tolerated, but new ones are blocked at the PR gate. Over time, the codebase improves organically as engineers touch files and fix violations along the way. + +#### How hold the line is implemented + +The mechanism relies on three things: PR detection, a git diff, and a two-tier filtering model. + +**PR detection.** The task asks the host (e.g. the GitHub Actions host) whether this is a PR build. On GitHub Actions, this is determined by inspecting the `GITHUB_REF` environment variable. If it matches the pattern `refs/pull//merge`, the build is a PR build. On non-PR builds (branch pushes, scheduled runs, manual triggers), hold-the-line never fails — there is no changed-file set to compare against. + +**Git diff.** The task lazily generates a diff by running `git diff HEAD~ HEAD` and writing the result to a temporary file. The diff is parsed into a list of `{ file, lines }` tuples, where `lines` contains the 0-based line numbers of *added* lines only (not removed or context lines). Deleted files are excluded entirely. + +**Two-tier filtering.** The task applies two different predicates depending on the diagnostic type: + +- *File-level matching* (used for annotations): A diagnostic matches if its source file path appears anywhere in the diff. This is a loose check — the error doesn't need to be on a changed line, just in a changed file. +- *Line-level matching* (used for suggestions): A diagnostic matches only if its source file *and* specific line number both appear in the diff. This is strict — the suggestion must point at a line the author actually added. + +**The failure decision.** The `shouldFail` method receives two lists: `filteredDiagnostics` (only diagnostics from changed files/lines) and `allDiagnostics` (every diagnostic found). Under hold-the-line, it checks whether the build is a PR and whether `filteredDiagnostics` contains any error-severity entries. Under hard mode, it checks `allDiagnostics` instead. Under soft mode, it always returns false. + +### Soft + +The task never fails, regardless of how many lint errors exist. Diagnostics are still collected and surfaced as GitHub annotations/suggestions, but the build stays green. + +### Hard + +The task fails if *any* error-severity diagnostic exists, regardless of whether the error comes from a changed file. This is appropriate for codebases that are already clean and want to enforce zero lint errors at all times. + +### Summary + +| Strategy | Fails on PR builds? | Fails on non-PR builds? | +|---|---|---| +| `soft` | Never | Never | +| `hold_the_line` | Only if errors are from changed files | Never | +| `hard` | If any errors exist | If any errors exist | + +## Bazel Invocation + +The task constructs a Bazel command with two additional flags beyond what the base task provides: + +- `--machine` — Requests structured (machine-readable) output from the CLI. +- `--lint_diagnostics_file=` — Tells the CLI to write lint results as a JSON file to a temporary path. This file is the primary input for all downstream processing. + +The temporary path is deterministic and namespaced by workspace and task ID to avoid collisions when multiple lint tasks run in the same pipeline. + +## From SARIF to GitHub Comments + +The path from linter output to GitHub annotations and suggestions spans three layers: the Aspect CLI (Go), the Rosetta lint task (TypeScript), and Marvin (the notification backend). This section traces the full journey. + +### Layer 1: Aspect CLI — SARIF to diagnostics + +Individual linters (eslint, flake8, etc.) produce SARIF reports and/or patch files. The Aspect CLI converts these into a unified diagnostics format before writing them to the JSON file specified by `--lint_diagnostics_file`. + +**SARIF reports become annotations.** The CLI walks each SARIF run's results and locations, producing one diagnostic per finding. The severity is mapped from the SARIF level (`error` becomes `ERROR`, everything else becomes `WARNING`). The source file comes from the artifact location URI. The line number comes from the region's `startLine`. Each diagnostic gets `baggage["lint_result_type"] = "annotation"` and `baggage["label"]` set to the originating Bazel target. + +**Patch files become suggestions.** When a linter emits a unified diff (a fix), the CLI parses the diff hunks and produces one diagnostic per hunk. The `help` field contains the suggested replacement text. The span's offset and height come from the diff line numbers. Each diagnostic gets `baggage["lint_result_type"] = "suggestion"`. + +The result is a JSON file with a top-level `diagnostics` array containing both annotations and suggestions, uniformly represented as `DiagnosticInput` objects. + +### Layer 2: Rosetta lint task — filtering and capping + +This is where the bulk of the logic described in this document lives. The lint task reads the diagnostics file, normalizes workspace paths, filters diagnostics against the git diff, sorts them, caps them, and determines pass/fail. The details are covered in [Diagnostics Processing](#diagnostics-processing). + +The output is a `lint-task-completed` event containing the processed diagnostics array, lint counts, repro/fix commands, and the pass/fail decision. This event is consumed by the Marvin listener. + +### Layer 3: Marvin — diagnostics to GitHub + +The Marvin listener receives the `lint-task-completed` event and forwards the diagnostics to the Marvin backend, which translates them into GitHub API calls. + +**Annotations become GitHub check annotations.** Diagnostics with `lint_result_type = "annotation"` (or no type) are posted as annotations on the GitHub check run. The severity maps to an annotation level: `ERROR` becomes `failure`, `WARNING` becomes `warning`, and everything else becomes `notice`. The annotation includes the file path, line range, title, and message. + +**Suggestions become GitHub PR review comments.** Diagnostics with `lint_result_type = "suggestion"` are posted as review comments on the pull request using the GitHub Pulls API. Each comment includes the file path, line number, span height (for multi-line suggestions), and the suggested replacement text from the `help` field. These render as GitHub's native suggestion blocks that the author can apply with one click. + +### Controlling what gets posted + +Two workflow-level configuration flags control whether diagnostics are surfaced on GitHub: + +- `notifications.github.annotations` (default `true`) — When false, no check run annotations are created. The lint task short-circuits annotation processing entirely and returns an empty list. +- `notifications.github.suggestions` (default `true`) — When false, no PR review suggestion comments are created. The lint task short-circuits suggestion processing entirely. + +A third flag, `notifications.github.show_aspect_cli_commands`, controls whether the repro and fix commands are included in the output. When false, these are omitted even if there are error-severity diagnostics. + +## Diagnostics Processing + +After Bazel finishes, the task reads the JSON diagnostics file. Processing happens in several stages. + +### 1. Parse + +The file contains a top-level `diagnostics` array. Each entry is a `DiagnosticInput` with fields like severity, message, title, source location, spans (line/column offsets), and a `baggage` map of arbitrary metadata. + +Two pieces of baggage are significant for lint: + +- `lint_result_type` — either `"annotation"` or `"suggestion"`. Annotations are "this is wrong" messages. Suggestions are "here is a fix" messages with replacement content. +- `label` — the Bazel label of the target that produced the diagnostic. Used to construct repro and fix commands. + +### 2. Workspace path normalization + +If the task runs in a subdirectory workspace (not the repo root), file paths in diagnostics need to be prefixed with the workspace path so they align with the repository-root-relative paths that GitHub expects. + +### 3. Changed file detection + +The task lazily generates a git diff (via `git diff HEAD~ HEAD`) that describes which files and lines changed in the current commit. The diff is parsed using the `parse-git-patch` library into a list of `{ file, lines }` tuples, where `lines` are the 0-based line numbers of added lines only. + +- **Changed file**: a diagnostic's source file appears anywhere in the diff. +- **Changed line**: a diagnostic's source file *and* specific line number (from the span offset) appear in the diff. Additionally, the diagnostic must have exactly one span with a valid offset. + +These two predicates are used differently depending on the diagnostic type (see below). + +### 4. Split into annotations and suggestions + +Diagnostics are partitioned by their `lint_result_type` baggage value. + +**Annotations** (errors and warnings): +- Filtered to changed *files* (not individual lines) when `only_annotate_changed_regions` is true. +- When `only_annotate_changed_regions` is false, all annotations are included. +- Capped at **25** per task invocation to avoid flooding the PR. +- The `help` field is stripped from annotations before publishing (suggestions carry help, annotations don't need it). + +**Suggestions** (auto-fixable issues): +- Always filtered to changed *lines* — suggestions are only relevant if they touch code the author just wrote. +- Capped at **10** per task invocation. +- The `message` field is stripped from suggestions before publishing (the suggestion content in `help` is the message). + +### 5. Sorting + +Both annotations and suggestions are sorted by a stable, multi-level comparator. The priority order (highest first) is: + +1. Diagnostic is from a changed line +2. Diagnostic is from a changed file +3. Higher severity (error > warning > info) +4. File path (alphabetical) +5. Line number (ascending) +6. Title, message, help (alphabetical tiebreakers) + +Because the lists are capped after sorting, this ordering ensures that the most relevant diagnostics — those closest to the author's changes and highest severity — survive the cut. + +### 6. Repro and fix commands + +If the workflow configuration has `show_aspect_cli_commands` enabled, the task constructs CLI commands users can run locally: + +- **Repro command**: `bazel lint ...` — reproduces the errors locally. Only includes targets from error-severity diagnostics, deduplicated. +- **Fix command**: Same as the repro command with `--fix` appended — auto-applies fixes where possible. + +## Error Handling + +The task handles several error scenarios: + +- **Non-lint Bazel failures** (exit codes other than 0 or the lint-specific failure code): The task fails immediately without attempting to parse diagnostics. No annotations or suggestions are produced. +- **Missing or unreadable diagnostics file**: The task fails. This typically indicates a CLI bug or a misconfigured pipeline. +- **Failed git diff parsing**: The task fails. A log diagnostic is emitted noting the failure. +- **Unexpected exceptions during diagnostic processing**: Caught and logged. The task fails conservatively. + +In all error cases, the `lint-task-completed` event is still published with `successful: false` and empty diagnostic lists, so Marvin receives a consistent signal and can update the check run accordingly. + +## Exit Code Mapping + +| Scenario | Bazel exit code | Task outcome | +|---|---|---| +| No lint issues | `0` (OK) | Pass | +| Lint issues found, strategy says pass | Lint failure code | Pass (exit code overridden to OK) | +| Lint issues found, strategy says fail | Lint failure code | Fail | +| Bazel internal error | Any other code | Fail | diff --git a/axel-f/docs/sarif-translation.md b/axel-f/docs/sarif-translation.md new file mode 100644 index 000000000..0306a485b --- /dev/null +++ b/axel-f/docs/sarif-translation.md @@ -0,0 +1,178 @@ +# SARIF to GitHub PR Comments Translation + +This document describes how to translate SARIF (Static Analysis Results Interchange Format) output from linters into GitHub PR review comments. + +## SARIF Input (from linter) + +```json +{ + "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", + "runs": [ + { + "tool": { + "driver": { + "name": "ESLint" + } + }, + "results": [ + { + "level": "error", + "message": { + "text": "'foo' is defined but never used" + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "src/index.ts" + }, + "region": { + "startLine": 5, + "startColumn": 7, + "endLine": 5, + "endColumn": 10 + } + } + } + ] + } + ] + } + ] +} +``` + +## GitHub PR Review API + +**Endpoint:** `POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews` + +**Payload:** +```json +{ + "commit_id": "abc123def456", + "event": "COMMENT", + "body": "Lint results", + "comments": [ + { + "path": "src/index.ts", + "line": 5, + "side": "RIGHT", + "body": "**ESLint** (error)\n\n'foo' is defined but never used" + } + ] +} +``` + +--- + +## Field Mapping: SARIF to GitHub + +| SARIF Path | GitHub Field | +|------------|--------------| +| `runs[].tool.driver.name` | Used in `comments[].body` prefix | +| `runs[].results[].level` | Used in `comments[].body` (error/warning) | +| `runs[].results[].message.text` | `comments[].body` content | +| `runs[].results[].locations[].physicalLocation.artifactLocation.uri` | `comments[].path` | +| `runs[].results[].locations[].physicalLocation.region.startLine` | `comments[].line` (single-line) or `comments[].start_line` (multi-line) | +| `runs[].results[].locations[].physicalLocation.region.endLine` | `comments[].line` (end of range) | + +--- + +## Patch Input (unified diff) + +```diff +--- a/src/index.ts ++++ b/src/index.ts +@@ -8,4 +8,3 @@ + const bar = 1; +-const unused = 2; +-const baz = unused + 1; ++const baz = bar + 1; +``` + +## GitHub PR Review with Suggestion + +```json +{ + "commit_id": "abc123def456", + "event": "COMMENT", + "comments": [ + { + "path": "src/index.ts", + "start_line": 9, + "line": 10, + "side": "RIGHT", + "body": "**ESLint**\n\n```suggestion\nconst baz = bar + 1;\n```" + } + ] +} +``` + +--- + +## Field Mapping: Patch to GitHub + +| Patch Component | GitHub Field | +|-----------------|--------------| +| `+++ b/path/to/file` (strip `b/`) | `comments[].path` | +| `@@ -8,4 +8,3 @@` new start line | `comments[].start_line` | +| Last affected line in hunk | `comments[].line` | +| Lines starting with `+` (without the `+`) | Content inside ` ```suggestion ``` ` block | + +--- + +## Multi-line Example + +**SARIF with range:** +```json +{ + "runs": [{ + "tool": {"driver": {"name": "Ruff"}}, + "results": [{ + "level": "warning", + "message": {"text": "Multiple imports on one line"}, + "locations": [{ + "physicalLocation": { + "artifactLocation": {"uri": "src/main.py"}, + "region": { + "startLine": 1, + "endLine": 3 + } + } + }] + }] + }] +} +``` + +**GitHub comment (multi-line):** +```json +{ + "commit_id": "abc123", + "event": "COMMENT", + "comments": [{ + "path": "src/main.py", + "start_line": 1, + "line": 3, + "side": "RIGHT", + "body": "**Ruff** (warning)\n\nMultiple imports on one line" + }] +} +``` + +--- + +## GitHub Suggestion Syntax + +The `body` field uses GitHub's suggestion markdown: + +```markdown +**ToolName** + +```suggestion +replacement code here +line 2 of replacement +``` +``` + +When rendered, GitHub displays an "Apply suggestion" button allowing one-click fixes. diff --git a/axel-f/docs/what_is_this.md b/axel-f/docs/what_is_this.md index cd8f13dcc..63ea1f8fb 100644 --- a/axel-f/docs/what_is_this.md +++ b/axel-f/docs/what_is_this.md @@ -15,12 +15,75 @@ It does not define its own tasks. Instead, it provides a `config.axl` that confi axel-f is an external package, shipped with the CLI by default but resolved through `MODULE.aspect` like any other dependency. The architecture: 1. **Rust runtime** - Starlark interpreter + native APIs (`ctx.bazel`, `ctx.http()`, `ctx.std.*`) -2. **Builtins** (compiled into the binary) - `build`, `test`, `axl add` -3. **External packages** (via `MODULE.aspect`) - axel-f, `aspect_rules_lint`, etc. +2. **Builtins** (compiled into the binary) - `@aspect` (build, test, axl add) and `@axel-f` (config) +3. **External packages** (via `MODULE.aspect`) - `aspect_rules_lint`, etc. 4. **Customer config** (`.aspect/config.axl`, optional) - customer-specific overrides and customization axel-f and packages like `aspect_rules_lint` are peers in the dependency graph. axel-f is the "batteries included" package that makes the built-in tasks work seamlessly in the Aspect Workflows environment. +## Packaging and embedding + +axel-f is a separate Rust crate that lives in its own repository. It is embedded into the CLI binary at compile time. + +### Crate structure + +``` +axel-f/ +├── Cargo.toml # crate definition +├── src/lib.rs # exports all .axl files via include_str! +├── MODULE.aspect # use_config() declarations +├── config.axl # main config function +├── lint_strategy.axl # lint strategy (GitHub-aware hold-the-line) +├── github.axl # GitHub API integration +├── sarif.axl # SARIF parsing +├── delivery.axl # artifact delivery +├── deliveryd.axl # delivery daemon client +├── migrate.axl # migration tooling +└── platform-config.axl # platform environment discovery +``` + +`src/lib.rs` is minimal — it exports a single constant: + +```rust +pub const FILES: &[(&str, &str)] = &[ + ("MODULE.aspect", include_str!("../MODULE.aspect")), + ("config.axl", include_str!("../config.axl")), + // ... all .axl files +]; +``` + +### How it ships + +The CLI's builtin system (`crates/axl-runtime/src/builtins/mod.rs`) treats axel-f the same as the `@aspect` builtin: + +- **Debug builds**: reads .axl files directly from the source tree (no extraction needed) +- **Release builds**: uses the `axel_f::FILES` constant (compiled into the binary via `include_str!`), extracts files to a content-hashed cache directory at runtime + +Both builtins are defined as `Builtin { name, files }` entries in a unified `ALL` array. A single loop handles hashing and extraction for all builtins. + +### Dependency tracking + +During development, the CLI workspace references axel-f as a local path dependency: + +```toml +# crates/axl-runtime/Cargo.toml +axel-f = { path = "../../axel-f" } +``` + +When axel-f moves to its own repo, this changes to a git reference: + +```toml +axel-f = { git = "https://github.com/aspect-build/axel-f", tag = "v0.1.0" } +``` + +The CLI can also use a git submodule pointing to the axel-f repo, with the Cargo.toml path pointing at the submodule checkout. This gives reproducible builds with a pinned commit SHA while keeping the repos independent. + +### Auto-enable + +Both `@aspect` and `@axel-f` builtins are auto-enabled for `use_config`. This is set in `disk_store.rs` where builtin deps are constructed with `use_config: true`. Customers don't need to declare anything — builtin configs just work. External packages (non-builtins) still require explicit `use_config = True` on the dep declaration in the customer's `MODULE.aspect`. + +If a customer explicitly declares a dep with the same name as a builtin (e.g. `axl_archive_dep(name = "axel-f", ...)`), the customer's dep overrides the builtin. In that case, the customer controls the `use_config` flag — the auto-enable only applies to the default builtin version. + ## What it does NOT do - Define core tasks (`build`, `test`, `lint`) - those are builtins or come from other packages @@ -33,7 +96,7 @@ axel-f and packages like `aspect_rules_lint` are peers in the dependency graph. ## Opt-in via use_config -Config evaluation from external packages is **never automatic**. A package having a `config.axl` file does nothing on its own. Two explicit declarations are required: +Config evaluation from external packages requires explicit opt-in. A package having a `config.axl` file does nothing on its own. Two declarations are required (builtins like `@aspect` and `@axel-f` are the exception — they are auto-enabled): ### Package side: declaring config availability @@ -102,7 +165,7 @@ Without `use_config = True`, the package's `use_config()` directives are ignored ### axel-f is auto-enabled -axel-f ships with the CLI as the default configuration package. Its `use_config` is automatically enabled - customers do not need to set `use_config = True` for it. Customers can disable it if needed. +axel-f ships with the CLI as a builtin (see [Packaging and embedding](#packaging-and-embedding)). Its `use_config` is automatically enabled via `disk_store.rs` — customers do not need to set `use_config = True` for it. If a customer overrides the builtin by declaring their own `axl_archive_dep(name = "axel-f", ...)`, auto-enable is replaced by the customer's explicit `use_config` flag. ### Config activation is not transitive diff --git a/axel-f/deliveryd.axl b/axel-f/lib/deliveryd.axl similarity index 100% rename from axel-f/deliveryd.axl rename to axel-f/lib/deliveryd.axl diff --git a/axel-f/github.axl b/axel-f/lib/github.axl similarity index 100% rename from axel-f/github.axl rename to axel-f/lib/github.axl diff --git a/axel-f/lint_strategy.axl b/axel-f/lib/linting.axl similarity index 100% rename from axel-f/lint_strategy.axl rename to axel-f/lib/linting.axl diff --git a/axel-f/platform-config.axl b/axel-f/lib/platform.axl similarity index 100% rename from axel-f/platform-config.axl rename to axel-f/lib/platform.axl diff --git a/axel-f/sarif.axl b/axel-f/lib/sarif.axl similarity index 100% rename from axel-f/sarif.axl rename to axel-f/lib/sarif.axl diff --git a/axel-f/src/lib.rs b/axel-f/src/lib.rs new file mode 100644 index 000000000..44d8f78f2 --- /dev/null +++ b/axel-f/src/lib.rs @@ -0,0 +1,31 @@ +pub const FILES: &[(&str, &str)] = &[ + ("MODULE.aspect", include_str!("../MODULE.aspect")), + // config/ + ( + "config/builtins.axl", + include_str!("../config/builtins.axl"), + ), + ( + "config/delivery.axl", + include_str!("../config/delivery.axl"), + ), + ("config/lint.axl", include_str!("../config/lint.axl")), + ("config/nolint.axl", include_str!("../config/nolint.axl")), + // tasks/ + ("tasks/delivery.axl", include_str!("../tasks/delivery.axl")), + ("tasks/migrate.axl", include_str!("../tasks/migrate.axl")), + ( + "tasks/dummy_lint.axl", + include_str!("../tasks/dummy_lint.axl"), + ), + ( + "tasks/dummy_format.axl", + include_str!("../tasks/dummy_format.axl"), + ), + // lib/ + ("lib/deliveryd.axl", include_str!("../lib/deliveryd.axl")), + ("lib/github.axl", include_str!("../lib/github.axl")), + ("lib/linting.axl", include_str!("../lib/linting.axl")), + ("lib/platform.axl", include_str!("../lib/platform.axl")), + ("lib/sarif.axl", include_str!("../lib/sarif.axl")), +]; diff --git a/axel-f/delivery.axl b/axel-f/tasks/delivery.axl similarity index 99% rename from axel-f/delivery.axl rename to axel-f/tasks/delivery.axl index ce863ef00..c6627c511 100644 --- a/axel-f/delivery.axl +++ b/axel-f/tasks/delivery.axl @@ -8,7 +8,7 @@ Uses deliveryd (Unix socket HTTP server) for all delivery state operations. """ load( - "./deliveryd.axl", + "../lib/deliveryd.axl", deliveryd_query = "query", deliveryd_deliver = "deliver", deliveryd_record = "record", diff --git a/axel-f/tasks/dummy_format.axl b/axel-f/tasks/dummy_format.axl new file mode 100644 index 000000000..5d6470063 --- /dev/null +++ b/axel-f/tasks/dummy_format.axl @@ -0,0 +1,22 @@ +""" +A stub 'format' task registered when aspect_rules_lint is not installed. +Prints a helpful message directing the user to install the lint package. +""" + +def _format_impl(ctx: TaskContext) -> int: + ctx.std.io.stderr.write("Error: The format task requires the aspect_rules_lint package.\n") + ctx.std.io.stderr.write("\n") + ctx.std.io.stderr.write("Install it by running:\n") + ctx.std.io.stderr.write("\n") + ctx.std.io.stderr.write(" aspect axl add gh:aspect-build/rules_lint\n") + ctx.std.io.stderr.write("\n") + return 1 + +format = task( + name = "format", + implementation = _format_impl, + description = "Format source code (requires aspect_rules_lint)", + args = { + "all": args.positional(minimum = 0, maximum = 1000) + } +) diff --git a/axel-f/tasks/dummy_lint.axl b/axel-f/tasks/dummy_lint.axl new file mode 100644 index 000000000..345211053 --- /dev/null +++ b/axel-f/tasks/dummy_lint.axl @@ -0,0 +1,22 @@ +""" +A stub 'lint' task registered when aspect_rules_lint is not installed. +Prints a helpful message directing the user to install the lint package. +""" + +def _lint_impl(ctx: TaskContext) -> int: + ctx.std.io.stderr.write("Error: The lint task requires the aspect_rules_lint package.\n") + ctx.std.io.stderr.write("\n") + ctx.std.io.stderr.write("Install it by running:\n") + ctx.std.io.stderr.write("\n") + ctx.std.io.stderr.write(" aspect axl add gh:aspect-build/rules_lint\n") + ctx.std.io.stderr.write("\n") + return 1 + +lint = task( + name = "lint", + implementation = _lint_impl, + description = "Run linters (requires aspect_rules_lint)", + args = { + "all": args.positional(minimum = 0, maximum = 1000) + } +) diff --git a/axel-f/migrate.axl b/axel-f/tasks/migrate.axl similarity index 100% rename from axel-f/migrate.axl rename to axel-f/tasks/migrate.axl diff --git a/crates/aspect-cli/src/main.rs b/crates/aspect-cli/src/main.rs index fd12e73fb..f707e217f 100644 --- a/crates/aspect-cli/src/main.rs +++ b/crates/aspect-cli/src/main.rs @@ -3,7 +3,7 @@ mod flags; mod helpers; mod trace; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::env::var; use std::path::PathBuf; use std::process::ExitCode; @@ -14,7 +14,7 @@ use axl_runtime::engine::task_arg::TaskArg; use axl_runtime::engine::task_args::TaskArgs; use axl_runtime::eval::{self, FrozenTaskModuleLike, ModuleScope, execute_task_with_args}; use axl_runtime::module::{AXL_MODULE_FILE, AXL_ROOT_MODULE_NAME}; -use axl_runtime::module::{AxlModuleEvaluator, DiskStore}; +use axl_runtime::module::{AxlModuleEvaluator, DiskStore, UseConfigEntry}; use clap::{Arg, ArgAction, Command}; use miette::{IntoDiagnostic, miette}; use starlark::environment::FrozenModule; @@ -87,26 +87,29 @@ async fn main() -> miette::Result { .evaluate(AXL_ROOT_MODULE_NAME.to_string(), repo_root.clone()) .into_diagnostic()?; - // Expand all module dependencies (including the builtin @aspect module) to the disk store and collect their root paths. - // This results in a Vec of (String, PathBuf) such as - // [ - // ( "aspect", "/Users/username/Library/Caches/axl/deps/27e6d838c365a7c5d79674a7b6c7ec7b8d22f686dbcc8088a8d1454a6489a9ae/aspect" ), - // ( "experimental", "/Users/username/Library/Caches/axl/deps/27e6d838c365a7c5d79674a7b6c7ec7b8d22f686dbcc8088a8d1454a6489a9ae/experimental" ), - // ( "local", "/Users/username/Library/Caches/axl/deps/27e6d838c365a7c5d79674a7b6c7ec7b8d22f686dbcc8088a8d1454a6489a9ae/local" ), - // ] + // Expand all module dependencies (including builtins) to the disk store. + // Returns (name, path, use_config) for each module. let module_roots = disk_store .expand_store(&root_module_store) .await .into_diagnostic()?; - // Collect root and dependency modules into a vector of modules with exported tasks. + // Build the set of deps with use_config enabled (as determined by disk_store) + let use_config_deps: HashSet = module_roots + .iter() + .filter(|(_, _, use_config)| *use_config) + .map(|(name, _, _)| name.clone()) + .collect(); + + // Collect root and dependency modules into a vector of modules with exported tasks and configs. let mut modules = vec![( root_module_store.module_name, root_module_store.module_root, root_module_store.tasks.take(), + root_module_store.configs.take(), )]; - for (name, root) in module_roots { + for (name, root, _) in module_roots { let module_store = module_eval.evaluate(name, root).into_diagnostic()?; if debug_mode() { eprintln!( @@ -118,6 +121,7 @@ async fn main() -> miette::Result { module_store.module_name, module_store.module_root, module_store.tasks.take(), + module_store.configs.take(), )) } @@ -175,7 +179,11 @@ async fn main() -> miette::Result { HashMap)>, )> = vec![]; - for (module_name, module_root, map) in modules.into_iter() { + // Collect configs from each module for use_config processing + let mut module_configs: Vec<(String, PathBuf, Vec)> = vec![]; + + for (module_name, module_root, map, configs) in modules.into_iter() { + module_configs.push((module_name.clone(), module_root.clone(), configs)); let mut mmap = HashMap::new(); for (path, (label, symbols)) in map.into_iter() { let rel_path = path.strip_prefix(&module_root).unwrap().to_path_buf(); @@ -239,18 +247,74 @@ async fn main() -> miette::Result { } } - // Build scoped configs list combining regular configs and env configs + // Build scoped configs: package configs first (from use_config), then customer configs last let root_scope = ModuleScope { name: AXL_ROOT_MODULE_NAME.to_string(), path: repo_root.clone(), }; - let mut scoped_configs: Vec<(ModuleScope, PathBuf)> = configs + // Collect resolved package names for requires/conflicts checking + let resolved_packages: HashSet = module_configs .iter() - .map(|path| (root_scope.clone(), path.clone())) + .map(|(name, _, _)| name.clone()) .collect(); - // Run environment configs, each with scope derived from parent directory + // Build package configs from use_config() declarations (dependency order, leaves first) + let mut scoped_configs: Vec<(ModuleScope, PathBuf, String)> = vec![]; + + for (module_name, module_root, configs_entries) in &module_configs { + // Skip if root module didn't enable use_config for this dep (root module is always allowed) + if module_name != AXL_ROOT_MODULE_NAME && !use_config_deps.contains(module_name) { + continue; + } + for entry in configs_entries { + // Check requires: all referenced packages must be present + let requires_met = entry.requires.iter().all(|(pkg, version_constraint)| { + if !resolved_packages.contains(pkg) { + return false; + } + // Version constraint checking deferred until modules carry version metadata + if version_constraint.is_some() { + // TODO: implement version constraint checking with semver crate + // For now, presence check is sufficient + } + true + }); + // Check conflicts: all referenced packages must be absent + let conflicts_clear = entry + .conflicts + .iter() + .all(|pkg| !resolved_packages.contains(pkg)); + + if requires_met && conflicts_clear { + let scope = ModuleScope { + name: module_name.clone(), + path: module_root.clone(), + }; + let abs_path = module_root.join(&entry.path); + scoped_configs.push((scope, abs_path, entry.function.clone())); + + if debug_mode() { + eprintln!( + "use_config: @{} -> {} (fn: {})", + module_name, entry.path, entry.function + ); + } + } else if debug_mode() { + eprintln!( + "use_config: @{} -> {} SKIPPED (requires={}, conflicts={})", + module_name, entry.path, requires_met, conflicts_clear + ); + } + } + } + + // Append customer configs (filesystem-discovered) — always last + for path in configs.iter() { + scoped_configs.push((root_scope.clone(), path.clone(), "config".to_string())); + } + + // Append environment configs, each with scope derived from parent directory if debug_mode() && !env_configs.is_empty() { eprintln!("AXL_CONFIG configs:"); for path in &env_configs { @@ -269,7 +333,7 @@ async fn main() -> miette::Result { name: "".to_string(), path: parent.to_path_buf(), }; - scoped_configs.push((scope, config_path.clone())); + scoped_configs.push((scope, config_path.clone(), "config".to_string())); } // Run all config functions, passing in vector of tasks for configuration diff --git a/crates/axl-runtime/BUILD.bazel b/crates/axl-runtime/BUILD.bazel index aa6d73e65..464effc1b 100644 --- a/crates/axl-runtime/BUILD.bazel +++ b/crates/axl-runtime/BUILD.bazel @@ -47,6 +47,7 @@ rust_library( "//crates/build-event-stream", "//crates/galvanize", "//crates/aspect-telemetry", + "//axel-f" ], proc_macro_deps = [ "@crates//:starlark_derive", diff --git a/crates/axl-runtime/Cargo.toml b/crates/axl-runtime/Cargo.toml index c50da0e63..4113cb4e9 100644 --- a/crates/axl-runtime/Cargo.toml +++ b/crates/axl-runtime/Cargo.toml @@ -50,6 +50,7 @@ liquid-core = "0.26.11" minijinja = "2.12.0" aspect-telemetry = { path = "../aspect-telemetry" } +axel-f = { path = "../../axel-f" } axl-proto = { path = "../axl-proto" } build-event-stream = { path = "../build-event-stream" } galvanize = { path = "../galvanize" } @@ -59,6 +60,7 @@ dirs = "6.0.0" fibre = "0.5.0" flate2 = "1.1.2" rand = "0.8.5" +semver = "1" sha256 = "1.6.0" ssri = "9.2.0" base64 = "0.22.1" diff --git a/crates/axl-runtime/src/builtins/mod.rs b/crates/axl-runtime/src/builtins/mod.rs index f59c18a67..d5093dee8 100644 --- a/crates/axl-runtime/src/builtins/mod.rs +++ b/crates/axl-runtime/src/builtins/mod.rs @@ -1,17 +1,45 @@ use std::path::PathBuf; +/// A builtin module: name and its embedded files (relative path, content). +#[cfg(not(debug_assertions))] +struct Builtin { + name: &'static str, + files: &'static [(&'static str, &'static str)], +} + +#[cfg(not(debug_assertions))] +const ASPECT: Builtin = Builtin { + name: "aspect", + files: &[ + ("build.axl", include_str!("./aspect/build.axl")), + ("test.axl", include_str!("./aspect/test.axl")), + ("axl_add.axl", include_str!("./aspect/axl_add.axl")), + ("MODULE.aspect", include_str!("./aspect/MODULE.aspect")), + ], +}; + +#[cfg(not(debug_assertions))] +const AXEL_F: Builtin = Builtin { + name: "axel-f", + files: axel_f::FILES, +}; + +#[cfg(not(debug_assertions))] +const ALL: &[&Builtin] = &[&ASPECT, &AXEL_F]; + #[cfg(debug_assertions)] pub fn expand_builtins( _root_dir: PathBuf, _broot: PathBuf, ) -> std::io::Result> { - // Use CARGO_MANIFEST_DIR to locate builtins relative to this crate's source, - // not the user's project root (which could be /tmp or anywhere) let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - Ok(vec![( - "aspect".to_string(), - manifest_dir.join("src/builtins/aspect"), - )]) + Ok(vec![ + ( + "aspect".to_string(), + manifest_dir.join("src/builtins/aspect"), + ), + ("axel-f".to_string(), manifest_dir.join("../../axel-f")), + ]) } #[cfg(not(debug_assertions))] @@ -21,37 +49,35 @@ pub fn expand_builtins( ) -> std::io::Result> { use std::fs; - const BUILTINS: &[(&str, &str)] = &[ - ("aspect/build.axl", include_str!("./aspect/build.axl")), - ("aspect/test.axl", include_str!("./aspect/test.axl")), - ("aspect/axl_add.axl", include_str!("./aspect/axl_add.axl")), - ( - "aspect/MODULE.aspect", - include_str!("./aspect/MODULE.aspect"), - ), - ]; - - // Hash content to ensure staleness is detected when files change, - // even without a version bump + // Hash all builtin content to detect staleness across versions let content_hash = { let mut combined = String::new(); - for (path, content) in BUILTINS { - combined.push_str(path); - combined.push_str(content); + for builtin in ALL { + combined.push_str(builtin.name); + for (path, content) in builtin.files { + combined.push_str(path); + combined.push_str(content); + } } sha256::digest(combined) }; let builtins_root = broot.join(content_hash); - // Only write if directory doesn't exist - content hash guarantees correctness - if !builtins_root.join("aspect").exists() { - for (path, content) in BUILTINS { - let out_path = builtins_root.join(path); - fs::create_dir_all(out_path.parent().unwrap())?; - fs::write(&out_path, content)?; + // Extract each builtin into its own directory + for builtin in ALL { + let dir = builtins_root.join(builtin.name); + if !dir.exists() { + for (path, content) in builtin.files { + let out_path = dir.join(path); + fs::create_dir_all(out_path.parent().unwrap())?; + fs::write(&out_path, content)?; + } } } - Ok(vec![("aspect".to_string(), builtins_root.join("aspect"))]) + Ok(ALL + .iter() + .map(|b| (b.name.to_string(), builtins_root.join(b.name))) + .collect()) } diff --git a/crates/axl-runtime/src/eval/config.rs b/crates/axl-runtime/src/eval/config.rs index bbb3c675e..cea51497c 100644 --- a/crates/axl-runtime/src/eval/config.rs +++ b/crates/axl-runtime/src/eval/config.rs @@ -54,7 +54,7 @@ impl<'l, 'p> ConfigEvaluator<'l, 'p> { /// The tasks are modified in place via set_attr calls from config functions. pub fn run_all( &self, - scoped_configs: Vec<(ModuleScope, PathBuf)>, + scoped_configs: Vec<(ModuleScope, PathBuf, String)>, tasks: Vec, ) -> Result, EvalError> { // Create temporary modules for evaluation @@ -81,7 +81,7 @@ impl<'l, 'p> ConfigEvaluator<'l, 'p> { } // Evaluate each config file with its associated scope - for (scope, path) in &scoped_configs { + for (scope, path, function_name) in &scoped_configs { self.loader.module_stack.borrow_mut().push(scope.clone()); let rel_path = path @@ -99,8 +99,8 @@ impl<'l, 'p> ConfigEvaluator<'l, 'p> { // Get the config function let def = frozen - .get("config") - .map_err(|_| EvalError::MissingSymbol("config".into()))?; + .get(function_name) + .map_err(|_| EvalError::MissingSymbol(function_name.clone()))?; let func = def.value(); diff --git a/crates/axl-runtime/src/module/disk_store.rs b/crates/axl-runtime/src/module/disk_store.rs index f7613062f..1d6e28f25 100644 --- a/crates/axl-runtime/src/module/disk_store.rs +++ b/crates/axl-runtime/src/module/disk_store.rs @@ -226,7 +226,7 @@ impl DiskStore { pub async fn expand_store( &self, store: &ModuleStore, - ) -> Result, StoreError> { + ) -> Result, StoreError> { let root = self.root(); fs::create_dir_all(&root).await?; fs::create_dir_all(self.deps_path()).await?; @@ -247,6 +247,7 @@ impl DiskStore { path: path, // Builtins tasks are always auto used auto_use_tasks: true, + use_config: true, }), ) }) @@ -261,11 +262,11 @@ impl DiskStore { let dep_path = self.dep_path(dep.name()); match dep { - Dep::Local(local) if local.auto_use_tasks => { - module_roots.push((local.name.clone(), dep_path.clone())) + Dep::Local(local) if local.auto_use_tasks || local.use_config => { + module_roots.push((local.name.clone(), dep_path.clone(), local.use_config)) } - Dep::Remote(remote) if remote.auto_use_tasks => { - module_roots.push((remote.name.clone(), dep_path.clone())) + Dep::Remote(remote) if remote.auto_use_tasks || remote.use_config => { + module_roots.push((remote.name.clone(), dep_path.clone(), remote.use_config)) } _ => {} }; diff --git a/crates/axl-runtime/src/module/eval.rs b/crates/axl-runtime/src/module/eval.rs index 4e8fa55cf..34864c4e8 100644 --- a/crates/axl-runtime/src/module/eval.rs +++ b/crates/axl-runtime/src/module/eval.rs @@ -21,7 +21,7 @@ use crate::module::Dep; use super::super::eval::{EvalError, validate_module_name}; -use super::store::{AxlArchiveDep, ModuleStore}; +use super::store::{AxlArchiveDep, ModuleStore, UseConfigEntry}; #[starlark_module] pub fn register_globals(globals: &mut GlobalsBuilder) { @@ -69,6 +69,7 @@ pub fn register_globals(globals: &mut GlobalsBuilder) { #[starlark(require = named)] urls: UnpackList, #[starlark(require = named)] dev: bool, #[starlark(require = named, default = false)] auto_use_tasks: bool, + #[starlark(require = named, default = false)] use_config: bool, #[starlark(require = named, default = String::new())] strip_prefix: String, eval: &mut Evaluator<'v, '_, '_>, ) -> anyhow::Result { @@ -107,6 +108,7 @@ pub fn register_globals(globals: &mut GlobalsBuilder) { integrity, dev: true, auto_use_tasks, + use_config, }), ); @@ -121,6 +123,7 @@ pub fn register_globals(globals: &mut GlobalsBuilder) { #[starlark(require = named)] name: String, #[starlark(require = named)] path: String, #[starlark(require = named, default = false)] auto_use_tasks: bool, + #[starlark(require = named, default = false)] use_config: bool, eval: &mut Evaluator<'v, '_, '_>, ) -> anyhow::Result { if name == AXL_ROOT_MODULE_NAME { @@ -149,6 +152,7 @@ pub fn register_globals(globals: &mut GlobalsBuilder) { name: name.clone(), path: abs_path, auto_use_tasks, + use_config, }), ); @@ -174,6 +178,59 @@ pub fn register_globals(globals: &mut GlobalsBuilder) { Ok(values::none::NoneType) } + + fn use_config<'v>( + #[starlark(require = pos)] path: String, + #[starlark(require = pos)] function: String, + #[starlark(require = named, default = UnpackList::default())] requires: UnpackList< + values::Value<'v>, + >, + #[starlark(require = named, default = UnpackList::default())] conflicts: UnpackList, + eval: &mut Evaluator<'v, '_, '_>, + ) -> anyhow::Result { + let store = ModuleStore::from_eval(eval)?; + let heap = eval.heap(); + + let mut parsed_requires = Vec::new(); + for req in requires.items { + if let Some(s) = req.unpack_str() { + parsed_requires.push((s.to_string(), None)); + } else if req.get_type() == "tuple" { + let len = req.length().map_err(|e| anyhow::anyhow!("{}", e))?; + if len != 2 { + anyhow::bail!( + "requires tuple must have exactly 2 elements (package, version_constraint)" + ); + } + let pkg = req + .at(heap.alloc(0), heap) + .map_err(|e| anyhow::anyhow!("{}", e))?; + let constraint = req + .at(heap.alloc(1), heap) + .map_err(|e| anyhow::anyhow!("{}", e))?; + let pkg = pkg.unpack_str().ok_or_else(|| { + anyhow::anyhow!("requires tuple first element must be a string") + })?; + let constraint = constraint.unpack_str().ok_or_else(|| { + anyhow::anyhow!("requires tuple second element must be a string") + })?; + parsed_requires.push((pkg.to_string(), Some(constraint.to_string()))); + } else { + anyhow::bail!( + "requires elements must be strings or tuples of (package, version_constraint)" + ); + } + } + + store.configs.borrow_mut().push(UseConfigEntry { + path, + function, + requires: parsed_requires, + conflicts: conflicts.items, + }); + + Ok(values::none::NoneType) + } } pub const AXL_MODULE_FILE: &str = "MODULE.aspect"; diff --git a/crates/axl-runtime/src/module/mod.rs b/crates/axl-runtime/src/module/mod.rs index 0dfc876b2..2c9298778 100644 --- a/crates/axl-runtime/src/module/mod.rs +++ b/crates/axl-runtime/src/module/mod.rs @@ -7,4 +7,4 @@ pub use eval::{ AXL_CONFIG_EXTENSION, AXL_MODULE_FILE, AXL_ROOT_MODULE_NAME, AXL_SCRIPT_EXTENSION, AXL_VERSION_EXTENSION, AxlModuleEvaluator, register_globals, }; -pub use store::{AxlArchiveDep, AxlLocalDep, Dep, ModuleStore}; +pub use store::{AxlArchiveDep, AxlLocalDep, Dep, ModuleStore, UseConfigEntry}; diff --git a/crates/axl-runtime/src/module/store.rs b/crates/axl-runtime/src/module/store.rs index 5b72d41ac..eeadd2501 100644 --- a/crates/axl-runtime/src/module/store.rs +++ b/crates/axl-runtime/src/module/store.rs @@ -14,6 +14,14 @@ use starlark::values::ProvidesStaticType; use starlark::values::StarlarkValue; use starlark::values::starlark_value; +#[derive(Clone, Debug)] +pub struct UseConfigEntry { + pub path: String, + pub function: String, + pub requires: Vec<(String, Option)>, + pub conflicts: Vec, +} + #[derive(Debug, ProvidesStaticType, Default)] pub struct ModuleStore { pub root_dir: PathBuf, @@ -21,6 +29,7 @@ pub struct ModuleStore { pub module_root: PathBuf, pub deps: Rc>>, pub tasks: Rc)>>>, + pub configs: Rc>>, } impl ModuleStore { @@ -31,6 +40,7 @@ impl ModuleStore { module_root, deps: Rc::new(RefCell::new(HashMap::new())), tasks: Rc::new(RefCell::new(HashMap::new())), + configs: Rc::new(RefCell::new(Vec::new())), } } @@ -46,6 +56,7 @@ impl ModuleStore { module_root: value.module_root.clone(), deps: Rc::clone(&value.deps), tasks: Rc::clone(&value.tasks), + configs: Rc::clone(&value.configs), }) } } @@ -63,6 +74,13 @@ impl Dep { Dep::Remote(remote) => &remote.name, } } + + pub fn use_config(&self) -> bool { + match self { + Dep::Local(local) => local.use_config, + Dep::Remote(remote) => remote.use_config, + } + } } #[derive(Clone, Debug, ProvidesStaticType, NoSerialize, Allocative, Display)] @@ -71,6 +89,7 @@ pub struct AxlLocalDep { pub name: String, pub path: PathBuf, pub auto_use_tasks: bool, + pub use_config: bool, } #[starlark_value(type = "AxlLocalDep")] @@ -88,6 +107,7 @@ pub struct AxlArchiveDep { pub name: String, pub strip_prefix: String, pub auto_use_tasks: bool, + pub use_config: bool, } #[starlark_value(type = "AxlArchiveDep")] From 872ab1997c3439765692d9ef4e4895db4c798df2 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Wed, 11 Feb 2026 13:01:00 -0800 Subject: [PATCH 58/65] spec mutable copy default --- MODULE.bazel.lock | 5 +- axel-f/config/builtins.axl | 26 ++--- axel-f/docs/what_is_this.md | 15 --- .../axl-runtime/src/builtins/aspect/build.axl | 102 +++++++++--------- crates/axl-runtime/src/engine/types/spec.rs | 56 +++++++++- 5 files changed, 119 insertions(+), 85 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 11c2fc884..cca6babee 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -104,7 +104,8 @@ "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", "https://bcr.bazel.build/modules/gazelle/0.45.0/MODULE.bazel": "ecd19ebe9f8e024e1ccffb6d997cc893a974bcc581f1ae08f386bdd448b10687", - "https://bcr.bazel.build/modules/gazelle/0.45.0/source.json": "111d182facc5f5e80f0b823d5f077b74128f40c3fd2eccc89a06f34191bd3392", + "https://bcr.bazel.build/modules/gazelle/0.47.0/MODULE.bazel": "b61bb007c4efad134aa30ee7f4a8e2a39b22aa5685f005edaa022fbd1de43ebc", + "https://bcr.bazel.build/modules/gazelle/0.47.0/source.json": "aeb2e5df14b7fb298625d75d08b9c65bdb0b56014c5eb89da9e5dd0572280ae6", "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", @@ -1207,6 +1208,7 @@ "hyper-tls_0.6.0": "{\"dependencies\":[{\"name\":\"bytes\",\"req\":\"^1\"},{\"name\":\"http-body-util\",\"req\":\"^0.1.0\"},{\"name\":\"hyper\",\"req\":\"^1\"},{\"features\":[\"client-legacy\",\"tokio\"],\"name\":\"hyper-util\",\"req\":\"^0.1.0\"},{\"features\":[\"http1\"],\"kind\":\"dev\",\"name\":\"hyper-util\",\"req\":\"^0.1.0\"},{\"name\":\"native-tls\",\"req\":\"^0.2.1\"},{\"name\":\"tokio\",\"req\":\"^1\"},{\"features\":[\"io-std\",\"macros\",\"io-util\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.0.0\"},{\"name\":\"tokio-native-tls\",\"req\":\"^0.3\"},{\"name\":\"tower-service\",\"req\":\"^0.3\"}],\"features\":{\"alpn\":[\"native-tls/alpn\"],\"vendored\":[\"native-tls/vendored\"]}}", "hyper-util_0.1.16": "{\"dependencies\":[{\"name\":\"base64\",\"optional\":true,\"req\":\"^0.22\"},{\"name\":\"bytes\",\"req\":\"^1.7.1\"},{\"kind\":\"dev\",\"name\":\"bytes\",\"req\":\"^1\"},{\"name\":\"futures-channel\",\"optional\":true,\"req\":\"^0.3\"},{\"name\":\"futures-core\",\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"futures-util\",\"optional\":true,\"req\":\"^0.3.16\"},{\"default_features\":false,\"features\":[\"alloc\"],\"kind\":\"dev\",\"name\":\"futures-util\",\"req\":\"^0.3.16\"},{\"name\":\"http\",\"req\":\"^1.0\"},{\"name\":\"http-body\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"http-body-util\",\"req\":\"^0.1.0\"},{\"name\":\"hyper\",\"req\":\"^1.6.0\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"hyper\",\"req\":\"^1.4.0\"},{\"name\":\"ipnet\",\"optional\":true,\"req\":\"^2.9\"},{\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2\"},{\"name\":\"percent-encoding\",\"optional\":true,\"req\":\"^2.3\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2.4\"},{\"kind\":\"dev\",\"name\":\"pnet_datalink\",\"req\":\"^0.35.0\",\"target\":\"cfg(any(target_os = \\\"linux\\\", target_os = \\\"macos\\\"))\"},{\"kind\":\"dev\",\"name\":\"pretty_env_logger\",\"req\":\"^0.5\"},{\"features\":[\"all\"],\"name\":\"socket2\",\"optional\":true,\"req\":\">=0.5.9, <0.7\"},{\"name\":\"system-configuration\",\"optional\":true,\"req\":\"^0.6.1\",\"target\":\"cfg(target_os = \\\"macos\\\")\"},{\"default_features\":false,\"name\":\"tokio\",\"optional\":true,\"req\":\"^1\"},{\"features\":[\"macros\",\"test-util\",\"signal\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4\"},{\"name\":\"tower-service\",\"optional\":true,\"req\":\"^0.3\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1\"},{\"name\":\"windows-registry\",\"optional\":true,\"req\":\"^0.5\",\"target\":\"cfg(windows)\"}],\"features\":{\"__internal_happy_eyeballs_tests\":[],\"client\":[\"hyper/client\",\"tokio/net\",\"dep:tracing\",\"dep:futures-channel\",\"dep:tower-service\"],\"client-legacy\":[\"client\",\"dep:socket2\",\"tokio/sync\",\"dep:libc\",\"dep:futures-util\"],\"client-proxy\":[\"client\",\"dep:base64\",\"dep:ipnet\",\"dep:percent-encoding\"],\"client-proxy-system\":[\"dep:system-configuration\",\"dep:windows-registry\"],\"default\":[],\"full\":[\"client\",\"client-legacy\",\"client-proxy\",\"client-proxy-system\",\"server\",\"server-auto\",\"server-graceful\",\"service\",\"http1\",\"http2\",\"tokio\",\"tracing\"],\"http1\":[\"hyper/http1\"],\"http2\":[\"hyper/http2\"],\"server\":[\"hyper/server\"],\"server-auto\":[\"server\",\"http1\",\"http2\"],\"server-graceful\":[\"server\",\"tokio/sync\"],\"service\":[\"dep:tower-service\"],\"tokio\":[\"dep:tokio\",\"tokio/rt\",\"tokio/time\"],\"tracing\":[\"dep:tracing\"]}}", "hyper_1.7.0": "{\"dependencies\":[{\"name\":\"atomic-waker\",\"optional\":true,\"req\":\"^1.1.2\"},{\"name\":\"bytes\",\"req\":\"^1.2\"},{\"kind\":\"dev\",\"name\":\"form_urlencoded\",\"req\":\"^1\"},{\"name\":\"futures-channel\",\"optional\":true,\"req\":\"^0.3\"},{\"features\":[\"sink\"],\"kind\":\"dev\",\"name\":\"futures-channel\",\"req\":\"^0.3\"},{\"name\":\"futures-core\",\"optional\":true,\"req\":\"^0.3.31\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"futures-util\",\"optional\":true,\"req\":\"^0.3\"},{\"default_features\":false,\"features\":[\"alloc\",\"sink\"],\"kind\":\"dev\",\"name\":\"futures-util\",\"req\":\"^0.3\"},{\"name\":\"h2\",\"optional\":true,\"req\":\"^0.4.2\"},{\"name\":\"http\",\"req\":\"^1\"},{\"name\":\"http-body\",\"req\":\"^1\"},{\"name\":\"http-body-util\",\"optional\":true,\"req\":\"^0.1\"},{\"kind\":\"dev\",\"name\":\"http-body-util\",\"req\":\"^0.1\"},{\"name\":\"httparse\",\"optional\":true,\"req\":\"^1.9\"},{\"name\":\"httpdate\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"itoa\",\"optional\":true,\"req\":\"^1\"},{\"name\":\"pin-project-lite\",\"optional\":true,\"req\":\"^0.2.4\"},{\"kind\":\"dev\",\"name\":\"pin-project-lite\",\"req\":\"^0.2.4\"},{\"name\":\"pin-utils\",\"optional\":true,\"req\":\"^0.1\"},{\"kind\":\"dev\",\"name\":\"pretty_env_logger\",\"req\":\"^0.5\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"features\":[\"const_generics\",\"const_new\"],\"name\":\"smallvec\",\"optional\":true,\"req\":\"^1.12\"},{\"kind\":\"dev\",\"name\":\"spmc\",\"req\":\"^0.3\"},{\"features\":[\"sync\"],\"name\":\"tokio\",\"req\":\"^1\"},{\"features\":[\"fs\",\"macros\",\"net\",\"io-std\",\"io-util\",\"rt\",\"rt-multi-thread\",\"sync\",\"time\",\"test-util\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4\"},{\"kind\":\"dev\",\"name\":\"tokio-util\",\"req\":\"^0.7.10\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1\"},{\"name\":\"want\",\"optional\":true,\"req\":\"^0.3\"}],\"features\":{\"capi\":[],\"client\":[\"dep:want\",\"dep:pin-project-lite\",\"dep:smallvec\"],\"default\":[],\"ffi\":[\"dep:http-body-util\",\"dep:futures-util\"],\"full\":[\"client\",\"http1\",\"http2\",\"server\"],\"http1\":[\"dep:atomic-waker\",\"dep:futures-channel\",\"dep:futures-core\",\"dep:httparse\",\"dep:itoa\",\"dep:pin-utils\"],\"http2\":[\"dep:futures-channel\",\"dep:futures-core\",\"dep:h2\"],\"nightly\":[],\"server\":[\"dep:httpdate\",\"dep:pin-project-lite\",\"dep:smallvec\"],\"tracing\":[\"dep:tracing\"]}}", + "hyperlocal_0.9.1": "{\"dependencies\":[{\"name\":\"hex\",\"req\":\"^0.4\"},{\"name\":\"http-body-util\",\"optional\":true,\"req\":\"^0.1\"},{\"name\":\"hyper\",\"req\":\"^1.3\"},{\"name\":\"hyper-util\",\"optional\":true,\"req\":\"^0.1.2\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2\"},{\"kind\":\"dev\",\"name\":\"thiserror\",\"req\":\"^1.0\"},{\"default_features\":false,\"features\":[\"net\"],\"name\":\"tokio\",\"req\":\"^1.35\"},{\"features\":[\"io-std\",\"io-util\",\"macros\",\"rt-multi-thread\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.35\"},{\"name\":\"tower-service\",\"optional\":true,\"req\":\"^0.3\"}],\"features\":{\"client\":[\"http-body-util\",\"hyper/client\",\"hyper/http1\",\"hyper-util/client-legacy\",\"hyper-util/http1\",\"hyper-util/tokio\",\"tower-service\"],\"default\":[\"client\",\"server\"],\"server\":[\"hyper/http1\",\"hyper/server\",\"hyper-util/tokio\"]}}", "iana-time-zone-haiku_0.1.2": "{\"dependencies\":[{\"kind\":\"build\",\"name\":\"cc\",\"req\":\"^1.0.79\"}],\"features\":{}}", "iana-time-zone_0.1.63": "{\"dependencies\":[{\"name\":\"android_system_properties\",\"req\":\"^0.1.5\",\"target\":\"cfg(target_os = \\\"android\\\")\"},{\"kind\":\"dev\",\"name\":\"chrono-tz\",\"req\":\"^0.10.1\"},{\"name\":\"core-foundation-sys\",\"req\":\"^0.8.6\",\"target\":\"cfg(target_vendor = \\\"apple\\\")\"},{\"kind\":\"dev\",\"name\":\"getrandom\",\"req\":\"^0.2.1\"},{\"features\":[\"js\"],\"kind\":\"dev\",\"name\":\"getrandom\",\"req\":\"^0.2.1\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"unknown\\\"))\"},{\"name\":\"iana-time-zone-haiku\",\"req\":\"^0.1.1\",\"target\":\"cfg(target_os = \\\"haiku\\\")\"},{\"name\":\"js-sys\",\"req\":\"^0.3.66\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"unknown\\\"))\"},{\"name\":\"log\",\"req\":\"^0.4.14\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"unknown\\\"))\"},{\"name\":\"wasm-bindgen\",\"req\":\"^0.2.89\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"unknown\\\"))\"},{\"kind\":\"dev\",\"name\":\"wasm-bindgen-test\",\"req\":\"^0.3.46\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"unknown\\\"))\"},{\"name\":\"windows-core\",\"req\":\">=0.56, <=0.61\",\"target\":\"cfg(target_os = \\\"windows\\\")\"}],\"features\":{\"fallback\":[]}}", "icu_collections_2.0.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5.0\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"default_features\":false,\"features\":[\"derive\"],\"name\":\"databake\",\"optional\":true,\"req\":\"^0.2.0\"},{\"default_features\":false,\"name\":\"displaydoc\",\"req\":\"^0.2.3\"},{\"kind\":\"dev\",\"name\":\"iai\",\"req\":\"^0.1.1\"},{\"default_features\":false,\"features\":[\"alloc\"],\"kind\":\"dev\",\"name\":\"postcard\",\"req\":\"^1.0.3\"},{\"default_features\":false,\"features\":[\"zerovec\"],\"name\":\"potential_utf\",\"req\":\"^0.1.1\"},{\"default_features\":false,\"features\":[\"derive\",\"alloc\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.110\"},{\"default_features\":false,\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0.110\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.45\"},{\"default_features\":false,\"features\":[\"parse\"],\"kind\":\"dev\",\"name\":\"toml\",\"req\":\"^0.8.0\"},{\"default_features\":false,\"features\":[\"derive\"],\"name\":\"yoke\",\"req\":\"^0.8.0\"},{\"default_features\":false,\"features\":[\"derive\"],\"name\":\"zerofrom\",\"req\":\"^0.1.3\"},{\"default_features\":false,\"features\":[\"derive\",\"yoke\"],\"name\":\"zerovec\",\"req\":\"^0.11.1\"}],\"features\":{\"alloc\":[\"zerovec/alloc\"],\"databake\":[\"dep:databake\",\"zerovec/databake\"],\"serde\":[\"dep:serde\",\"zerovec/serde\",\"potential_utf/serde\",\"alloc\"]}}", @@ -1391,6 +1393,7 @@ "security-framework_2.11.1": "{\"dependencies\":[{\"name\":\"bitflags\",\"req\":\"^2.6\"},{\"name\":\"core-foundation\",\"req\":\"^0.9.4\"},{\"name\":\"core-foundation-sys\",\"req\":\"^0.8.6\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.10\"},{\"kind\":\"dev\",\"name\":\"hex\",\"req\":\"^0.4.3\"},{\"name\":\"libc\",\"req\":\"^0.2.139\"},{\"name\":\"log\",\"optional\":true,\"req\":\"^0.4.20\"},{\"name\":\"num-bigint\",\"optional\":true,\"req\":\"^0.4.6\"},{\"default_features\":false,\"name\":\"security-framework-sys\",\"req\":\"^2.11.1\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.3.0\"},{\"kind\":\"dev\",\"name\":\"time\",\"req\":\"^0.3.17\"},{\"kind\":\"dev\",\"name\":\"x509-parser\",\"req\":\"^0.16\"}],\"features\":{\"OSX_10_10\":[\"OSX_10_9\",\"security-framework-sys/OSX_10_10\"],\"OSX_10_11\":[\"OSX_10_10\",\"security-framework-sys/OSX_10_11\"],\"OSX_10_12\":[\"OSX_10_11\",\"security-framework-sys/OSX_10_12\"],\"OSX_10_13\":[\"OSX_10_12\",\"security-framework-sys/OSX_10_13\",\"alpn\",\"session-tickets\",\"serial-number-bigint\"],\"OSX_10_14\":[\"OSX_10_13\",\"security-framework-sys/OSX_10_14\"],\"OSX_10_15\":[\"OSX_10_14\",\"security-framework-sys/OSX_10_15\"],\"OSX_10_9\":[\"security-framework-sys/OSX_10_9\"],\"alpn\":[],\"default\":[\"OSX_10_12\"],\"job-bless\":[],\"nightly\":[],\"serial-number-bigint\":[\"dep:num-bigint\"],\"session-tickets\":[]}}", "security-framework_3.3.0": "{\"dependencies\":[{\"name\":\"bitflags\",\"req\":\"^2.6\"},{\"name\":\"core-foundation\",\"req\":\"^0.10\"},{\"name\":\"core-foundation-sys\",\"req\":\"^0.8.6\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.10\"},{\"kind\":\"dev\",\"name\":\"hex\",\"req\":\"^0.4.3\"},{\"name\":\"libc\",\"req\":\"^0.2.139\"},{\"name\":\"log\",\"optional\":true,\"req\":\"^0.4.20\"},{\"default_features\":false,\"name\":\"security-framework-sys\",\"req\":\"^2.14\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.12.0\"},{\"kind\":\"dev\",\"name\":\"time\",\"req\":\"^0.3.23\"},{\"kind\":\"dev\",\"name\":\"x509-parser\",\"req\":\"^0.16\"}],\"features\":{\"OSX_10_12\":[\"security-framework-sys/OSX_10_12\"],\"OSX_10_13\":[\"OSX_10_12\",\"security-framework-sys/OSX_10_13\",\"alpn\",\"session-tickets\"],\"OSX_10_14\":[\"OSX_10_13\",\"security-framework-sys/OSX_10_14\"],\"OSX_10_15\":[\"OSX_10_14\",\"security-framework-sys/OSX_10_15\"],\"alpn\":[],\"default\":[\"OSX_10_12\"],\"job-bless\":[],\"nightly\":[],\"session-tickets\":[],\"sync-keychain\":[\"OSX_10_13\"]}}", "seize_0.5.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.7.0\"},{\"kind\":\"dev\",\"name\":\"crossbeam-epoch\",\"req\":\"^0.9.8\"},{\"kind\":\"dev\",\"name\":\"haphazard\",\"req\":\"^0.1.8\"},{\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2\"},{\"features\":[\"Win32_System_Threading\"],\"name\":\"windows-sys\",\"optional\":true,\"req\":\">=0.52, <=0.61\",\"target\":\"cfg(windows)\"}],\"features\":{\"default\":[\"fast-barrier\"],\"fast-barrier\":[\"windows-sys\",\"libc\"]}}", + "semver_1.0.27": "{\"dependencies\":[{\"default_features\":false,\"name\":\"serde\",\"optional\":true,\"package\":\"serde_core\",\"req\":\"^1.0.220\"},{\"default_features\":false,\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.220\",\"target\":\"cfg(any())\"}],\"features\":{\"default\":[\"std\"],\"serde\":[\"dep:serde\"],\"std\":[]}}", "serde_1.0.227": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"result\"],\"name\":\"serde_core\",\"req\":\"=1.0.227\"},{\"name\":\"serde_derive\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"alloc\":[\"serde_core/alloc\"],\"default\":[\"std\"],\"derive\":[\"serde_derive\"],\"rc\":[\"serde_core/rc\"],\"std\":[\"serde_core/std\"],\"unstable\":[\"serde_core/unstable\"]}}", "serde_core_1.0.227": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1\"},{\"name\":\"serde_derive\",\"req\":\"=1.0.227\",\"target\":\"cfg(any())\"},{\"kind\":\"dev\",\"name\":\"serde_derive\",\"req\":\"^1\"}],\"features\":{\"alloc\":[],\"default\":[\"std\",\"result\"],\"rc\":[],\"result\":[],\"std\":[],\"unstable\":[]}}", "serde_derive_1.0.227": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"proc-macro\"],\"name\":\"proc-macro2\",\"req\":\"^1.0.74\"},{\"default_features\":false,\"features\":[\"proc-macro\"],\"name\":\"quote\",\"req\":\"^1.0.35\"},{\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"clone-impls\",\"derive\",\"parsing\",\"printing\",\"proc-macro\"],\"name\":\"syn\",\"req\":\"^2.0.81\"}],\"features\":{\"default\":[],\"deserialize_in_place\":[]}}", diff --git a/axel-f/config/builtins.axl b/axel-f/config/builtins.axl index 2dc9391ce..7f075b8f2 100644 --- a/axel-f/config/builtins.axl +++ b/axel-f/config/builtins.axl @@ -119,25 +119,19 @@ def configure_builtins(ctx: ConfigContext): user = ctx.std.env.var("USER") - def flags(flags, type): - if user != "thesayyn" and type in flags: - flags += flags[type] - return flags - bessie_endpoint = platform_config.get("bessie_endpoint", None) - def build_event_sinks(): - sinks = [] - if user != "thesayyn" and bessie_endpoint: - sinks.append(bazel.build_events.grpc( - uri = bessie_endpoint, - metadata = {} # TODO: how does bessie authenticate? - )) - return sinks + bessie_sinks = [] + if user != "thesayyn" and bessie_endpoint: + bessie_sinks.append(bazel.build_events.grpc( + uri = bessie_endpoint, + metadata = {} # TODO: how does bessie authenticate? + )) for task in ctx.tasks: if task.name == "build" and task.path.endswith("aspect/build.axl"): - task.config.startup_flags = lambda f: flags(f, "startup") - task.config.flags = lambda f: flags(f, "build") + if user != "thesayyn": + task.config.extra_startup_flags.extend(flags.get("startup", [])) + task.config.extra_flags.extend(flags.get("build", [])) task.config.build_start = lambda: print("+++ :bazel: Building") - task.config.build_event_sinks = build_event_sinks + task.config.build_event_sinks.extend(bessie_sinks) task.config.build_event = on_build_event \ No newline at end of file diff --git a/axel-f/docs/what_is_this.md b/axel-f/docs/what_is_this.md index 63ea1f8fb..fa22ddede 100644 --- a/axel-f/docs/what_is_this.md +++ b/axel-f/docs/what_is_this.md @@ -27,21 +27,6 @@ axel-f is a separate Rust crate that lives in its own repository. It is embedded ### Crate structure -``` -axel-f/ -├── Cargo.toml # crate definition -├── src/lib.rs # exports all .axl files via include_str! -├── MODULE.aspect # use_config() declarations -├── config.axl # main config function -├── lint_strategy.axl # lint strategy (GitHub-aware hold-the-line) -├── github.axl # GitHub API integration -├── sarif.axl # SARIF parsing -├── delivery.axl # artifact delivery -├── deliveryd.axl # delivery daemon client -├── migrate.axl # migration tooling -└── platform-config.axl # platform environment discovery -``` - `src/lib.rs` is minimal — it exports a single constant: ```rust diff --git a/crates/axl-runtime/src/builtins/aspect/build.axl b/crates/axl-runtime/src/builtins/aspect/build.axl index f7a5e7a54..bebad3947 100644 --- a/crates/axl-runtime/src/builtins/aspect/build.axl +++ b/crates/axl-runtime/src/builtins/aspect/build.axl @@ -3,77 +3,85 @@ A default 'build' task that wraps a 'bazel build' command. """ BuildConfig = spec( - startup_flags = attr(typing.Callable[[list[str]], list[str]], lambda flags: flags), - flags = attr(typing.Callable[[list[str]], list[str]], lambda flags: flags), - build_event_sinks = attr(typing.Callable[[], list[bazel.build.BuildEventSink]], lambda: []), + # Declarative data — composable, zero-cost reads + extra_flags = attr(list[str], []), + extra_startup_flags = attr(list[str], []), + build_event_sinks = attr(list[bazel.build.BuildEventSink], []), - # Lifecycle - build_start = attr(typing.Callable[[], None], lambda: None), + # Optional transforms — only called when set + flags = attr(typing.Callable[[list[str]], list[str]] | None, None), + startup_flags = attr(typing.Callable[[list[str]], list[str]] | None, None), + + # Lifecycle — only called when set + build_start = attr(typing.Callable[[], None] | None, None), build_event = attr(typing.Callable[[dict, str, str], None] | None, None), - build_end = attr(typing.Callable[[int], None], lambda status: None) + build_end = attr(typing.Callable[[int], None] | None, None), ) -def impl(ctx: TaskContext) -> int: - stdout = ctx.std.io.stdout - - build_events = True +def _collect_bes_from_args(ctx): + """Collect BES sinks from CLI args (--bes_backend/--bes_header).""" + sinks = [] for bes_backend in ctx.args.bes_backend: metadata = {} for bes_header in ctx.args.bes_header: (k, _, v) = bes_header.partition("=") metadata[k] = v - if type(build_events) != "list": - build_events = [] - build_events.append( + sinks.append( bazel.build_events.grpc( uri = bes_backend, - metadata = metadata + metadata = metadata, ) ) + return sinks - extra_sinks = ctx.config.build_event_sinks() - if extra_sinks: - if type(build_events) != "list": - build_events = [] - build_events.extend(extra_sinks) - - if ctx.config.build_event: - # flip build_events to true - # when its a list, it is automatically enabled. - if type(build_events) == "bool": +def impl(ctx: TaskContext) -> int: + # Flags: accumulate data, then optionally transform + flags = ["--isatty=" + str(int(ctx.std.io.stdout.is_tty))] + flags.extend(ctx.args.bazel_flag) + flags.extend(ctx.config.extra_flags) + if ctx.config.flags: + flags = ctx.config.flags(flags) + + startup_flags = list(ctx.args.bazel_startup_flag) + startup_flags.extend(ctx.config.extra_startup_flags) + if ctx.config.startup_flags: + startup_flags = ctx.config.startup_flags(startup_flags) + + # BES: merge arg-based sinks with config sinks + build_events = _collect_bes_from_args(ctx) + if ctx.config.build_event_sinks: + build_events.extend(ctx.config.build_event_sinks) + + # Coerce to bool/list for ctx.bazel.build: + # - non-empty list → stream to those sinks + build_events() iterator. + # - True → stream without explicit sinks (build_event handler only) + # - False → no BEP stream at all + if not build_events: + if ctx.config.build_event: build_events = True + else: + build_events = False - - bazel_flags = ["--isatty=" + str(int(ctx.std.io.stdout.is_tty))] - for bazel_flag in ctx.args.bazel_flag: - bazel_flags.append(bazel_flag) - - bazel_startup_flags = [] - for flag in ctx.args.bazel_startup_flag: - bazel_startup_flags.append(flag) - - # Apply flags and startup flags by config - bazel_flags = ctx.config.flags(bazel_flags) - bazel_startup_flags = ctx.config.startup_flags(bazel_startup_flags) - - ctx.config.build_start() + if ctx.config.build_start: + ctx.config.build_start() build = ctx.bazel.build( build_events = build_events, - flags = bazel_flags, - startup_flags = bazel_startup_flags, - *ctx.args.target_pattern + flags = flags, + startup_flags = startup_flags, + *ctx.args.target_pattern, ) if ctx.config.build_event: - build_event = ctx.config.build_event - state = dict() + handler = ctx.config.build_event + state = {} for event in build.build_events(): - build_event(ctx, state, event) + handler(ctx, state, event) build_status = build.wait() - ctx.config.build_end(build_status.code) + if ctx.config.build_end: + ctx.config.build_end(build_status.code) return build_status.code @@ -81,8 +89,6 @@ build = task( implementation = impl, config = BuildConfig, args = { - # TODO: Support a long --pattern_file like bazel does (@./targets) - # TODO: Support - (list from stdin) "target_pattern": args.positional(minimum = 1, maximum = 512, default = ["..."]), "bazel_flag": args.string_list(), "bazel_startup_flag": args.string_list(), @@ -90,5 +96,5 @@ build = task( "remote_cache": args.string(), "bes_backend": args.string_list(), "bes_header": args.string_list(), - } + }, ) diff --git a/crates/axl-runtime/src/engine/types/spec.rs b/crates/axl-runtime/src/engine/types/spec.rs index e3ebfbb40..1cc6bdd62 100644 --- a/crates/axl-runtime/src/engine/types/spec.rs +++ b/crates/axl-runtime/src/engine/types/spec.rs @@ -6,11 +6,13 @@ use allocative::Allocative; use dupe::Dupe; use starlark::environment::{GlobalsBuilder, Methods, MethodsBuilder, MethodsStatic}; use starlark::starlark_module; +use starlark::values::dict::AllocDict; +use starlark::values::list::AllocList; use starlark::values::typing::TypeCompiled; use starlark::values::{ - starlark_value, AllocFrozenValue, AllocValue, Freeze, FreezeError, Freezer, FrozenHeap, - FrozenValue, Heap, NoSerialize, ProvidesStaticType, StarlarkValue, Trace, Tracer, Value, - ValueLike, + AllocFrozenValue, AllocValue, Freeze, FreezeError, Freezer, FrozenHeap, FrozenValue, Heap, + NoSerialize, ProvidesStaticType, StarlarkValue, Trace, Tracer, Value, ValueLike, + starlark_value, }; use starlark_map::small_map::SmallMap; @@ -171,6 +173,30 @@ impl Freeze for FieldValue<'_> { } } +/// Deep-copy a default value if it's a mutable container (list or dict). +/// This ensures each spec instance gets its own mutable copy rather than +/// sharing the (potentially frozen) default. +fn copy_default_value<'v>(value: Value<'v>, heap: &'v Heap) -> starlark::Result> { + match value.get_type() { + "list" => { + let items: Vec> = value.iterate(heap)?.collect(); + Ok(heap.alloc(AllocList(items))) + } + "dict" => { + let keys: Vec> = value.iterate(heap)?.collect(); + let items: Vec<(Value<'v>, Value<'v>)> = keys + .into_iter() + .map(|k| { + let v = value.at(k, heap)?; + Ok((k, v)) + }) + .collect::>()?; + Ok(heap.alloc(AllocDict(items))) + } + _ => Ok(value), + } +} + /// Create fresh TypeCompiled values from field type values at runtime. /// This ensures type checking works correctly for types like starlark Records /// whose frozen TypeCompiled matchers may not function properly. @@ -265,7 +291,7 @@ impl<'v> StarlarkValue<'v> for SpecType<'v> { let value = if let Some(v) = kwargs.get(field_name.as_str()) { *v } else if let Some(default) = field.default { - default + copy_default_value(default, eval.heap())? } else { return Err(starlark::Error::new_other(anyhow::anyhow!( "Missing required field `{}` for {}", @@ -377,7 +403,7 @@ impl<'v> StarlarkValue<'v> for FrozenSpecType { let value = if let Some(v) = kwargs.get(field_name.as_str()) { *v } else if let Some(default) = field.default { - default.to_value() + copy_default_value(default.to_value(), eval.heap())? } else { return Err(starlark::Error::new_other(anyhow::anyhow!( "Missing required field `{}` for {}", @@ -804,12 +830,25 @@ impl Freeze for Spec<'_> { pub fn register_globals(globals: &mut GlobalsBuilder) { /// Creates a spec type with the given fields. /// + /// Each field can be a bare type (required, no default) or an `attr()` + /// definition (with type and optional default). + /// + /// Mutable defaults (lists, dicts) are deep-copied per instance, so each + /// instance gets its own independent copy. No `default_factory` needed. + /// /// Example: /// ```starlark /// MySpec = spec(host=str, port=int) /// r = MySpec(host="localhost", port=80) /// print(r.host) # "localhost" /// print(r.port) # 80 + /// + /// # Mutable defaults are safe: + /// ListSpec = spec(items=attr(list[str], [])) + /// a = ListSpec() + /// b = ListSpec() + /// a.items.append("x") + /// print(b.items) # [] — each instance has its own list /// ``` fn spec<'v>( #[starlark(kwargs)] kwargs: SmallMap<&str, Value<'v>>, @@ -846,10 +885,17 @@ pub fn register_globals(globals: &mut GlobalsBuilder) { /// Creates a field definition with a type and optional default value. /// + /// Mutable defaults (lists, dicts) are deep-copied when a spec instance is + /// created, so each instance gets its own independent copy. + /// /// Example: /// ```starlark /// MySpec = spec(host=str, port=attr(int, 80)) /// r = MySpec(host="localhost") # port defaults to 80 + /// + /// # Mutable defaults are copied per instance: + /// attr(list[str], []) # each instance gets a fresh [] + /// attr(dict[str, int], {}) # each instance gets a fresh {} /// ``` fn attr<'v>( #[starlark(require = pos)] typ: Value<'v>, From cb7352471baf744dce45141efa82fa193409e2d3 Mon Sep 17 00:00:00 2001 From: David Zbarsky Date: Thu, 12 Feb 2026 09:06:37 -0500 Subject: [PATCH 59/65] Add go bootstrap SDK --- .bazelrc | 4 + .gitignore | 1 + MODULE.bazel | 20 ++- MODULE.bazel.lock | 186 +++++++++++++++++++++++--- bazel/patches/go_compiler_flags.patch | 84 ++++++++++++ examples/deliveryd/BUILD.bazel | 2 + examples/deliveryd/MODULE.bazel | 2 +- examples/deliveryd/go.mod | 2 +- 8 files changed, 278 insertions(+), 23 deletions(-) create mode 100644 bazel/patches/go_compiler_flags.patch diff --git a/.bazelrc b/.bazelrc index c64522bab..6a22dccbd 100644 --- a/.bazelrc +++ b/.bazelrc @@ -6,9 +6,13 @@ common --repo_env=BAZEL_NO_APPLE_CPP_TOOLCHAIN=1 # Check local dev setup common --workspace_status_command=tools/githooks/check-config.sh +common --toolchain_resolution_debug='\Q@@rules_rs++rules_rust+rules_rust//rust:toolchain_type\E' + common:macos --build_tag_filters=-no-macos common:linux --host_platform=//bazel/platforms:linux_host_platform +common --@rules_go//go/toolchain:source=bootstrapped + common --@rules_cc//cc/toolchains/args/archiver_flags:use_libtool_on_macos=False common --@toolchains_llvm_bootstrapped//config:experimental_stub_libgcc_s=True diff --git a/.gitignore b/.gitignore index 5f7657ab7..fe3055476 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +*.swp .jj .envrc.user workflow-samples diff --git a/MODULE.bazel b/MODULE.bazel index 21d9a9afd..89704d364 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -11,17 +11,31 @@ bazel_dep(name = "buildifier_prebuilt", version = "8.2.0.2") bazel_dep(name = "gazelle", version = "0.45.0") bazel_dep(name = "platforms", version = "1.0.0") bazel_dep(name = "rules_cc", version = "0.2.16") -bazel_dep(name = "rules_go", version = "0.59.0") bazel_dep(name = "rules_pkg", version = "1.1.0") bazel_dep(name = "rules_shell", version = "0.6.1") bazel_dep(name = "with_cfg.bzl", version = "0.12.0") -bazel_dep(name = "toolchains_llvm_bootstrapped", version = "0.5.2") +bazel_dep(name = "toolchains_llvm_bootstrapped", version = "0.5.5") bazel_dep(name = "deliveryd", version = "0.0.0") +bazel_dep(name = "rules_go", version = "0.60.0") +archive_override( + module_name = "rules_go", + integrity = "sha256-8ezQcDyHHp/+xa9NbUJO/3/kDEFFmJaV4pb1fd99m74=", + strip_prefix = "rules_go-62d798d48ae153e048a7f9c43ba68cfa1ea10924", + url = "https://github.com/bazel-contrib/rules_go/archive/62d798d48ae153e048a7f9c43ba68cfa1ea10924.tar.gz", +) +go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") +go_sdk.from_file( + name = "go_bootstrap_sdk", + experimental_build_compiler_from_source = True, + go_mod = "@deliveryd//:go.mod", + patch_strip = 1, + patches = ["//bazel/patches:go_compiler_flags.patch"], +) local_path_override( module_name = "deliveryd", - path = "./examples/deliveryd" + path = "./examples/deliveryd", ) register_toolchains("@toolchains_llvm_bootstrapped//toolchain:all") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index cca6babee..ca644f987 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -45,7 +45,6 @@ "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.3.2/source.json": "c6f5c39e6f32eb395f8fdaea63031a233bbe96d49a3bfb9f75f6fce9b74bec6c", "https://bcr.bazel.build/modules/bazel_features/0.1.0/MODULE.bazel": "47011d645b0f949f42ee67f2e8775188a9cf4a0a1528aa2fa4952f2fd00906fd", "https://bcr.bazel.build/modules/bazel_features/1.0.0/MODULE.bazel": "d7f022dc887efb96e1ee51cec7b2e48d41e36ff59a6e4f216c40e4029e1585bf", - "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", @@ -63,6 +62,7 @@ "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", "https://bcr.bazel.build/modules/bazel_features/1.34.0/MODULE.bazel": "e8475ad7c8965542e0c7aac8af68eb48c4af904be3d614b6aa6274c092c2ea1e", + "https://bcr.bazel.build/modules/bazel_features/1.36.0/MODULE.bazel": "596cb62090b039caf1cad1d52a8bc35cf188ca9a4e279a828005e7ee49a1bec3", "https://bcr.bazel.build/modules/bazel_features/1.39.0/MODULE.bazel": "28739425c1fc283c91931619749c832b555e60bcd1010b40d8441ce0a5cf726d", "https://bcr.bazel.build/modules/bazel_features/1.39.0/source.json": "f63cbeb4c602098484d57001e5a07d31cb02bbccde9b5e2c9bf0b29d05283e93", "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", @@ -70,7 +70,8 @@ "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", "https://bcr.bazel.build/modules/bazel_lib/3.0.0-beta.1/MODULE.bazel": "407729e232f611c3270005b016b437005daa7b1505826798ea584169a476e878", "https://bcr.bazel.build/modules/bazel_lib/3.0.0/MODULE.bazel": "22b70b80ac89ad3f3772526cd9feee2fa412c2b01933fea7ed13238a448d370d", - "https://bcr.bazel.build/modules/bazel_lib/3.0.0/source.json": "895f21909c6fba01d7c17914bb6c8e135982275a1b18cdaa4e62272217ef1751", + "https://bcr.bazel.build/modules/bazel_lib/3.2.0/MODULE.bazel": "39b50d94b9be6bda507862254e20c263f9b950e3160112348d10a938be9ce2c2", + "https://bcr.bazel.build/modules/bazel_lib/3.2.0/source.json": "a6f45a903134bebbf33a6166dd42b4c7ab45169de094b37a85f348ca41170a84", "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", @@ -97,10 +98,6 @@ "https://bcr.bazel.build/modules/download_utils/1.0.1/source.json": "05ddc5a3b1f7d8f3e5e0fd1617479e1cf72d63d59ab2b1f0463557a14fc6be0a", "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "cdf8cbe5ee750db04b78878c9633cc76e80dcf4416cbe982ac3a9222f80713c8", "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/source.json": "fa7b512dfcb5eafd90ce3959cf42a2a6fe96144ebbb4b3b3928054895f2afac2", - "https://bcr.bazel.build/modules/gazelle/0.27.0/MODULE.bazel": "3446abd608295de6d90b4a8a118ed64a9ce11dcb3dda2dc3290a22056bd20996", - "https://bcr.bazel.build/modules/gazelle/0.30.0/MODULE.bazel": "f888a1effe338491f35f0e0e85003b47bb9d8295ccba73c37e07702d8d31c65b", - "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", - "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350", "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", "https://bcr.bazel.build/modules/gazelle/0.45.0/MODULE.bazel": "ecd19ebe9f8e024e1ccffb6d997cc893a974bcc581f1ae08f386bdd448b10687", @@ -139,12 +136,11 @@ "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", - "https://bcr.bazel.build/modules/protobuf/29.0-rc2.bcr.1/MODULE.bazel": "52f4126f63a2f0bbf36b99c2a87648f08467a4eaf92ba726bc7d6a500bbf770c", "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", + "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", - "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573", "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", "https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d", "https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42", @@ -187,15 +183,6 @@ "https://bcr.bazel.build/modules/rules_diff/1.0.0/source.json": "fc3824aed007b4db160ffb994036c6e558550857b6634a8e9ccee3e74c659312", "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", - "https://bcr.bazel.build/modules/rules_go/0.33.0/MODULE.bazel": "a2b11b64cd24bf94f57454f53288a5dacfe6cb86453eee7761b7637728c1910c", - "https://bcr.bazel.build/modules/rules_go/0.38.1/MODULE.bazel": "fb8e73dd3b6fc4ff9d260ceacd830114891d49904f5bda1c16bc147bcc254f71", - "https://bcr.bazel.build/modules/rules_go/0.39.1/MODULE.bazel": "d34fb2a249403a5f4339c754f1e63dc9e5ad70b47c5e97faee1441fc6636cd61", - "https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8", - "https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270", - "https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd", - "https://bcr.bazel.build/modules/rules_go/0.53.0/MODULE.bazel": "a4ed760d3ac0dbc0d7b967631a9a3fd9100d28f7d9fcf214b4df87d4bfff5f9a", - "https://bcr.bazel.build/modules/rules_go/0.59.0/MODULE.bazel": "b7e43e7414a3139a7547d1b4909b29085fbe5182b6c58cbe1ed4c6272815aeae", - "https://bcr.bazel.build/modules/rules_go/0.59.0/source.json": "1df17bb7865cfc029492c30163cee891d0dd8658ea0d5bfdf252c4b6db5c1ef6", "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39", @@ -296,7 +283,8 @@ "https://bcr.bazel.build/modules/toolchain_utils/1.0.2/MODULE.bazel": "9b8be503a4fcfd3b8b952525bff0869177a5234d5c35dc3e566b9f5ca2f755a1", "https://bcr.bazel.build/modules/toolchain_utils/1.0.2/source.json": "88769ec576dddacafd8cca4631812cf8eead89f10a29d9405d9f7a553de6bf87", "https://bcr.bazel.build/modules/toolchains_llvm_bootstrapped/0.5.2/MODULE.bazel": "f7c822cea99caef928d7cbe695498096e53c4b2c0ea45997e9a64bf6b77b43b0", - "https://bcr.bazel.build/modules/toolchains_llvm_bootstrapped/0.5.2/source.json": "13d260b3a10804b3b2ab822c49e329c36ef5cd325fa01d0f9a1616c5364b7fff", + "https://bcr.bazel.build/modules/toolchains_llvm_bootstrapped/0.5.5/MODULE.bazel": "a2f1469b2920fcc9c043c87301b7a207d320231615abecd7771d89e516fc3d0b", + "https://bcr.bazel.build/modules/toolchains_llvm_bootstrapped/0.5.5/source.json": "8498c094703da13a859d19dd2a200152f75870fb7f22a9770df99d230a4f50d1", "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", "https://bcr.bazel.build/modules/with_cfg.bzl/0.12.0/MODULE.bazel": "b573395fe63aef4299ba095173e2f62ccfee5ad9bbf7acaa95dba73af9fc2b38", "https://bcr.bazel.build/modules/with_cfg.bzl/0.12.0/source.json": "3f3fbaeafecaf629877ad152a2c9def21f8d330d91aa94c5dc75bbb98c10b8b8", @@ -1039,6 +1027,168 @@ "go1.25.0.windows-arm64.zip", "27bab004c72b3d7bd05a69b6ec0fc54a309b4b78cc569dd963d8b3ec28bfdb8c" ] + }, + "1.26.0": { + "aix_ppc64": [ + "go1.26.0.aix-ppc64.tar.gz", + "ca464cc9c48d66e905e6978924554057b693f0aea697372fa8f7e108cc212261" + ], + "darwin_amd64": [ + "go1.26.0.darwin-amd64.tar.gz", + "1ca28b7703cbea05a65b2a1d92d6b308610ef92f8824578a0874f2e60c9d5a22" + ], + "darwin_arm64": [ + "go1.26.0.darwin-arm64.tar.gz", + "b1640525dfe68f066d56f200bef7bf4dce955a1a893bd061de6754c211431023" + ], + "dragonfly_amd64": [ + "go1.26.0.dragonfly-amd64.tar.gz", + "f688f36f1b3ae17f2ca0a6f8d5e8cba46a972de26ef6241b21ab9645b291243e" + ], + "freebsd_386": [ + "go1.26.0.freebsd-386.tar.gz", + "9f07792e085f0d212c75ba403cb73e7f2f71eace48a38fab58711270dd7b1cef" + ], + "freebsd_amd64": [ + "go1.26.0.freebsd-amd64.tar.gz", + "7bba5a430d2c562af87b6c1a31cccf72c43107b7318b48aa8a02441df61acd08" + ], + "freebsd_arm": [ + "go1.26.0.freebsd-arm.tar.gz", + "fe15a74bdb33954ebc9312efb01ac1871f7fc9cc712993058de8fc2a4dc8c8f7" + ], + "freebsd_arm64": [ + "go1.26.0.freebsd-arm64.tar.gz", + "5d92e2d65a543811dca9f76a2b533cbdc051bdd5015bf789b137e2dcc33b2d52" + ], + "illumos_amd64": [ + "go1.26.0.illumos-amd64.tar.gz", + "2191668cd3aea0a05e646e6f7919ea357e666c15facf417f33e5cf18b7f00dd9" + ], + "linux_386": [ + "go1.26.0.linux-386.tar.gz", + "35e2ec7a7ae6905a1fae5459197b70e3fcbc5e0a786a7d6ba8e49bcd38ad2e26" + ], + "linux_amd64": [ + "go1.26.0.linux-amd64.tar.gz", + "aac1b08a0fb0c4e0a7c1555beb7b59180b05dfc5a3d62e40e9de90cd42f88235" + ], + "linux_arm64": [ + "go1.26.0.linux-arm64.tar.gz", + "bd03b743eb6eb4193ea3c3fd3956546bf0e3ca5b7076c8226334afe6b75704cd" + ], + "linux_armv6l": [ + "go1.26.0.linux-armv6l.tar.gz", + "3f6b48d96f0d8dff77e4625aa179e0449f6bbe79b6986bfa711c2cfc1257ebd8" + ], + "linux_loong64": [ + "go1.26.0.linux-loong64.tar.gz", + "33947cd7686f1cd5f097d2a5a30427a4ade114ea00b7570c85a2abf1af3d0507" + ], + "linux_mips": [ + "go1.26.0.linux-mips.tar.gz", + "a4ece61d4bac43b6983fde2c6b9cfc1af7f0d5d6a073219583d4e93b11559c25" + ], + "linux_mips64": [ + "go1.26.0.linux-mips64.tar.gz", + "197c2e97fa9ec1ad05998e0982d1a1ae761980df154424e5f29f3912e9ea4e5e" + ], + "linux_mips64le": [ + "go1.26.0.linux-mips64le.tar.gz", + "61c52b4ab0dceae29f10df29045483596c3f06810c9b511e8336a97428a95a1b" + ], + "linux_mipsle": [ + "go1.26.0.linux-mipsle.tar.gz", + "b3a13cc5a5f9250b02cf4ba19914c90c7034e68a5ccb9affa5198aadbcedac9a" + ], + "linux_ppc64": [ + "go1.26.0.linux-ppc64.tar.gz", + "ef7232a49101d163a93bac34d03bfbc4fb18f75d7526d77ac307e16d9d83c300" + ], + "linux_ppc64le": [ + "go1.26.0.linux-ppc64le.tar.gz", + "3066b2284b554da76cf664d217490792ba6f292ec0fc20bf9615e173cc0d2800" + ], + "linux_riscv64": [ + "go1.26.0.linux-riscv64.tar.gz", + "ab9226ecddda0f682365c949114b653a66c2e9330e7b8d3edea80858437d2ff2" + ], + "linux_s390x": [ + "go1.26.0.linux-s390x.tar.gz", + "d62137f11530b97f3503453ad7d9e570af070770599fb8054f4e8cd0e905a453" + ], + "netbsd_386": [ + "go1.26.0.netbsd-386.tar.gz", + "f79ae29d97980bf4c42120c0bebea758426dfa250ab39bcd909bccf057d5eced" + ], + "netbsd_amd64": [ + "go1.26.0.netbsd-amd64.tar.gz", + "22fc488ddd2c5958378fba2560866d6dae298160ba198e51ca5b998dc77b92f1" + ], + "netbsd_arm": [ + "go1.26.0.netbsd-arm.tar.gz", + "1c70fd89c12dfda71f755dae1d7796f14702442b50ef2831117a641358276c5a" + ], + "netbsd_arm64": [ + "go1.26.0.netbsd-arm64.tar.gz", + "379d6ef6dfa8b67a7776744a536e69a1dc0fe5aeed48eb882ac71f89a98ba8ab" + ], + "openbsd_386": [ + "go1.26.0.openbsd-386.tar.gz", + "02084b48b800d28a434f89e8d19c7c5d47b7eb1339d5cf6104da56a7ad0aa23a" + ], + "openbsd_amd64": [ + "go1.26.0.openbsd-amd64.tar.gz", + "97884d7e5f566230f65820c02019ea253b53800157975918b6b6b7f03bf1b022" + ], + "openbsd_arm": [ + "go1.26.0.openbsd-arm.tar.gz", + "2618746ffa6b93216d698c2ae923738373bd433c1253438c5ad8efdd2fd0a388" + ], + "openbsd_arm64": [ + "go1.26.0.openbsd-arm64.tar.gz", + "5a43668bf3c49d302ec50ac55d7e3f28a410cbda56485d7ebb9759f83e03e56f" + ], + "openbsd_ppc64": [ + "go1.26.0.openbsd-ppc64.tar.gz", + "00fbd0df705ac70f2833f97a893b7819f99704a3711c2096907f859703fe3e83" + ], + "openbsd_riscv64": [ + "go1.26.0.openbsd-riscv64.tar.gz", + "d00373b08c4fa396887fab8f6217824b5d3cad5409db326d535cfcf68916b9ea" + ], + "plan9_386": [ + "go1.26.0.plan9-386.tar.gz", + "d8bcdb292a902e52adcce3b96a12474bd69cfd331bf92ad399afb51e009503b4" + ], + "plan9_amd64": [ + "go1.26.0.plan9-amd64.tar.gz", + "847fa33e55206b0c40b99252e0219cc356ff58ccd4e143ce0a378ebfd75446b0" + ], + "plan9_arm": [ + "go1.26.0.plan9-arm.tar.gz", + "8872abd44fb3087e9c1bc0982e4c3be442018c4ad7cb5150ed29d68839e75ce4" + ], + "solaris_amd64": [ + "go1.26.0.solaris-amd64.tar.gz", + "ec424798ae65c23dea6f4ef58d5fed85c56305eeb4a74e7af9a7d73bf335c93c" + ], + "source": [ + "go1.26.0.src.tar.gz", + "c9132a8a1f6bd2aa4aad1d74b8231d95274950483a4950657ee6c56e6e817790" + ], + "windows_386": [ + "go1.26.0.windows-386.zip", + "50674f3d6a071fa1a4c1d76dc37fafa0330df87d84087a262fee020da5396b6b" + ], + "windows_amd64": [ + "go1.26.0.windows-amd64.zip", + "9bbe0fc64236b2b51f6255c05c4232532b8ecc0e6d2e00950bd3021d8a4d07d4" + ], + "windows_arm64": [ + "go1.26.0.windows-arm64.zip", + "73bdbb9f64aa152758024485c5243a1098182bb741fcc603b6fb664ee5e0fe35" + ] } }, "@@rules_rs+//rs:extensions.bzl%crate": { diff --git a/bazel/patches/go_compiler_flags.patch b/bazel/patches/go_compiler_flags.patch new file mode 100644 index 000000000..1e21552da --- /dev/null +++ b/bazel/patches/go_compiler_flags.patch @@ -0,0 +1,84 @@ +From 99d7121934a9cfa7963d3a9bfd840779fd2869f6 Mon Sep 17 00:00:00 2001 +From: Corentin Kerisit +Date: Tue, 16 Dec 2025 23:53:01 +0000 +Subject: [PATCH] cmd/link: add more clang driver flags when testing flag + +This changes does 2 things: + +- Move `-L` to `prefixesToKeep` since it allows providing a custom +default libs search path. + +- Allow various flags that impact the behaviour of the clang driver. + +The latter allows for LLVM only toolchains to be compatible with +linkerFlagSupported checks. + +The end goal of this PR is to allow fully hermetic toolchains, +especially pure LLVM ones, to be used to cross-compile CGO. + +Fixes #76825 + +Change-Id: I2311c9566ce9c7e8f6b325258af58eb333663cf0 +GitHub-Last-Rev: 74342aae35124cf174a3f8b888999ffd4cea191f +GitHub-Pull-Request: golang/go#76858 +Reviewed-on: https://go-review.googlesource.com/c/go/+/730561 +Auto-Submit: Ian Lance Taylor +Reviewed-by: Dmitri Shuralyov +LUCI-TryBot-Result: Go LUCI +Reviewed-by: Michael Pratt +Reviewed-by: Ian Lance Taylor +--- + src/cmd/link/internal/ld/lib.go | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go +index bcad5add4abe19..3799aafac769fa 100644 +--- a/src/cmd/link/internal/ld/lib.go ++++ b/src/cmd/link/internal/ld/lib.go +@@ -2208,20 +2208,30 @@ func trimLinkerArgv(argv []string) []string { + flagsWithNextArgSkip := []string{ + "-F", + "-l", +- "-L", + "-framework", + "-Wl,-framework", + "-Wl,-rpath", + "-Wl,-undefined", + } + flagsWithNextArgKeep := []string{ ++ "-B", ++ "-L", + "-arch", + "-isysroot", + "--sysroot", + "-target", + "--target", ++ "-resource-dir", ++ "-rtlib", ++ "--rtlib", ++ "-stdlib", ++ "--stdlib", ++ "-unwindlib", ++ "--unwindlib", + } + prefixesToKeep := []string{ ++ "-B", ++ "-L", + "-f", + "-m", + "-p", +@@ -2231,6 +2241,14 @@ func trimLinkerArgv(argv []string) []string { + "--sysroot", + "-target", + "--target", ++ "-resource-dir", ++ "-rtlib", ++ "--rtlib", ++ "-stdlib", ++ "--stdlib", ++ "-unwindlib", ++ "--unwindlib", ++ "-nostdlib++", + } + + var flags []string diff --git a/examples/deliveryd/BUILD.bazel b/examples/deliveryd/BUILD.bazel index 82873d27f..00b1d40af 100644 --- a/examples/deliveryd/BUILD.bazel +++ b/examples/deliveryd/BUILD.bazel @@ -1,5 +1,7 @@ load("@rules_go//go:def.bzl", "go_binary", "go_library") +exports_files(["go.mod"]) + go_library( name = "deliveryd_lib", srcs = [ diff --git a/examples/deliveryd/MODULE.bazel b/examples/deliveryd/MODULE.bazel index 3a2489622..8077dcebd 100644 --- a/examples/deliveryd/MODULE.bazel +++ b/examples/deliveryd/MODULE.bazel @@ -4,7 +4,7 @@ module( ) bazel_dep(name = "platforms", version = "0.0.10") -bazel_dep(name = "rules_go", version = "0.59.0") +bazel_dep(name = "rules_go", version = "0.60.0") bazel_dep(name = "gazelle", version = "0.47.0") go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps") diff --git a/examples/deliveryd/go.mod b/examples/deliveryd/go.mod index 38ab0799f..0aea4b63c 100644 --- a/examples/deliveryd/go.mod +++ b/examples/deliveryd/go.mod @@ -1,6 +1,6 @@ module github.com/aspect-build/deliveryd -go 1.22 +go 1.26.0 require github.com/redis/go-redis/v9 v9.7.0 From 1fd0e997fecce8e2a0a18148a7316bfae43fe33c Mon Sep 17 00:00:00 2001 From: David Zbarsky Date: Thu, 12 Feb 2026 09:06:37 -0500 Subject: [PATCH 60/65] Add go bootstrap SDK --- MODULE.bazel | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 89704d364..3eed53c85 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -24,13 +24,17 @@ archive_override( url = "https://github.com/bazel-contrib/rules_go/archive/62d798d48ae153e048a7f9c43ba68cfa1ea10924.tar.gz", ) +bazel_dep(name = "rules_go", version = "0.60.0") +archive_override( + module_name = "rules_go", + strip_prefix = "rules_go-62d798d48ae153e048a7f9c43ba68cfa1ea10924", + url = "https://github.com/bazel-contrib/rules_go/archive/62d798d48ae153e048a7f9c43ba68cfa1ea10924.tar.gz", +) go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") go_sdk.from_file( name = "go_bootstrap_sdk", - experimental_build_compiler_from_source = True, go_mod = "@deliveryd//:go.mod", - patch_strip = 1, - patches = ["//bazel/patches:go_compiler_flags.patch"], + experimental_build_compiler_from_source = True, ) local_path_override( From 543003bb44f7b004a1519ad2c21c660ddd6155cd Mon Sep 17 00:00:00 2001 From: thesayyn Date: Fri, 13 Feb 2026 10:31:44 -0800 Subject: [PATCH 61/65] warming --- axel-f/MODULE.aspect | 7 +- axel-f/config/lint.axl | 55 ------- axel-f/docs/status.md | 75 ++++++++++ axel-f/lib/platform.axl | 29 ++++ axel-f/tasks/warming.axl | 139 ++++++++++++++++++ .../axl-runtime/src/builtins/aspect/bazel.axl | 41 ++++++ .../axl-runtime/src/builtins/aspect/build.axl | 30 ++-- crates/axl-runtime/src/builtins/mod.rs | 1 + 8 files changed, 308 insertions(+), 69 deletions(-) create mode 100644 axel-f/docs/status.md create mode 100644 axel-f/tasks/warming.axl create mode 100644 crates/axl-runtime/src/builtins/aspect/bazel.axl diff --git a/axel-f/MODULE.aspect b/axel-f/MODULE.aspect index 409d5bc8c..a7aed57a7 100644 --- a/axel-f/MODULE.aspect +++ b/axel-f/MODULE.aspect @@ -1,7 +1,10 @@ -# Configure delivery task +# Register warming tasks. +use_task("tasks/warming.axl", "restore", "update") + +# Configure delivery use_config("config/delivery.axl", "configure_delivery") -# Configure builtins for Workflows environment +# Configure builtins use_config("config/builtins.axl", "configure_builtins") # Configure rules_lint if its declared by user diff --git a/axel-f/config/lint.axl b/axel-f/config/lint.axl index 380f774f5..0e39a9ec0 100644 --- a/axel-f/config/lint.axl +++ b/axel-f/config/lint.axl @@ -29,67 +29,12 @@ load("../lib/linting.axl", "make_github_strategy", "make_github_changed_files_pr -def _check_deliveryd_health(ctx, socket_path): - """ - Check if deliveryd is healthy by calling the /health endpoint. - - Returns: - True if healthy, False otherwise - """ - http = ctx.http() - response = http.get( - url="http://localhost/health", - unix_socket=socket_path, - ) - - result = response.map_err(lambda e: str(e)).block() - if type(result) == "string": - return False - return result.status >= 200 and result.status < 300 - -def _start_deliveryd(ctx, delivery_db_endpoint, socket_path = "/tmp/deliveryd.sock"): - """ - Start the deliveryd process in the background if not already running. - - Args: - ctx: Config context - delivery_db_endpoint: Redis endpoint URL (redis:// or rediss:// for TLS) - socket_path: Unix socket path for deliveryd - """ - # Check if deliveryd is already running by checking for the socket - if ctx.std.fs.exists(socket_path): - # Socket exists, check if the instance is healthy - if _check_deliveryd_health(ctx, socket_path): - print("deliveryd already running and healthy (socket: {})".format(socket_path)) - return - else: - # Stale socket, remove it - print("deliveryd socket exists but instance is unhealthy, removing stale socket") - ctx.std.fs.remove_file(socket_path) - - cmd = ctx.std.process.command("deliveryd") - cmd.arg("--socket=" + socket_path) - cmd.arg("--redis-endpoint=" + delivery_db_endpoint) - - # Run in background - cmd.stdout("null") - cmd.stderr("null") - cmd.spawn() - - print("Started deliveryd (socket: {}, endpoint: {})".format(socket_path, delivery_db_endpoint)) - - def configure_rules_lint(ctx: ConfigContext): CI = ctx.std.env.var("BUILDKITE") # Read platform config from disk platform_config = read_platform_config(ctx.std.fs) - # Start deliveryd if delivery_db_endpoint is configured - delivery_db_endpoint = platform_config.get("delivery_db_endpoint") - if delivery_db_endpoint: - _start_deliveryd(ctx, delivery_db_endpoint) - # Read host config from environment host_config = read_host_config(ctx.std.env, ctx.std.io) diff --git a/axel-f/docs/status.md b/axel-f/docs/status.md new file mode 100644 index 000000000..03ac43f8a --- /dev/null +++ b/axel-f/docs/status.md @@ -0,0 +1,75 @@ +# Rosetta Feature Migration Status + +Tracking what existed in Rosetta (TypeScript) and where each feature ended up in the new architecture. + +## Architecture Changes + +The new system no longer wraps the CI configuration file. Instead, the CI configuration calls into the Aspect CLI directly. This eliminates the need for pipeline generation, condition expressions, multi-workspace orchestration, and several system tasks that only existed to support the wrapper model. + +## Task Types + +| Task | Status | Notes | +|------|--------|-------| +| build | Implemented | `@aspect//build.axl` builtin + axel-f config hooks | +| test | Implemented | `@aspect//test.axl` builtin + axel-f config hooks | +| lint | Implemented | Via `@aspect_rules_lint` package + axel-f GitHub integration | +| format | Implemented | Via `@aspect_rules_lint` package | +| delivery | Implemented | `axel-f/tasks/delivery.axl` with deliveryd integration | +| configure | Not yet implemented | Third-party package | +| gazelle | Not yet implemented | Third-party package | +| buildifier | Not yet implemented | Third-party package | +| warming | Not yet implemented | `bazel build --nobuild` to pre-warm cache on dedicated queue | +| checkout / branch freshness | Not yet implemented | Stale branch detection, rebase/merge, annotations | +| bazel_health_probe | Removed | No longer needed | +| finalization | Removed | No longer needed | +| delivery_manifest | Removed | Architectural change — delivery no longer uses manifests | +| noop | Removed | Was only used for testing | + +## Major Features + +### Implemented in axel-f + +| Feature | Location | Notes | +|---------|----------|-------| +| Platform config reading | `lib/platform.axl` | Reads `/etc/aspect/workflows/platform/` files | +| Bazelrc flag generation | `lib/platform.axl` | Dynamic flags based on Bazel version, host, platform config | +| BES sink configuration | `config/builtins.axl` | Reads bessie_endpoint, configures gRPC sink | +| GitHub check runs | `lib/github.axl` | Create/update check runs with annotations | +| GitHub PR reviews | `lib/github.axl` | Review comments, code suggestions | +| SARIF translation | `lib/sarif.axl` | SARIF lint output to GitHub review comments | +| Lint hold-the-line | `config/lint.axl` | GitHub-aware lint strategy with changed file filtering | +| CI config migration | `tasks/migrate.axl` | Generates GitHub Actions / Buildkite configs from old workflows.yaml | +| Bazel exit codes | `@aspect//bazel.axl` | Exit code constants and default retry predicate | +| Build metadata | `config/builtins.axl` | CI info attached to bazel invocations | +| Deliveryd integration | `lib/deliveryd.axl` | Unix socket HTTP client for delivery daemon | + +### Moved to Aspect CLI (Rust) + +| Feature | Notes | +|---------|-------| +| OpenTelemetry tracing & metrics | Built into the CLI runtime | +| Bazel version detection | Built into the CLI runtime | +| Shell execution with tracing | Built into the CLI runtime | + +### Removed — architectural changes + +| Feature | Reason | +|---------|--------| +| Pipeline generation (steps command) | CI config now calls the CLI directly, not the other way around | +| Condition expressions (`when:` clauses) | No longer wrapping CI config; CI platform handles conditional execution | +| Multi-workspace orchestration | CI config handles workspace matrix; CLI runs in a single workspace | +| Marvin result reporting | Replaced with direct GitHub API calls from axel-f | +| Configuration validation (config command) | No longer have a workflows.yaml to validate | +| Event bus (RxJS pub/sub) | Not needed; task lifecycle is simpler without the wrapper model | +| CI host abstraction (Host interface) | CI platform is known at config time; no runtime detection needed | +| Buildkite annotations (buildkite-agent annotate) | CI platform handles its own annotations | +| Task hooks (before_task / after_task) | CI platform handles pre/post steps natively | +| Bazel server log archiving on crash | Can be handled by CI platform artifact upload | +| Debug assistance mode (execution logs, gRPC logs) | Users enable these via bazel flags directly | + +## Not Yet Implemented + +| Feature | Priority | Description | +|---------|----------|-------------| +| Warming task | TBD | Run `bazel build --nobuild` on targets from build/test tasks to warm the remote cache on a dedicated queue | +| Checkout / branch freshness | TBD | Detect stale branches, run rebase/merge, post annotations with fix commands | diff --git a/axel-f/lib/platform.axl b/axel-f/lib/platform.axl index 227b48aa9..2e8088d01 100644 --- a/axel-f/lib/platform.axl +++ b/axel-f/lib/platform.axl @@ -8,6 +8,7 @@ This is the AXL equivalent of rosetta's bazel/flags.ts and related modules. # Constants DEFAULT_STORAGE_PATH = "/mnt/ephemeral" DEFAULT_PLATFORM_DIR = "/etc/aspect/workflows/platform" +DEFAULT_BIN_DIR = "/etc/aspect/workflows/bin" # Map of logical keys to filenames PLATFORM_CONFIG_KEYS = { @@ -144,6 +145,34 @@ def read_platform_config(fs, platform_dir = DEFAULT_PLATFORM_DIR): return config +def read_warming_config(fs, platform_dir = DEFAULT_PLATFORM_DIR): + """ + Read warming-specific configuration from platform config files. + + Args: + fs: Filesystem interface (ctx.std.fs) + platform_dir: Path to platform config directory + + Returns: + dict with optional keys: warming_bucket, warming_additional_paths + """ + config = {} + + bucket_path = platform_dir + "/warming_bucket" + if fs.exists(bucket_path): + content = fs.read_to_string(bucket_path) + if content: + config["warming_bucket"] = content.strip() + + paths_path = platform_dir + "/warming_additional_paths" + if fs.exists(paths_path): + content = fs.read_to_string(paths_path) + if content: + config["warming_additional_paths"] = content.strip() + + return config + + def read_host_config(env, io): """ Read host/CI configuration from environment. diff --git a/axel-f/tasks/warming.axl b/axel-f/tasks/warming.axl new file mode 100644 index 000000000..2a91a8fcf --- /dev/null +++ b/axel-f/tasks/warming.axl @@ -0,0 +1,139 @@ +""" +Warming tasks for archiving and restoring Bazel caches on CI runners. + +These tasks wrap the existing warming shell scripts that handle tarring up +caches (repository cache, bazel server, output base) and streaming them +to/from cloud storage (S3 or GCS). + +- update: Archives the current caches and uploads to cloud storage after + a `bazel build --nobuild` warming pass (which is a separate concern). +- restore: Downloads and extracts cached archives during runner bootstrap + so subsequent builds start warm. + +Both tasks require the Aspect Workflows runner infrastructure to be present. +""" + +load( + "../lib/platform.axl", + "read_warming_config", + "DEFAULT_BIN_DIR", + "DEFAULT_PLATFORM_DIR", +) + + +def _is_workflows_runner(fs, platform_dir): + """Check if we are running on an Aspect Workflows runner.""" + return fs.exists(platform_dir + "/aws") or fs.exists(platform_dir + "/gcp") + + +def _warmup_update_impl(ctx): + """Archive warming caches and upload to cloud storage.""" + platform_dir = ctx.args.platform_dir + bin_dir = ctx.args.bin_dir + archive_bin = bin_dir + "/warming_archive" + + if not _is_workflows_runner(ctx.std.fs, platform_dir): + print("Error: Not running on an Aspect Workflows runner.") + print("The warming update task requires the Workflows runner infrastructure.") + return 1 + + if not ctx.std.fs.exists(archive_bin): + print("Error: warming archive binary not found at: " + archive_bin) + print("Ensure the Workflows runner bootstrap has completed.") + return 1 + + print("Archiving warming caches...") + + child = ctx.std.process.command(archive_bin) \ + .stdout("inherit") \ + .stderr("inherit") \ + .spawn() + + status = child.wait() + + if status.code != 0: + print("Error: warming archive failed with exit code " + str(status.code)) + + return status.code + + +update = task( + name = "update", + implementation = _warmup_update_impl, + group = ["workflows", "runner", "warming"], + args = { + "bin_dir": args.string(default = DEFAULT_BIN_DIR), + "platform_dir": args.string(default = DEFAULT_PLATFORM_DIR), + }, +) + + +def _warmup_restore_impl(ctx): + """Restore warming caches from cloud storage.""" + platform_dir = ctx.args.platform_dir + bin_dir = ctx.args.bin_dir + restore_bin = bin_dir + "/warming_restore" + + if not _is_workflows_runner(ctx.std.fs, platform_dir): + print("Error: Not running on an Aspect Workflows runner.") + print("The warming restore task requires the Workflows runner infrastructure.") + return 1 + + if not ctx.std.fs.exists(restore_bin): + print("Error: warming restore binary not found at: " + restore_bin) + print("Ensure the Workflows runner bootstrap has completed.") + return 1 + + # Resolve bucket: CLI arg > platform config file + bucket = ctx.args.bucket + additional_paths = ctx.args.additional_paths + + if not bucket or not additional_paths: + warming_config = read_warming_config(ctx.std.fs, platform_dir) + if not bucket: + bucket = warming_config.get("warming_bucket", "") + if not additional_paths: + additional_paths = warming_config.get("warming_additional_paths", "") + + if not bucket: + print("Error: warming bucket not specified.") + print("Use --bucket= or write the bucket name to " + platform_dir + "/warming_bucket") + return 1 + + print("Restoring warming caches from bucket: " + bucket) + + child = ctx.std.process.command(restore_bin) \ + .arg(bucket) \ + .arg(additional_paths) \ + .stdout("inherit") \ + .stderr("inherit") \ + .spawn() + + status = child.wait() + + if status.code != 0: + print("Warning: warming restore exited with code " + str(status.code)) + # Exit codes 10, 11 mean the agent is warm but from a fallback. + # Exit codes 20-24 mean the agent is cold. + if status.code in [10, 11]: + print("Agent is warm (restored from fallback cache).") + elif status.code in [20, 21, 23, 24]: + print("Agent is cold (cache restore failed).") + else: + print("Unexpected exit code from warming restore.") + + return status.code + + +# aspect runner warming restore +restore = task( + name = "restore", + implementation = _warmup_restore_impl, + group = ["workflows", "runner", "warming"], + args = { + "bin_dir": args.string(default = DEFAULT_BIN_DIR), + "platform_dir": args.string(default = DEFAULT_PLATFORM_DIR), + "bucket": args.string(default = ""), + "additional_paths": args.string(default = ""), + }, +) diff --git a/crates/axl-runtime/src/builtins/aspect/bazel.axl b/crates/axl-runtime/src/builtins/aspect/bazel.axl new file mode 100644 index 000000000..f3ef897c5 --- /dev/null +++ b/crates/axl-runtime/src/builtins/aspect/bazel.axl @@ -0,0 +1,41 @@ +""" +Bazel exit code constants. + +These correspond to the exit codes defined in Bazel's ExitCode.java: +https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/util/ExitCode.java +""" + +exit_codes = struct( + SUCCESS = 0, + BUILD_FAILURE = 1, + PARSING_FAILURE = 1, + COMMAND_LINE_ERROR = 2, + TESTS_FAILED = 3, + PARTIAL_ANALYSIS_FAILURE = 3, + NO_TESTS_FOUND = 4, + RUN_FAILURE = 6, + ANALYSIS_FAILURE = 7, + INTERRUPTED = 8, + LOCK_HELD_NOBLOCK_FOR_LOCK = 9, + REMOTE_ENVIRONMENTAL_ERROR = 32, + OOM_ERROR = 33, + REMOTE_ERROR = 34, + LOCAL_ENVIRONMENTAL_ERROR = 36, + BLAZE_INTERNAL_ERROR = 37, + TRANSIENT_BUILD_EVENT_SERVICE_UPLOAD_ERROR = 38, + REMOTE_CACHE_EVICTED = 39, + PERSISTENT_BUILD_EVENT_SERVICE_UPLOAD_ERROR = 45, + EXTERNAL_DEPS_ERROR = 48, +) + +# https://bazel.build/run/scripts#exit-codes +def default_retry(code: int) -> bool: + """Returns True if the given exit code is retryable. + + Retryable codes are those indicating transient infrastructure failures + where re-running the command may succeed: + - BLAZE_INTERNAL_ERROR (37): Bazel server crash. + - LOCAL_ENVIRONMENTAL_ERROR (36): Local env failure, often caused by + a queued command failing because the server is crashing. + """ + return code == exit_codes.BLAZE_INTERNAL_ERROR or code == exit_codes.LOCAL_ENVIRONMENTAL_ERROR diff --git a/crates/axl-runtime/src/builtins/aspect/build.axl b/crates/axl-runtime/src/builtins/aspect/build.axl index bebad3947..14d1d3092 100644 --- a/crates/axl-runtime/src/builtins/aspect/build.axl +++ b/crates/axl-runtime/src/builtins/aspect/build.axl @@ -1,6 +1,7 @@ """ A default 'build' task that wraps a 'bazel build' command. """ +load("./bazel.axl", "default_retry") BuildConfig = spec( # Declarative data — composable, zero-cost reads @@ -15,6 +16,7 @@ BuildConfig = spec( # Lifecycle — only called when set build_start = attr(typing.Callable[[], None] | None, None), build_event = attr(typing.Callable[[dict, str, str], None] | None, None), + build_retry = attr(typing.Callable[[int], bool], default_retry), build_end = attr(typing.Callable[[int], None] | None, None), ) @@ -65,20 +67,24 @@ def impl(ctx: TaskContext) -> int: if ctx.config.build_start: ctx.config.build_start() - build = ctx.bazel.build( - build_events = build_events, - flags = flags, - startup_flags = startup_flags, - *ctx.args.target_pattern, - ) + for _ in range(10): + build = ctx.bazel.build( + build_events = build_events, + flags = flags, + startup_flags = startup_flags, + *ctx.args.target_pattern, + ) + + if ctx.config.build_event: + handler = ctx.config.build_event + state = {} + for event in build.build_events(): + handler(ctx, state, event) - if ctx.config.build_event: - handler = ctx.config.build_event - state = {} - for event in build.build_events(): - handler(ctx, state, event) + build_status = build.wait() - build_status = build.wait() + if build_status.code == 0 or not ctx.config.build_retry(build_status.code): + break if ctx.config.build_end: ctx.config.build_end(build_status.code) diff --git a/crates/axl-runtime/src/builtins/mod.rs b/crates/axl-runtime/src/builtins/mod.rs index d5093dee8..034c2b05d 100644 --- a/crates/axl-runtime/src/builtins/mod.rs +++ b/crates/axl-runtime/src/builtins/mod.rs @@ -11,6 +11,7 @@ struct Builtin { const ASPECT: Builtin = Builtin { name: "aspect", files: &[ + ("bazel.axl", include_str!("./aspect/bazel.axl")), ("build.axl", include_str!("./aspect/build.axl")), ("test.axl", include_str!("./aspect/test.axl")), ("axl_add.axl", include_str!("./aspect/axl_add.axl")), From 5a7b18da5218cc50fbe80a4037d9293a9a4575ae Mon Sep 17 00:00:00 2001 From: thesayyn Date: Sun, 15 Feb 2026 15:02:20 -0800 Subject: [PATCH 62/65] version.axl is now working --- .aspect/imagination.axl | 25 + .aspect/version.axl | 2 +- Cargo.lock | 7 +- Cargo.toml | 2 +- axel-f/BUILD.bazel | 14 - axel-f/Cargo.toml | 4 - axel-f/MODULE.aspect | 21 - axel-f/docs/lint-task.md | 199 ----- axel-f/docs/sarif-translation.md | 178 ----- axel-f/docs/status.md | 75 -- axel-f/docs/what_is_this.md | 268 ------- axel-f/src/lib.rs | 31 - bazel/proto/BUILD.bazel | 3 +- bazel/proto/MODULE.bazel.lock | 731 ++++++++++++++++++ crates/aspect-cli/src/main.rs | 4 +- crates/aspect-launcher/src/config.rs | 12 +- crates/axl-proto/Cargo.toml | 3 +- crates/axl-proto/build.rs | 22 +- crates/axl-proto/descriptor.bin | Bin 485220 -> 612404 bytes crates/axl-proto/src/lib.rs | 38 + crates/axl-runtime/BUILD.bazel | 1 - crates/axl-runtime/Cargo.toml | 1 - .../src/builtins/aspect/MODULE.aspect | 22 + .../src/builtins/aspect}/config/builtins.axl | 0 .../src/builtins/aspect}/config/delivery.axl | 0 .../src/builtins/aspect}/config/lint.axl | 0 .../src/builtins/aspect}/config/nolint.axl | 0 .../src/builtins/aspect}/lib/deliveryd.axl | 0 .../src/builtins/aspect}/lib/github.axl | 0 .../src/builtins/aspect}/lib/linting.axl | 0 .../src/builtins/aspect}/lib/platform.axl | 0 .../src/builtins/aspect}/lib/sarif.axl | 0 .../src/builtins/aspect}/tasks/delivery.axl | 0 .../builtins/aspect}/tasks/dummy_format.axl | 0 .../src/builtins/aspect}/tasks/dummy_lint.axl | 0 .../src/builtins/aspect}/tasks/migrate.axl | 0 .../src/builtins/aspect}/tasks/warming.axl | 0 crates/axl-runtime/src/builtins/mod.rs | 69 +- crates/axl-runtime/src/engine/mod.rs | 7 + crates/starbuf-derive/src/lib.rs | 499 +++++++++++- docs/lib.md | 58 +- docs/lib/future.md | 16 + docs/lib/http.md | 15 +- docs/lib/remote.md | 3 + docs/lib/remote/execution.md | 5 + examples/deliveryd/MODULE.bazel.lock | 634 +++++++++++++++ examples/imagination/go.mod | 3 + examples/imagination/imagination.wasm | Bin 0 -> 1620077 bytes examples/imagination/main.go | 41 + examples/large_bes/MODULE.bazel.lock | 191 +++++ 50 files changed, 2366 insertions(+), 838 deletions(-) create mode 100644 .aspect/imagination.axl delete mode 100644 axel-f/BUILD.bazel delete mode 100644 axel-f/Cargo.toml delete mode 100644 axel-f/MODULE.aspect delete mode 100644 axel-f/docs/lint-task.md delete mode 100644 axel-f/docs/sarif-translation.md delete mode 100644 axel-f/docs/status.md delete mode 100644 axel-f/docs/what_is_this.md delete mode 100644 axel-f/src/lib.rs create mode 100644 bazel/proto/MODULE.bazel.lock rename {axel-f => crates/axl-runtime/src/builtins/aspect}/config/builtins.axl (100%) rename {axel-f => crates/axl-runtime/src/builtins/aspect}/config/delivery.axl (100%) rename {axel-f => crates/axl-runtime/src/builtins/aspect}/config/lint.axl (100%) rename {axel-f => crates/axl-runtime/src/builtins/aspect}/config/nolint.axl (100%) rename {axel-f => crates/axl-runtime/src/builtins/aspect}/lib/deliveryd.axl (100%) rename {axel-f => crates/axl-runtime/src/builtins/aspect}/lib/github.axl (100%) rename {axel-f => crates/axl-runtime/src/builtins/aspect}/lib/linting.axl (100%) rename {axel-f => crates/axl-runtime/src/builtins/aspect}/lib/platform.axl (100%) rename {axel-f => crates/axl-runtime/src/builtins/aspect}/lib/sarif.axl (100%) rename {axel-f => crates/axl-runtime/src/builtins/aspect}/tasks/delivery.axl (100%) rename {axel-f => crates/axl-runtime/src/builtins/aspect}/tasks/dummy_format.axl (100%) rename {axel-f => crates/axl-runtime/src/builtins/aspect}/tasks/dummy_lint.axl (100%) rename {axel-f => crates/axl-runtime/src/builtins/aspect}/tasks/migrate.axl (100%) rename {axel-f => crates/axl-runtime/src/builtins/aspect}/tasks/warming.axl (100%) create mode 100644 docs/lib/remote.md create mode 100644 docs/lib/remote/execution.md create mode 100644 examples/deliveryd/MODULE.bazel.lock create mode 100644 examples/imagination/go.mod create mode 100755 examples/imagination/imagination.wasm create mode 100644 examples/imagination/main.go create mode 100644 examples/large_bes/MODULE.bazel.lock diff --git a/.aspect/imagination.axl b/.aspect/imagination.axl new file mode 100644 index 000000000..3a12b86b6 --- /dev/null +++ b/.aspect/imagination.axl @@ -0,0 +1,25 @@ +def _img_impl(ctx): + ac = remote.execution.ActionCache( + uri = "grpcs://testing.buildbuddy.io", + headers = {}, + timeout = 10000, + ) + ac.connect(ctx) + + req = remote.execution.GetActionResultRequest( + instance_name = "example-instance", + action_digest = remote.execution.Digest( + hash = "0123456789abcdef", + size_bytes = 123, + ), + inline_stdout = True, + inline_stderr = True, + ) + + result = ac.GetActionResult(req) + print("action result:", result) + +imagine = task( + implementation = _img_impl, + args = {} +) diff --git a/.aspect/version.axl b/.aspect/version.axl index 31802e199..5c04253b1 100644 --- a/.aspect/version.axl +++ b/.aspect/version.axl @@ -1,5 +1,5 @@ version( - "2025.46.20", + use = "2025.46.20", sources = [ local("target/debug/aspect-cli"), local("bazel-bin/crates/aspect-cli/aspect-cli"), diff --git a/Cargo.lock b/Cargo.lock index a3a9b7604..476b51066 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -271,10 +271,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" -[[package]] -name = "axel-f" -version = "0.0.1" - [[package]] name = "axl-docgen" version = "0.0.0-dev" @@ -314,6 +310,7 @@ dependencies = [ "starbuf-types", "starlark", "starlark_derive", + "tokio", "tonic", "tonic-build", "tonic-prost", @@ -328,7 +325,6 @@ dependencies = [ "anyhow", "arc-slice", "aspect-telemetry", - "axel-f", "axl-proto", "base64 0.22.1", "build-event-stream", @@ -4570,6 +4566,7 @@ dependencies = [ "tower-layer", "tower-service", "tracing", + "webpki-roots", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index bf3db772c..73aeb0629 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["crates/*", "axel-f"] +members = ["crates/*"] exclude = ["crates/example-tui", "examples/lint"] default-members = ["crates/aspect-cli"] resolver = "2" diff --git a/axel-f/BUILD.bazel b/axel-f/BUILD.bazel deleted file mode 100644 index 05df07ffd..000000000 --- a/axel-f/BUILD.bazel +++ /dev/null @@ -1,14 +0,0 @@ -load("//bazel/rust:defs.bzl", "rust_library") - -rust_library( - name = "axel-f", - srcs = glob(["src/**/*.rs"]), - compile_data = glob([ - "**/*.axl", - "**/*.aspect", - ]), - visibility = [ - "//crates/axl-runtime:__pkg__", - "//crates/aspect-cli:__pkg__", - ], -) diff --git a/axel-f/Cargo.toml b/axel-f/Cargo.toml deleted file mode 100644 index a332e24f1..000000000 --- a/axel-f/Cargo.toml +++ /dev/null @@ -1,4 +0,0 @@ -[package] -name = "axel-f" -version = "0.0.1" -edition.workspace = true diff --git a/axel-f/MODULE.aspect b/axel-f/MODULE.aspect deleted file mode 100644 index a7aed57a7..000000000 --- a/axel-f/MODULE.aspect +++ /dev/null @@ -1,21 +0,0 @@ -# Register warming tasks. -use_task("tasks/warming.axl", "restore", "update") - -# Configure delivery -use_config("config/delivery.axl", "configure_delivery") - -# Configure builtins -use_config("config/builtins.axl", "configure_builtins") - -# Configure rules_lint if its declared by user -use_config( - "config/lint.axl", - "configure_rules_lint", - requires = ["aspect_rules_lint"] -) - -use_config( - "config/nolint.axl", - "configure_dummy_lint", - conflicts = ["aspect_rules_lint"] -) diff --git a/axel-f/docs/lint-task.md b/axel-f/docs/lint-task.md deleted file mode 100644 index 458d2ded3..000000000 --- a/axel-f/docs/lint-task.md +++ /dev/null @@ -1,199 +0,0 @@ -# Lint Task - -This document describes how the lint task works within the Rosetta workflow system. It is aimed at internal engineers who maintain or extend the task. - -## Overview - -The lint task wraps `aspect lint` — a Bazel-native linting command — and adds CI-aware behavior on top of it. Its primary job is to: - -1. Run `aspect lint` against a set of Bazel targets. -2. Parse the structured lint output (a JSON diagnostics file produced from SARIF). -3. Decide which diagnostics are relevant to the current change. -4. Determine whether the task should pass or fail. -5. Surface results as GitHub check annotations and PR review suggestions. - -## Configuration - -The lint task is configured through a schema that extends the base Bazel task configuration. The lint-specific fields are: - -| Field | Type | Default | Description | -|---|---|---|---| -| `targets` | `string[]` | `['//...']` | Bazel target patterns to lint. | -| `failure_strategy` | `'soft' \| 'hard' \| 'hold_the_line'` | `'hold_the_line'` | Controls when a lint failure causes the task to go red. See [Failure Strategies](#failure-strategies). | -| `only_annotate_changed_regions` | `boolean` | `true` | When true, GitHub annotations are scoped to files changed in the current PR. When false, all lint issues are annotated. | -| `icon` | `string` | `'broom'` | Emoji used in the task label. | - -## Failure Strategies - -### The problem - -Large codebases accumulate lint violations over time. Turning on a new linter — or tightening rules — would flag thousands of pre-existing issues. If the build went red for all of them, the lint task would be unusable until every legacy violation was cleaned up. That is rarely practical. - -At the same time, purely advisory linting ("soft" mode) is easy to ignore, and violations continue to pile up. - -### Hold the line - -The default strategy, `hold_the_line`, is a middle ground. It answers the question: *"Did this PR make things worse?"* - -- On a PR build, the task compares lint errors against the set of files changed in the PR. If any error-severity diagnostics come from changed files, the task fails. -- On a non-PR build (e.g. a post-merge CI run on `main`), the task never fails, because there is no meaningful "changed file" set to compare against. - -This lets teams adopt new linters immediately. Existing violations are tolerated, but new ones are blocked at the PR gate. Over time, the codebase improves organically as engineers touch files and fix violations along the way. - -#### How hold the line is implemented - -The mechanism relies on three things: PR detection, a git diff, and a two-tier filtering model. - -**PR detection.** The task asks the host (e.g. the GitHub Actions host) whether this is a PR build. On GitHub Actions, this is determined by inspecting the `GITHUB_REF` environment variable. If it matches the pattern `refs/pull//merge`, the build is a PR build. On non-PR builds (branch pushes, scheduled runs, manual triggers), hold-the-line never fails — there is no changed-file set to compare against. - -**Git diff.** The task lazily generates a diff by running `git diff HEAD~ HEAD` and writing the result to a temporary file. The diff is parsed into a list of `{ file, lines }` tuples, where `lines` contains the 0-based line numbers of *added* lines only (not removed or context lines). Deleted files are excluded entirely. - -**Two-tier filtering.** The task applies two different predicates depending on the diagnostic type: - -- *File-level matching* (used for annotations): A diagnostic matches if its source file path appears anywhere in the diff. This is a loose check — the error doesn't need to be on a changed line, just in a changed file. -- *Line-level matching* (used for suggestions): A diagnostic matches only if its source file *and* specific line number both appear in the diff. This is strict — the suggestion must point at a line the author actually added. - -**The failure decision.** The `shouldFail` method receives two lists: `filteredDiagnostics` (only diagnostics from changed files/lines) and `allDiagnostics` (every diagnostic found). Under hold-the-line, it checks whether the build is a PR and whether `filteredDiagnostics` contains any error-severity entries. Under hard mode, it checks `allDiagnostics` instead. Under soft mode, it always returns false. - -### Soft - -The task never fails, regardless of how many lint errors exist. Diagnostics are still collected and surfaced as GitHub annotations/suggestions, but the build stays green. - -### Hard - -The task fails if *any* error-severity diagnostic exists, regardless of whether the error comes from a changed file. This is appropriate for codebases that are already clean and want to enforce zero lint errors at all times. - -### Summary - -| Strategy | Fails on PR builds? | Fails on non-PR builds? | -|---|---|---| -| `soft` | Never | Never | -| `hold_the_line` | Only if errors are from changed files | Never | -| `hard` | If any errors exist | If any errors exist | - -## Bazel Invocation - -The task constructs a Bazel command with two additional flags beyond what the base task provides: - -- `--machine` — Requests structured (machine-readable) output from the CLI. -- `--lint_diagnostics_file=` — Tells the CLI to write lint results as a JSON file to a temporary path. This file is the primary input for all downstream processing. - -The temporary path is deterministic and namespaced by workspace and task ID to avoid collisions when multiple lint tasks run in the same pipeline. - -## From SARIF to GitHub Comments - -The path from linter output to GitHub annotations and suggestions spans three layers: the Aspect CLI (Go), the Rosetta lint task (TypeScript), and Marvin (the notification backend). This section traces the full journey. - -### Layer 1: Aspect CLI — SARIF to diagnostics - -Individual linters (eslint, flake8, etc.) produce SARIF reports and/or patch files. The Aspect CLI converts these into a unified diagnostics format before writing them to the JSON file specified by `--lint_diagnostics_file`. - -**SARIF reports become annotations.** The CLI walks each SARIF run's results and locations, producing one diagnostic per finding. The severity is mapped from the SARIF level (`error` becomes `ERROR`, everything else becomes `WARNING`). The source file comes from the artifact location URI. The line number comes from the region's `startLine`. Each diagnostic gets `baggage["lint_result_type"] = "annotation"` and `baggage["label"]` set to the originating Bazel target. - -**Patch files become suggestions.** When a linter emits a unified diff (a fix), the CLI parses the diff hunks and produces one diagnostic per hunk. The `help` field contains the suggested replacement text. The span's offset and height come from the diff line numbers. Each diagnostic gets `baggage["lint_result_type"] = "suggestion"`. - -The result is a JSON file with a top-level `diagnostics` array containing both annotations and suggestions, uniformly represented as `DiagnosticInput` objects. - -### Layer 2: Rosetta lint task — filtering and capping - -This is where the bulk of the logic described in this document lives. The lint task reads the diagnostics file, normalizes workspace paths, filters diagnostics against the git diff, sorts them, caps them, and determines pass/fail. The details are covered in [Diagnostics Processing](#diagnostics-processing). - -The output is a `lint-task-completed` event containing the processed diagnostics array, lint counts, repro/fix commands, and the pass/fail decision. This event is consumed by the Marvin listener. - -### Layer 3: Marvin — diagnostics to GitHub - -The Marvin listener receives the `lint-task-completed` event and forwards the diagnostics to the Marvin backend, which translates them into GitHub API calls. - -**Annotations become GitHub check annotations.** Diagnostics with `lint_result_type = "annotation"` (or no type) are posted as annotations on the GitHub check run. The severity maps to an annotation level: `ERROR` becomes `failure`, `WARNING` becomes `warning`, and everything else becomes `notice`. The annotation includes the file path, line range, title, and message. - -**Suggestions become GitHub PR review comments.** Diagnostics with `lint_result_type = "suggestion"` are posted as review comments on the pull request using the GitHub Pulls API. Each comment includes the file path, line number, span height (for multi-line suggestions), and the suggested replacement text from the `help` field. These render as GitHub's native suggestion blocks that the author can apply with one click. - -### Controlling what gets posted - -Two workflow-level configuration flags control whether diagnostics are surfaced on GitHub: - -- `notifications.github.annotations` (default `true`) — When false, no check run annotations are created. The lint task short-circuits annotation processing entirely and returns an empty list. -- `notifications.github.suggestions` (default `true`) — When false, no PR review suggestion comments are created. The lint task short-circuits suggestion processing entirely. - -A third flag, `notifications.github.show_aspect_cli_commands`, controls whether the repro and fix commands are included in the output. When false, these are omitted even if there are error-severity diagnostics. - -## Diagnostics Processing - -After Bazel finishes, the task reads the JSON diagnostics file. Processing happens in several stages. - -### 1. Parse - -The file contains a top-level `diagnostics` array. Each entry is a `DiagnosticInput` with fields like severity, message, title, source location, spans (line/column offsets), and a `baggage` map of arbitrary metadata. - -Two pieces of baggage are significant for lint: - -- `lint_result_type` — either `"annotation"` or `"suggestion"`. Annotations are "this is wrong" messages. Suggestions are "here is a fix" messages with replacement content. -- `label` — the Bazel label of the target that produced the diagnostic. Used to construct repro and fix commands. - -### 2. Workspace path normalization - -If the task runs in a subdirectory workspace (not the repo root), file paths in diagnostics need to be prefixed with the workspace path so they align with the repository-root-relative paths that GitHub expects. - -### 3. Changed file detection - -The task lazily generates a git diff (via `git diff HEAD~ HEAD`) that describes which files and lines changed in the current commit. The diff is parsed using the `parse-git-patch` library into a list of `{ file, lines }` tuples, where `lines` are the 0-based line numbers of added lines only. - -- **Changed file**: a diagnostic's source file appears anywhere in the diff. -- **Changed line**: a diagnostic's source file *and* specific line number (from the span offset) appear in the diff. Additionally, the diagnostic must have exactly one span with a valid offset. - -These two predicates are used differently depending on the diagnostic type (see below). - -### 4. Split into annotations and suggestions - -Diagnostics are partitioned by their `lint_result_type` baggage value. - -**Annotations** (errors and warnings): -- Filtered to changed *files* (not individual lines) when `only_annotate_changed_regions` is true. -- When `only_annotate_changed_regions` is false, all annotations are included. -- Capped at **25** per task invocation to avoid flooding the PR. -- The `help` field is stripped from annotations before publishing (suggestions carry help, annotations don't need it). - -**Suggestions** (auto-fixable issues): -- Always filtered to changed *lines* — suggestions are only relevant if they touch code the author just wrote. -- Capped at **10** per task invocation. -- The `message` field is stripped from suggestions before publishing (the suggestion content in `help` is the message). - -### 5. Sorting - -Both annotations and suggestions are sorted by a stable, multi-level comparator. The priority order (highest first) is: - -1. Diagnostic is from a changed line -2. Diagnostic is from a changed file -3. Higher severity (error > warning > info) -4. File path (alphabetical) -5. Line number (ascending) -6. Title, message, help (alphabetical tiebreakers) - -Because the lists are capped after sorting, this ordering ensures that the most relevant diagnostics — those closest to the author's changes and highest severity — survive the cut. - -### 6. Repro and fix commands - -If the workflow configuration has `show_aspect_cli_commands` enabled, the task constructs CLI commands users can run locally: - -- **Repro command**: `bazel lint ...` — reproduces the errors locally. Only includes targets from error-severity diagnostics, deduplicated. -- **Fix command**: Same as the repro command with `--fix` appended — auto-applies fixes where possible. - -## Error Handling - -The task handles several error scenarios: - -- **Non-lint Bazel failures** (exit codes other than 0 or the lint-specific failure code): The task fails immediately without attempting to parse diagnostics. No annotations or suggestions are produced. -- **Missing or unreadable diagnostics file**: The task fails. This typically indicates a CLI bug or a misconfigured pipeline. -- **Failed git diff parsing**: The task fails. A log diagnostic is emitted noting the failure. -- **Unexpected exceptions during diagnostic processing**: Caught and logged. The task fails conservatively. - -In all error cases, the `lint-task-completed` event is still published with `successful: false` and empty diagnostic lists, so Marvin receives a consistent signal and can update the check run accordingly. - -## Exit Code Mapping - -| Scenario | Bazel exit code | Task outcome | -|---|---|---| -| No lint issues | `0` (OK) | Pass | -| Lint issues found, strategy says pass | Lint failure code | Pass (exit code overridden to OK) | -| Lint issues found, strategy says fail | Lint failure code | Fail | -| Bazel internal error | Any other code | Fail | diff --git a/axel-f/docs/sarif-translation.md b/axel-f/docs/sarif-translation.md deleted file mode 100644 index 0306a485b..000000000 --- a/axel-f/docs/sarif-translation.md +++ /dev/null @@ -1,178 +0,0 @@ -# SARIF to GitHub PR Comments Translation - -This document describes how to translate SARIF (Static Analysis Results Interchange Format) output from linters into GitHub PR review comments. - -## SARIF Input (from linter) - -```json -{ - "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", - "runs": [ - { - "tool": { - "driver": { - "name": "ESLint" - } - }, - "results": [ - { - "level": "error", - "message": { - "text": "'foo' is defined but never used" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "src/index.ts" - }, - "region": { - "startLine": 5, - "startColumn": 7, - "endLine": 5, - "endColumn": 10 - } - } - } - ] - } - ] - } - ] -} -``` - -## GitHub PR Review API - -**Endpoint:** `POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews` - -**Payload:** -```json -{ - "commit_id": "abc123def456", - "event": "COMMENT", - "body": "Lint results", - "comments": [ - { - "path": "src/index.ts", - "line": 5, - "side": "RIGHT", - "body": "**ESLint** (error)\n\n'foo' is defined but never used" - } - ] -} -``` - ---- - -## Field Mapping: SARIF to GitHub - -| SARIF Path | GitHub Field | -|------------|--------------| -| `runs[].tool.driver.name` | Used in `comments[].body` prefix | -| `runs[].results[].level` | Used in `comments[].body` (error/warning) | -| `runs[].results[].message.text` | `comments[].body` content | -| `runs[].results[].locations[].physicalLocation.artifactLocation.uri` | `comments[].path` | -| `runs[].results[].locations[].physicalLocation.region.startLine` | `comments[].line` (single-line) or `comments[].start_line` (multi-line) | -| `runs[].results[].locations[].physicalLocation.region.endLine` | `comments[].line` (end of range) | - ---- - -## Patch Input (unified diff) - -```diff ---- a/src/index.ts -+++ b/src/index.ts -@@ -8,4 +8,3 @@ - const bar = 1; --const unused = 2; --const baz = unused + 1; -+const baz = bar + 1; -``` - -## GitHub PR Review with Suggestion - -```json -{ - "commit_id": "abc123def456", - "event": "COMMENT", - "comments": [ - { - "path": "src/index.ts", - "start_line": 9, - "line": 10, - "side": "RIGHT", - "body": "**ESLint**\n\n```suggestion\nconst baz = bar + 1;\n```" - } - ] -} -``` - ---- - -## Field Mapping: Patch to GitHub - -| Patch Component | GitHub Field | -|-----------------|--------------| -| `+++ b/path/to/file` (strip `b/`) | `comments[].path` | -| `@@ -8,4 +8,3 @@` new start line | `comments[].start_line` | -| Last affected line in hunk | `comments[].line` | -| Lines starting with `+` (without the `+`) | Content inside ` ```suggestion ``` ` block | - ---- - -## Multi-line Example - -**SARIF with range:** -```json -{ - "runs": [{ - "tool": {"driver": {"name": "Ruff"}}, - "results": [{ - "level": "warning", - "message": {"text": "Multiple imports on one line"}, - "locations": [{ - "physicalLocation": { - "artifactLocation": {"uri": "src/main.py"}, - "region": { - "startLine": 1, - "endLine": 3 - } - } - }] - }] - }] -} -``` - -**GitHub comment (multi-line):** -```json -{ - "commit_id": "abc123", - "event": "COMMENT", - "comments": [{ - "path": "src/main.py", - "start_line": 1, - "line": 3, - "side": "RIGHT", - "body": "**Ruff** (warning)\n\nMultiple imports on one line" - }] -} -``` - ---- - -## GitHub Suggestion Syntax - -The `body` field uses GitHub's suggestion markdown: - -```markdown -**ToolName** - -```suggestion -replacement code here -line 2 of replacement -``` -``` - -When rendered, GitHub displays an "Apply suggestion" button allowing one-click fixes. diff --git a/axel-f/docs/status.md b/axel-f/docs/status.md deleted file mode 100644 index 03ac43f8a..000000000 --- a/axel-f/docs/status.md +++ /dev/null @@ -1,75 +0,0 @@ -# Rosetta Feature Migration Status - -Tracking what existed in Rosetta (TypeScript) and where each feature ended up in the new architecture. - -## Architecture Changes - -The new system no longer wraps the CI configuration file. Instead, the CI configuration calls into the Aspect CLI directly. This eliminates the need for pipeline generation, condition expressions, multi-workspace orchestration, and several system tasks that only existed to support the wrapper model. - -## Task Types - -| Task | Status | Notes | -|------|--------|-------| -| build | Implemented | `@aspect//build.axl` builtin + axel-f config hooks | -| test | Implemented | `@aspect//test.axl` builtin + axel-f config hooks | -| lint | Implemented | Via `@aspect_rules_lint` package + axel-f GitHub integration | -| format | Implemented | Via `@aspect_rules_lint` package | -| delivery | Implemented | `axel-f/tasks/delivery.axl` with deliveryd integration | -| configure | Not yet implemented | Third-party package | -| gazelle | Not yet implemented | Third-party package | -| buildifier | Not yet implemented | Third-party package | -| warming | Not yet implemented | `bazel build --nobuild` to pre-warm cache on dedicated queue | -| checkout / branch freshness | Not yet implemented | Stale branch detection, rebase/merge, annotations | -| bazel_health_probe | Removed | No longer needed | -| finalization | Removed | No longer needed | -| delivery_manifest | Removed | Architectural change — delivery no longer uses manifests | -| noop | Removed | Was only used for testing | - -## Major Features - -### Implemented in axel-f - -| Feature | Location | Notes | -|---------|----------|-------| -| Platform config reading | `lib/platform.axl` | Reads `/etc/aspect/workflows/platform/` files | -| Bazelrc flag generation | `lib/platform.axl` | Dynamic flags based on Bazel version, host, platform config | -| BES sink configuration | `config/builtins.axl` | Reads bessie_endpoint, configures gRPC sink | -| GitHub check runs | `lib/github.axl` | Create/update check runs with annotations | -| GitHub PR reviews | `lib/github.axl` | Review comments, code suggestions | -| SARIF translation | `lib/sarif.axl` | SARIF lint output to GitHub review comments | -| Lint hold-the-line | `config/lint.axl` | GitHub-aware lint strategy with changed file filtering | -| CI config migration | `tasks/migrate.axl` | Generates GitHub Actions / Buildkite configs from old workflows.yaml | -| Bazel exit codes | `@aspect//bazel.axl` | Exit code constants and default retry predicate | -| Build metadata | `config/builtins.axl` | CI info attached to bazel invocations | -| Deliveryd integration | `lib/deliveryd.axl` | Unix socket HTTP client for delivery daemon | - -### Moved to Aspect CLI (Rust) - -| Feature | Notes | -|---------|-------| -| OpenTelemetry tracing & metrics | Built into the CLI runtime | -| Bazel version detection | Built into the CLI runtime | -| Shell execution with tracing | Built into the CLI runtime | - -### Removed — architectural changes - -| Feature | Reason | -|---------|--------| -| Pipeline generation (steps command) | CI config now calls the CLI directly, not the other way around | -| Condition expressions (`when:` clauses) | No longer wrapping CI config; CI platform handles conditional execution | -| Multi-workspace orchestration | CI config handles workspace matrix; CLI runs in a single workspace | -| Marvin result reporting | Replaced with direct GitHub API calls from axel-f | -| Configuration validation (config command) | No longer have a workflows.yaml to validate | -| Event bus (RxJS pub/sub) | Not needed; task lifecycle is simpler without the wrapper model | -| CI host abstraction (Host interface) | CI platform is known at config time; no runtime detection needed | -| Buildkite annotations (buildkite-agent annotate) | CI platform handles its own annotations | -| Task hooks (before_task / after_task) | CI platform handles pre/post steps natively | -| Bazel server log archiving on crash | Can be handled by CI platform artifact upload | -| Debug assistance mode (execution logs, gRPC logs) | Users enable these via bazel flags directly | - -## Not Yet Implemented - -| Feature | Priority | Description | -|---------|----------|-------------| -| Warming task | TBD | Run `bazel build --nobuild` on targets from build/test tasks to warm the remote cache on a dedicated queue | -| Checkout / branch freshness | TBD | Detect stale branches, run rebase/merge, post annotations with fix commands | diff --git a/axel-f/docs/what_is_this.md b/axel-f/docs/what_is_this.md deleted file mode 100644 index fa22ddede..000000000 --- a/axel-f/docs/what_is_this.md +++ /dev/null @@ -1,268 +0,0 @@ -# What is axel-f? - -axel-f is a configuration library for the Aspect CLI. It hooks into the CLI's built-in tasks (`build`, `test`, and conditionally `lint`) to augment them for the Aspect Workflows environment. - -It does not define its own tasks. Instead, it provides a `config.axl` that configures existing tasks with: - -- **Environment discovery** - reads platform configuration from disk (`/etc/aspect/workflows/platform/`) to detect available services like remote cache endpoints, BES endpoints, and RBE configuration. -- **Service detection** - automatically detects and connects to services available during Aspect Workflows CI runs (e.g. deliveryd for artifact delivery, remote cache, build result storage). -- **Flag injection** - generates and injects bazelrc flags (startup flags, build flags) based on the detected environment, Bazel version, and host configuration. -- **CI integration** - when running in CI (GitHub Actions, Buildkite), integrates with GitHub APIs to post check runs, PR review comments, and lint suggestions with auto-fix support. -- **Lifecycle hooks** - hooks into task lifecycle events (build start/end, build events, delivery) to coordinate reporting and artifact management. - -## How it fits in - -axel-f is an external package, shipped with the CLI by default but resolved through `MODULE.aspect` like any other dependency. The architecture: - -1. **Rust runtime** - Starlark interpreter + native APIs (`ctx.bazel`, `ctx.http()`, `ctx.std.*`) -2. **Builtins** (compiled into the binary) - `@aspect` (build, test, axl add) and `@axel-f` (config) -3. **External packages** (via `MODULE.aspect`) - `aspect_rules_lint`, etc. -4. **Customer config** (`.aspect/config.axl`, optional) - customer-specific overrides and customization - -axel-f and packages like `aspect_rules_lint` are peers in the dependency graph. axel-f is the "batteries included" package that makes the built-in tasks work seamlessly in the Aspect Workflows environment. - -## Packaging and embedding - -axel-f is a separate Rust crate that lives in its own repository. It is embedded into the CLI binary at compile time. - -### Crate structure - -`src/lib.rs` is minimal — it exports a single constant: - -```rust -pub const FILES: &[(&str, &str)] = &[ - ("MODULE.aspect", include_str!("../MODULE.aspect")), - ("config.axl", include_str!("../config.axl")), - // ... all .axl files -]; -``` - -### How it ships - -The CLI's builtin system (`crates/axl-runtime/src/builtins/mod.rs`) treats axel-f the same as the `@aspect` builtin: - -- **Debug builds**: reads .axl files directly from the source tree (no extraction needed) -- **Release builds**: uses the `axel_f::FILES` constant (compiled into the binary via `include_str!`), extracts files to a content-hashed cache directory at runtime - -Both builtins are defined as `Builtin { name, files }` entries in a unified `ALL` array. A single loop handles hashing and extraction for all builtins. - -### Dependency tracking - -During development, the CLI workspace references axel-f as a local path dependency: - -```toml -# crates/axl-runtime/Cargo.toml -axel-f = { path = "../../axel-f" } -``` - -When axel-f moves to its own repo, this changes to a git reference: - -```toml -axel-f = { git = "https://github.com/aspect-build/axel-f", tag = "v0.1.0" } -``` - -The CLI can also use a git submodule pointing to the axel-f repo, with the Cargo.toml path pointing at the submodule checkout. This gives reproducible builds with a pinned commit SHA while keeping the repos independent. - -### Auto-enable - -Both `@aspect` and `@axel-f` builtins are auto-enabled for `use_config`. This is set in `disk_store.rs` where builtin deps are constructed with `use_config: true`. Customers don't need to declare anything — builtin configs just work. External packages (non-builtins) still require explicit `use_config = True` on the dep declaration in the customer's `MODULE.aspect`. - -If a customer explicitly declares a dep with the same name as a builtin (e.g. `axl_archive_dep(name = "axel-f", ...)`), the customer's dep overrides the builtin. In that case, the customer controls the `use_config` flag — the auto-enable only applies to the default builtin version. - -## What it does NOT do - -- Define core tasks (`build`, `test`, `lint`) - those are builtins or come from other packages -- Replace or wrap the Bazel command - the CLI invokes Bazel as a subprocess -- Require customer configuration - it works out of the box by auto-detecting the environment - ---- - -# Config evaluation model - -## Opt-in via use_config - -Config evaluation from external packages requires explicit opt-in. A package having a `config.axl` file does nothing on its own. Two declarations are required (builtins like `@aspect` and `@axel-f` are the exception — they are auto-enabled): - -### Package side: declaring config availability - -A package declares its config functions in its own `MODULE.aspect`: - -```python -# In the package's MODULE.aspect -use_config("./config.axl", "config") -use_config("./lint_config.axl", "lint_config", - requires = [("aspect_rules_lint", "^1.0.0")]) -``` - -This says "I offer these config functions" but has no effect until the consumer enables them. A package can declare multiple `use_config()` directives for different config functions from the same or different files. - -#### Conditional activation with `requires` and `conflicts` - -`use_config()` supports two parameters for conditional activation based on the resolved dependency graph: - -- **`requires`** - packages that must be present for this config to activate -- **`conflicts`** - packages that must be absent for this config to activate - -If any condition is not met, the runtime **skips the entire file** - it is never loaded, so `load()` statements referencing conditional packages never execute. - -`requires` accepts either bare strings (any version) or `(name, version_constraint)` tuples: - -```python -requires = ["aspect_rules_lint"] # any version -requires = [("aspect_rules_lint", "^1.0.0")] # version-constrained -requires = [("aspect_rules_lint", ">= 1.0.0, < 2.0.0")] # explicit range -``` - -`conflicts` accepts bare package name strings: - -```python -conflicts = ["aspect_rules_lint"] -``` - -Multiple entries in either list are AND-ed: all conditions must be satisfied. - -#### Version constraint syntax - -Version constraints follow Cargo/semver conventions: - -| Syntax | Meaning | Example | -|---|---|---| -| `^1.0.0` | Compatible with version | `>= 1.0.0` and `< 2.0.0` | -| `~1.0.0` | Patch-level changes only | `>= 1.0.0` and `< 1.1.0` | -| `>= 1.0.0, < 2.0.0` | Explicit range | Comma-separated constraints | -| `= 1.5.0` | Exact version | Only `1.5.0` | -| `*` | Any version | Same as bare string in `requires` | - -### Consumer side: enabling config - -The root `MODULE.aspect` enables a package's config via `use_config = True`: - -```python -# In the customer's MODULE.aspect -axl_archive_dep( - name = "aspect_rules_lint", - urls = [...], - use_config = True, # activate this package's config functions -) -``` - -Without `use_config = True`, the package's `use_config()` directives are ignored. The package's `.axl` files are still available for `load()` - only config evaluation is gated. - -### axel-f is auto-enabled - -axel-f ships with the CLI as a builtin (see [Packaging and embedding](#packaging-and-embedding)). Its `use_config` is automatically enabled via `disk_store.rs` — customers do not need to set `use_config = True` for it. If a customer overrides the builtin by declaring their own `axl_archive_dep(name = "axel-f", ...)`, auto-enable is replaced by the customer's explicit `use_config` flag. - -### Config activation is not transitive - -If package A has `use_config = True` and package A depends on package B (which also declares `use_config()`), package B's config is **not** automatically enabled. The root `MODULE.aspect` must independently enable each package's config. This prevents transitive dependencies from silently injecting config behavior. - -## Three phases - -Config evaluation follows three strictly ordered phases: - -### Phase 1: Resolution - -`MODULE.aspect` is evaluated to produce the full dependency graph. All packages are fetched. `use_config()` directives are collected from each package's `MODULE.aspect`, but only those with `use_config = True` in the root are registered for phase 3. No `config.axl` code runs during this phase. - -### Phase 2: Module loading - -All `.axl` files across all resolved packages become available for `load()`. This is pure Starlark module evaluation - top-level code runs, functions and types are defined and cached. Config files registered in phase 1 are loaded as modules (their top-level code executes) but their config functions are **not** called. Config files whose `requires` or `conflicts` conditions are not satisfied are **not loaded at all**. - -### Phase 3: Configuration pipeline - -The runtime calls registered config functions in **topological dependency order** (leaves first, dependents later). Each config function receives the accumulated task state from all previous calls. The customer's `.aspect/config.axl` (if present) runs **last**, giving it full visibility and final say. - -``` -rules_lint config() -> axel-f config() -> .aspect/config.axl config() - (leaf dep) (depends on (customer, always last) - rules_lint) -``` - -### Why this ordering works - -- **Leaves first** means foundational packages (like `rules_lint`) establish defaults before packages that build on them (like `axel-f`). -- **Customer last** means customers can inspect and override anything any package has set. -- **Deterministic** - ordering is derived from the dependency graph via topological sort, so it doesn't change unless dependencies change. - -## Cycles are prevented by design - -`load()` statements inside config functions (phase 3) resolve against the module cache populated in phase 2. They never trigger another package's config evaluation. These are two separate concerns: - -- `load("@aspect_rules_lint//lint/lint.axl", "Strategy")` -> fetches a cached module, returns types/functions -- `rules_lint`'s `config()` -> called by the runtime in the pipeline, not by `load()` - -A config function can `load()` from its declared dependencies, but loading a module and evaluating its config are completely decoupled. - -## Error handling - -By default, a failing config function halts the pipeline with a clear error attributing the failure to the specific package. Packages can opt into best-effort mode, marking their config as optional so the pipeline continues if they fail. - -## Config API - -Each config function receives raw mutable access to task state via `ConfigContext`. This is the same model as today - `config()` iterates `ctx.tasks`, inspects and modifies task configs directly. There are no merge semantics or overwrite protection. The pipeline ordering (leaves first, customer last) provides the coordination model: later configs see and can override earlier ones. - -## Conditional config: the lint task - -The `lint` task is not a builtin - it comes from `@aspect_rules_lint`. axel-f configures lint (sets the strategy, changed files provider, GitHub integration) but only when the customer has `rules_lint` installed. This is the motivating example for the `requires` and `conflicts` parameters on `use_config()`. - -### The problem - -axel-f's lint configuration needs to: -1. `load("@aspect_rules_lint//lint/lint.axl", "StrategyHoldTheLine")` - import types from rules_lint -2. Set `task.config.strategy` and `task.config.changed_files_provider` on the lint task - -Both fail if `rules_lint` isn't in the dependency graph. The `load()` is especially problematic because it's a top-level statement - it runs unconditionally at module load time (phase 2) before any config function is called. - -Additionally, version compatibility matters: if axel-f loads types from `rules_lint`, the version the customer installed must be compatible with what axel-f was written against. - -### The solution - -axel-f splits its config into separate files and uses `requires`/`conflicts` to gate activation: - -```python -# axel-f's MODULE.aspect -use_config("./config.axl", "config") - -# When rules_lint IS present: configure lint with GitHub integration -use_config("./lint_config.axl", "lint_config", - requires = [("aspect_rules_lint", "^1.0.0")]) - -# When rules_lint is NOT present: add helpful stub task -use_config("./lint_stub_config.axl", "lint_stub_config", - conflicts = ["aspect_rules_lint"]) -``` - -**`lint_config.axl`** contains the `load("@aspect_rules_lint//...")` statements and the lint-specific configuration. If `aspect_rules_lint` is not in the resolved dep graph, the runtime never loads this file - the `load()` never executes, no error occurs. The version constraint `^1.0.0` ensures compatibility when both packages are present. - -**`lint_stub_config.axl`** activates only when `aspect_rules_lint` is absent (via `conflicts`). It registers a stub `lint` task that prints a helpful message directing the user to install `rules_lint`: - -```python -def _lint_stub_impl(ctx): - print("The lint task requires aspect_rules_lint.") - print("Run: aspect axl add gh:aspect-build/rules_lint") - return 1 - -lint = task(name = "lint", implementation = _lint_stub_impl) - -def lint_stub_config(ctx): - ctx.tasks.add(lint) -``` - -### How it plays out - -| Customer has `rules_lint`? | `lint_config.axl` | `lint_stub_config.axl` | `aspect lint` behavior | -|---|---|---|---| -| Yes, at `^1.0.0` | Loaded and evaluated | Skipped (conflicts) | Full lint with GitHub integration | -| Yes, at `0.5.0` | Skipped (version mismatch) | Skipped (conflicts) | rules_lint's default lint, no axel-f hooks | -| No | Skipped (requires not met) | Loaded and evaluated | Helpful error with install instructions | - -## Design constraints - -- **Explicit opt-in on both sides** - packages declare config availability via `use_config()`, consumers enable it via `use_config = True`. Neither side alone is sufficient. -- **Not transitive** - only the root `MODULE.aspect` can enable config evaluation for a package. Intermediate dependencies cannot enable configs on behalf of their deps. -- **No config evaluation during phase 1** - MODULE.aspect resolution must complete fully before any config code runs. -- **load() never triggers config evaluation** - module loading and config evaluation are separate phases. -- **Topological ordering from dep graph** - no explicit ordering declarations needed. If you need your config to run after another package, declare a dependency on it. -- **Customer config always runs last** - `.aspect/config.axl` has final authority regardless of the dependency graph. -- **Full runtime access** - config functions have access to `ctx.std.process`, `ctx.http()`, `ctx.std.fs`, etc. Packages are trusted code. -- **Cargo-style version constraints** - `^`, `~`, comparison operators, comma-separated. Evaluated against the resolved dependency graph. diff --git a/axel-f/src/lib.rs b/axel-f/src/lib.rs deleted file mode 100644 index 44d8f78f2..000000000 --- a/axel-f/src/lib.rs +++ /dev/null @@ -1,31 +0,0 @@ -pub const FILES: &[(&str, &str)] = &[ - ("MODULE.aspect", include_str!("../MODULE.aspect")), - // config/ - ( - "config/builtins.axl", - include_str!("../config/builtins.axl"), - ), - ( - "config/delivery.axl", - include_str!("../config/delivery.axl"), - ), - ("config/lint.axl", include_str!("../config/lint.axl")), - ("config/nolint.axl", include_str!("../config/nolint.axl")), - // tasks/ - ("tasks/delivery.axl", include_str!("../tasks/delivery.axl")), - ("tasks/migrate.axl", include_str!("../tasks/migrate.axl")), - ( - "tasks/dummy_lint.axl", - include_str!("../tasks/dummy_lint.axl"), - ), - ( - "tasks/dummy_format.axl", - include_str!("../tasks/dummy_format.axl"), - ), - // lib/ - ("lib/deliveryd.axl", include_str!("../lib/deliveryd.axl")), - ("lib/github.axl", include_str!("../lib/github.axl")), - ("lib/linting.axl", include_str!("../lib/linting.axl")), - ("lib/platform.axl", include_str!("../lib/platform.axl")), - ("lib/sarif.axl", include_str!("../lib/sarif.axl")), -]; diff --git a/bazel/proto/BUILD.bazel b/bazel/proto/BUILD.bazel index 89feba0ef..a1b828413 100644 --- a/bazel/proto/BUILD.bazel +++ b/bazel/proto/BUILD.bazel @@ -15,6 +15,7 @@ descriptor_set( "@bazel//src/main/protobuf:failure_details_proto", "@bazel//src/main/protobuf:invocation_policy_proto", "@bazel//src/main/protobuf:build_proto", - "@googleapis//google/devtools/build/v1:build_proto" + "@googleapis//google/devtools/build/v1:build_proto", + "@remoteapis//:build_bazel_remote_execution_v2_remote_execution_proto" ], ) diff --git a/bazel/proto/MODULE.bazel.lock b/bazel/proto/MODULE.bazel.lock new file mode 100644 index 000000000..7519bf87e --- /dev/null +++ b/bazel/proto/MODULE.bazel.lock @@ -0,0 +1,731 @@ +{ + "lockFileVersion": 16, + "registryFileHashes": { + "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", + "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", + "https://bcr.bazel.build/modules/abseil-cpp/20220623.1/MODULE.bazel": "73ae41b6818d423a11fd79d95aedef1258f304448193d4db4ff90e5e7a0f076c", + "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.0/MODULE.bazel": "98dc378d64c12a4e4741ad3362f87fb737ee6a0886b2d90c3cdbb4d93ea3e0bf", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", + "https://bcr.bazel.build/modules/abseil-cpp/20240722.0/MODULE.bazel": "88668a07647adbdc14cb3a7cd116fb23c9dda37a90a1681590b6c9d8339a5b84", + "https://bcr.bazel.build/modules/abseil-cpp/20240722.0/source.json": "59af9f8a8a4817092624e21263fe1fb7d7951a3b06f0570c610c7e5a9caf5f29", + "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", + "https://bcr.bazel.build/modules/apple_support/1.15.1/source.json": "517f2b77430084c541bc9be2db63fdcbb7102938c5f64c17ee60ffda2e5cf07b", + "https://bcr.bazel.build/modules/apple_support/1.8.1/MODULE.bazel": "500f7aa32c008222e360dc9a158c248c2dbaeb3b6246c19e7269981dbd61e29b", + "https://bcr.bazel.build/modules/bazel_ci_rules/1.0.0/MODULE.bazel": "0f92c944b9c466066ed484cfc899cf43fca765df78caca18984c62479f7925eb", + "https://bcr.bazel.build/modules/bazel_ci_rules/1.0.0/source.json": "3405a2a7f9f827a44934b01470faeac1b56fb1304955c98ee9fcd03ad2ca5dcc", + "https://bcr.bazel.build/modules/bazel_features/1.0.0/MODULE.bazel": "d7f022dc887efb96e1ee51cec7b2e48d41e36ff59a6e4f216c40e4029e1585bf", + "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", + "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", + "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", + "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", + "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", + "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", + "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", + "https://bcr.bazel.build/modules/bazel_features/1.28.0/source.json": "16a3fc5b4483cb307643791f5a4b7365fa98d2e70da7c378cdbde55f0c0b32cf", + "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", + "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", + "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", + "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", + "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", + "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/source.json": "f121b43eeefc7c29efbd51b83d08631e2347297c95aac9764a701f2a6a2bb953", + "https://bcr.bazel.build/modules/blake3/1.5.1.bcr.1/MODULE.bazel": "6f22a783790d834c8e2c91ab85848e781e65078a96304e99e4595763622b171a", + "https://bcr.bazel.build/modules/blake3/1.5.1.bcr.1/source.json": "0e27e27f359ae8fdc140f8ae0891bb719664c3d6a0ab1e7cdb9b8ae372c72f17", + "https://bcr.bazel.build/modules/boringssl/0.0.0-20211025-d4f1ab9/MODULE.bazel": "6ee6353f8b1a701fe2178e1d925034294971350b6d3ac37e67e5a7d463267834", + "https://bcr.bazel.build/modules/boringssl/0.0.0-20230215-5c22014/MODULE.bazel": "4b03dc0d04375fa0271174badcd202ed249870c8e895b26664fd7298abea7282", + "https://bcr.bazel.build/modules/boringssl/0.0.0-20230215-5c22014/source.json": "f90873cd3d891bb63ece55a527d97366da650f84c79c2109bea29c17629bee20", + "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/c-ares/1.15.0/MODULE.bazel": "ba0a78360fdc83f02f437a9e7df0532ad1fbaa59b722f6e715c11effebaa0166", + "https://bcr.bazel.build/modules/c-ares/1.15.0/source.json": "5e3ed991616c5ec4cc09b0893b29a19232de4a1830eb78c567121bfea87453f7", + "https://bcr.bazel.build/modules/curl/8.4.0/MODULE.bazel": "0bc250aa1cb69590049383df7a9537c809591fcf876c620f5f097c58fdc9bc10", + "https://bcr.bazel.build/modules/curl/8.4.0/source.json": "8b9532397af6a24be4ec118d8637b1f4e3e5a0d4be672c94b2275d675c7f7d6b", + "https://bcr.bazel.build/modules/gazelle/0.27.0/MODULE.bazel": "3446abd608295de6d90b4a8a118ed64a9ce11dcb3dda2dc3290a22056bd20996", + "https://bcr.bazel.build/modules/gazelle/0.30.0/MODULE.bazel": "f888a1effe338491f35f0e0e85003b47bb9d8295ccba73c37e07702d8d31c65b", + "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", + "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350", + "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", + "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", + "https://bcr.bazel.build/modules/gazelle/0.36.0/source.json": "0823f097b127e0201ae55d85647c94095edfe27db0431a7ae880dcab08dfaa04", + "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", + "https://bcr.bazel.build/modules/google_benchmark/1.8.4/MODULE.bazel": "c6d54a11dcf64ee63545f42561eda3fd94c1b5f5ebe1357011de63ae33739d5e", + "https://bcr.bazel.build/modules/google_benchmark/1.8.4/source.json": "84590f7bc5a1fd99e1ef274ee16bb41c214f705e62847b42e705010dfa81fe53", + "https://bcr.bazel.build/modules/googleapis-rules-registry/1.0.0/MODULE.bazel": "97c6a4d413b373d4cc97065da3de1b2166e22cbbb5f4cc9f05760bfa83619e24", + "https://bcr.bazel.build/modules/googleapis-rules-registry/1.0.0/source.json": "cf611c836a60e98e2e2ab2de8004f119e9f06878dcf4ea2d95a437b1b7a89fe9", + "https://bcr.bazel.build/modules/googleapis/0.0.0-20240326-1c8d509c5/MODULE.bazel": "a4b7e46393c1cdcc5a00e6f85524467c48c565256b22b5fae20f84ab4a999a68", + "https://bcr.bazel.build/modules/googleapis/0.0.0-20240819-fe8ba054a/MODULE.bazel": "117b7c7be7327ed5d6c482274533f2dbd78631313f607094d4625c28203cacdf", + "https://bcr.bazel.build/modules/googleapis/0.0.0-20250604-de157ca3/MODULE.bazel": "de6044bf0edf78f1f51b800a0633dc7dd305aaf6ee878116757f98cd1a05477d", + "https://bcr.bazel.build/modules/googleapis/0.0.0-20250604-de157ca3/source.json": "44b8b8174f416116daaa9345857b87b87351baf8b19e8f838a32f1ce08345be6", + "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", + "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", + "https://bcr.bazel.build/modules/googletest/1.15.2/source.json": "dbdda654dcb3a0d7a8bc5d0ac5fc7e150b58c2a986025ae5bc634bb2cb61f470", + "https://bcr.bazel.build/modules/grpc-java/1.62.2/MODULE.bazel": "99b8771e8c7cacb130170fed2a10c9e8fed26334a93e73b42d2953250885a158", + "https://bcr.bazel.build/modules/grpc-java/1.66.0/MODULE.bazel": "86ff26209fac846adb89db11f3714b3dc0090fb2fb81575673cc74880cda4e7e", + "https://bcr.bazel.build/modules/grpc-java/1.66.0/source.json": "f841b339ff8516c86c3a5272cd053194dd0cb2fdd63157123835e1157a28328d", + "https://bcr.bazel.build/modules/grpc-proto/0.0.0-20240627-ec30f58/MODULE.bazel": "88de79051e668a04726e9ea94a481ec6f1692086735fd6f488ab908b3b909238", + "https://bcr.bazel.build/modules/grpc-proto/0.0.0-20240627-ec30f58/source.json": "5035d379c61042930244ab59e750106d893ec440add92ec0df6a0098ca7f131d", + "https://bcr.bazel.build/modules/grpc/1.41.0/MODULE.bazel": "5bcbfc2b274dabea628f0649dc50c90cf36543b1cfc31624832538644ad1aae8", + "https://bcr.bazel.build/modules/grpc/1.56.3.bcr.1/MODULE.bazel": "cd5b1eb276b806ec5ab85032921f24acc51735a69ace781be586880af20ab33f", + "https://bcr.bazel.build/modules/grpc/1.66.0.bcr.2/MODULE.bazel": "0fa2b0fd028ce354febf0fe90f1ed8fecfbfc33118cddd95ac0418cc283333a0", + "https://bcr.bazel.build/modules/grpc/1.66.0.bcr.2/source.json": "d2b273a925507d47b5e2d6852f194e70d2991627d71b13793cc2498400d4f99e", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/source.json": "4108ee5085dd2885a341c7fab149429db457b3169b86eb081fa245eadf69169d", + "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/libpfm/4.11.0/source.json": "caaffb3ac2b59b8aac456917a4ecf3167d40478ee79f15ab7a877ec9273937c9", + "https://bcr.bazel.build/modules/nlohmann_json/3.11.3/MODULE.bazel": "87023db2f55fc3a9949c7b08dc711fae4d4be339a80a99d04453c4bb3998eefc", + "https://bcr.bazel.build/modules/nlohmann_json/3.11.3/source.json": "296c63a90c6813e53b3812d24245711981fc7e563d98fe15625f55181494488a", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", + "https://bcr.bazel.build/modules/opentelemetry-cpp/1.14.2/MODULE.bazel": "089a5613c2a159c7dfde098dabfc61e966889c7d6a81a98422a84c51535ed17d", + "https://bcr.bazel.build/modules/opentelemetry-cpp/1.14.2/source.json": "0c5f85ab9e5894c6f1382cf58ba03a6cd024f0592bee2229f99db216ef0c6764", + "https://bcr.bazel.build/modules/opentelemetry-proto/1.1.0/MODULE.bazel": "a49f406e99bf05ab43ed4f5b3322fbd33adfd484b6546948929d1316299b68bf", + "https://bcr.bazel.build/modules/opentelemetry-proto/1.1.0/source.json": "39ffadc4b7d9ccc0c0f45422510cbaeb8eca7b26e68d4142fc3ff18b4c2711b6", + "https://bcr.bazel.build/modules/opentracing-cpp/1.6.0/MODULE.bazel": "b3925269f63561b8b880ae7cf62ccf81f6ece55b62cd791eda9925147ae116ec", + "https://bcr.bazel.build/modules/opentracing-cpp/1.6.0/source.json": "da1cb1add160f5e5074b7272e9db6fd8f1b3336c15032cd0a653af9d2f484aed", + "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", + "https://bcr.bazel.build/modules/platforms/0.0.10/source.json": "f22828ff4cf021a6b577f1bf6341cb9dcd7965092a439f64fc1bb3b7a5ae4bd5", + "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", + "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", + "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", + "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", + "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", + "https://bcr.bazel.build/modules/prometheus-cpp/1.2.4/MODULE.bazel": "0fbe5dcff66311947a3f6b86ebc6a6d9328e31a28413ca864debc4a043f371e5", + "https://bcr.bazel.build/modules/prometheus-cpp/1.2.4/source.json": "aa58bb10d0bb0dcaf4ad2c509ddcec23d2e94c3935e21517a5adbc2363248a55", + "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/23.1/MODULE.bazel": "88b393b3eb4101d18129e5db51847cd40a5517a53e81216144a8c32dfeeca52a", + "https://bcr.bazel.build/modules/protobuf/26.0.bcr.2/MODULE.bazel": "62e0b84ca727bdeb55a6fe1ef180e6b191bbe548a58305ea1426c158067be534", + "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", + "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", + "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", + "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", + "https://bcr.bazel.build/modules/protobuf/29.1/source.json": "04cca85dce26b895ed037d98336d860367fe09919208f2ad383f0df1aff63199", + "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573", + "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680", + "https://bcr.bazel.build/modules/re2/2021-09-01/MODULE.bazel": "bcb6b96f3b071e6fe2d8bed9cc8ada137a105f9d2c5912e91d27528b3d123833", + "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", + "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", + "https://bcr.bazel.build/modules/re2/2024-07-02/source.json": "547d0111a9d4f362db32196fef805abbf3676e8d6afbe44d395d87816c1130ca", + "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", + "https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e", + "https://bcr.bazel.build/modules/rules_apple/3.5.1/MODULE.bazel": "3d1bbf65ad3692003d36d8a29eff54d4e5c1c5f4bfb60f79e28646a924d9101c", + "https://bcr.bazel.build/modules/rules_apple/3.5.1/source.json": "e7593cdf26437d35dbda64faeaf5b82cbdd9df72674b0f041fdde75c1d20dda7", + "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", + "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", + "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac", + "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", + "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", + "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", + "https://bcr.bazel.build/modules/rules_cc/0.0.5/MODULE.bazel": "be41f87587998fe8890cd82ea4e848ed8eb799e053c224f78f3ff7fe1a1d9b74", + "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", + "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37", + "https://bcr.bazel.build/modules/rules_cc/0.2.13/source.json": "f872e892c5265c5532e526857532f4868708f88d64e5ebe517ea72e09da61bdb", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.10.1/MODULE.bazel": "b9527010e5fef060af92b6724edb3691970a5b1f76f74b21d39f7d433641be60", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.10.1/source.json": "9300e71df0cdde0952f10afff1401fa664e9fc5d9ae6204660ba1b158d90d6a6", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/source.json": "c8b1e2c717646f1702290959a3302a178fb639d987ab61d548105019f11e527e", + "https://bcr.bazel.build/modules/rules_go/0.33.0/MODULE.bazel": "a2b11b64cd24bf94f57454f53288a5dacfe6cb86453eee7761b7637728c1910c", + "https://bcr.bazel.build/modules/rules_go/0.38.1/MODULE.bazel": "fb8e73dd3b6fc4ff9d260ceacd830114891d49904f5bda1c16bc147bcc254f71", + "https://bcr.bazel.build/modules/rules_go/0.39.1/MODULE.bazel": "d34fb2a249403a5f4339c754f1e63dc9e5ad70b47c5e97faee1441fc6636cd61", + "https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8", + "https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270", + "https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd", + "https://bcr.bazel.build/modules/rules_go/0.48.0/MODULE.bazel": "d00ebcae0908ee3f5e6d53f68677a303d6d59a77beef879598700049c3980a03", + "https://bcr.bazel.build/modules/rules_go/0.48.0/source.json": "895dc1698fd7c5959f92868f3a87156ad1ed8d876668bfa918fa0a623fb1eb22", + "https://bcr.bazel.build/modules/rules_graalvm/0.11.1/MODULE.bazel": "0caaea2dff60b70b8f9b9ceb6e5ae815b85ae610a0392433a22c755b2f2c2456", + "https://bcr.bazel.build/modules/rules_graalvm/0.11.1/source.json": "23d59a63e1dce95df987d19284bad81a4bf7e4df788d47b0ad99c217447bceca", + "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/5.1.0/MODULE.bazel": "324b6478b0343a3ce7a9add8586ad75d24076d6d43d2f622990b9c1cfd8a1b15", + "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", + "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39", + "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6", + "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", + "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", + "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", + "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", + "https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2", + "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel": "a592852f8a3dd539e82ee6542013bf2cadfc4c6946be8941e189d224500a8934", + "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", + "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", + "https://bcr.bazel.build/modules/rules_java/8.6.1/source.json": "f18d9ad3c4c54945bf422ad584fa6c5ca5b3116ff55a5b1bc77e5c1210be5960", + "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", + "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d", + "https://bcr.bazel.build/modules/rules_jvm_external/6.0/MODULE.bazel": "37c93a5a78d32e895d52f86a8d0416176e915daabd029ccb5594db422e87c495", + "https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/source.json": "6f5f5a5a4419ae4e37c35a5bb0a6ae657ed40b7abc5a5189111b47fcebe43197", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5", + "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", + "https://bcr.bazel.build/modules/rules_license/0.0.4/MODULE.bazel": "6a88dd22800cf1f9f79ba32cacad0d3a423ed28efa2c2ed5582eaa78dd3ac1e5", + "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", + "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", + "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a", + "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", + "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", + "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", + "https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f", + "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", + "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", + "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", + "https://bcr.bazel.build/modules/rules_python/0.20.0/MODULE.bazel": "bfe14d17f20e3fe900b9588f526f52c967a6f281e47a1d6b988679bd15082286", + "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", + "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", + "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", + "https://bcr.bazel.build/modules/rules_python/0.29.0/MODULE.bazel": "2ac8cd70524b4b9ec49a0b8284c79e4cd86199296f82f6e0d5da3f783d660c82", + "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", + "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", + "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7", + "https://bcr.bazel.build/modules/rules_python/0.40.0/source.json": "939d4bd2e3110f27bfb360292986bb79fd8dcefb874358ccd6cdaa7bda029320", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/source.json": "7f27af3c28037d9701487c4744b5448d26537cc66cdef0d8df7ae85411f8de95", + "https://bcr.bazel.build/modules/rules_swift/1.18.0/MODULE.bazel": "a6aba73625d0dc64c7b4a1e831549b6e375fbddb9d2dde9d80c9de6ec45b24c9", + "https://bcr.bazel.build/modules/rules_swift/1.18.0/source.json": "9e636cabd446f43444ea2662341a9cbb74ecd87ab0557225ae73f1127cb7ff52", + "https://bcr.bazel.build/modules/rules_testing/0.6.0/MODULE.bazel": "8518d53bc742c462536d3f1a0de0c265bd7b51f32797fea4132007223ed2926f", + "https://bcr.bazel.build/modules/rules_testing/0.6.0/source.json": "915ae13ae2247c986cc57289f21e7f1d9711cd2ecfdf5867b51dc0484f3b043b", + "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", + "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", + "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef", + "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7", + "https://bcr.bazel.build/modules/stardoc/0.7.1/source.json": "b6500ffcd7b48cd72c29bb67bcac781e12701cc0d6d55d266a652583cfcdab01", + "https://bcr.bazel.build/modules/upb/0.0.0-20211020-160625a/MODULE.bazel": "6cced416be2dc5b9c05efd5b997049ba795e5e4e6fafbe1624f4587767638928", + "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/upb/0.0.0-20230907-e7430e6/MODULE.bazel": "3a7dedadf70346e678dc059dbe44d05cbf3ab17f1ce43a1c7a42edc7cbf93fd9", + "https://bcr.bazel.build/modules/upb/0.0.0-20230907-e7430e6/source.json": "6e513de1d26d1ded97a1c98a8ee166ff9be371a71556d4bc91220332dd3aa48e", + "https://bcr.bazel.build/modules/with_cfg.bzl/0.6.0/MODULE.bazel": "174257966441fb8af45c939854ba38fd8364b7e48e3155c7c0ce5ef869af80aa", + "https://bcr.bazel.build/modules/with_cfg.bzl/0.6.0/source.json": "4acda83067113064cd7c43f9b9ab4a7e7155d260c1a526f48f02aa3fbb809d17", + "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", + "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", + "https://bcr.bazel.build/modules/zlib/1.2.13/MODULE.bazel": "aa6deb1b83c18ffecd940c4119aff9567cd0a671d7bba756741cb2ef043a29d5", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.1/MODULE.bazel": "6a9fe6e3fc865715a7be9823ce694ceb01e364c35f7a846bf0d2b34762bc066b", + "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://bcr.bazel.build/modules/zlib/1.3/MODULE.bazel": "6a9c02f19a24dcedb05572b2381446e27c272cd383aed11d41d99da9e3167a72", + "https://bcr.bazel.build/modules/zstd-jni/1.5.2-3.bcr.1/MODULE.bazel": "cb11f12dc4c8454bede2b64855a8126b547cc89cf77838188513f647d9edd86e", + "https://bcr.bazel.build/modules/zstd-jni/1.5.2-3.bcr.1/source.json": "f728c0f2384b4d047a759f4ff5d9cd05a81a78388fbe9cc3981b773e5536be38" + }, + "selectedYankedVersions": {}, + "moduleExtensions": { + "@@apple_support+//crosstool:setup.bzl%apple_cc_configure_extension": { + "general": { + "bzlTransitiveDigest": "p7Ghcq3+nnQxCrf+U3xnhdn7yOSTDbcFyGHK7Ja+rU4=", + "usagesDigest": "yAC1H7cg3wkisnNswc7hxM2fAxrH04yqn7CXVasZPgc=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "local_config_apple_cc_toolchains": { + "repoRuleId": "@@apple_support+//crosstool:setup.bzl%_apple_cc_autoconf_toolchains", + "attributes": {} + }, + "local_config_apple_cc": { + "repoRuleId": "@@apple_support+//crosstool:setup.bzl%_apple_cc_autoconf", + "attributes": {} + } + }, + "recordedRepoMappingEntries": [ + [ + "apple_support+", + "bazel_tools", + "bazel_tools" + ], + [ + "bazel_tools", + "rules_cc", + "rules_cc+" + ] + ] + } + }, + "@@platforms//host:extension.bzl%host_platform": { + "general": { + "bzlTransitiveDigest": "xelQcPZH8+tmuOHVjL9vDxMnnQNMlwj0SlvgoqBkm4U=", + "usagesDigest": "SeQiIN/f8/Qt9vYQk7qcXp4I4wJeEC0RnQDiaaJ4tb8=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "host_platform": { + "repoRuleId": "@@platforms//host:extension.bzl%host_platform_repo", + "attributes": {} + } + }, + "recordedRepoMappingEntries": [] + } + }, + "@@rules_foreign_cc+//foreign_cc:extensions.bzl%tools": { + "general": { + "bzlTransitiveDigest": "FApcIcVN43WOEs7g8eg7Cy1hrfRbVNEoUu8IiF+8WOc=", + "usagesDigest": "9LXdVp01HkdYQT8gYPjYLO6VLVJHo9uFfxWaU1ymiRE=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "rules_foreign_cc_framework_toolchain_linux": { + "repoRuleId": "@@rules_foreign_cc+//foreign_cc/private/framework:toolchain.bzl%framework_toolchain_repository", + "attributes": { + "commands_src": "@rules_foreign_cc//foreign_cc/private/framework/toolchains:linux_commands.bzl", + "exec_compatible_with": [ + "@platforms//os:linux" + ] + } + }, + "rules_foreign_cc_framework_toolchain_freebsd": { + "repoRuleId": "@@rules_foreign_cc+//foreign_cc/private/framework:toolchain.bzl%framework_toolchain_repository", + "attributes": { + "commands_src": "@rules_foreign_cc//foreign_cc/private/framework/toolchains:freebsd_commands.bzl", + "exec_compatible_with": [ + "@platforms//os:freebsd" + ] + } + }, + "rules_foreign_cc_framework_toolchain_windows": { + "repoRuleId": "@@rules_foreign_cc+//foreign_cc/private/framework:toolchain.bzl%framework_toolchain_repository", + "attributes": { + "commands_src": "@rules_foreign_cc//foreign_cc/private/framework/toolchains:windows_commands.bzl", + "exec_compatible_with": [ + "@platforms//os:windows" + ] + } + }, + "rules_foreign_cc_framework_toolchain_macos": { + "repoRuleId": "@@rules_foreign_cc+//foreign_cc/private/framework:toolchain.bzl%framework_toolchain_repository", + "attributes": { + "commands_src": "@rules_foreign_cc//foreign_cc/private/framework/toolchains:macos_commands.bzl", + "exec_compatible_with": [ + "@platforms//os:macos" + ] + } + }, + "rules_foreign_cc_framework_toolchains": { + "repoRuleId": "@@rules_foreign_cc+//foreign_cc/private/framework:toolchain.bzl%framework_toolchain_repository_hub", + "attributes": {} + }, + "cmake_src": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "filegroup(\n name = \"all_srcs\",\n srcs = glob([\"**\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "sha256": "f316b40053466f9a416adf981efda41b160ca859e97f6a484b447ea299ff26aa", + "strip_prefix": "cmake-3.23.2", + "urls": [ + "https://github.com/Kitware/CMake/releases/download/v3.23.2/cmake-3.23.2.tar.gz" + ] + } + }, + "gnumake_src": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "filegroup(\n name = \"all_srcs\",\n srcs = glob([\"**\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "sha256": "581f4d4e872da74b3941c874215898a7d35802f03732bdccee1d4a7979105d18", + "strip_prefix": "make-4.4", + "urls": [ + "https://mirror.bazel.build/ftpmirror.gnu.org/gnu/make/make-4.4.tar.gz", + "http://ftpmirror.gnu.org/gnu/make/make-4.4.tar.gz" + ] + } + }, + "ninja_build_src": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "filegroup(\n name = \"all_srcs\",\n srcs = glob([\"**\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "sha256": "31747ae633213f1eda3842686f83c2aa1412e0f5691d1c14dbbcc67fe7400cea", + "strip_prefix": "ninja-1.11.1", + "urls": [ + "https://github.com/ninja-build/ninja/archive/v1.11.1.tar.gz" + ] + } + }, + "meson_src": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "exports_files([\"meson.py\"])\n\nfilegroup(\n name = \"runtime\",\n srcs = glob([\"mesonbuild/**\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "strip_prefix": "meson-1.1.1", + "url": "https://github.com/mesonbuild/meson/releases/download/1.1.1/meson-1.1.1.tar.gz" + } + }, + "glib_dev": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_cc//cc:defs.bzl\", \"cc_library\")\n\ncc_import(\n name = \"glib_dev\",\n hdrs = glob([\"include/**\"]),\n shared_library = \"@glib_runtime//:bin/libglib-2.0-0.dll\",\n visibility = [\"//visibility:public\"],\n)\n ", + "sha256": "bdf18506df304d38be98a4b3f18055b8b8cca81beabecad0eece6ce95319c369", + "urls": [ + "https://download.gnome.org/binaries/win64/glib/2.26/glib-dev_2.26.1-1_win64.zip" + ] + } + }, + "glib_src": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\ncc_import(\n name = \"msvc_hdr\",\n hdrs = [\"msvc_recommended_pragmas.h\"],\n visibility = [\"//visibility:public\"],\n)\n ", + "sha256": "bc96f63112823b7d6c9f06572d2ad626ddac7eb452c04d762592197f6e07898e", + "strip_prefix": "glib-2.26.1", + "urls": [ + "https://download.gnome.org/sources/glib/2.26/glib-2.26.1.tar.gz" + ] + } + }, + "glib_runtime": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nexports_files(\n [\n \"bin/libgio-2.0-0.dll\",\n \"bin/libglib-2.0-0.dll\",\n \"bin/libgmodule-2.0-0.dll\",\n \"bin/libgobject-2.0-0.dll\",\n \"bin/libgthread-2.0-0.dll\",\n ],\n visibility = [\"//visibility:public\"],\n)\n ", + "sha256": "88d857087e86f16a9be651ee7021880b3f7ba050d34a1ed9f06113b8799cb973", + "urls": [ + "https://download.gnome.org/binaries/win64/glib/2.26/glib_2.26.1-1_win64.zip" + ] + } + }, + "gettext_runtime": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\ncc_import(\n name = \"gettext_runtime\",\n shared_library = \"bin/libintl-8.dll\",\n visibility = [\"//visibility:public\"],\n)\n ", + "sha256": "1f4269c0e021076d60a54e98da6f978a3195013f6de21674ba0edbc339c5b079", + "urls": [ + "https://download.gnome.org/binaries/win64/dependencies/gettext-runtime_0.18.1.1-2_win64.zip" + ] + } + }, + "pkgconfig_src": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "filegroup(\n name = \"all_srcs\",\n srcs = glob([\"**\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "sha256": "6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591", + "strip_prefix": "pkg-config-0.29.2", + "patches": [ + "@@rules_foreign_cc+//toolchains:pkgconfig-detectenv.patch", + "@@rules_foreign_cc+//toolchains:pkgconfig-makefile-vc.patch" + ], + "urls": [ + "https://pkgconfig.freedesktop.org/releases/pkg-config-0.29.2.tar.gz" + ] + } + }, + "bazel_skylib": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz" + ], + "sha256": "f7be3474d42aae265405a592bb7da8e171919d74c16f082a5457840f06054728" + } + }, + "rules_python": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "84aec9e21cc56fbc7f1335035a71c850d1b9b5cc6ff497306f84cced9a769841", + "strip_prefix": "rules_python-0.23.1", + "url": "https://github.com/bazelbuild/rules_python/archive/refs/tags/0.23.1.tar.gz" + } + }, + "cmake-3.23.2-linux-aarch64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/Kitware/CMake/releases/download/v3.23.2/cmake-3.23.2-linux-aarch64.tar.gz" + ], + "sha256": "f2654bf780b53f170bbbec44d8ac67d401d24788e590faa53036a89476efa91e", + "strip_prefix": "cmake-3.23.2-linux-aarch64", + "build_file_content": "load(\"@rules_foreign_cc//toolchains/native_tools:native_tools_toolchain.bzl\", \"native_tool_toolchain\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"cmake_data\",\n srcs = glob(\n [\n \"**\",\n ],\n exclude = [\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n \"BUILD\",\n \"BUILD.bazel\",\n ],\n ),\n)\n\nnative_tool_toolchain(\n name = \"cmake_tool\",\n path = \"bin/cmake\",\n target = \":cmake_data\",\n)\n" + } + }, + "cmake-3.23.2-linux-x86_64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/Kitware/CMake/releases/download/v3.23.2/cmake-3.23.2-linux-x86_64.tar.gz" + ], + "sha256": "aaced6f745b86ce853661a595bdac6c5314a60f8181b6912a0a4920acfa32708", + "strip_prefix": "cmake-3.23.2-linux-x86_64", + "build_file_content": "load(\"@rules_foreign_cc//toolchains/native_tools:native_tools_toolchain.bzl\", \"native_tool_toolchain\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"cmake_data\",\n srcs = glob(\n [\n \"**\",\n ],\n exclude = [\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n \"BUILD\",\n \"BUILD.bazel\",\n ],\n ),\n)\n\nnative_tool_toolchain(\n name = \"cmake_tool\",\n path = \"bin/cmake\",\n target = \":cmake_data\",\n)\n" + } + }, + "cmake-3.23.2-macos-universal": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/Kitware/CMake/releases/download/v3.23.2/cmake-3.23.2-macos-universal.tar.gz" + ], + "sha256": "853a0f9af148c5ef47282ffffee06c4c9f257be2635936755f39ca13c3286c88", + "strip_prefix": "cmake-3.23.2-macos-universal/CMake.app/Contents", + "build_file_content": "load(\"@rules_foreign_cc//toolchains/native_tools:native_tools_toolchain.bzl\", \"native_tool_toolchain\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"cmake_data\",\n srcs = glob(\n [\n \"**\",\n ],\n exclude = [\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n \"BUILD\",\n \"BUILD.bazel\",\n ],\n ),\n)\n\nnative_tool_toolchain(\n name = \"cmake_tool\",\n path = \"bin/cmake\",\n target = \":cmake_data\",\n)\n" + } + }, + "cmake-3.23.2-windows-i386": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/Kitware/CMake/releases/download/v3.23.2/cmake-3.23.2-windows-i386.zip" + ], + "sha256": "6a4fcd6a2315b93cb23c93507efccacc30c449c2bf98f14d6032bb226c582e07", + "strip_prefix": "cmake-3.23.2-windows-i386", + "build_file_content": "load(\"@rules_foreign_cc//toolchains/native_tools:native_tools_toolchain.bzl\", \"native_tool_toolchain\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"cmake_data\",\n srcs = glob(\n [\n \"**\",\n ],\n exclude = [\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n \"BUILD\",\n \"BUILD.bazel\",\n ],\n ),\n)\n\nnative_tool_toolchain(\n name = \"cmake_tool\",\n path = \"bin/cmake.exe\",\n target = \":cmake_data\",\n)\n" + } + }, + "cmake-3.23.2-windows-x86_64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/Kitware/CMake/releases/download/v3.23.2/cmake-3.23.2-windows-x86_64.zip" + ], + "sha256": "2329387f3166b84c25091c86389fb891193967740c9bcf01e7f6d3306f7ffda0", + "strip_prefix": "cmake-3.23.2-windows-x86_64", + "build_file_content": "load(\"@rules_foreign_cc//toolchains/native_tools:native_tools_toolchain.bzl\", \"native_tool_toolchain\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"cmake_data\",\n srcs = glob(\n [\n \"**\",\n ],\n exclude = [\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n \"BUILD\",\n \"BUILD.bazel\",\n ],\n ),\n)\n\nnative_tool_toolchain(\n name = \"cmake_tool\",\n path = \"bin/cmake.exe\",\n target = \":cmake_data\",\n)\n" + } + }, + "cmake_3.23.2_toolchains": { + "repoRuleId": "@@rules_foreign_cc+//toolchains:prebuilt_toolchains_repository.bzl%prebuilt_toolchains_repository", + "attributes": { + "repos": { + "cmake-3.23.2-linux-aarch64": [ + "@platforms//cpu:aarch64", + "@platforms//os:linux" + ], + "cmake-3.23.2-linux-x86_64": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "cmake-3.23.2-macos-universal": [ + "@platforms//os:macos" + ], + "cmake-3.23.2-windows-i386": [ + "@platforms//cpu:x86_32", + "@platforms//os:windows" + ], + "cmake-3.23.2-windows-x86_64": [ + "@platforms//cpu:x86_64", + "@platforms//os:windows" + ] + }, + "tool": "cmake" + } + }, + "ninja_1.11.1_linux": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-linux.zip" + ], + "sha256": "b901ba96e486dce377f9a070ed4ef3f79deb45f4ffe2938f8e7ddc69cfb3df77", + "strip_prefix": "", + "build_file_content": "load(\"@rules_foreign_cc//toolchains/native_tools:native_tools_toolchain.bzl\", \"native_tool_toolchain\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"ninja_bin\",\n srcs = [\"ninja\"],\n)\n\nnative_tool_toolchain(\n name = \"ninja_tool\",\n env = {\"NINJA\": \"$(execpath :ninja_bin)\"},\n path = \"$(execpath :ninja_bin)\",\n target = \":ninja_bin\",\n)\n" + } + }, + "ninja_1.11.1_mac": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-mac.zip" + ], + "sha256": "482ecb23c59ae3d4f158029112de172dd96bb0e97549c4b1ca32d8fad11f873e", + "strip_prefix": "", + "build_file_content": "load(\"@rules_foreign_cc//toolchains/native_tools:native_tools_toolchain.bzl\", \"native_tool_toolchain\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"ninja_bin\",\n srcs = [\"ninja\"],\n)\n\nnative_tool_toolchain(\n name = \"ninja_tool\",\n env = {\"NINJA\": \"$(execpath :ninja_bin)\"},\n path = \"$(execpath :ninja_bin)\",\n target = \":ninja_bin\",\n)\n" + } + }, + "ninja_1.11.1_win": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-win.zip" + ], + "sha256": "524b344a1a9a55005eaf868d991e090ab8ce07fa109f1820d40e74642e289abc", + "strip_prefix": "", + "build_file_content": "load(\"@rules_foreign_cc//toolchains/native_tools:native_tools_toolchain.bzl\", \"native_tool_toolchain\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"ninja_bin\",\n srcs = [\"ninja.exe\"],\n)\n\nnative_tool_toolchain(\n name = \"ninja_tool\",\n env = {\"NINJA\": \"$(execpath :ninja_bin)\"},\n path = \"$(execpath :ninja_bin)\",\n target = \":ninja_bin\",\n)\n" + } + }, + "ninja_1.11.1_toolchains": { + "repoRuleId": "@@rules_foreign_cc+//toolchains:prebuilt_toolchains_repository.bzl%prebuilt_toolchains_repository", + "attributes": { + "repos": { + "ninja_1.11.1_linux": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "ninja_1.11.1_mac": [ + "@platforms//cpu:x86_64", + "@platforms//os:macos" + ], + "ninja_1.11.1_win": [ + "@platforms//cpu:x86_64", + "@platforms//os:windows" + ] + }, + "tool": "ninja" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_foreign_cc+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_foreign_cc+", + "rules_foreign_cc", + "rules_foreign_cc+" + ] + ] + } + }, + "@@rules_graalvm+//:extensions.bzl%graalvm": { + "general": { + "bzlTransitiveDigest": "i0x35JJR57FKhcEk8ExwoG+DGBTXVhlQQuaoQCNX3fA=", + "usagesDigest": "eRL31Ff6BONMH7tPoZ33ymdqu8/PPwm9lkAl1F9fu88=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "graalvm_toolchains": { + "repoRuleId": "@@rules_graalvm+//internal:graalvm_bindist.bzl%_toolchain_config", + "attributes": { + "build_file": "\nalias(\n name = \"toolchain_gvm\",\n actual = \"gvm\",\n visibility = [\"//visibility:public\"],\n)\ntoolchain(\n name = \"gvm\",\n exec_compatible_with = [\n \n ],\n target_compatible_with = [\n \n ],\n toolchain = \"@graalvm//:gvm\",\n toolchain_type = \"@rules_graalvm//graalvm/toolchain\",\n visibility = [\"//visibility:public\"],\n)\n\nconfig_setting(\n name = \"prefix_version_setting\",\n values = {\"java_runtime_version\": \"graalvm_21\"},\n visibility = [\"//visibility:private\"],\n)\ntoolchain(\n name = \"toolchain\",\n target_compatible_with = [],\n target_settings = [\":prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:runtime_toolchain_type\",\n toolchain = \"@graalvm//:jdk\",\n visibility = [\"//visibility:public\"],\n)\n\ntoolchain(\n name = \"bootstrap_runtime_toolchain\",\n # These constraints are not required for correctness, but prevent fetches of remote JDK for\n # different architectures. As every Java compilation toolchain depends on a bootstrap runtime in\n # the same configuration, this constraint will not result in toolchain resolution failures.\n exec_compatible_with = [],\n target_settings = [\":prefix_version_setting\"],\n toolchain_type = \"@bazel_tools//tools/jdk:bootstrap_runtime_toolchain_type\",\n toolchain = \"@graalvm//:jdk\",\n visibility = [\"//visibility:public\"],\n)\n\n" + } + }, + "graalvm": { + "repoRuleId": "@@rules_graalvm+//internal:graalvm_bindist.bzl%_graalvm_bindist_repository", + "attributes": { + "version": "21.0.2", + "java_version": "21", + "distribution": "ce", + "components": [], + "setup_actions": [], + "enable_toolchain": true, + "toolchain_config": "graalvm_toolchains" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_graalvm+", + "bazel_skylib", + "bazel_skylib+" + ] + ] + } + }, + "@@rules_java+//java:rules_java_deps.bzl%compatibility_proxy": { + "general": { + "bzlTransitiveDigest": "84xJEZ1jnXXwo8BXMprvBm++rRt4jsTu9liBxz0ivps=", + "usagesDigest": "jTQDdLDxsS43zuRmg1faAjIEPWdLAbDAowI1pInQSoo=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "compatibility_proxy": { + "repoRuleId": "@@rules_java+//java:rules_java_deps.bzl%_compatibility_proxy_repo_rule", + "attributes": {} + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_java+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": { + "general": { + "bzlTransitiveDigest": "sFhcgPbDQehmbD1EOXzX4H1q/CD5df8zwG4kp4jbvr8=", + "usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "com_github_jetbrains_kotlin_git": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_compiler_git_repository", + "attributes": { + "urls": [ + "https://github.com/JetBrains/kotlin/releases/download/v1.9.23/kotlin-compiler-1.9.23.zip" + ], + "sha256": "93137d3aab9afa9b27cb06a824c2324195c6b6f6179d8a8653f440f5bd58be88" + } + }, + "com_github_jetbrains_kotlin": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_capabilities_repository", + "attributes": { + "git_repository_name": "com_github_jetbrains_kotlin_git", + "compiler_version": "1.9.23" + } + }, + "com_github_google_ksp": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:ksp.bzl%ksp_compiler_plugin_repository", + "attributes": { + "urls": [ + "https://github.com/google/ksp/releases/download/1.9.23-1.0.20/artifacts.zip" + ], + "sha256": "ee0618755913ef7fd6511288a232e8fad24838b9af6ea73972a76e81053c8c2d", + "strip_version": "1.9.23-1.0.20" + } + }, + "com_github_pinterest_ktlint": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "sha256": "01b2e0ef893383a50dbeb13970fe7fa3be36ca3e83259e01649945b09d736985", + "urls": [ + "https://github.com/pinterest/ktlint/releases/download/1.3.0/ktlint" + ], + "executable": true + } + }, + "rules_android": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806", + "strip_prefix": "rules_android-0.1.1", + "urls": [ + "https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip" + ] + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_kotlin+", + "bazel_tools", + "bazel_tools" + ] + ] + } + } + } +} diff --git a/crates/aspect-cli/src/main.rs b/crates/aspect-cli/src/main.rs index f707e217f..c03e8abf2 100644 --- a/crates/aspect-cli/src/main.rs +++ b/crates/aspect-cli/src/main.rs @@ -61,7 +61,7 @@ async fn main() -> miette::Result { } // Initialize tracing for logging and instrumentation. - let _tracing = trace::init(); + // let _tracing = trace::init(); // Enter the root tracing span for the entire application. let _root = info_span!("root").entered(); @@ -519,7 +519,7 @@ async fn main() -> miette::Result { match out.await { Ok(result) => { drop(_root); - drop(_tracing); + // drop(_tracing); result } Err(err) => panic!("{:?}", err), diff --git a/crates/aspect-launcher/src/config.rs b/crates/aspect-launcher/src/config.rs index d8003eb64..90e19b237 100644 --- a/crates/aspect-launcher/src/config.rs +++ b/crates/aspect-launcher/src/config.rs @@ -249,16 +249,10 @@ fn parse_version_axl(content: &str) -> Result { for arg in &args.args { match &arg.node { - ArgumentP::Positional(expr) => { - if version.is_none() { + ArgumentP::Named(name, expr) => match name.node.as_str() { + "use" => { version = Some(extract_string_literal(expr)?.to_owned()); - } else { - return Err(miette!( - "version() accepts only one positional argument (the version string)" - )); } - } - ArgumentP::Named(name, expr) => match name.node.as_str() { "sources" => { if let Expr::List(items) = &expr.node { let mut src_list = Vec::new(); @@ -275,7 +269,7 @@ fn parse_version_axl(content: &str) -> Result { } }, _ => { - return Err(miette!("unexpected *args or **kwargs in version() call")); + return Err(miette!("version() only accepts named arguments (use, sources)")); } } } diff --git a/crates/axl-proto/Cargo.toml b/crates/axl-proto/Cargo.toml index 50ca9ff0a..cac41303a 100644 --- a/crates/axl-proto/Cargo.toml +++ b/crates/axl-proto/Cargo.toml @@ -20,8 +20,9 @@ starbuf-derive = { path = "../starbuf-derive" } starbuf-types = { path = "../starbuf-types" } starlark = "0.13.0" starlark_derive = "0.13.0" -tonic = "0.14.2" +tonic = { version = "0.14.2", features = ["transport", "tls-webpki-roots"] } tonic-prost = "0.14.2" +tokio = { version = "1", features = ["rt-multi-thread", "macros"] } [build-dependencies] prost-build = "0.14.1" diff --git a/crates/axl-proto/build.rs b/crates/axl-proto/build.rs index 0f1f7c312..41d41095c 100644 --- a/crates/axl-proto/build.rs +++ b/crates/axl-proto/build.rs @@ -110,7 +110,7 @@ fn main() -> Result<(), std::io::Error> { } for file in &fds.file { - if file.package() == "google.devtools.build.v1" { + if file.package() == "google.devtools.build.v1" || file.package() == "google.longrunning" { continue; } traverse( @@ -178,6 +178,26 @@ pub mod protos {{ }} +}} + "#, + tools = tools, + ), + )?; + + let v2 = fs::read_to_string(format!( + "{out_dir}/build.bazel.remote.execution.v2.rs" + ))?; + + fs::write( + format!("{out_dir}/build.bazel.remote.execution.v2.rs"), + format!( + r#" +/// @Generated by build.rs +#[starbuf_derive::types] +pub mod v2 {{ + +{v2} + }} "# ), diff --git a/crates/axl-proto/descriptor.bin b/crates/axl-proto/descriptor.bin index ebe10d52d6bd52303b13596ca0d47f0e5a640e2c..8092429aee6c649e5f7fdf3fb24284f030c47136 100644 GIT binary patch delta 122513 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 G{(k`lB9&tR delta 23 ecmdn8LG{Tw*@hOz7N!>F7M2#)7Pc+yDd_-o+X##R diff --git a/crates/axl-proto/src/lib.rs b/crates/axl-proto/src/lib.rs index 80218d42b..77e82ec83 100644 --- a/crates/axl-proto/src/lib.rs +++ b/crates/axl-proto/src/lib.rs @@ -14,6 +14,38 @@ include!(concat!(env!("OUT_DIR"), "/workspace_log.rs")); include!(concat!(env!("OUT_DIR"), "/build_event_stream.rs")); include!(concat!(env!("OUT_DIR"), "/blaze_query.rs")); include!(concat!(env!("OUT_DIR"), "/tools.protos.rs")); +pub mod build { + pub mod bazel { + pub mod semver { + include!(concat!(env!("OUT_DIR"), "/build.bazel.semver.rs")); + } + pub mod remote { + pub mod execution { + include!(concat!( + env!("OUT_DIR"), + "/build.bazel.remote.execution.v2.rs" + )); + + #[starbuf_derive::service( + client = "crate::build::bazel::remote::execution::v2::action_cache_client::ActionCacheClient", + methods( + name = "GetActionResult", + method = "get_action_result", + request = "crate::build::bazel::remote::execution::v2::GetActionResultRequest", + response = "crate::build::bazel::remote::execution::v2::ActionResult", + ), + methods( + name = "UpdateActionResult", + method = "update_action_result", + request = "crate::build::bazel::remote::execution::v2::UpdateActionResultRequest", + response = "crate::build::bazel::remote::execution::v2::ActionResult", + ) + )] + pub struct ActionCache; + } + } + } +} #[path = "./pb_impl.rs"] mod pb_impl; @@ -26,6 +58,12 @@ pub mod google { } } } + pub mod rpc { + include!(concat!(env!("OUT_DIR"), "/google.rpc.rs")); + } + pub mod longrunning { + include!(concat!(env!("OUT_DIR"), "/google.longrunning.rs")); + } } pub mod analysis { diff --git a/crates/axl-runtime/BUILD.bazel b/crates/axl-runtime/BUILD.bazel index 464effc1b..aa6d73e65 100644 --- a/crates/axl-runtime/BUILD.bazel +++ b/crates/axl-runtime/BUILD.bazel @@ -47,7 +47,6 @@ rust_library( "//crates/build-event-stream", "//crates/galvanize", "//crates/aspect-telemetry", - "//axel-f" ], proc_macro_deps = [ "@crates//:starlark_derive", diff --git a/crates/axl-runtime/Cargo.toml b/crates/axl-runtime/Cargo.toml index 4113cb4e9..ed67c518b 100644 --- a/crates/axl-runtime/Cargo.toml +++ b/crates/axl-runtime/Cargo.toml @@ -50,7 +50,6 @@ liquid-core = "0.26.11" minijinja = "2.12.0" aspect-telemetry = { path = "../aspect-telemetry" } -axel-f = { path = "../../axel-f" } axl-proto = { path = "../axl-proto" } build-event-stream = { path = "../build-event-stream" } galvanize = { path = "../galvanize" } diff --git a/crates/axl-runtime/src/builtins/aspect/MODULE.aspect b/crates/axl-runtime/src/builtins/aspect/MODULE.aspect index bd4ae78fe..9822e3885 100644 --- a/crates/axl-runtime/src/builtins/aspect/MODULE.aspect +++ b/crates/axl-runtime/src/builtins/aspect/MODULE.aspect @@ -1,3 +1,25 @@ use_task("build.axl", "build") use_task("test.axl", "test") use_task("axl_add.axl", "add") + +# Register warming tasks. +use_task("tasks/warming.axl", "restore", "update") + +# Configure delivery +use_config("config/delivery.axl", "configure_delivery") + +# Configure builtins +use_config("config/builtins.axl", "configure_builtins") + +# Configure rules_lint if its declared by user +use_config( + "config/lint.axl", + "configure_rules_lint", + requires = ["aspect_rules_lint"] +) + +use_config( + "config/nolint.axl", + "configure_dummy_lint", + conflicts = ["aspect_rules_lint"] +) diff --git a/axel-f/config/builtins.axl b/crates/axl-runtime/src/builtins/aspect/config/builtins.axl similarity index 100% rename from axel-f/config/builtins.axl rename to crates/axl-runtime/src/builtins/aspect/config/builtins.axl diff --git a/axel-f/config/delivery.axl b/crates/axl-runtime/src/builtins/aspect/config/delivery.axl similarity index 100% rename from axel-f/config/delivery.axl rename to crates/axl-runtime/src/builtins/aspect/config/delivery.axl diff --git a/axel-f/config/lint.axl b/crates/axl-runtime/src/builtins/aspect/config/lint.axl similarity index 100% rename from axel-f/config/lint.axl rename to crates/axl-runtime/src/builtins/aspect/config/lint.axl diff --git a/axel-f/config/nolint.axl b/crates/axl-runtime/src/builtins/aspect/config/nolint.axl similarity index 100% rename from axel-f/config/nolint.axl rename to crates/axl-runtime/src/builtins/aspect/config/nolint.axl diff --git a/axel-f/lib/deliveryd.axl b/crates/axl-runtime/src/builtins/aspect/lib/deliveryd.axl similarity index 100% rename from axel-f/lib/deliveryd.axl rename to crates/axl-runtime/src/builtins/aspect/lib/deliveryd.axl diff --git a/axel-f/lib/github.axl b/crates/axl-runtime/src/builtins/aspect/lib/github.axl similarity index 100% rename from axel-f/lib/github.axl rename to crates/axl-runtime/src/builtins/aspect/lib/github.axl diff --git a/axel-f/lib/linting.axl b/crates/axl-runtime/src/builtins/aspect/lib/linting.axl similarity index 100% rename from axel-f/lib/linting.axl rename to crates/axl-runtime/src/builtins/aspect/lib/linting.axl diff --git a/axel-f/lib/platform.axl b/crates/axl-runtime/src/builtins/aspect/lib/platform.axl similarity index 100% rename from axel-f/lib/platform.axl rename to crates/axl-runtime/src/builtins/aspect/lib/platform.axl diff --git a/axel-f/lib/sarif.axl b/crates/axl-runtime/src/builtins/aspect/lib/sarif.axl similarity index 100% rename from axel-f/lib/sarif.axl rename to crates/axl-runtime/src/builtins/aspect/lib/sarif.axl diff --git a/axel-f/tasks/delivery.axl b/crates/axl-runtime/src/builtins/aspect/tasks/delivery.axl similarity index 100% rename from axel-f/tasks/delivery.axl rename to crates/axl-runtime/src/builtins/aspect/tasks/delivery.axl diff --git a/axel-f/tasks/dummy_format.axl b/crates/axl-runtime/src/builtins/aspect/tasks/dummy_format.axl similarity index 100% rename from axel-f/tasks/dummy_format.axl rename to crates/axl-runtime/src/builtins/aspect/tasks/dummy_format.axl diff --git a/axel-f/tasks/dummy_lint.axl b/crates/axl-runtime/src/builtins/aspect/tasks/dummy_lint.axl similarity index 100% rename from axel-f/tasks/dummy_lint.axl rename to crates/axl-runtime/src/builtins/aspect/tasks/dummy_lint.axl diff --git a/axel-f/tasks/migrate.axl b/crates/axl-runtime/src/builtins/aspect/tasks/migrate.axl similarity index 100% rename from axel-f/tasks/migrate.axl rename to crates/axl-runtime/src/builtins/aspect/tasks/migrate.axl diff --git a/axel-f/tasks/warming.axl b/crates/axl-runtime/src/builtins/aspect/tasks/warming.axl similarity index 100% rename from axel-f/tasks/warming.axl rename to crates/axl-runtime/src/builtins/aspect/tasks/warming.axl diff --git a/crates/axl-runtime/src/builtins/mod.rs b/crates/axl-runtime/src/builtins/mod.rs index 034c2b05d..a31d23ef4 100644 --- a/crates/axl-runtime/src/builtins/mod.rs +++ b/crates/axl-runtime/src/builtins/mod.rs @@ -16,17 +16,61 @@ const ASPECT: Builtin = Builtin { ("test.axl", include_str!("./aspect/test.axl")), ("axl_add.axl", include_str!("./aspect/axl_add.axl")), ("MODULE.aspect", include_str!("./aspect/MODULE.aspect")), + // config/ + ( + "config/builtins.axl", + include_str!("./aspect/config/builtins.axl"), + ), + ( + "config/delivery.axl", + include_str!("./aspect/config/delivery.axl"), + ), + ("config/lint.axl", include_str!("./aspect/config/lint.axl")), + ( + "config/nolint.axl", + include_str!("./aspect/config/nolint.axl"), + ), + // tasks/ + ( + "tasks/delivery.axl", + include_str!("./aspect/tasks/delivery.axl"), + ), + ( + "tasks/dummy_lint.axl", + include_str!("./aspect/tasks/dummy_lint.axl"), + ), + ( + "tasks/dummy_format.axl", + include_str!("./aspect/tasks/dummy_format.axl"), + ), + ( + "tasks/migrate.axl", + include_str!("./aspect/tasks/migrate.axl"), + ), + ( + "tasks/warming.axl", + include_str!("./aspect/tasks/warming.axl"), + ), + // lib/ + ( + "lib/deliveryd.axl", + include_str!("./aspect/lib/deliveryd.axl"), + ), + ("lib/github.axl", include_str!("./aspect/lib/github.axl")), + ( + "lib/linting.axl", + include_str!("./aspect/lib/linting.axl"), + ), + ( + "lib/platform.axl", + include_str!("./aspect/lib/platform.axl"), + ), + ("lib/sarif.axl", include_str!("./aspect/lib/sarif.axl")), ], }; #[cfg(not(debug_assertions))] -const AXEL_F: Builtin = Builtin { - name: "axel-f", - files: axel_f::FILES, -}; - -#[cfg(not(debug_assertions))] -const ALL: &[&Builtin] = &[&ASPECT, &AXEL_F]; +const ALL: &[&Builtin] = &[&ASPECT]; #[cfg(debug_assertions)] pub fn expand_builtins( @@ -34,13 +78,10 @@ pub fn expand_builtins( _broot: PathBuf, ) -> std::io::Result> { let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - Ok(vec![ - ( - "aspect".to_string(), - manifest_dir.join("src/builtins/aspect"), - ), - ("axel-f".to_string(), manifest_dir.join("../../axel-f")), - ]) + Ok(vec![( + "aspect".to_string(), + manifest_dir.join("src/builtins/aspect"), + )]) } #[cfg(not(debug_assertions))] diff --git a/crates/axl-runtime/src/engine/mod.rs b/crates/axl-runtime/src/engine/mod.rs index da8b8ab20..09772eee5 100644 --- a/crates/axl-runtime/src/engine/mod.rs +++ b/crates/axl-runtime/src/engine/mod.rs @@ -1,3 +1,4 @@ +use axl_proto::build::bazel::remote::execution as remote_execution; use starlark::{ environment::GlobalsBuilder, starlark_module, values::starlark_value_as_type::StarlarkValueAsType, @@ -41,6 +42,12 @@ pub fn register_globals(globals: &mut GlobalsBuilder) { globals.namespace("args", task_arg::register_globals); globals.namespace("bazel", bazel::register_globals); + globals.namespace("remote", |g| { + g.namespace("execution", |g| { + remote_execution::action_cache_service(g); + remote_execution::v2_toplevels(g); + }); + }); globals.namespace("std", std::register_globals); globals.namespace("wasm", wasm::register_wasm_types); } diff --git a/crates/starbuf-derive/src/lib.rs b/crates/starbuf-derive/src/lib.rs index e0242b6b3..9e288a95e 100644 --- a/crates/starbuf-derive/src/lib.rs +++ b/crates/starbuf-derive/src/lib.rs @@ -7,7 +7,8 @@ use darling::{FromField, FromMeta, FromVariant}; use proc_macro2::{Span, TokenStream}; use quote::{ToTokens, quote}; use syn::Item; -use syn::{Attribute, Field, parse_str, spanned::Spanned}; +use syn::parse::Parser; +use syn::{Attribute, Field, ItemStruct, Lit, Meta, parse_str, spanned::Spanned}; use syn::{ Data, DataEnum, DataStruct, DeriveInput, Expr, Fields, FieldsNamed, FieldsUnnamed, Ident, Type, Variant, @@ -99,10 +100,11 @@ fn try_types(input: TokenStream) -> Result { if let Item::Mod(smod) = subitem { let subident = &smod.ident; let subpath = quote! {#subpath::#subident}; + let sub_key = subpath.to_string(); let subgenerator_fn = Ident::new( &format!( "{}_toplevels", - subpath.to_string().replace("::", "_").replace(" ", "") + sub_key.replace("::", "_").replace(" ", "") ), Span::call_site(), ); @@ -111,6 +113,8 @@ fn try_types(input: TokenStream) -> Result { .or_insert_with(|| (vec![], vec![])) .1 .push(quote! { globals.namespace(#subidentstr, #subgenerator_fn); }); + // Ensure the sub-module entry exists even if it has no processable items + defs.entry(sub_key).or_insert_with(|| (vec![], vec![])); } traverse(subpath, defs, &subitem) @@ -123,13 +127,27 @@ fn try_types(input: TokenStream) -> Result { .0 .push(quote! {}); } - Item::Struct(st) => { + Item::Struct(st) if st.generics.params.is_empty() => { let ident = &st.ident; let subpaths = prefix.to_string(); - defs.entry(subpaths).or_insert_with(|| (vec![], vec![])).0.push(quote! { - const #ident: ::starlark::values::starlark_value_as_type::StarlarkValueAsType<#prefix::#ident> = - starlark::values::starlark_value_as_type::StarlarkValueAsType::new(); - }); + defs.entry(subpaths.clone()) + .or_insert_with(|| (vec![], vec![])) + .0 + .push(quote! { + const #ident: ::starlark::values::starlark_value_as_type::StarlarkValueAsType<#prefix::#ident> = + starlark::values::starlark_value_as_type::StarlarkValueAsType::new(); + }); + let ident_snake = snake(ident.to_string()); + let constructor_fn = Ident::new( + &format!("{}_constructor", ident_snake), + ident.span(), + ); + defs.entry(subpaths) + .or_insert_with(|| (vec![], vec![])) + .1 + .push(quote! { + #prefix::#constructor_fn(globals); + }); } _ => {} }; @@ -175,6 +193,115 @@ fn try_types(input: TokenStream) -> Result { Ok(expanded) } +struct ServiceRpc { + name: Ident, + method: Ident, + request: Type, + response: Type, +} + +fn parse_service_attr(attr: TokenStream) -> Result<(Type, Vec), Error> { + let args: syn::punctuated::Punctuated = + syn::punctuated::Punctuated::parse_terminated.parse2(attr)?; + + let mut client: Option = None; + let mut methods: Vec = Vec::new(); + + for arg in args { + match arg { + Meta::NameValue(nv) if nv.path.is_ident("client") => { + let syn::Expr::Lit(expr_lit) = &nv.value else { + bail!("client must be a string literal type path"); + }; + let Lit::Str(lit) = &expr_lit.lit else { + bail!("client must be a string literal type path"); + }; + let ty: Type = parse_str(&lit.value())?; + client = Some(ty); + } + Meta::List(list) if list.path.is_ident("methods") => { + let mut name: Option = None; + let mut method: Option = None; + let mut request: Option = None; + let mut response: Option = None; + + let nested: syn::punctuated::Punctuated = + syn::punctuated::Punctuated::parse_terminated.parse2(list.tokens.clone())?; + + for nested_meta in nested.iter() { + match nested_meta { + Meta::NameValue(nv) if nv.path.is_ident("name") => { + let syn::Expr::Lit(expr_lit) = &nv.value else { + bail!("method name must be a string literal"); + }; + let Lit::Str(lit) = &expr_lit.lit else { + bail!("method name must be a string literal"); + }; + name = Some(Ident::new(&lit.value(), lit.span())); + } + Meta::NameValue(nv) if nv.path.is_ident("method") => { + let syn::Expr::Lit(expr_lit) = &nv.value else { + bail!("tonic method must be a string literal"); + }; + let Lit::Str(lit) = &expr_lit.lit else { + bail!("tonic method must be a string literal"); + }; + method = Some(Ident::new(&lit.value(), lit.span())); + } + Meta::NameValue(nv) if nv.path.is_ident("request") => { + let syn::Expr::Lit(expr_lit) = &nv.value else { + bail!("request must be a string literal type path"); + }; + let Lit::Str(lit) = &expr_lit.lit else { + bail!("request must be a string literal type path"); + }; + request = Some(parse_str(&lit.value())?); + } + Meta::NameValue(nv) if nv.path.is_ident("response") => { + let syn::Expr::Lit(expr_lit) = &nv.value else { + bail!("response must be a string literal type path"); + }; + let Lit::Str(lit) = &expr_lit.lit else { + bail!("response must be a string literal type path"); + }; + response = Some(parse_str(&lit.value())?); + } + _ => {} + } + } + let Some(name) = name else { + bail!("each methods(...) entry must include name"); + }; + let Some(method) = method else { + bail!("each methods(...) entry must include method"); + }; + let Some(request) = request else { + bail!("each methods(...) entry must include request"); + }; + let Some(response) = response else { + bail!("each methods(...) entry must include response"); + }; + + methods.push(ServiceRpc { + name, + method, + request, + response, + }); + } + _ => {} + } + } + + let client = client + .ok_or_else(|| anyhow::anyhow!("service attribute requires client = \"path::Type\""))?; + if methods.is_empty() { + bail!("service attribute requires at least one methods(...) entry"); + } + + Ok((client, methods)) +} + #[proc_macro_attribute] pub fn types( _attr: proc_macro::TokenStream, @@ -373,6 +500,138 @@ fn try_message(input: TokenStream) -> Result { let ident_snake = snake(ident.to_string()); let methods_ident = Ident::new(&format!("{}_methods", &ident_snake), ident.span()); + let constructor_fn_ident = Ident::new(&format!("{}_constructor", &ident_snake), ident.span()); + + let constructor_arms: Vec = fields + .iter() + .filter_map(|(field, sattrs, attrs, _)| { + let has_deprecated = field.attrs.iter().any(|v| v.path().is_ident("deprecated")); + if sattrs.skip + || has_deprecated + || sattrs.any + || sattrs.duration + || sattrs.timestamp + || attrs.bytes.is_some() + || attrs.map.is_some() + || attrs.oneof.is_some() + { + return None; + } + + let fident = field.ident.as_ref()?; + let fident_str = fident.to_string(); + + let conversion = if attrs.optional && attrs.message { + let inner_ty = extract_inner_type(&field.ty, "core::option::Option")?; + let inner_str = inner_ty.to_token_stream().to_string().replace(' ', ""); + if matches!(inner_str.as_str(), "u32" | "i32" | "u64" | "i64" | "f32" | "f64" | "bool") { + // prost wraps proto3 optional scalars as message+optional — skip in constructor + return None; + } + quote! { + use ::starlark::values::ValueLike; + result.#fident = Some(value.downcast_ref_err::<#inner_ty>()?.clone()); + } + } else if attrs.optional && attrs.string { + quote! { + result.#fident = Some(value.unpack_str() + .ok_or_else(|| ::anyhow::anyhow!("field '{}' expects a string", #fident_str))? + .to_string()); + } + } else if attrs.optional && (attrs.int32 || attrs.uint32 || attrs.int64 || attrs.uint64) { + quote! { + result.#fident = Some(::unpack_value(value)? + .ok_or_else(|| ::anyhow::anyhow!("expected int"))? as _); + } + } else if attrs.optional && attrs.bool { + quote! { + result.#fident = Some(value.unpack_bool() + .ok_or_else(|| ::anyhow::anyhow!("field '{}' expects a bool", #fident_str))?); + } + } else if attrs.optional && attrs.enumeration.is_some() { + quote! { + result.#fident = Some(::unpack_value(value)? + .ok_or_else(|| ::anyhow::anyhow!("expected int"))? as i32); + } + } else if attrs.repeated && attrs.message { + let inner_ty = extract_inner_type(&field.ty, "prost::alloc::vec::Vec")?; + quote! { + use ::starlark::values::ValueLike; + let list = ::starlark::values::list::ListRef::from_value(value) + .ok_or_else(|| ::anyhow::anyhow!("field '{}' expects a list", #fident_str))?; + for item in list.iter() { + result.#fident.push(item.downcast_ref_err::<#inner_ty>()?.clone()); + } + } + } else if attrs.repeated && attrs.string { + quote! { + let list = ::starlark::values::list::ListRef::from_value(value) + .ok_or_else(|| ::anyhow::anyhow!("field '{}' expects a list", #fident_str))?; + for item in list.iter() { + result.#fident.push(item.unpack_str() + .ok_or_else(|| ::anyhow::anyhow!("list items for '{}' must be strings", #fident_str))? + .to_string()); + } + } + } else if attrs.repeated && (attrs.int32 || attrs.uint32 || attrs.int64 || attrs.uint64) { + quote! { + let list = ::starlark::values::list::ListRef::from_value(value) + .ok_or_else(|| ::anyhow::anyhow!("field '{}' expects a list", #fident_str))?; + for item in list.iter() { + result.#fident.push(::unpack_value(item)? + .ok_or_else(|| ::anyhow::anyhow!("expected int"))? as _); + } + } + } else if attrs.repeated && attrs.enumeration.is_some() { + quote! { + let list = ::starlark::values::list::ListRef::from_value(value) + .ok_or_else(|| ::anyhow::anyhow!("field '{}' expects a list", #fident_str))?; + for item in list.iter() { + result.#fident.push(::unpack_value(item)? + .ok_or_else(|| ::anyhow::anyhow!("expected int"))? as i32); + } + } + } else if attrs.string { + quote! { + result.#fident = value.unpack_str() + .ok_or_else(|| ::anyhow::anyhow!("field '{}' expects a string", #fident_str))? + .to_string(); + } + } else if attrs.bool { + quote! { + result.#fident = value.unpack_bool() + .ok_or_else(|| ::anyhow::anyhow!("field '{}' expects a bool", #fident_str))?; + } + } else if attrs.int32 || attrs.uint32 { + quote! { + result.#fident = ::unpack_value(value)? + .ok_or_else(|| ::anyhow::anyhow!("expected int"))? as _; + } + } else if attrs.int64 || attrs.uint64 { + quote! { + result.#fident = ::unpack_value(value)? + .ok_or_else(|| ::anyhow::anyhow!("expected int"))? as _; + } + } else if attrs.enumeration.is_some() { + quote! { + result.#fident = ::unpack_value(value)? + .ok_or_else(|| ::anyhow::anyhow!("expected int"))? as i32; + } + } else if attrs.message { + let ty = &field.ty; + quote! { + use ::starlark::values::ValueLike; + result.#fident = value.downcast_ref_err::<#ty>()?.clone(); + } + } else { + return None; + }; + + Some(quote! { + #fident_str => { #conversion }, + }) + }) + .collect(); let expanded = quote! { impl<'v> ::starlark::values::AllocValue<'v> for #ident { @@ -390,11 +649,29 @@ fn try_message(input: TokenStream) -> Result { } } - #[::starlark::starlark_module] pub(crate) fn #methods_ident(registry: &mut ::starlark::environment::MethodsBuilder) { #(#starlark_attributes)* } + + #[::starlark::starlark_module] + pub fn #constructor_fn_ident(globals: &mut ::starlark::environment::GlobalsBuilder) { + fn #ident<'v>( + #[starlark(kwargs)] kwargs: ::starlark::collections::SmallMap<&str, ::starlark::values::Value<'v>>, + ) -> ::starlark::Result<#ident> { + let mut result = #ident::default(); + for (key, val) in kwargs.iter() { + let value = *val; + match *key { + #(#constructor_arms)* + other => return Err(::anyhow::anyhow!( + "unknown field '{}' for {}", other, stringify!(#ident) + ).into()), + } + } + Ok(result) + } + } }; Ok(expanded) @@ -491,6 +768,28 @@ pub fn oneof(input: proc_macro::TokenStream) -> proc_macro::TokenStream { try_oneof(input.into()).unwrap().into() } +fn extract_inner_type(ty: &Type, expected_path: &str) -> Option { + if let Type::Path(p) = ty { + let tys = p + .path + .segments + .iter() + .map(|i| i.ident.to_string()) + .collect::>() + .join("::"); + if tys == expected_path { + if let Some(last_seg) = p.path.segments.last() { + if let syn::PathArguments::AngleBracketed(args) = &last_seg.arguments { + if let Some(syn::GenericArgument::Type(inner_ty)) = args.args.first() { + return Some(inner_ty.clone()); + } + } + } + } + } + None +} + fn snake(s: String) -> String { let mut result = String::new(); let mut chars = s.chars().peekable(); @@ -573,6 +872,190 @@ pub fn enumeration(input: proc_macro::TokenStream) -> proc_macro::TokenStream { try_enumeration(input.into()).unwrap().into() } +fn try_service(attr: TokenStream, item: TokenStream) -> Result { + let (client_ty, methods) = parse_service_attr(attr)?; + + let input: ItemStruct = syn::parse2(item)?; + let ident = &input.ident; + + let handle_ident = Ident::new(&format!("{}ClientHandle", ident), ident.span()); + let ident_snake = snake(ident.to_string()); + let methods_ident = Ident::new(&format!("{}_client_methods", ident_snake), ident.span()); + let module_ident = Ident::new(&format!("{}_service", ident_snake), ident.span()); + let starlark_type = format!("{}_client", ident_snake); + + let rpc_methods = methods.iter().map(|rpc| { + let rpc_name = &rpc.name; + let rpc_method = &rpc.method; + let req = &rpc.request; + let resp = &rpc.response; + + quote! { + fn #rpc_name<'v>( + this: ::starlark::values::Value<'v>, + req: ::starlark::values::Value<'v>, + ) -> ::starlark::Result<#resp> { + use ::starlark::values::ValueLike; + let handle = this.downcast_ref_err::<#handle_ident>()?; + let req = req.downcast_ref_err::<#req>()?.clone(); + + let client = handle.client.get() + .ok_or_else(|| ::starlark::Error::from(::anyhow::anyhow!( + "service not connected; call .connect(ctx) first")))? + .clone(); + let rt = handle.rt.get() + .ok_or_else(|| ::starlark::Error::from(::anyhow::anyhow!( + "service not connected; call .connect(ctx) first")))? + .clone(); + + let headers = handle.headers.clone(); + + let resp = rt.block_on(async move { + let mut c = client.as_ref().clone(); + let mut request = ::tonic::Request::new(req); + for (key, value) in &headers { + request.metadata_mut().insert( + key.parse::<::tonic::metadata::MetadataKey<::tonic::metadata::Ascii>>() + .map_err(|e| ::anyhow::anyhow!("invalid header key '{}': {}", key, e))?, + value.parse::<::tonic::metadata::MetadataValue<::tonic::metadata::Ascii>>() + .map_err(|e| ::anyhow::anyhow!("invalid header value: {}", e))?, + ); + } + let resp = c + .#rpc_method(request) + .await + .map_err(::anyhow::Error::new)? + .into_inner(); + Ok::<#resp, ::anyhow::Error>(resp) + }) + .map_err(|e| ::starlark::Error::from(::anyhow::anyhow!(e)))?; + + Ok(resp) + } + } + }); + + let expanded = quote! { + #[derive(Debug, ::allocative::Allocative, ::starlark::values::NoSerialize, ::starlark::values::ProvidesStaticType)] + pub struct #handle_ident { + uri: String, + headers: Vec<(String, String)>, + timeout: ::std::time::Duration, + #[allocative(skip)] + client: ::std::sync::OnceLock<::std::sync::Arc<#client_ty<::tonic::transport::Channel>>>, + #[allocative(skip)] + rt: ::std::sync::OnceLock<::tokio::runtime::Handle>, + } + + unsafe impl<'v> ::starlark::values::Trace<'v> for #handle_ident { + fn trace(&mut self, _tracer: &::starlark::values::Tracer<'v>) {} + } + + impl ::std::fmt::Display for #handle_ident { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!(f, stringify!(#handle_ident)) + } + } + + impl<'v> ::starlark::values::AllocValue<'v> for #handle_ident { + fn alloc_value(self, heap: &'v ::starlark::values::Heap) -> ::starlark::values::Value<'v> { + heap.alloc_simple(self) + } + } + + #[::starlark::values::starlark_value(type = #starlark_type)] + impl<'v> ::starlark::values::StarlarkValue<'v> for #handle_ident { + fn get_methods() -> ::core::option::Option<&'static ::starlark::environment::Methods> { + static RES: ::starlark::environment::MethodsStatic = ::starlark::environment::MethodsStatic::new(); + RES.methods(#methods_ident) + } + } + + #[::starlark::starlark_module] + pub(crate) fn #methods_ident(registry: &mut ::starlark::environment::MethodsBuilder) { + fn connect<'v>( + this: ::starlark::values::Value<'v>, + ctx: ::starlark::values::Value<'v>, + ) -> ::starlark::Result<::starlark::values::none::NoneType> { + use ::starlark::values::ValueLike; + let handle = this.downcast_ref_err::<#handle_ident>()?; + + // Normalize grpcs:// to https:// + let uri = if handle.uri.starts_with("grpcs://") { + format!("https://{}", &handle.uri["grpcs://".len()..]) + } else { + handle.uri.clone() + }; + + let rt = ::tokio::runtime::Handle::current(); + + let ep = ::tonic::transport::Endpoint::from_shared(uri.clone()) + .map_err(|e| ::anyhow::anyhow!("invalid URI: {}", e))? + .connect_timeout(::std::time::Duration::from_secs(5)) + .timeout(handle.timeout); + + let ep = if uri.starts_with("https://") { + ep.tls_config(::tonic::transport::ClientTlsConfig::new()) + .map_err(|e| ::anyhow::anyhow!("TLS config error: {}", e))? + } else { + ep + }; + + let channel = ep.connect_lazy(); + let client = #client_ty::new(channel); + + handle.client.set(::std::sync::Arc::new(client)) + .map_err(|_| ::anyhow::anyhow!("service already connected"))?; + handle.rt.set(rt) + .map_err(|_| ::anyhow::anyhow!("service already connected"))?; + + Ok(::starlark::values::none::NoneType) + } + + #(#rpc_methods)* + } + + #[::starlark::starlark_module] + pub fn #module_ident(globals: &mut ::starlark::environment::GlobalsBuilder) { + fn #ident<'v>( + #[starlark(require = named)] uri: String, + #[starlark(require = named)] headers: ::starlark::values::Value<'v>, + #[starlark(require = named, default = 10000)] timeout: u64, + ) -> ::starlark::Result<#handle_ident> { + let mut h = Vec::new(); + if let Some(dict) = ::starlark::values::dict::DictRef::from_value(headers) { + for (k, v) in dict.iter() { + let key = k.unpack_str() + .ok_or_else(|| ::anyhow::anyhow!("header key must be a string"))?; + let val = v.unpack_str() + .ok_or_else(|| ::anyhow::anyhow!("header value must be a string"))?; + h.push((key.to_string(), val.to_string())); + } + } + Ok(#handle_ident { + uri, + headers: h, + timeout: ::std::time::Duration::from_millis(timeout), + client: ::std::sync::OnceLock::new(), + rt: ::std::sync::OnceLock::new(), + }) + } + } + + #input + }; + + Ok(expanded) +} + +#[proc_macro_attribute] +pub fn service( + attr: proc_macro::TokenStream, + item: proc_macro::TokenStream, +) -> proc_macro::TokenStream { + try_service(attr.into(), item.into()).unwrap().into() +} + #[cfg(test)] mod tests { use super::*; diff --git a/docs/lib.md b/docs/lib.md index 1fa18d059..c08d0667a 100644 --- a/docs/lib.md +++ b/docs/lib.md @@ -50,6 +50,8 @@ `module` [json](/lib/json) +`module` [remote](/lib/remote) + `module` [std](/lib/std) `module` [typing](/lib/typing) @@ -110,6 +112,30 @@ any([0, 0]) == False any([0, False]) == False ``` +`function` **attr** + +
def attr(
+    typ: typing.Any,
+    default: typing.Any = ...,
+    /
+) -> field
+ +Creates a field definition with a type and optional default value. + +Mutable defaults (lists, dicts) are deep-copied when a spec instance is +created, so each instance gets its own independent copy. + +Example: + +```starlark +MySpec = spec(host=str, port=attr(int, 80)) +r = MySpec(host="localhost") # port defaults to 80 + +# Mutable defaults are copied per instance: +attr(list[str], []) # each instance gets a fresh [] +attr(dict[str, int], {}) # each instance gets a fresh {} +``` + `function` **breakpoint**
def breakpoint() -> None
@@ -627,6 +653,36 @@ sorted(["two", "three", "four"], key=len) == ["two", "four", "thr sorted(["two", "three", "four"], key=len, reverse=True) == ["three", "four", "two"] # longest to shortest ``` +`function` **spec** + +
def spec(
+    **kwargs: typing.Any
+) -> spec
+ +Creates a spec type with the given fields. + +Each field can be a bare type (required, no default) or an `attr()` +definition (with type and optional default). + +Mutable defaults (lists, dicts) are deep-copied per instance, so each +instance gets its own independent copy. No `default_factory` needed. + +Example: + +```starlark +MySpec = spec(host=str, port=int) +r = MySpec(host="localhost", port=80) +print(r.host) # "localhost" +print(r.port) # 80 + +# Mutable defaults are safe: +ListSpec = spec(items=attr(list[str], [])) +a = ListSpec() +b = ListSpec() +a.items.append("x") +print(b.items) # [] — each instance has its own list +``` + `function` **task**
def task(
@@ -653,7 +709,7 @@ build = task(
     task_args = {
         "target": args.string(),
     },
-    config = None  # Optional user-defined config (e.g., a record); defaults to None if not provided
+    config = lambda: MyConfig(key = "value")  # Optional lambda that returns config; evaluated at task creation
 )
 ```
 
diff --git a/docs/lib/future.md b/docs/lib/future.md
index deb2c6424..d5584c011 100644
--- a/docs/lib/future.md
+++ b/docs/lib/future.md
@@ -3,3 +3,19 @@
 `function` **Future.block**
 
 
def Future.block() -> typing.Any
+ +`function` **Future.map\_err** + +
def Future.map_err(callable: typing.Any) -> Future
+ +`function` **Future.map\_ok** + +
def Future.map_ok(callable: typing.Any) -> Future
+ +`function` **Future.map\_ok\_or\_else** + +
def Future.map_ok_or_else(
+    *,
+    map_ok: typing.Any,
+    map_err: typing.Any
+) -> Future
diff --git a/docs/lib/http.md b/docs/lib/http.md index f1aa34c3d..0f18798d8 100644 --- a/docs/lib/http.md +++ b/docs/lib/http.md @@ -1,5 +1,14 @@ +`function` **Http.delete** + +
def Http.delete(
+    *,
+    url: str,
+    headers: dict[str, str] = ...,
+    unix_socket: None | str = None
+) -> Future
+ `function` **Http.download**
def Http.download(
@@ -22,7 +31,8 @@ The checksum is verified in a streaming fashion during download.
 
def Http.get(
     *,
     url: str,
-    headers: dict[str, str] = ...
+    headers: dict[str, str] = ...,
+    unix_socket: None | str = None
 ) -> Future
`function` **Http.post** @@ -31,5 +41,6 @@ The checksum is verified in a streaming fashion during download. url
: str, *, headers: dict[str, str] = ..., - data: str + data: str, + unix_socket: None | str = None ) -> Future
diff --git a/docs/lib/remote.md b/docs/lib/remote.md new file mode 100644 index 000000000..89c2255bf --- /dev/null +++ b/docs/lib/remote.md @@ -0,0 +1,3 @@ + + +`module` [execution](/lib/remote/execution) diff --git a/docs/lib/remote/execution.md b/docs/lib/remote/execution.md new file mode 100644 index 000000000..4c81b718f --- /dev/null +++ b/docs/lib/remote/execution.md @@ -0,0 +1,5 @@ + + +`function` **ActionCache** + +
def ActionCache(addr: str, timeout_ms: int = ...) -> action_cache_client
diff --git a/examples/deliveryd/MODULE.bazel.lock b/examples/deliveryd/MODULE.bazel.lock new file mode 100644 index 000000000..691fbe1f0 --- /dev/null +++ b/examples/deliveryd/MODULE.bazel.lock @@ -0,0 +1,634 @@ +{ + "lockFileVersion": 26, + "registryFileHashes": { + "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", + "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", + "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1", + "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/source.json": "cea3901d7e299da7320700abbaafe57a65d039f10d0d7ea601c4a66938ea4b0c", + "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", + "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", + "https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e", + "https://bcr.bazel.build/modules/apple_support/1.21.1/MODULE.bazel": "5809fa3efab15d1f3c3c635af6974044bac8a4919c62238cce06acee8a8c11f1", + "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4", + "https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d", + "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", + "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", + "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", + "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", + "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", + "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", + "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a", + "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", + "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", + "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", + "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", + "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", + "https://bcr.bazel.build/modules/bazel_features/1.33.0/source.json": "13617db3930328c2cd2807a0f13d52ca870ac05f96db9668655113265147b2a6", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", + "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", + "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", + "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", + "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", + "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb", + "https://bcr.bazel.build/modules/buildozer/8.2.1/MODULE.bazel": "61e9433c574c2bd9519cad7fa66b9c1d2b8e8d5f3ae5d6528a2c2d26e68d874d", + "https://bcr.bazel.build/modules/buildozer/8.2.1/source.json": "7c33f6a26ee0216f85544b4bca5e9044579e0219b6898dd653f5fb449cf2e484", + "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", + "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350", + "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", + "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", + "https://bcr.bazel.build/modules/gazelle/0.47.0/MODULE.bazel": "b61bb007c4efad134aa30ee7f4a8e2a39b22aa5685f005edaa022fbd1de43ebc", + "https://bcr.bazel.build/modules/gazelle/0.47.0/source.json": "aeb2e5df14b7fb298625d75d08b9c65bdb0b56014c5eb89da9e5dd0572280ae6", + "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", + "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", + "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46", + "https://bcr.bazel.build/modules/googletest/1.17.0/source.json": "38e4454b25fc30f15439c0378e57909ab1fd0a443158aa35aec685da727cd713", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000", + "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9", + "https://bcr.bazel.build/modules/package_metadata/0.0.5/MODULE.bazel": "ef4f9439e3270fdd6b9fd4dbc3d2f29d13888e44c529a1b243f7a31dfbc2e8e4", + "https://bcr.bazel.build/modules/package_metadata/0.0.5/source.json": "2326db2f6592578177751c3e1f74786b79382cd6008834c9d01ec865b9126a85", + "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", + "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", + "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", + "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", + "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", + "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", + "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", + "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", + "https://bcr.bazel.build/modules/platforms/1.0.0/source.json": "f4ff1fd412e0246fd38c82328eb209130ead81d62dcd5a9e40910f867f733d96", + "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", + "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2.bcr.1/MODULE.bazel": "52f4126f63a2f0bbf36b99c2a87648f08467a4eaf92ba726bc7d6a500bbf770c", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", + "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", + "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", + "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573", + "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", + "https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d", + "https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42", + "https://bcr.bazel.build/modules/protobuf/33.4/source.json": "555f8686b4c7d6b5ba731fbea13bf656b4bfd9a7ff629c1d9d3f6e1d6155de79", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680", + "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/source.json": "2ff292be6ef3340325ce8a045ecc326e92cbfab47c7cbab4bd85d28971b97ac4", + "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", + "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", + "https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e", + "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/MODULE.bazel": "76e10fd4a48038d3fc7c5dc6e63b7063bbf5304a2e3bd42edda6ec660eebea68", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/source.json": "8ee81e1708756f81b343a5eb2b2f0b953f1d25c4ab3d4a68dc02754872e80715", + "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", + "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", + "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", + "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", + "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", + "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", + "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", + "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", + "https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0", + "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", + "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c", + "https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37", + "https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8", + "https://bcr.bazel.build/modules/rules_cc/0.2.14/source.json": "55d0a4587c5592fad350f6e698530f4faf0e7dd15e69d43f8d87e220c78bea54", + "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", + "https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8", + "https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270", + "https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd", + "https://bcr.bazel.build/modules/rules_go/0.53.0/MODULE.bazel": "a4ed760d3ac0dbc0d7b967631a9a3fd9100d28f7d9fcf214b4df87d4bfff5f9a", + "https://bcr.bazel.build/modules/rules_go/0.59.0/MODULE.bazel": "b7e43e7414a3139a7547d1b4909b29085fbe5182b6c58cbe1ed4c6272815aeae", + "https://bcr.bazel.build/modules/rules_go/0.59.0/source.json": "1df17bb7865cfc029492c30163cee891d0dd8658ea0d5bfdf252c4b6db5c1ef6", + "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", + "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", + "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", + "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", + "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", + "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", + "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", + "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", + "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", + "https://bcr.bazel.build/modules/rules_java/9.0.3/MODULE.bazel": "1f98ed015f7e744a745e0df6e898a7c5e83562d6b759dfd475c76456dda5ccea", + "https://bcr.bazel.build/modules/rules_java/9.0.3/source.json": "b038c0c07e12e658135bbc32cc1a2ded6e33785105c9d41958014c592de4593e", + "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", + "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/source.json": "5426f412d0a7fc6b611643376c7e4a82dec991491b9ce5cb1cfdd25fe2e92be4", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5", + "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", + "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", + "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", + "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a", + "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", + "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", + "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", + "https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f", + "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", + "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", + "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", + "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", + "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", + "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", + "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", + "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", + "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", + "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", + "https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", + "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/source.json": "20ec05cd5e592055e214b2da8ccb283c7f2a421ea0dc2acbf1aa792e11c03d0c", + "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", + "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", + "https://bcr.bazel.build/modules/rules_swift/2.4.0/MODULE.bazel": "1639617eb1ede28d774d967a738b4a68b0accb40650beadb57c21846beab5efd", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/MODULE.bazel": "72c8f5cf9d26427cee6c76c8e3853eb46ce6b0412a081b2b6db6e8ad56267400", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/source.json": "e85761f3098a6faf40b8187695e3de6d97944e98abd0d8ce579cb2daf6319a66", + "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", + "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", + "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "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/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/MODULE.bazel": "75aab2373a4bbe2a1260b9bf2a1ebbdbf872d3bd36f80bff058dccd82e89422f", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/source.json": "5fba48bbe0ba48761f9e9f75f92876cafb5d07c0ce059cc7a8027416de94a05b", + "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.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", + "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" + }, + "selectedYankedVersions": {}, + "moduleExtensions": { + "@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": { + "general": { + "bzlTransitiveDigest": "ABI1D/sbS1ovwaW/kHDoj8nnXjQ0oKU9fzmzEG4iT8o=", + "usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=", + "recordedInputs": [ + "REPO_MAPPING:rules_kotlin+,bazel_tools bazel_tools" + ], + "generatedRepoSpecs": { + "com_github_jetbrains_kotlin_git": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_compiler_git_repository", + "attributes": { + "urls": [ + "https://github.com/JetBrains/kotlin/releases/download/v1.9.23/kotlin-compiler-1.9.23.zip" + ], + "sha256": "93137d3aab9afa9b27cb06a824c2324195c6b6f6179d8a8653f440f5bd58be88" + } + }, + "com_github_jetbrains_kotlin": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_capabilities_repository", + "attributes": { + "git_repository_name": "com_github_jetbrains_kotlin_git", + "compiler_version": "1.9.23" + } + }, + "com_github_google_ksp": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:ksp.bzl%ksp_compiler_plugin_repository", + "attributes": { + "urls": [ + "https://github.com/google/ksp/releases/download/1.9.23-1.0.20/artifacts.zip" + ], + "sha256": "ee0618755913ef7fd6511288a232e8fad24838b9af6ea73972a76e81053c8c2d", + "strip_version": "1.9.23-1.0.20" + } + }, + "com_github_pinterest_ktlint": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "sha256": "01b2e0ef893383a50dbeb13970fe7fa3be36ca3e83259e01649945b09d736985", + "urls": [ + "https://github.com/pinterest/ktlint/releases/download/1.3.0/ktlint" + ], + "executable": true + } + }, + "rules_android": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806", + "strip_prefix": "rules_android-0.1.1", + "urls": [ + "https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip" + ] + } + } + } + } + }, + "@@rules_python+//python/extensions:config.bzl%config": { + "general": { + "bzlTransitiveDigest": "2hLgIvNVTLgxus0ZuXtleBe70intCfo0cHs8qvt6cdM=", + "usagesDigest": "ZVSXMAGpD+xzVNPuvF1IoLBkty7TROO0+akMapt1pAg=", + "recordedInputs": [ + "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_python+,pypi__build rules_python++config+pypi__build", + "REPO_MAPPING:rules_python+,pypi__click rules_python++config+pypi__click", + "REPO_MAPPING:rules_python+,pypi__colorama rules_python++config+pypi__colorama", + "REPO_MAPPING:rules_python+,pypi__importlib_metadata rules_python++config+pypi__importlib_metadata", + "REPO_MAPPING:rules_python+,pypi__installer rules_python++config+pypi__installer", + "REPO_MAPPING:rules_python+,pypi__more_itertools rules_python++config+pypi__more_itertools", + "REPO_MAPPING:rules_python+,pypi__packaging rules_python++config+pypi__packaging", + "REPO_MAPPING:rules_python+,pypi__pep517 rules_python++config+pypi__pep517", + "REPO_MAPPING:rules_python+,pypi__pip rules_python++config+pypi__pip", + "REPO_MAPPING:rules_python+,pypi__pip_tools rules_python++config+pypi__pip_tools", + "REPO_MAPPING:rules_python+,pypi__pyproject_hooks rules_python++config+pypi__pyproject_hooks", + "REPO_MAPPING:rules_python+,pypi__setuptools rules_python++config+pypi__setuptools", + "REPO_MAPPING:rules_python+,pypi__tomli rules_python++config+pypi__tomli", + "REPO_MAPPING:rules_python+,pypi__wheel rules_python++config+pypi__wheel", + "REPO_MAPPING:rules_python+,pypi__zipp rules_python++config+pypi__zipp" + ], + "generatedRepoSpecs": { + "rules_python_internal": { + "repoRuleId": "@@rules_python+//python/private:internal_config_repo.bzl%internal_config_repo", + "attributes": { + "transition_setting_generators": {}, + "transition_settings": [] + } + }, + "pypi__build": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e2/03/f3c8ba0a6b6e30d7d18c40faab90807c9bb5e9a1e3b2fe2008af624a9c97/build-1.2.1-py3-none-any.whl", + "sha256": "75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__click": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", + "sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__colorama": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", + "sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__importlib_metadata": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/2d/0a/679461c511447ffaf176567d5c496d1de27cbe34a87df6677d7171b2fbd4/importlib_metadata-7.1.0-py3-none-any.whl", + "sha256": "30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__installer": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e5/ca/1172b6638d52f2d6caa2dd262ec4c811ba59eee96d54a7701930726bce18/installer-0.7.0-py3-none-any.whl", + "sha256": "05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__more_itertools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/50/e2/8e10e465ee3987bb7c9ab69efb91d867d93959095f4807db102d07995d94/more_itertools-10.2.0-py3-none-any.whl", + "sha256": "686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__packaging": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", + "sha256": "2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pep517": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/25/6e/ca4a5434eb0e502210f591b97537d322546e4833dcb4d470a48c375c5540/pep517-0.13.1-py3-none-any.whl", + "sha256": "31b206f67165b3536dd577c5c3f1518e8fbaf38cbc57efff8369a392feff1721", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl", + "sha256": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip_tools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/0d/dc/38f4ce065e92c66f058ea7a368a9c5de4e702272b479c0992059f7693941/pip_tools-7.4.1-py3-none-any.whl", + "sha256": "4c690e5fbae2f21e87843e89c26191f0d9454f362d8acdbd695716493ec8b3a9", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pyproject_hooks": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl", + "sha256": "7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__setuptools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/90/99/158ad0609729111163fc1f674a5a42f2605371a4cf036d0441070e2f7455/setuptools-78.1.1-py3-none-any.whl", + "sha256": "c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__tomli": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", + "sha256": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__wheel": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/7d/cd/d7460c9a869b16c3dd4e1e403cce337df165368c71d6af229a74699622ce/wheel-0.43.0-py3-none-any.whl", + "sha256": "55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__zipp": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/da/55/a03fd7240714916507e1fcf7ae355bd9d9ed2e6db492595f1a67f61681be/zipp-3.18.2-py3-none-any.whl", + "sha256": "dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + } + } + } + }, + "@@rules_python+//python/uv:uv.bzl%uv": { + "general": { + "bzlTransitiveDigest": "ijW9KS7qsIY+yBVvJ+Nr1mzwQox09j13DnE3iIwaeTM=", + "usagesDigest": "H8dQoNZcoqP+Mu0tHZTi4KHATzvNkM5ePuEqoQdklIU=", + "recordedInputs": [ + "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_python+,platforms platforms" + ], + "generatedRepoSpecs": { + "uv": { + "repoRuleId": "@@rules_python+//python/uv/private:uv_toolchains_repo.bzl%uv_toolchains_repo", + "attributes": { + "toolchain_type": "'@@rules_python+//python/uv:uv_toolchain_type'", + "toolchain_names": [ + "none" + ], + "toolchain_implementations": { + "none": "'@@rules_python+//python:none'" + }, + "toolchain_compatible_with": { + "none": [ + "@platforms//:incompatible" + ] + }, + "toolchain_target_settings": {} + } + } + } + } + } + }, + "facts": { + "@@rules_go+//go:extensions.bzl%go_sdk": { + "1.25.0": { + "aix_ppc64": [ + "go1.25.0.aix-ppc64.tar.gz", + "e5234a7dac67bc86c528fe9752fc9d63557918627707a733ab4cac1a6faed2d4" + ], + "darwin_amd64": [ + "go1.25.0.darwin-amd64.tar.gz", + "5bd60e823037062c2307c71e8111809865116714d6f6b410597cf5075dfd80ef" + ], + "darwin_arm64": [ + "go1.25.0.darwin-arm64.tar.gz", + "544932844156d8172f7a28f77f2ac9c15a23046698b6243f633b0a0b00c0749c" + ], + "dragonfly_amd64": [ + "go1.25.0.dragonfly-amd64.tar.gz", + "5ed3cf9a810a1483822538674f1336c06b51aa1b94d6d545a1a0319a48177120" + ], + "freebsd_386": [ + "go1.25.0.freebsd-386.tar.gz", + "abea5d5c6697e6b5c224731f2158fe87c602996a2a233ac0c4730cd57bf8374e" + ], + "freebsd_amd64": [ + "go1.25.0.freebsd-amd64.tar.gz", + "86e6fe0a29698d7601c4442052dac48bd58d532c51cccb8f1917df648138730b" + ], + "freebsd_arm": [ + "go1.25.0.freebsd-arm.tar.gz", + "d90b78e41921f72f30e8bbc81d9dec2cff7ff384a33d8d8debb24053e4336bfe" + ], + "freebsd_arm64": [ + "go1.25.0.freebsd-arm64.tar.gz", + "451d0da1affd886bfb291b7c63a6018527b269505db21ce6e14724f22ab0662e" + ], + "freebsd_riscv64": [ + "go1.25.0.freebsd-riscv64.tar.gz", + "7b565f76bd8bda46549eeaaefe0e53b251e644c230577290c0f66b1ecdb3cdbe" + ], + "illumos_amd64": [ + "go1.25.0.illumos-amd64.tar.gz", + "b1e1fdaab1ad25aa1c08d7a36c97d45d74b98b89c3f78c6d2145f77face54a2c" + ], + "linux_386": [ + "go1.25.0.linux-386.tar.gz", + "8c602dd9d99bc9453b3995d20ce4baf382cc50855900a0ece5de9929df4a993a" + ], + "linux_amd64": [ + "go1.25.0.linux-amd64.tar.gz", + "2852af0cb20a13139b3448992e69b868e50ed0f8a1e5940ee1de9e19a123b613" + ], + "linux_arm64": [ + "go1.25.0.linux-arm64.tar.gz", + "05de75d6994a2783699815ee553bd5a9327d8b79991de36e38b66862782f54ae" + ], + "linux_armv6l": [ + "go1.25.0.linux-armv6l.tar.gz", + "a5a8f8198fcf00e1e485b8ecef9ee020778bf32a408a4e8873371bfce458cd09" + ], + "linux_loong64": [ + "go1.25.0.linux-loong64.tar.gz", + "cab86b1cf761b1cb3bac86a8877cfc92e7b036fc0d3084123d77013d61432afc" + ], + "linux_mips": [ + "go1.25.0.linux-mips.tar.gz", + "d66b6fb74c3d91b9829dc95ec10ca1f047ef5e89332152f92e136cf0e2da5be1" + ], + "linux_mips64": [ + "go1.25.0.linux-mips64.tar.gz", + "4082e4381a8661bc2a839ff94ba3daf4f6cde20f8fb771b5b3d4762dc84198a2" + ], + "linux_mips64le": [ + "go1.25.0.linux-mips64le.tar.gz", + "70002c299ec7f7175ac2ef673b1b347eecfa54ae11f34416a6053c17f855afcc" + ], + "linux_mipsle": [ + "go1.25.0.linux-mipsle.tar.gz", + "b00a3a39eff099f6df9f1c7355bf28e4589d0586f42d7d4a394efb763d145a73" + ], + "linux_ppc64": [ + "go1.25.0.linux-ppc64.tar.gz", + "df166f33bd98160662560a72ff0b4ba731f969a80f088922bddcf566a88c1ec1" + ], + "linux_ppc64le": [ + "go1.25.0.linux-ppc64le.tar.gz", + "0f18a89e7576cf2c5fa0b487a1635d9bcbf843df5f110e9982c64df52a983ad0" + ], + "linux_riscv64": [ + "go1.25.0.linux-riscv64.tar.gz", + "c018ff74a2c48d55c8ca9b07c8e24163558ffec8bea08b326d6336905d956b67" + ], + "linux_s390x": [ + "go1.25.0.linux-s390x.tar.gz", + "34e5a2e19f2292fbaf8783e3a241e6e49689276aef6510a8060ea5ef54eee408" + ], + "netbsd_386": [ + "go1.25.0.netbsd-386.tar.gz", + "f8586cdb7aa855657609a5c5f6dbf523efa00c2bbd7c76d3936bec80aa6c0aba" + ], + "netbsd_amd64": [ + "go1.25.0.netbsd-amd64.tar.gz", + "ae8dc1469385b86a157a423bb56304ba45730de8a897615874f57dd096db2c2a" + ], + "netbsd_arm": [ + "go1.25.0.netbsd-arm.tar.gz", + "1ff7e4cc764425fc9dd6825eaee79d02b3c7cafffbb3691687c8d672ade76cb7" + ], + "netbsd_arm64": [ + "go1.25.0.netbsd-arm64.tar.gz", + "e1b310739f26724216aa6d7d7208c4031f9ff54c9b5b9a796ddc8bebcb4a5f16" + ], + "openbsd_386": [ + "go1.25.0.openbsd-386.tar.gz", + "4802a9b20e533da91adb84aab42e94aa56cfe3e5475d0550bed3385b182e69d8" + ], + "openbsd_amd64": [ + "go1.25.0.openbsd-amd64.tar.gz", + "c016cd984bebe317b19a4f297c4f50def120dc9788490540c89f28e42f1dabe1" + ], + "openbsd_arm": [ + "go1.25.0.openbsd-arm.tar.gz", + "a1e31d0bf22172ddde42edf5ec811ef81be43433df0948ece52fecb247ccfd8d" + ], + "openbsd_arm64": [ + "go1.25.0.openbsd-arm64.tar.gz", + "343ea8edd8c218196e15a859c6072d0dd3246fbbb168481ab665eb4c4140458d" + ], + "openbsd_ppc64": [ + "go1.25.0.openbsd-ppc64.tar.gz", + "694c14da1bcaeb5e3332d49bdc2b6d155067648f8fe1540c5de8f3cf8e157154" + ], + "openbsd_riscv64": [ + "go1.25.0.openbsd-riscv64.tar.gz", + "aa510ad25cf54c06cd9c70b6d80ded69cb20188ac6e1735655eef29ff7e7885f" + ], + "plan9_386": [ + "go1.25.0.plan9-386.tar.gz", + "46f8cef02086cf04bf186c5912776b56535178d4cb319cd19c9fdbdd29231986" + ], + "plan9_amd64": [ + "go1.25.0.plan9-amd64.tar.gz", + "29b34391d84095e44608a228f63f2f88113a37b74a79781353ec043dfbcb427b" + ], + "plan9_arm": [ + "go1.25.0.plan9-arm.tar.gz", + "0a047107d13ebe7943aaa6d54b1d7bbd2e45e68ce449b52915a818da715799c2" + ], + "solaris_amd64": [ + "go1.25.0.solaris-amd64.tar.gz", + "9977f9e4351984364a3b2b78f8b88bfd1d339812356d5237678514594b7d3611" + ], + "windows_386": [ + "go1.25.0.windows-386.zip", + "df9f39db82a803af0db639e3613a36681ab7a42866b1384b3f3a1045663961a7" + ], + "windows_amd64": [ + "go1.25.0.windows-amd64.zip", + "89efb4f9b30812eee083cc1770fdd2913c14d301064f6454851428f9707d190b" + ], + "windows_arm64": [ + "go1.25.0.windows-arm64.zip", + "27bab004c72b3d7bd05a69b6ec0fc54a309b4b78cc569dd963d8b3ec28bfdb8c" + ] + } + } + } +} diff --git a/examples/imagination/go.mod b/examples/imagination/go.mod new file mode 100644 index 000000000..2ecb82b17 --- /dev/null +++ b/examples/imagination/go.mod @@ -0,0 +1,3 @@ +module imagination + +go 1.24 diff --git a/examples/imagination/imagination.wasm b/examples/imagination/imagination.wasm new file mode 100755 index 0000000000000000000000000000000000000000..c0699f4f629f681bbd74ceada54334125678217b GIT binary patch literal 1620077 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Ǡ~QVc8hQKcvahI3DI7-Ex*xnE|uHJPZugNMB6v| zUVm>JeUNT6xz#jWpBpw>Qt{KaT3Fz+ZTvj^6PHo!#-i#NLqDX{6;?F?bt?!^U>XIrH9WF5Ued+wXO82USv47iZnMx-%k?i~@^REyUR7;-BHFttEHC!4XQsUqhh>XsG7MS!L2sD$5Y&38yxp4L<2 zU+^pd3*xc;6gI}{;u zi4_d=)XZ9k{2V}Ukh^a4hz6IX%~)|*77SKQsF6JC!2Zyg4Etl?GH44=8kB~!EcbTQ zotX>I)vYHmc9s`>KrL`Q7H$j`*A-NL*L8Usad6VqN^h!QEV}cB(g@uoY|pDJJo}K% zk=+qTB1V2_T5t@q4VhS(Y?ZKzjt3vHhV7LGZj94PVPs-@`Ci3}N)>pRkjF5^PWVaU zQ(qL3Cmhn3Ae7ca{j{Yr5{q6Hd3!4EimU5oacWCF>UH{oITg0lnX_gc_xdqp>VFfjiQ8SS ze#_I(B>nGy{|7WrKX$YY88|l~1OI@cja@D+G?6wG2toynM)^}{vy_CgNOKd=eu8K( zPZLtNxEY&Q)c6MZq4a$Z7E>HXW z%Upl9$>#BL7`EUqq~S79y2=~6Um5V9hnDR8JX%5F_eCjyGUJ~Oh?mLxP*lcAv7&64 z*Lv$JPq2mnDjHXz;%;iK@8$TWbx!K&LKod!p%Q|fgT1N zd2j}+{UNKt?9!W^HjkEf~+RWiNg4Y8irg8kj;UoQwVD2~>fAsDu zU8*iL1lPUwODzZ>Nv!QSTEhsP{^uozIe{{1#g4s`p6qlG^?^`2g-{Vn2I3U-r%)>4K9- zFV2Ui5Qc-h%`aJh0>$aJt~nL9@zLAx2%cophq!(5ytB97&!hDRS>UY$jbHHZNtg(F zl4oy`Uh6&Lk-rDeK55z$b}MUwZ(^)1V-Fzyz+@7`pRw5t-GwEY9V58uaxYX!aw#`Z zCPc{9`{F`lU1cSH%yw`GEikeh3yPvG3q6752tCYUiEengAY|JXor?@9K^EYvZ0SU_ z1Vb|y;A{MS!a(Ck{EIZcJ+w{ZSQY=D()cDHA~!D_X&6^Eg(s%)i0-isdy=o;D5L5X z68Qr@cmp2nA)uh=rvo-mDa{*aVfmJ!$OB$E3&24KG~6d)gX%R=9nN4`!n0K(sXHz7efpT^6FH z=4G6cl7a;aOp;aCJ5H2j#Yn*2ldM>e26^)?iR#DGP9K)*0o^eiWhAPslN!ALy-;U5 z>tvfA3j~)klk)A3p zwiw0s(LL{VY?&lCZr&_w8|rnMr$^nu`oV3k$;PKkyTI$%G9AP^-smDPV9WF>X*9oI z=^iifIxBSTc`2(H^DZQg9UGfu z*PvY@jLp7#KWBLz+YAY;jBJ*;p_}P-Ru<~ei?iDb!jXp8qI7}D%&vF8W0UYbBxoa> zLxK$Ei~*Y%8U4dj%Iu@!51Xyz1e2mRxMICXf|47Pkq8B&S3?$ z?*m_GX9YZ*fQlvjPsFF$s$2&OZE0>^S1>|BhjXwx!Zb;jG zVj>KNSyCEO-voy)@TECYG_O7tU}!~&(jM!kz`D*W+CGQ@*BAW~FHlJ0_S1b}MEP}M zK5FAH?H|k;zgOW0CPm3{D8Ws%V`v^3GhiSnq{V{qn%D5Y`}#1A7`*acF1$bdaNc(> zPGPWOV7=PdAl4=}2)c~GZA(rps8wdo@23~rFK)(47Vb7{Alv=}zrvp0&cg4q#ZLzI zM#xXE^qusEayO`NyP63NaR8AG)@zbSW-qii14@p*fp7!@G19FOj*uMsR53o95S2~Z zaD{ec=Gz)M-b(NBmt6u;M+1AZI%y4*Kvg&o%<8`j>43IMa4BgLgHeC9Za6aH`H=(J z=XcBs)`hfFBM@jXt0xeBz7OCbRi%ZgNxl#^v!PLcZb}98CEJ*v2*)>lUVQ0ryw=$A;1Yd8G@yk|}P};^L}WJ&ZYm3(BsF38f7vT;eTRnBQRvKSkTT?4BTP=qm(A zFhoRnqqyq`eUvn(Bb0&1G{50=5rDH%wL{e>L40c2&?H68Y;Y1{GaU9N5j4St8U;b< zvNTxJNF40@;rQNT-;coeUi*F|zW3Spqwu}ozP}FN_pt9r<2&

R2uH>MHjhvJI= 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� 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%0D-@SpiU&uw05Gh5D+EU}Llow%djtg2 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

3>#z+6a0-{O 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
Vd;SQ`nfAx#ebU-WnO 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 TyO&0sE*}iMivlfp(Z>G=_)_=4 literal 0 HcmV?d00001 diff --git a/examples/imagination/main.go b/examples/imagination/main.go new file mode 100644 index 000000000..77d36d40f --- /dev/null +++ b/examples/imagination/main.go @@ -0,0 +1,41 @@ +// Simple WASI-enabled wasm module for exercising the AXL wasm engine. +// +// Build with: +// +// GOOS=wasip1 GOARCH=wasm go build -o imagination.wasm . +package main + +import "unsafe" + +// host_add is provided by the host via WASM imports. +// +//go:wasmimport env host_add +func host_add(a int32, b int32) int32 + +// message is returned to the host via a pointer/length pair. +var message = []byte("Hello from the imagination wasm module!") + +// get_message returns a packed pointer/length pair (lower 32 bits pointer, upper 32 bits length). +// +//go:wasmexport get_message +func get_message() uint64 { + ptr := uint32(uintptr(unsafe.Pointer(&message[0]))) + length := uint32(len(message)) + return uint64(ptr) | (uint64(length) << 32) +} + +// add_numbers adds two integers inside the wasm module. +// +//go:wasmexport add_numbers +func add_numbers(a int32, b int32) int32 { + return a + b +} + +// add_with_host forwards to the host-provided add function. +// +//go:wasmexport add_with_host +func add_with_host(a int32, b int32) int32 { + return host_add(a, b) +} + +func main() {} diff --git a/examples/large_bes/MODULE.bazel.lock b/examples/large_bes/MODULE.bazel.lock new file mode 100644 index 000000000..891271ffc --- /dev/null +++ b/examples/large_bes/MODULE.bazel.lock @@ -0,0 +1,191 @@ +{ + "lockFileVersion": 26, + "registryFileHashes": { + "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", + "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", + "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1", + "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/source.json": "cea3901d7e299da7320700abbaafe57a65d039f10d0d7ea601c4a66938ea4b0c", + "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", + "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", + "https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e", + "https://bcr.bazel.build/modules/apple_support/1.21.1/MODULE.bazel": "5809fa3efab15d1f3c3c635af6974044bac8a4919c62238cce06acee8a8c11f1", + "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4", + "https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d", + "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", + "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", + "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", + "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", + "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", + "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a", + "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", + "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", + "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", + "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", + "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", + "https://bcr.bazel.build/modules/bazel_features/1.33.0/source.json": "13617db3930328c2cd2807a0f13d52ca870ac05f96db9668655113265147b2a6", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", + "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", + "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", + "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", + "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", + "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb", + "https://bcr.bazel.build/modules/buildozer/8.2.1/MODULE.bazel": "61e9433c574c2bd9519cad7fa66b9c1d2b8e8d5f3ae5d6528a2c2d26e68d874d", + "https://bcr.bazel.build/modules/buildozer/8.2.1/source.json": "7c33f6a26ee0216f85544b4bca5e9044579e0219b6898dd653f5fb449cf2e484", + "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", + "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", + "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46", + "https://bcr.bazel.build/modules/googletest/1.17.0/source.json": "38e4454b25fc30f15439c0378e57909ab1fd0a443158aa35aec685da727cd713", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000", + "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9", + "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", + "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", + "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", + "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", + "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", + "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", + "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", + "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", + "https://bcr.bazel.build/modules/platforms/1.0.0/source.json": "f4ff1fd412e0246fd38c82328eb209130ead81d62dcd5a9e40910f867f733d96", + "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", + "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", + "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", + "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d", + "https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42", + "https://bcr.bazel.build/modules/protobuf/33.4/source.json": "555f8686b4c7d6b5ba731fbea13bf656b4bfd9a7ff629c1d9d3f6e1d6155de79", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680", + "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/source.json": "2ff292be6ef3340325ce8a045ecc326e92cbfab47c7cbab4bd85d28971b97ac4", + "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", + "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", + "https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e", + "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/MODULE.bazel": "76e10fd4a48038d3fc7c5dc6e63b7063bbf5304a2e3bd42edda6ec660eebea68", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/source.json": "8ee81e1708756f81b343a5eb2b2f0b953f1d25c4ab3d4a68dc02754872e80715", + "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", + "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", + "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", + "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", + "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", + "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", + "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", + "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", + "https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0", + "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", + "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c", + "https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37", + "https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8", + "https://bcr.bazel.build/modules/rules_cc/0.2.14/source.json": "55d0a4587c5592fad350f6e698530f4faf0e7dd15e69d43f8d87e220c78bea54", + "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", + "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", + "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", + "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", + "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", + "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", + "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", + "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", + "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", + "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", + "https://bcr.bazel.build/modules/rules_java/9.0.3/MODULE.bazel": "1f98ed015f7e744a745e0df6e898a7c5e83562d6b759dfd475c76456dda5ccea", + "https://bcr.bazel.build/modules/rules_java/9.0.3/source.json": "b038c0c07e12e658135bbc32cc1a2ded6e33785105c9d41958014c592de4593e", + "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", + "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/source.json": "5426f412d0a7fc6b611643376c7e4a82dec991491b9ce5cb1cfdd25fe2e92be4", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5", + "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", + "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", + "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", + "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a", + "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", + "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", + "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", + "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", + "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", + "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", + "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", + "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", + "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", + "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", + "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", + "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", + "https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", + "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/source.json": "20ec05cd5e592055e214b2da8ccb283c7f2a421ea0dc2acbf1aa792e11c03d0c", + "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", + "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", + "https://bcr.bazel.build/modules/rules_swift/2.4.0/MODULE.bazel": "1639617eb1ede28d774d967a738b4a68b0accb40650beadb57c21846beab5efd", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/MODULE.bazel": "72c8f5cf9d26427cee6c76c8e3853eb46ce6b0412a081b2b6db6e8ad56267400", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/source.json": "e85761f3098a6faf40b8187695e3de6d97944e98abd0d8ce579cb2daf6319a66", + "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", + "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", + "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "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/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/MODULE.bazel": "75aab2373a4bbe2a1260b9bf2a1ebbdbf872d3bd36f80bff058dccd82e89422f", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/source.json": "5fba48bbe0ba48761f9e9f75f92876cafb5d07c0ce059cc7a8027416de94a05b", + "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.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", + "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" + }, + "selectedYankedVersions": {}, + "moduleExtensions": {}, + "facts": {} +} From a382fb463f976d62cac7a0581f2c558cf1e74597 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Sun, 15 Feb 2026 17:26:40 -0800 Subject: [PATCH 63/65] Update platform.axl --- crates/axl-runtime/src/builtins/aspect/lib/platform.axl | 3 --- 1 file changed, 3 deletions(-) diff --git a/crates/axl-runtime/src/builtins/aspect/lib/platform.axl b/crates/axl-runtime/src/builtins/aspect/lib/platform.axl index 2e8088d01..2c43add0f 100644 --- a/crates/axl-runtime/src/builtins/aspect/lib/platform.axl +++ b/crates/axl-runtime/src/builtins/aspect/lib/platform.axl @@ -18,9 +18,6 @@ PLATFORM_CONFIG_KEYS = { "bessie_endpoint": "bessie_endpoint", "build_result_ui_base_url": "build_result_ui_base_url", "delivery_db_endpoint": "delivery_db_endpoint", - "api_key": "api_key", - "api_client_id": "api_client_id", - "brs_api_endpoint": "brs_api_endpoint", } # Bazel command lists From be73ea25ad701d0871d317a3528287eb867733f8 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Mon, 16 Feb 2026 10:42:45 -0800 Subject: [PATCH 64/65] revert --- .aspect/version.axl | 2 +- crates/aspect-launcher/src/config.rs | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.aspect/version.axl b/.aspect/version.axl index 5c04253b1..31802e199 100644 --- a/.aspect/version.axl +++ b/.aspect/version.axl @@ -1,5 +1,5 @@ version( - use = "2025.46.20", + "2025.46.20", sources = [ local("target/debug/aspect-cli"), local("bazel-bin/crates/aspect-cli/aspect-cli"), diff --git a/crates/aspect-launcher/src/config.rs b/crates/aspect-launcher/src/config.rs index 90e19b237..d8003eb64 100644 --- a/crates/aspect-launcher/src/config.rs +++ b/crates/aspect-launcher/src/config.rs @@ -249,10 +249,16 @@ fn parse_version_axl(content: &str) -> Result { for arg in &args.args { match &arg.node { - ArgumentP::Named(name, expr) => match name.node.as_str() { - "use" => { + ArgumentP::Positional(expr) => { + if version.is_none() { version = Some(extract_string_literal(expr)?.to_owned()); + } else { + return Err(miette!( + "version() accepts only one positional argument (the version string)" + )); } + } + ArgumentP::Named(name, expr) => match name.node.as_str() { "sources" => { if let Expr::List(items) = &expr.node { let mut src_list = Vec::new(); @@ -269,7 +275,7 @@ fn parse_version_axl(content: &str) -> Result { } }, _ => { - return Err(miette!("version() only accepts named arguments (use, sources)")); + return Err(miette!("unexpected *args or **kwargs in version() call")); } } } From 875d7ac55f55c86c0ef0c33d6bc387381e196f76 Mon Sep 17 00:00:00 2001 From: thesayyn Date: Mon, 16 Feb 2026 12:29:09 -0800 Subject: [PATCH 65/65] revert some of the changes --- .aspect/imagination.axl | 25 - .bazelrc | 2 - .buildkite/hooks/pre-command | 27 +- .buildkite/pipeline.yaml | 1 - .gitignore | 1 + Cargo.lock | 2 - MODULE.bazel | 27 -- MODULE.bazel.lock | 410 +++-------------- bazel/proto/BUILD.bazel | 1 + bazel/release/hashes.bzl | 48 +- bazel/release/sha256sum/BUILD.bazel | 17 - bazel/release/sha256sum/main.go | 32 -- crates/aspect-cli/src/helpers.rs | 44 -- crates/aspect-cli/src/main.rs | 29 +- crates/axl-proto/Cargo.toml | 3 +- crates/axl-proto/build.rs | 11 +- crates/axl-proto/descriptor.bin | Bin 612404 -> 630454 bytes crates/starbuf-derive/src/lib.rs | 299 +++++++++++- examples/deliveryd/.bazelversion | 1 - examples/deliveryd/BUILD.bazel | 24 - examples/deliveryd/MODULE.bazel | 12 - examples/deliveryd/MODULE.bazel.lock | 634 -------------------------- examples/deliveryd/go.mod | 10 - examples/deliveryd/go.sum | 10 - examples/deliveryd/handlers.go | 177 ------- examples/deliveryd/main.go | 53 --- examples/deliveryd/redis.go | 149 ------ examples/deliveryd/server.go | 46 -- examples/deliveryd/types.go | 48 -- examples/imagination/go.mod | 3 - examples/imagination/imagination.wasm | Bin 1620077 -> 0 bytes examples/imagination/main.go | 41 -- 32 files changed, 391 insertions(+), 1796 deletions(-) delete mode 100644 .aspect/imagination.axl delete mode 100644 bazel/release/sha256sum/BUILD.bazel delete mode 100644 bazel/release/sha256sum/main.go delete mode 100644 examples/deliveryd/.bazelversion delete mode 100644 examples/deliveryd/BUILD.bazel delete mode 100644 examples/deliveryd/MODULE.bazel delete mode 100644 examples/deliveryd/MODULE.bazel.lock delete mode 100644 examples/deliveryd/go.mod delete mode 100644 examples/deliveryd/go.sum delete mode 100644 examples/deliveryd/handlers.go delete mode 100644 examples/deliveryd/main.go delete mode 100644 examples/deliveryd/redis.go delete mode 100644 examples/deliveryd/server.go delete mode 100644 examples/deliveryd/types.go delete mode 100644 examples/imagination/go.mod delete mode 100755 examples/imagination/imagination.wasm delete mode 100644 examples/imagination/main.go diff --git a/.aspect/imagination.axl b/.aspect/imagination.axl deleted file mode 100644 index 3a12b86b6..000000000 --- a/.aspect/imagination.axl +++ /dev/null @@ -1,25 +0,0 @@ -def _img_impl(ctx): - ac = remote.execution.ActionCache( - uri = "grpcs://testing.buildbuddy.io", - headers = {}, - timeout = 10000, - ) - ac.connect(ctx) - - req = remote.execution.GetActionResultRequest( - instance_name = "example-instance", - action_digest = remote.execution.Digest( - hash = "0123456789abcdef", - size_bytes = 123, - ), - inline_stdout = True, - inline_stderr = True, - ) - - result = ac.GetActionResult(req) - print("action result:", result) - -imagine = task( - implementation = _img_impl, - args = {} -) diff --git a/.bazelrc b/.bazelrc index 6a22dccbd..d53f6d766 100644 --- a/.bazelrc +++ b/.bazelrc @@ -11,8 +11,6 @@ common --toolchain_resolution_debug='\Q@@rules_rs++rules_rust+rules_rust//rust:t common:macos --build_tag_filters=-no-macos common:linux --host_platform=//bazel/platforms:linux_host_platform -common --@rules_go//go/toolchain:source=bootstrapped - common --@rules_cc//cc/toolchains/args/archiver_flags:use_libtool_on_macos=False common --@toolchains_llvm_bootstrapped//config:experimental_stub_libgcc_s=True diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index 796e047dd..8433bcbe5 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -22,11 +22,11 @@ mkdir -p "$ASPECT_BIN_DIR" # Get current commit CURRENT_COMMIT="$(git rev-parse HEAD)" -# Check if crates/ or examples/deliveryd/ changed between two commits +# Check if crates/ changed between two commits crates_changed() { local old_commit="$1" local new_commit="$2" - git diff --name-only "$old_commit" "$new_commit" -- crates/ examples/deliveryd/ | grep -q . + git diff --name-only "$old_commit" "$new_commit" -- crates/ | grep -q . } # Build and install aspect-cli if not present or crates/ changed @@ -49,26 +49,3 @@ else echo "$CURRENT_COMMIT" > "$ASPECT_COMMIT_FILE" echo "aspect-cli installed to $ASPECT_BIN_DIR/aspect (commit: $CURRENT_COMMIT)" fi - -# Build and install deliveryd if not present or crates/ changed (local_path_override in root module) -DELIVERYD_COMMIT_FILE="$ASPECT_BIN_DIR/deliveryd.commit" -CACHED_DELIVERYD_COMMIT="" -if [ -f "$DELIVERYD_COMMIT_FILE" ]; then - CACHED_DELIVERYD_COMMIT="$(cat "$DELIVERYD_COMMIT_FILE")" -fi - -if [ -x "$ASPECT_BIN_DIR/deliveryd" ] && [ -n "$CACHED_DELIVERYD_COMMIT" ] && ! crates_changed "$CACHED_DELIVERYD_COMMIT" "$CURRENT_COMMIT"; then - echo "DEBUG: Found existing deliveryd binary (no crates/ changes since $CACHED_DELIVERYD_COMMIT)" -else - echo "--- Building deliveryd" - # Kill any running deliveryd instances before rebuilding - pkill -9 deliveryd 2>/dev/null || true - bazel $BAZEL_STARTUP_OPTS build $BAZEL_BUILD_OPTS -c dbg --remote_download_toplevel @deliveryd//:deliveryd - - DELIVERYD_PATH="$(bazel $BAZEL_STARTUP_OPTS cquery $BAZEL_BUILD_OPTS -c dbg --output=files @deliveryd//:deliveryd 2>/dev/null)" - ls -la "$DELIVERYD_PATH" 2>&1 || echo "DEBUG: File does not exist!" - cp -f "$DELIVERYD_PATH" "$ASPECT_BIN_DIR/deliveryd" - chmod 0755 "$ASPECT_BIN_DIR/deliveryd" - echo "$CURRENT_COMMIT" > "$DELIVERYD_COMMIT_FILE" - echo "deliveryd installed to $ASPECT_BIN_DIR/deliveryd (commit: $CURRENT_COMMIT)" -fi diff --git a/.buildkite/pipeline.yaml b/.buildkite/pipeline.yaml index 17c986121..6e953495f 100644 --- a/.buildkite/pipeline.yaml +++ b/.buildkite/pipeline.yaml @@ -4,7 +4,6 @@ env: PATH: "/home/aspect-runner/.aspect/bin:$PATH" - AXL_CONFIG: "/mnt/ephemeral/workdir/aspect-build/aspect-cli/axel-f/config.axl" ASPECT_DEBUG: "1" steps: - key: __main__::debug diff --git a/.gitignore b/.gitignore index fe3055476..2eb9433bf 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ site .DS_Store .workflows + diff --git a/Cargo.lock b/Cargo.lock index 476b51066..47cfdc704 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -301,7 +301,6 @@ version = "0.0.0-dev" dependencies = [ "allocative", "anyhow", - "derive_more 2.0.1", "display_container", "prost", "prost-build", @@ -4566,7 +4565,6 @@ dependencies = [ "tower-layer", "tower-service", "tracing", - "webpki-roots", ] [[package]] diff --git a/MODULE.bazel b/MODULE.bazel index 3eed53c85..8c5a0f52e 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -8,39 +8,12 @@ bazel_dep(name = "rules_nodejs", version = "6.7.3") # Transitive dep; bump for bazel_dep(name = "bazel_skylib", version = "1.8.2") bazel_dep(name = "bazelrc-preset.bzl", version = "1.4.0") bazel_dep(name = "buildifier_prebuilt", version = "8.2.0.2") -bazel_dep(name = "gazelle", version = "0.45.0") bazel_dep(name = "platforms", version = "1.0.0") bazel_dep(name = "rules_cc", version = "0.2.16") bazel_dep(name = "rules_pkg", version = "1.1.0") bazel_dep(name = "rules_shell", version = "0.6.1") bazel_dep(name = "with_cfg.bzl", version = "0.12.0") bazel_dep(name = "toolchains_llvm_bootstrapped", version = "0.5.5") -bazel_dep(name = "deliveryd", version = "0.0.0") -bazel_dep(name = "rules_go", version = "0.60.0") -archive_override( - module_name = "rules_go", - integrity = "sha256-8ezQcDyHHp/+xa9NbUJO/3/kDEFFmJaV4pb1fd99m74=", - strip_prefix = "rules_go-62d798d48ae153e048a7f9c43ba68cfa1ea10924", - url = "https://github.com/bazel-contrib/rules_go/archive/62d798d48ae153e048a7f9c43ba68cfa1ea10924.tar.gz", -) - -bazel_dep(name = "rules_go", version = "0.60.0") -archive_override( - module_name = "rules_go", - strip_prefix = "rules_go-62d798d48ae153e048a7f9c43ba68cfa1ea10924", - url = "https://github.com/bazel-contrib/rules_go/archive/62d798d48ae153e048a7f9c43ba68cfa1ea10924.tar.gz", -) -go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") -go_sdk.from_file( - name = "go_bootstrap_sdk", - go_mod = "@deliveryd//:go.mod", - experimental_build_compiler_from_source = True, -) - -local_path_override( - module_name = "deliveryd", - path = "./examples/deliveryd", -) register_toolchains("@toolchains_llvm_bootstrapped//toolchain:all") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index ca644f987..bce4ae46f 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -45,6 +45,7 @@ "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.3.2/source.json": "c6f5c39e6f32eb395f8fdaea63031a233bbe96d49a3bfb9f75f6fce9b74bec6c", "https://bcr.bazel.build/modules/bazel_features/0.1.0/MODULE.bazel": "47011d645b0f949f42ee67f2e8775188a9cf4a0a1528aa2fa4952f2fd00906fd", "https://bcr.bazel.build/modules/bazel_features/1.0.0/MODULE.bazel": "d7f022dc887efb96e1ee51cec7b2e48d41e36ff59a6e4f216c40e4029e1585bf", + "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", @@ -62,7 +63,6 @@ "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", "https://bcr.bazel.build/modules/bazel_features/1.34.0/MODULE.bazel": "e8475ad7c8965542e0c7aac8af68eb48c4af904be3d614b6aa6274c092c2ea1e", - "https://bcr.bazel.build/modules/bazel_features/1.36.0/MODULE.bazel": "596cb62090b039caf1cad1d52a8bc35cf188ca9a4e279a828005e7ee49a1bec3", "https://bcr.bazel.build/modules/bazel_features/1.39.0/MODULE.bazel": "28739425c1fc283c91931619749c832b555e60bcd1010b40d8441ce0a5cf726d", "https://bcr.bazel.build/modules/bazel_features/1.39.0/source.json": "f63cbeb4c602098484d57001e5a07d31cb02bbccde9b5e2c9bf0b29d05283e93", "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", @@ -98,11 +98,12 @@ "https://bcr.bazel.build/modules/download_utils/1.0.1/source.json": "05ddc5a3b1f7d8f3e5e0fd1617479e1cf72d63d59ab2b1f0463557a14fc6be0a", "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "cdf8cbe5ee750db04b78878c9633cc76e80dcf4416cbe982ac3a9222f80713c8", "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/source.json": "fa7b512dfcb5eafd90ce3959cf42a2a6fe96144ebbb4b3b3928054895f2afac2", + "https://bcr.bazel.build/modules/gazelle/0.27.0/MODULE.bazel": "3446abd608295de6d90b4a8a118ed64a9ce11dcb3dda2dc3290a22056bd20996", + "https://bcr.bazel.build/modules/gazelle/0.30.0/MODULE.bazel": "f888a1effe338491f35f0e0e85003b47bb9d8295ccba73c37e07702d8d31c65b", + "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", + "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350", "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", - "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", - "https://bcr.bazel.build/modules/gazelle/0.45.0/MODULE.bazel": "ecd19ebe9f8e024e1ccffb6d997cc893a974bcc581f1ae08f386bdd448b10687", - "https://bcr.bazel.build/modules/gazelle/0.47.0/MODULE.bazel": "b61bb007c4efad134aa30ee7f4a8e2a39b22aa5685f005edaa022fbd1de43ebc", - "https://bcr.bazel.build/modules/gazelle/0.47.0/source.json": "aeb2e5df14b7fb298625d75d08b9c65bdb0b56014c5eb89da9e5dd0572280ae6", + "https://bcr.bazel.build/modules/gazelle/0.34.0/source.json": "cdf0182297e3adabbdea2da88d5b930b2ee5e56511c3e7d6512069db6315a1f7", "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", @@ -138,9 +139,9 @@ "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", - "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573", "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", "https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d", "https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42", @@ -183,6 +184,12 @@ "https://bcr.bazel.build/modules/rules_diff/1.0.0/source.json": "fc3824aed007b4db160ffb994036c6e558550857b6634a8e9ccee3e74c659312", "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", + "https://bcr.bazel.build/modules/rules_go/0.33.0/MODULE.bazel": "a2b11b64cd24bf94f57454f53288a5dacfe6cb86453eee7761b7637728c1910c", + "https://bcr.bazel.build/modules/rules_go/0.38.1/MODULE.bazel": "fb8e73dd3b6fc4ff9d260ceacd830114891d49904f5bda1c16bc147bcc254f71", + "https://bcr.bazel.build/modules/rules_go/0.39.1/MODULE.bazel": "d34fb2a249403a5f4339c754f1e63dc9e5ad70b47c5e97faee1441fc6636cd61", + "https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8", + "https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270", + "https://bcr.bazel.build/modules/rules_go/0.42.0/source.json": "33cd3d725806ad432753c4263ffd0459692010fdc940cce60b2c0e32282b45c5", "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39", @@ -477,6 +484,65 @@ } } }, + "@@rules_go+//go:extensions.bzl%go_sdk": { + "os:osx,arch:aarch64": { + "bzlTransitiveDigest": "u6ipp4B4trSrM0FoJr/iOAbAzHnadJmFUMourQbBdA0=", + "usagesDigest": "igIBXyqNg9Be63Cuu6kZxOeoDRDMqxSv8BcoWiqSh3w=", + "recordedInputs": [ + "REPO_MAPPING:bazel_features+,bazel_features_globals bazel_features++version_extension+bazel_features_globals", + "REPO_MAPPING:bazel_features+,bazel_features_version bazel_features++version_extension+bazel_features_version", + "REPO_MAPPING:rules_go+,bazel_features bazel_features+", + "REPO_MAPPING:rules_go+,bazel_tools bazel_tools" + ], + "generatedRepoSpecs": { + "go_default_sdk": { + "repoRuleId": "@@rules_go+//go/private:sdk.bzl%go_download_sdk_rule", + "attributes": { + "goos": "", + "goarch": "", + "sdks": {}, + "experiments": [], + "patches": [], + "patch_strip": 0, + "urls": [ + "https://dl.google.com/go/{}" + ], + "version": "1.21.1", + "strip_prefix": "go" + } + }, + "go_host_compatible_sdk_label": { + "repoRuleId": "@@rules_go+//go/private:extensions.bzl%host_compatible_toolchain", + "attributes": { + "toolchain": "@go_default_sdk//:ROOT" + } + }, + "go_toolchains": { + "repoRuleId": "@@rules_go+//go/private:sdk.bzl%go_multiple_toolchains", + "attributes": { + "prefixes": [ + "_0000_go_default_sdk_" + ], + "geese": [ + "" + ], + "goarchs": [ + "" + ], + "sdk_repos": [ + "go_default_sdk" + ], + "sdk_types": [ + "remote" + ], + "sdk_versions": [ + "1.21.1" + ] + } + } + } + } + }, "@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": { "general": { "bzlTransitiveDigest": "ABI1D/sbS1ovwaW/kHDoj8nnXjQ0oKU9fzmzEG4iT8o=", @@ -865,332 +931,6 @@ } }, "facts": { - "@@rules_go+//go:extensions.bzl%go_sdk": { - "1.25.0": { - "aix_ppc64": [ - "go1.25.0.aix-ppc64.tar.gz", - "e5234a7dac67bc86c528fe9752fc9d63557918627707a733ab4cac1a6faed2d4" - ], - "darwin_amd64": [ - "go1.25.0.darwin-amd64.tar.gz", - "5bd60e823037062c2307c71e8111809865116714d6f6b410597cf5075dfd80ef" - ], - "darwin_arm64": [ - "go1.25.0.darwin-arm64.tar.gz", - "544932844156d8172f7a28f77f2ac9c15a23046698b6243f633b0a0b00c0749c" - ], - "dragonfly_amd64": [ - "go1.25.0.dragonfly-amd64.tar.gz", - "5ed3cf9a810a1483822538674f1336c06b51aa1b94d6d545a1a0319a48177120" - ], - "freebsd_386": [ - "go1.25.0.freebsd-386.tar.gz", - "abea5d5c6697e6b5c224731f2158fe87c602996a2a233ac0c4730cd57bf8374e" - ], - "freebsd_amd64": [ - "go1.25.0.freebsd-amd64.tar.gz", - "86e6fe0a29698d7601c4442052dac48bd58d532c51cccb8f1917df648138730b" - ], - "freebsd_arm": [ - "go1.25.0.freebsd-arm.tar.gz", - "d90b78e41921f72f30e8bbc81d9dec2cff7ff384a33d8d8debb24053e4336bfe" - ], - "freebsd_arm64": [ - "go1.25.0.freebsd-arm64.tar.gz", - "451d0da1affd886bfb291b7c63a6018527b269505db21ce6e14724f22ab0662e" - ], - "freebsd_riscv64": [ - "go1.25.0.freebsd-riscv64.tar.gz", - "7b565f76bd8bda46549eeaaefe0e53b251e644c230577290c0f66b1ecdb3cdbe" - ], - "illumos_amd64": [ - "go1.25.0.illumos-amd64.tar.gz", - "b1e1fdaab1ad25aa1c08d7a36c97d45d74b98b89c3f78c6d2145f77face54a2c" - ], - "linux_386": [ - "go1.25.0.linux-386.tar.gz", - "8c602dd9d99bc9453b3995d20ce4baf382cc50855900a0ece5de9929df4a993a" - ], - "linux_amd64": [ - "go1.25.0.linux-amd64.tar.gz", - "2852af0cb20a13139b3448992e69b868e50ed0f8a1e5940ee1de9e19a123b613" - ], - "linux_arm64": [ - "go1.25.0.linux-arm64.tar.gz", - "05de75d6994a2783699815ee553bd5a9327d8b79991de36e38b66862782f54ae" - ], - "linux_armv6l": [ - "go1.25.0.linux-armv6l.tar.gz", - "a5a8f8198fcf00e1e485b8ecef9ee020778bf32a408a4e8873371bfce458cd09" - ], - "linux_loong64": [ - "go1.25.0.linux-loong64.tar.gz", - "cab86b1cf761b1cb3bac86a8877cfc92e7b036fc0d3084123d77013d61432afc" - ], - "linux_mips": [ - "go1.25.0.linux-mips.tar.gz", - "d66b6fb74c3d91b9829dc95ec10ca1f047ef5e89332152f92e136cf0e2da5be1" - ], - "linux_mips64": [ - "go1.25.0.linux-mips64.tar.gz", - "4082e4381a8661bc2a839ff94ba3daf4f6cde20f8fb771b5b3d4762dc84198a2" - ], - "linux_mips64le": [ - "go1.25.0.linux-mips64le.tar.gz", - "70002c299ec7f7175ac2ef673b1b347eecfa54ae11f34416a6053c17f855afcc" - ], - "linux_mipsle": [ - "go1.25.0.linux-mipsle.tar.gz", - "b00a3a39eff099f6df9f1c7355bf28e4589d0586f42d7d4a394efb763d145a73" - ], - "linux_ppc64": [ - "go1.25.0.linux-ppc64.tar.gz", - "df166f33bd98160662560a72ff0b4ba731f969a80f088922bddcf566a88c1ec1" - ], - "linux_ppc64le": [ - "go1.25.0.linux-ppc64le.tar.gz", - "0f18a89e7576cf2c5fa0b487a1635d9bcbf843df5f110e9982c64df52a983ad0" - ], - "linux_riscv64": [ - "go1.25.0.linux-riscv64.tar.gz", - "c018ff74a2c48d55c8ca9b07c8e24163558ffec8bea08b326d6336905d956b67" - ], - "linux_s390x": [ - "go1.25.0.linux-s390x.tar.gz", - "34e5a2e19f2292fbaf8783e3a241e6e49689276aef6510a8060ea5ef54eee408" - ], - "netbsd_386": [ - "go1.25.0.netbsd-386.tar.gz", - "f8586cdb7aa855657609a5c5f6dbf523efa00c2bbd7c76d3936bec80aa6c0aba" - ], - "netbsd_amd64": [ - "go1.25.0.netbsd-amd64.tar.gz", - "ae8dc1469385b86a157a423bb56304ba45730de8a897615874f57dd096db2c2a" - ], - "netbsd_arm": [ - "go1.25.0.netbsd-arm.tar.gz", - "1ff7e4cc764425fc9dd6825eaee79d02b3c7cafffbb3691687c8d672ade76cb7" - ], - "netbsd_arm64": [ - "go1.25.0.netbsd-arm64.tar.gz", - "e1b310739f26724216aa6d7d7208c4031f9ff54c9b5b9a796ddc8bebcb4a5f16" - ], - "openbsd_386": [ - "go1.25.0.openbsd-386.tar.gz", - "4802a9b20e533da91adb84aab42e94aa56cfe3e5475d0550bed3385b182e69d8" - ], - "openbsd_amd64": [ - "go1.25.0.openbsd-amd64.tar.gz", - "c016cd984bebe317b19a4f297c4f50def120dc9788490540c89f28e42f1dabe1" - ], - "openbsd_arm": [ - "go1.25.0.openbsd-arm.tar.gz", - "a1e31d0bf22172ddde42edf5ec811ef81be43433df0948ece52fecb247ccfd8d" - ], - "openbsd_arm64": [ - "go1.25.0.openbsd-arm64.tar.gz", - "343ea8edd8c218196e15a859c6072d0dd3246fbbb168481ab665eb4c4140458d" - ], - "openbsd_ppc64": [ - "go1.25.0.openbsd-ppc64.tar.gz", - "694c14da1bcaeb5e3332d49bdc2b6d155067648f8fe1540c5de8f3cf8e157154" - ], - "openbsd_riscv64": [ - "go1.25.0.openbsd-riscv64.tar.gz", - "aa510ad25cf54c06cd9c70b6d80ded69cb20188ac6e1735655eef29ff7e7885f" - ], - "plan9_386": [ - "go1.25.0.plan9-386.tar.gz", - "46f8cef02086cf04bf186c5912776b56535178d4cb319cd19c9fdbdd29231986" - ], - "plan9_amd64": [ - "go1.25.0.plan9-amd64.tar.gz", - "29b34391d84095e44608a228f63f2f88113a37b74a79781353ec043dfbcb427b" - ], - "plan9_arm": [ - "go1.25.0.plan9-arm.tar.gz", - "0a047107d13ebe7943aaa6d54b1d7bbd2e45e68ce449b52915a818da715799c2" - ], - "solaris_amd64": [ - "go1.25.0.solaris-amd64.tar.gz", - "9977f9e4351984364a3b2b78f8b88bfd1d339812356d5237678514594b7d3611" - ], - "windows_386": [ - "go1.25.0.windows-386.zip", - "df9f39db82a803af0db639e3613a36681ab7a42866b1384b3f3a1045663961a7" - ], - "windows_amd64": [ - "go1.25.0.windows-amd64.zip", - "89efb4f9b30812eee083cc1770fdd2913c14d301064f6454851428f9707d190b" - ], - "windows_arm64": [ - "go1.25.0.windows-arm64.zip", - "27bab004c72b3d7bd05a69b6ec0fc54a309b4b78cc569dd963d8b3ec28bfdb8c" - ] - }, - "1.26.0": { - "aix_ppc64": [ - "go1.26.0.aix-ppc64.tar.gz", - "ca464cc9c48d66e905e6978924554057b693f0aea697372fa8f7e108cc212261" - ], - "darwin_amd64": [ - "go1.26.0.darwin-amd64.tar.gz", - "1ca28b7703cbea05a65b2a1d92d6b308610ef92f8824578a0874f2e60c9d5a22" - ], - "darwin_arm64": [ - "go1.26.0.darwin-arm64.tar.gz", - "b1640525dfe68f066d56f200bef7bf4dce955a1a893bd061de6754c211431023" - ], - "dragonfly_amd64": [ - "go1.26.0.dragonfly-amd64.tar.gz", - "f688f36f1b3ae17f2ca0a6f8d5e8cba46a972de26ef6241b21ab9645b291243e" - ], - "freebsd_386": [ - "go1.26.0.freebsd-386.tar.gz", - "9f07792e085f0d212c75ba403cb73e7f2f71eace48a38fab58711270dd7b1cef" - ], - "freebsd_amd64": [ - "go1.26.0.freebsd-amd64.tar.gz", - "7bba5a430d2c562af87b6c1a31cccf72c43107b7318b48aa8a02441df61acd08" - ], - "freebsd_arm": [ - "go1.26.0.freebsd-arm.tar.gz", - "fe15a74bdb33954ebc9312efb01ac1871f7fc9cc712993058de8fc2a4dc8c8f7" - ], - "freebsd_arm64": [ - "go1.26.0.freebsd-arm64.tar.gz", - "5d92e2d65a543811dca9f76a2b533cbdc051bdd5015bf789b137e2dcc33b2d52" - ], - "illumos_amd64": [ - "go1.26.0.illumos-amd64.tar.gz", - "2191668cd3aea0a05e646e6f7919ea357e666c15facf417f33e5cf18b7f00dd9" - ], - "linux_386": [ - "go1.26.0.linux-386.tar.gz", - "35e2ec7a7ae6905a1fae5459197b70e3fcbc5e0a786a7d6ba8e49bcd38ad2e26" - ], - "linux_amd64": [ - "go1.26.0.linux-amd64.tar.gz", - "aac1b08a0fb0c4e0a7c1555beb7b59180b05dfc5a3d62e40e9de90cd42f88235" - ], - "linux_arm64": [ - "go1.26.0.linux-arm64.tar.gz", - "bd03b743eb6eb4193ea3c3fd3956546bf0e3ca5b7076c8226334afe6b75704cd" - ], - "linux_armv6l": [ - "go1.26.0.linux-armv6l.tar.gz", - "3f6b48d96f0d8dff77e4625aa179e0449f6bbe79b6986bfa711c2cfc1257ebd8" - ], - "linux_loong64": [ - "go1.26.0.linux-loong64.tar.gz", - "33947cd7686f1cd5f097d2a5a30427a4ade114ea00b7570c85a2abf1af3d0507" - ], - "linux_mips": [ - "go1.26.0.linux-mips.tar.gz", - "a4ece61d4bac43b6983fde2c6b9cfc1af7f0d5d6a073219583d4e93b11559c25" - ], - "linux_mips64": [ - "go1.26.0.linux-mips64.tar.gz", - "197c2e97fa9ec1ad05998e0982d1a1ae761980df154424e5f29f3912e9ea4e5e" - ], - "linux_mips64le": [ - "go1.26.0.linux-mips64le.tar.gz", - "61c52b4ab0dceae29f10df29045483596c3f06810c9b511e8336a97428a95a1b" - ], - "linux_mipsle": [ - "go1.26.0.linux-mipsle.tar.gz", - "b3a13cc5a5f9250b02cf4ba19914c90c7034e68a5ccb9affa5198aadbcedac9a" - ], - "linux_ppc64": [ - "go1.26.0.linux-ppc64.tar.gz", - "ef7232a49101d163a93bac34d03bfbc4fb18f75d7526d77ac307e16d9d83c300" - ], - "linux_ppc64le": [ - "go1.26.0.linux-ppc64le.tar.gz", - "3066b2284b554da76cf664d217490792ba6f292ec0fc20bf9615e173cc0d2800" - ], - "linux_riscv64": [ - "go1.26.0.linux-riscv64.tar.gz", - "ab9226ecddda0f682365c949114b653a66c2e9330e7b8d3edea80858437d2ff2" - ], - "linux_s390x": [ - "go1.26.0.linux-s390x.tar.gz", - "d62137f11530b97f3503453ad7d9e570af070770599fb8054f4e8cd0e905a453" - ], - "netbsd_386": [ - "go1.26.0.netbsd-386.tar.gz", - "f79ae29d97980bf4c42120c0bebea758426dfa250ab39bcd909bccf057d5eced" - ], - "netbsd_amd64": [ - "go1.26.0.netbsd-amd64.tar.gz", - "22fc488ddd2c5958378fba2560866d6dae298160ba198e51ca5b998dc77b92f1" - ], - "netbsd_arm": [ - "go1.26.0.netbsd-arm.tar.gz", - "1c70fd89c12dfda71f755dae1d7796f14702442b50ef2831117a641358276c5a" - ], - "netbsd_arm64": [ - "go1.26.0.netbsd-arm64.tar.gz", - "379d6ef6dfa8b67a7776744a536e69a1dc0fe5aeed48eb882ac71f89a98ba8ab" - ], - "openbsd_386": [ - "go1.26.0.openbsd-386.tar.gz", - "02084b48b800d28a434f89e8d19c7c5d47b7eb1339d5cf6104da56a7ad0aa23a" - ], - "openbsd_amd64": [ - "go1.26.0.openbsd-amd64.tar.gz", - "97884d7e5f566230f65820c02019ea253b53800157975918b6b6b7f03bf1b022" - ], - "openbsd_arm": [ - "go1.26.0.openbsd-arm.tar.gz", - "2618746ffa6b93216d698c2ae923738373bd433c1253438c5ad8efdd2fd0a388" - ], - "openbsd_arm64": [ - "go1.26.0.openbsd-arm64.tar.gz", - "5a43668bf3c49d302ec50ac55d7e3f28a410cbda56485d7ebb9759f83e03e56f" - ], - "openbsd_ppc64": [ - "go1.26.0.openbsd-ppc64.tar.gz", - "00fbd0df705ac70f2833f97a893b7819f99704a3711c2096907f859703fe3e83" - ], - "openbsd_riscv64": [ - "go1.26.0.openbsd-riscv64.tar.gz", - "d00373b08c4fa396887fab8f6217824b5d3cad5409db326d535cfcf68916b9ea" - ], - "plan9_386": [ - "go1.26.0.plan9-386.tar.gz", - "d8bcdb292a902e52adcce3b96a12474bd69cfd331bf92ad399afb51e009503b4" - ], - "plan9_amd64": [ - "go1.26.0.plan9-amd64.tar.gz", - "847fa33e55206b0c40b99252e0219cc356ff58ccd4e143ce0a378ebfd75446b0" - ], - "plan9_arm": [ - "go1.26.0.plan9-arm.tar.gz", - "8872abd44fb3087e9c1bc0982e4c3be442018c4ad7cb5150ed29d68839e75ce4" - ], - "solaris_amd64": [ - "go1.26.0.solaris-amd64.tar.gz", - "ec424798ae65c23dea6f4ef58d5fed85c56305eeb4a74e7af9a7d73bf335c93c" - ], - "source": [ - "go1.26.0.src.tar.gz", - "c9132a8a1f6bd2aa4aad1d74b8231d95274950483a4950657ee6c56e6e817790" - ], - "windows_386": [ - "go1.26.0.windows-386.zip", - "50674f3d6a071fa1a4c1d76dc37fafa0330df87d84087a262fee020da5396b6b" - ], - "windows_amd64": [ - "go1.26.0.windows-amd64.zip", - "9bbe0fc64236b2b51f6255c05c4232532b8ecc0e6d2e00950bd3021d8a4d07d4" - ], - "windows_arm64": [ - "go1.26.0.windows-arm64.zip", - "73bdbb9f64aa152758024485c5243a1098182bb741fcc603b6fb664ee5e0fe35" - ] - } - }, "@@rules_rs+//rs:extensions.bzl%crate": { "Inflector_0.11.4": "{\"dependencies\":[{\"name\":\"lazy_static\",\"optional\":true,\"req\":\"^1.2.0\"},{\"name\":\"regex\",\"optional\":true,\"req\":\"^1.1\"}],\"features\":{\"default\":[\"heavyweight\"],\"heavyweight\":[\"regex\",\"lazy_static\"],\"unstable\":[]}}", "addr2line_0.24.2": "{\"dependencies\":[{\"name\":\"alloc\",\"optional\":true,\"package\":\"rustc-std-workspace-alloc\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"backtrace\",\"req\":\"^0.3.13\"},{\"features\":[\"wrap_help\"],\"name\":\"clap\",\"optional\":true,\"req\":\"^4.3.21\"},{\"name\":\"compiler_builtins\",\"optional\":true,\"req\":\"^0.1.2\"},{\"name\":\"core\",\"optional\":true,\"package\":\"rustc-std-workspace-core\",\"req\":\"^1.0.0\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"cpp_demangle\",\"optional\":true,\"req\":\"^0.4\"},{\"default_features\":false,\"name\":\"fallible-iterator\",\"optional\":true,\"req\":\"^0.3.0\"},{\"kind\":\"dev\",\"name\":\"findshlibs\",\"req\":\"^0.10\"},{\"default_features\":false,\"features\":[\"read\"],\"name\":\"gimli\",\"req\":\"^0.31.1\"},{\"kind\":\"dev\",\"name\":\"libtest-mimic\",\"req\":\"^0.7.2\"},{\"name\":\"memmap2\",\"optional\":true,\"req\":\"^0.9.4\"},{\"default_features\":false,\"features\":[\"read\",\"compression\"],\"name\":\"object\",\"optional\":true,\"req\":\"^0.36.0\"},{\"name\":\"rustc-demangle\",\"optional\":true,\"req\":\"^0.1\"},{\"default_features\":false,\"name\":\"smallvec\",\"optional\":true,\"req\":\"^1\"},{\"name\":\"typed-arena\",\"optional\":true,\"req\":\"^2\"}],\"features\":{\"all\":[\"bin\"],\"bin\":[\"loader\",\"rustc-demangle\",\"cpp_demangle\",\"fallible-iterator\",\"smallvec\",\"dep:clap\"],\"cargo-all\":[],\"default\":[\"rustc-demangle\",\"cpp_demangle\",\"loader\",\"fallible-iterator\",\"smallvec\"],\"loader\":[\"std\",\"dep:object\",\"dep:memmap2\",\"dep:typed-arena\"],\"rustc-dep-of-std\":[\"core\",\"alloc\",\"compiler_builtins\",\"gimli/rustc-dep-of-std\"],\"std\":[\"gimli/std\"]}}", @@ -1549,7 +1289,6 @@ "serde_derive_1.0.227": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"proc-macro\"],\"name\":\"proc-macro2\",\"req\":\"^1.0.74\"},{\"default_features\":false,\"features\":[\"proc-macro\"],\"name\":\"quote\",\"req\":\"^1.0.35\"},{\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"clone-impls\",\"derive\",\"parsing\",\"printing\",\"proc-macro\"],\"name\":\"syn\",\"req\":\"^2.0.81\"}],\"features\":{\"default\":[],\"deserialize_in_place\":[]}}", "serde_json_1.0.145": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"automod\",\"req\":\"^1.0.11\"},{\"name\":\"indexmap\",\"optional\":true,\"req\":\"^2.2.3\"},{\"kind\":\"dev\",\"name\":\"indoc\",\"req\":\"^2.0.2\"},{\"name\":\"itoa\",\"req\":\"^1.0\"},{\"default_features\":false,\"name\":\"memchr\",\"req\":\"^2\"},{\"kind\":\"dev\",\"name\":\"ref-cast\",\"req\":\"^1.0.18\"},{\"kind\":\"dev\",\"name\":\"rustversion\",\"req\":\"^1.0.13\"},{\"name\":\"ryu\",\"req\":\"^1.0\"},{\"default_features\":false,\"name\":\"serde\",\"req\":\"^1.0.220\",\"target\":\"cfg(any())\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0.194\"},{\"kind\":\"dev\",\"name\":\"serde_bytes\",\"req\":\"^0.11.10\"},{\"default_features\":false,\"name\":\"serde_core\",\"req\":\"^1.0.220\"},{\"kind\":\"dev\",\"name\":\"serde_derive\",\"req\":\"^1.0.166\"},{\"kind\":\"dev\",\"name\":\"serde_stacker\",\"req\":\"^0.1.8\"},{\"features\":[\"diff\"],\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0.108\"}],\"features\":{\"alloc\":[\"serde_core/alloc\"],\"arbitrary_precision\":[],\"default\":[\"std\"],\"float_roundtrip\":[],\"preserve_order\":[\"indexmap\",\"std\"],\"raw_value\":[],\"std\":[\"memchr/std\",\"serde_core/std\"],\"unbounded_depth\":[]}}", "serde_repr_0.1.20": "{\"dependencies\":[{\"name\":\"proc-macro2\",\"req\":\"^1.0.74\"},{\"name\":\"quote\",\"req\":\"^1.0.35\"},{\"kind\":\"dev\",\"name\":\"rustversion\",\"req\":\"^1.0.13\"},{\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0.166\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.100\"},{\"name\":\"syn\",\"req\":\"^2.0.46\"},{\"features\":[\"diff\"],\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0.81\"}],\"features\":{}}", - "serde_spanned_0.6.9": "{\"dependencies\":[{\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.145\"},{\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"serde-untagged\",\"req\":\"^0.1\"},{\"kind\":\"dev\",\"name\":\"serde_derive\",\"req\":\"^1\"}],\"features\":{}}", "serde_urlencoded_0.7.1": "{\"dependencies\":[{\"name\":\"form_urlencoded\",\"req\":\"^1\"},{\"name\":\"itoa\",\"req\":\"^1\"},{\"name\":\"ryu\",\"req\":\"^1\"},{\"name\":\"serde\",\"req\":\"^1.0.69\"},{\"kind\":\"dev\",\"name\":\"serde_derive\",\"req\":\"^1\"}],\"features\":{}}", "serial2_0.2.33": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"assert2\",\"req\":\"^0.3.11\"},{\"name\":\"cfg-if\",\"req\":\"^1.0.0\",\"target\":\"cfg(unix)\"},{\"name\":\"libc\",\"req\":\"^0.2.109\",\"target\":\"cfg(unix)\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.108\"},{\"features\":[\"commapi\",\"fileapi\",\"handleapi\",\"ioapiset\",\"std\",\"synchapi\",\"winbase\",\"winerror\",\"winreg\"],\"name\":\"winapi\",\"req\":\"^0.3.9\",\"target\":\"cfg(windows)\"}],\"features\":{\"doc\":[],\"doc-cfg\":[],\"rs4xx\":[],\"serde\":[\"dep:serde\"],\"unix\":[],\"windows\":[]}}", "sha-1_0.10.1": "{\"dependencies\":[{\"name\":\"cfg-if\",\"req\":\"^1.0\"},{\"name\":\"cpufeatures\",\"req\":\"^0.2\",\"target\":\"cfg(any(target_arch = \\\"aarch64\\\", target_arch = \\\"x86\\\", target_arch = \\\"x86_64\\\"))\"},{\"name\":\"digest\",\"req\":\"^0.10.4\"},{\"features\":[\"dev\"],\"kind\":\"dev\",\"name\":\"digest\",\"req\":\"^0.10.4\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.2.2\"},{\"name\":\"sha1-asm\",\"optional\":true,\"req\":\"^0.5\",\"target\":\"cfg(any(target_arch = \\\"aarch64\\\", target_arch = \\\"x86\\\", target_arch = \\\"x86_64\\\"))\"}],\"features\":{\"asm\":[\"sha1-asm\"],\"compress\":[],\"default\":[\"std\"],\"force-soft\":[],\"oid\":[\"digest/oid\"],\"std\":[\"digest/std\"]}}", @@ -1619,10 +1358,6 @@ "tokio-stream_0.1.17": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"async-stream\",\"req\":\"^0.3\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"futures\",\"req\":\"^0.3\"},{\"name\":\"futures-core\",\"req\":\"^0.3.0\"},{\"kind\":\"dev\",\"name\":\"parking_lot\",\"req\":\"^0.12.0\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2.11\"},{\"features\":[\"sync\"],\"name\":\"tokio\",\"req\":\"^1.15.0\"},{\"features\":[\"full\",\"test-util\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.2.0\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4\"},{\"name\":\"tokio-util\",\"optional\":true,\"req\":\"^0.7.0\"}],\"features\":{\"default\":[\"time\"],\"fs\":[\"tokio/fs\"],\"full\":[\"time\",\"net\",\"io-util\",\"fs\",\"sync\",\"signal\"],\"io-util\":[\"tokio/io-util\"],\"net\":[\"tokio/net\"],\"signal\":[\"tokio/signal\"],\"sync\":[\"tokio/sync\",\"tokio-util\"],\"time\":[\"tokio/time\"]}}", "tokio-util_0.7.16": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"async-stream\",\"req\":\"^0.3.0\"},{\"name\":\"bytes\",\"req\":\"^1.5.0\"},{\"kind\":\"dev\",\"name\":\"futures\",\"req\":\"^0.3.0\"},{\"name\":\"futures-core\",\"req\":\"^0.3.0\"},{\"name\":\"futures-io\",\"optional\":true,\"req\":\"^0.3.0\"},{\"name\":\"futures-sink\",\"req\":\"^0.3.0\"},{\"kind\":\"dev\",\"name\":\"futures-test\",\"req\":\"^0.3.5\"},{\"name\":\"futures-util\",\"optional\":true,\"req\":\"^0.3.0\"},{\"default_features\":false,\"name\":\"hashbrown\",\"optional\":true,\"req\":\"^0.15.0\"},{\"kind\":\"dev\",\"name\":\"parking_lot\",\"req\":\"^0.12.0\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2.11\"},{\"name\":\"slab\",\"optional\":true,\"req\":\"^0.4.4\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.1.0\"},{\"features\":[\"sync\"],\"name\":\"tokio\",\"req\":\"^1.28.0\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"tokio-stream\",\"req\":\"^0.1\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4.0\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1.29\"}],\"features\":{\"__docs_rs\":[\"futures-util\"],\"codec\":[],\"compat\":[\"futures-io\"],\"default\":[],\"full\":[\"codec\",\"compat\",\"io-util\",\"time\",\"net\",\"rt\",\"join-map\"],\"io\":[],\"io-util\":[\"io\",\"tokio/rt\",\"tokio/io-util\"],\"join-map\":[\"rt\",\"hashbrown\"],\"net\":[\"tokio/net\"],\"rt\":[\"tokio/rt\",\"tokio/sync\",\"futures-util\"],\"time\":[\"tokio/time\",\"slab\"]}}", "tokio_1.47.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"async-stream\",\"req\":\"^0.3\"},{\"name\":\"backtrace\",\"req\":\"^0.3.58\",\"target\":\"cfg(tokio_taskdump)\"},{\"name\":\"bytes\",\"optional\":true,\"req\":\"^1.2.1\"},{\"features\":[\"async-await\"],\"kind\":\"dev\",\"name\":\"futures\",\"req\":\"^0.3.0\"},{\"kind\":\"dev\",\"name\":\"futures-concurrency\",\"req\":\"^7.6.3\"},{\"default_features\":false,\"name\":\"io-uring\",\"req\":\"^0.7.6\",\"target\":\"cfg(all(tokio_uring, target_os = \\\"linux\\\"))\"},{\"name\":\"libc\",\"req\":\"^0.2.168\",\"target\":\"cfg(all(tokio_uring, target_os = \\\"linux\\\"))\"},{\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2.168\",\"target\":\"cfg(unix)\"},{\"kind\":\"dev\",\"name\":\"libc\",\"req\":\"^0.2.168\",\"target\":\"cfg(unix)\"},{\"features\":[\"futures\",\"checkpoint\"],\"kind\":\"dev\",\"name\":\"loom\",\"req\":\"^0.7\",\"target\":\"cfg(loom)\"},{\"default_features\":false,\"features\":[\"os-poll\",\"os-ext\"],\"name\":\"mio\",\"req\":\"^1.0.1\",\"target\":\"cfg(all(tokio_uring, target_os = \\\"linux\\\"))\"},{\"default_features\":false,\"name\":\"mio\",\"optional\":true,\"req\":\"^1.0.1\"},{\"features\":[\"tokio\"],\"kind\":\"dev\",\"name\":\"mio-aio\",\"req\":\"^1\",\"target\":\"cfg(target_os = \\\"freebsd\\\")\"},{\"kind\":\"dev\",\"name\":\"mockall\",\"req\":\"^0.13.0\"},{\"default_features\":false,\"features\":[\"aio\",\"fs\",\"socket\"],\"kind\":\"dev\",\"name\":\"nix\",\"req\":\"^0.29.0\",\"target\":\"cfg(unix)\"},{\"name\":\"parking_lot\",\"optional\":true,\"req\":\"^0.12.0\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2.11\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1\",\"target\":\"cfg(not(target_family = \\\"wasm\\\"))\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9\",\"target\":\"cfg(not(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\")))\"},{\"name\":\"signal-hook-registry\",\"optional\":true,\"req\":\"^1.1.1\",\"target\":\"cfg(unix)\"},{\"name\":\"slab\",\"req\":\"^0.4.9\",\"target\":\"cfg(all(tokio_uring, target_os = \\\"linux\\\"))\"},{\"features\":[\"all\"],\"name\":\"socket2\",\"optional\":true,\"req\":\"^0.6.0\",\"target\":\"cfg(not(target_family = \\\"wasm\\\"))\"},{\"kind\":\"dev\",\"name\":\"socket2\",\"req\":\"^0.6.0\",\"target\":\"cfg(not(target_family = \\\"wasm\\\"))\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.1.0\",\"target\":\"cfg(not(target_family = \\\"wasm\\\"))\"},{\"name\":\"tokio-macros\",\"optional\":true,\"req\":\"~2.5.0\"},{\"kind\":\"dev\",\"name\":\"tokio-stream\",\"req\":\"^0.1\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4.0\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1.29\",\"target\":\"cfg(tokio_unstable)\"},{\"kind\":\"dev\",\"name\":\"tracing-mock\",\"req\":\"=0.1.0-beta.1\",\"target\":\"cfg(all(tokio_unstable, target_has_atomic = \\\"64\\\"))\"},{\"kind\":\"dev\",\"name\":\"wasm-bindgen-test\",\"req\":\"^0.3.0\",\"target\":\"cfg(all(target_family = \\\"wasm\\\", not(target_os = \\\"wasi\\\")))\"},{\"name\":\"windows-sys\",\"optional\":true,\"req\":\"^0.59\",\"target\":\"cfg(windows)\"},{\"features\":[\"Win32_Foundation\",\"Win32_Security_Authorization\"],\"kind\":\"dev\",\"name\":\"windows-sys\",\"req\":\"^0.59\",\"target\":\"cfg(windows)\"}],\"features\":{\"default\":[],\"fs\":[],\"full\":[\"fs\",\"io-util\",\"io-std\",\"macros\",\"net\",\"parking_lot\",\"process\",\"rt\",\"rt-multi-thread\",\"signal\",\"sync\",\"time\"],\"io-std\":[],\"io-util\":[\"bytes\"],\"macros\":[\"tokio-macros\"],\"net\":[\"libc\",\"mio/os-poll\",\"mio/os-ext\",\"mio/net\",\"socket2\",\"windows-sys/Win32_Foundation\",\"windows-sys/Win32_Security\",\"windows-sys/Win32_Storage_FileSystem\",\"windows-sys/Win32_System_Pipes\",\"windows-sys/Win32_System_SystemServices\"],\"process\":[\"bytes\",\"libc\",\"mio/os-poll\",\"mio/os-ext\",\"mio/net\",\"signal-hook-registry\",\"windows-sys/Win32_Foundation\",\"windows-sys/Win32_System_Threading\",\"windows-sys/Win32_System_WindowsProgramming\"],\"rt\":[],\"rt-multi-thread\":[\"rt\"],\"signal\":[\"libc\",\"mio/os-poll\",\"mio/net\",\"mio/os-ext\",\"signal-hook-registry\",\"windows-sys/Win32_Foundation\",\"windows-sys/Win32_System_Console\"],\"sync\":[],\"test-util\":[\"rt\",\"sync\",\"time\"],\"time\":[]}}", - "toml_0.8.23": "{\"dependencies\":[{\"name\":\"indexmap\",\"optional\":true,\"req\":\"^2.0.0\"},{\"name\":\"serde\",\"req\":\"^1.0.145\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0.199\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.116\"},{\"features\":[\"serde\"],\"name\":\"serde_spanned\",\"req\":\"^0.6.9\"},{\"kind\":\"dev\",\"name\":\"snapbox\",\"req\":\"^0.6.0\"},{\"kind\":\"dev\",\"name\":\"toml-test-data\",\"req\":\"^2.3.0\"},{\"features\":[\"snapshot\"],\"kind\":\"dev\",\"name\":\"toml-test-harness\",\"req\":\"^1.3.2\"},{\"features\":[\"serde\"],\"name\":\"toml_datetime\",\"req\":\"^0.6.11\"},{\"default_features\":false,\"features\":[\"serde\"],\"name\":\"toml_edit\",\"optional\":true,\"req\":\"^0.22.27\"},{\"kind\":\"dev\",\"name\":\"walkdir\",\"req\":\"^2.5.0\"}],\"features\":{\"default\":[\"parse\",\"display\"],\"display\":[\"dep:toml_edit\",\"toml_edit?/display\"],\"parse\":[\"dep:toml_edit\",\"toml_edit?/parse\"],\"preserve_order\":[\"indexmap\"],\"unbounded\":[\"toml_edit?/unbounded\"]}}", - "toml_datetime_0.6.11": "{\"dependencies\":[{\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.145\"},{\"kind\":\"dev\",\"name\":\"snapbox\",\"req\":\"^0.6.21\"}],\"features\":{}}", - "toml_edit_0.22.27": "{\"dependencies\":[{\"features\":[\"std\"],\"name\":\"indexmap\",\"req\":\"^2.3.0\"},{\"features\":[\"max_inline\"],\"name\":\"kstring\",\"optional\":true,\"req\":\"^2.0.0\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1.5.0\"},{\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.145\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0.199\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.116\"},{\"features\":[\"serde\"],\"name\":\"serde_spanned\",\"optional\":true,\"req\":\"^0.6.9\"},{\"kind\":\"dev\",\"name\":\"snapbox\",\"req\":\"^0.6.0\"},{\"kind\":\"dev\",\"name\":\"toml-test-data\",\"req\":\"^2.3.0\"},{\"features\":[\"snapshot\"],\"kind\":\"dev\",\"name\":\"toml-test-harness\",\"req\":\"^1.3.2\"},{\"name\":\"toml_datetime\",\"req\":\"^0.6.11\"},{\"name\":\"toml_write\",\"optional\":true,\"req\":\"^0.1.2\"},{\"kind\":\"dev\",\"name\":\"walkdir\",\"req\":\"^2.5.0\"},{\"name\":\"winnow\",\"optional\":true,\"req\":\"^0.7.10\"}],\"features\":{\"default\":[\"parse\",\"display\"],\"display\":[\"dep:toml_write\"],\"parse\":[\"dep:winnow\"],\"perf\":[\"dep:kstring\"],\"serde\":[\"dep:serde\",\"toml_datetime/serde\",\"dep:serde_spanned\"],\"unbounded\":[],\"unstable-debug\":[\"winnow?/debug\"]}}", - "toml_write_0.1.2": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1.6.0\"},{\"kind\":\"dev\",\"name\":\"snapbox\",\"req\":\"^0.6.0\"},{\"kind\":\"dev\",\"name\":\"toml_old\",\"package\":\"toml\",\"req\":\"^0.5.10\"}],\"features\":{\"alloc\":[],\"default\":[\"std\"],\"std\":[\"alloc\"]}}", "tonic-build_0.14.2": "{\"dependencies\":[{\"name\":\"prettyplease\",\"req\":\"^0.2\"},{\"name\":\"proc-macro2\",\"req\":\"^1.0\"},{\"name\":\"quote\",\"req\":\"^1.0\"},{\"name\":\"syn\",\"req\":\"^2.0\"}],\"features\":{\"default\":[\"transport\"],\"transport\":[]}}", "tonic-prost-build_0.14.2": "{\"dependencies\":[{\"name\":\"prettyplease\",\"req\":\"^0.2\"},{\"name\":\"proc-macro2\",\"req\":\"^1.0\"},{\"name\":\"prost-build\",\"req\":\"^0.14\"},{\"name\":\"prost-types\",\"req\":\"^0.14\"},{\"name\":\"quote\",\"req\":\"^1.0\"},{\"name\":\"syn\",\"req\":\"^2.0\"},{\"name\":\"tempfile\",\"req\":\"^3.0\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"tonic\",\"req\":\"^0.14.0\"},{\"default_features\":false,\"name\":\"tonic-build\",\"req\":\"^0.14.0\"}],\"features\":{\"cleanup-markdown\":[\"prost-build/cleanup-markdown\"],\"default\":[\"transport\",\"cleanup-markdown\"],\"transport\":[\"tonic-build/transport\"]}}", "tonic-prost_0.14.2": "{\"dependencies\":[{\"name\":\"bytes\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"http-body\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"http-body-util\",\"req\":\"^0.1\"},{\"name\":\"prost\",\"req\":\"^0.14\"},{\"features\":[\"macros\",\"rt-multi-thread\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"tokio-stream\",\"req\":\"^0.1\"},{\"default_features\":false,\"name\":\"tonic\",\"req\":\"^0.14.0\"}],\"features\":{}}", @@ -1721,7 +1456,6 @@ "windows_x86_64_gnullvm_0.53.0": "{\"dependencies\":[],\"features\":{}}", "windows_x86_64_msvc_0.52.6": "{\"dependencies\":[],\"features\":{}}", "windows_x86_64_msvc_0.53.0": "{\"dependencies\":[],\"features\":{}}", - "winnow_0.7.13": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"annotate-snippets\",\"req\":\"^0.11.3\"},{\"name\":\"anstream\",\"optional\":true,\"req\":\"^0.3.2\"},{\"name\":\"anstyle\",\"optional\":true,\"req\":\"^1.0.1\"},{\"kind\":\"dev\",\"name\":\"anyhow\",\"req\":\"^1.0.86\"},{\"kind\":\"dev\",\"name\":\"automod\",\"req\":\"^1.0.14\"},{\"kind\":\"dev\",\"name\":\"circular\",\"req\":\"^0.3.0\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5.1\"},{\"name\":\"is_terminal_polyfill\",\"optional\":true,\"req\":\"^1.48.0\"},{\"kind\":\"dev\",\"name\":\"lexopt\",\"req\":\"^0.3.0\"},{\"default_features\":false,\"name\":\"memchr\",\"optional\":true,\"req\":\"^2.5\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1.2.0\"},{\"kind\":\"dev\",\"name\":\"rustc-hash\",\"req\":\"^1.1.0\"},{\"features\":[\"examples\"],\"kind\":\"dev\",\"name\":\"snapbox\",\"req\":\"^0.6.21\"},{\"kind\":\"dev\",\"name\":\"term-transcript\",\"req\":\"^0.2.0\"},{\"name\":\"terminal_size\",\"optional\":true,\"req\":\"^0.4.0\"}],\"features\":{\"alloc\":[],\"debug\":[\"std\",\"dep:anstream\",\"dep:anstyle\",\"dep:is_terminal_polyfill\",\"dep:terminal_size\"],\"default\":[\"std\"],\"simd\":[\"dep:memchr\"],\"std\":[\"alloc\",\"memchr?/std\"],\"unstable-doc\":[\"alloc\",\"std\",\"simd\",\"unstable-recover\"],\"unstable-recover\":[]}}", "winreg_0.10.1": "{\"dependencies\":[{\"name\":\"chrono\",\"optional\":true,\"req\":\"^0.4.6\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.3\"},{\"name\":\"serde\",\"optional\":true,\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"serde_derive\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"~3.0\"},{\"features\":[\"impl-default\",\"impl-debug\",\"minwindef\",\"minwinbase\",\"timezoneapi\",\"winerror\",\"winnt\",\"winreg\",\"handleapi\"],\"name\":\"winapi\",\"req\":\"^0.3.9\"}],\"features\":{\"serialization-serde\":[\"transactions\",\"serde\"],\"transactions\":[\"winapi/ktmw32\"]}}", "winx_0.36.4": "{\"dependencies\":[{\"name\":\"bitflags\",\"req\":\"^2.4\"},{\"features\":[\"Win32_Foundation\",\"Win32_Storage_FileSystem\",\"Win32_System_IO\",\"Win32_System_Ioctl\",\"Win32_System_LibraryLoader\",\"Win32_System_Performance\",\"Win32_System_SystemServices\"],\"name\":\"windows-sys\",\"req\":\">=0.52, <=0.59\",\"target\":\"cfg(windows)\"}],\"features\":{}}", "wit-bindgen-rt_0.39.0": "{\"dependencies\":[{\"name\":\"bitflags\",\"optional\":true,\"req\":\"^2.3.3\"},{\"name\":\"futures\",\"optional\":true,\"req\":\"^0.3.30\"},{\"name\":\"once_cell\",\"optional\":true,\"req\":\"^1.19.0\"}],\"features\":{\"async\":[\"dep:futures\",\"dep:once_cell\"]}}", diff --git a/bazel/proto/BUILD.bazel b/bazel/proto/BUILD.bazel index a1b828413..d99bbc8ed 100644 --- a/bazel/proto/BUILD.bazel +++ b/bazel/proto/BUILD.bazel @@ -15,6 +15,7 @@ descriptor_set( "@bazel//src/main/protobuf:failure_details_proto", "@bazel//src/main/protobuf:invocation_policy_proto", "@bazel//src/main/protobuf:build_proto", + "@bazel//src/main/protobuf:remote_execution_log_proto", "@googleapis//google/devtools/build/v1:build_proto", "@remoteapis//:build_bazel_remote_execution_v2_remote_execution_proto" ], diff --git a/bazel/release/hashes.bzl b/bazel/release/hashes.bzl index 316cee510..a92f47c58 100644 --- a/bazel/release/hashes.bzl +++ b/bazel/release/hashes.bzl @@ -6,6 +6,22 @@ via output groups. Based on https://github.com/bazelbuild/examples/blob/main/rules/implicit_output/hash.bzl """ +_COREUTILS_TOOLCHAIN = "@aspect_bazel_lib//lib:coreutils_toolchain_type" + +def _hash_action(ctx, coreutils, algorithm, src, out): + ctx.actions.run_shell( + outputs = [out], + inputs = [src], + tools = [coreutils.bin], + command = "{coreutils} hashsum --{algorithm} {src} > {out}".format( + coreutils = coreutils.bin.path, + algorithm = algorithm, + src = src.path, + out = out.path, + ), + toolchain = _COREUTILS_TOOLCHAIN, + ) + def _impl(ctx): # Create actions to generate the three output files. # Actions are run only when the corresponding file is requested. @@ -13,32 +29,16 @@ def _impl(ctx): if ctx.file.src.is_directory: fail("src expected to be a file but got a directory") + coreutils = ctx.toolchains[_COREUTILS_TOOLCHAIN].coreutils_info + md5out = ctx.actions.declare_file("{}.md5".format(ctx.file.src.basename)) - ctx.actions.run_shell( - outputs = [md5out], - inputs = [ctx.file.src], - command = "ROOT=$PWD && cd {} && md5sum {} > $ROOT/{}".format(ctx.file.src.dirname, ctx.file.src.basename, md5out.path), - ) + _hash_action(ctx, coreutils, "md5", ctx.file.src, md5out) sha1out = ctx.actions.declare_file("{}.sha1".format(ctx.file.src.basename)) - ctx.actions.run_shell( - outputs = [sha1out], - inputs = [ctx.file.src], - command = "ROOT=$PWD && cd {} && sha1sum {} > $ROOT/{}".format(ctx.file.src.dirname, ctx.file.src.basename, sha1out.path), - ) + _hash_action(ctx, coreutils, "sha1", ctx.file.src, sha1out) sha256out = ctx.actions.declare_file("{}.sha256".format(ctx.file.src.basename)) - ctx.actions.run_shell( - outputs = [sha256out], - inputs = [ctx.file.src], - command = "ROOT=$PWD && cd {dirname} && $ROOT/{sha256sum} {basename} > $ROOT/{path}".format( - dirname = ctx.file.src.dirname, - sha256sum = ctx.executable._sha256sum.path, - basename = ctx.file.src.basename, - path = sha256out.path, - ), - tools = [ctx.executable._sha256sum], - ) + _hash_action(ctx, coreutils, "sha256", ctx.file.src, sha256out) # By default (if you run `bazel build` on this target, or if you use it as a # source of another target), only the sha256 is computed. @@ -60,12 +60,8 @@ _hashes = rule( allow_single_file = True, mandatory = True, ), - "_sha256sum": attr.label( - executable = True, - cfg = "exec", - default = "//bazel/release/sha256sum", - ), }, + toolchains = [_COREUTILS_TOOLCHAIN], ) def hashes(name, src, **kwargs): diff --git a/bazel/release/sha256sum/BUILD.bazel b/bazel/release/sha256sum/BUILD.bazel deleted file mode 100644 index 4bef6d218..000000000 --- a/bazel/release/sha256sum/BUILD.bazel +++ /dev/null @@ -1,17 +0,0 @@ -load("@rules_go//go:def.bzl", "go_binary", "go_library") - -go_library( - name = "sha256sum_lib", - srcs = ["main.go"], - importpath = "github.com/aspect-build/silo/bazel/release/sha256sum", - visibility = ["//visibility:private"], -) - -go_binary( - name = "sha256sum", - embed = [":sha256sum_lib"], - visibility = [ - "//bazel/release:__pkg__", - "//cli:__pkg__", - ], -) diff --git a/bazel/release/sha256sum/main.go b/bazel/release/sha256sum/main.go deleted file mode 100644 index 18f272286..000000000 --- a/bazel/release/sha256sum/main.go +++ /dev/null @@ -1,32 +0,0 @@ -package main - -import ( - "crypto/sha256" - "fmt" - "io" - "log" - "os" -) - -func main() { - var input io.Reader - var filename string - if len(os.Args) == 1 { - input = os.Stdin - filename = "-" - } else { - f, err := os.Open(os.Args[1]) - if err != nil { - log.Fatal(err) - } - defer f.Close() - input = f - filename = os.Args[1] - } - - hash := sha256.New() - if _, err := io.Copy(hash, input); err != nil { - log.Fatal(err) - } - fmt.Printf("%x %s\n", hash.Sum(nil), filename) -} diff --git a/crates/aspect-cli/src/helpers.rs b/crates/aspect-cli/src/helpers.rs index 5a1b5cdc7..5ff94f13e 100644 --- a/crates/aspect-cli/src/helpers.rs +++ b/crates/aspect-cli/src/helpers.rs @@ -6,50 +6,6 @@ use axl_runtime::module::{ use tokio::fs; use tracing::instrument; -/// Parse the AXL_CONFIG environment variable for additional config paths. -/// Supports both individual .config.axl files and directories to scan. -/// Paths are separated by ':' on Unix and ';' on Windows. -pub async fn parse_axl_config_env() -> Result, std::io::Error> { - let separator = if cfg!(windows) { ';' } else { ':' }; - - let env_val = match std::env::var("AXL_CONFIG") { - Ok(val) if !val.is_empty() => val, - _ => return Ok(vec![]), - }; - - let mut configs = Vec::new(); - - for path_str in env_val.split(separator) { - let path = PathBuf::from(path_str.trim()); - - if !path.exists() { - eprintln!( - "warning: AXL_CONFIG path does not exist: {}", - path.display() - ); - continue; - } - - if path.is_file() { - // Check it's a .config.axl file - if path.to_string_lossy().ends_with(AXL_CONFIG_EXTENSION) { - configs.push(path); - } else { - eprintln!( - "warning: AXL_CONFIG file is not a .config.axl file: {}", - path.display() - ); - } - } else if path.is_dir() { - // Scan directory for .config.axl files - let (_, dir_configs) = search_sources(&vec![path]).await?; - configs.extend(dir_configs); - } - } - - Ok(configs) -} - // Constants for special directory names used in module resolution. // These define the structure for local modules (e.g., .aspect/axl/module_name). pub const DOT_ASPECT_FOLDER: &str = ".aspect"; diff --git a/crates/aspect-cli/src/main.rs b/crates/aspect-cli/src/main.rs index c03e8abf2..23ba4fa39 100644 --- a/crates/aspect-cli/src/main.rs +++ b/crates/aspect-cli/src/main.rs @@ -25,9 +25,7 @@ use tokio::task::spawn_blocking; use tracing::info_span; use crate::cmd_tree::{BUILTIN_COMMAND_DISPLAY_ORDER, CommandTree, make_command_from_task}; -use crate::helpers::{ - find_repo_root, get_default_axl_search_paths, parse_axl_config_env, search_sources, -}; +use crate::helpers::{find_repo_root, get_default_axl_search_paths, search_sources}; // Helper function to check if debug mode is enabled based on the ASPECT_DEBUG environment variable. fn debug_mode() -> bool { @@ -130,9 +128,6 @@ async fn main() -> miette::Result { let search_paths = get_default_axl_search_paths(¤t_work_dir, &repo_root); let (scripts, configs) = search_sources(&search_paths).await.into_diagnostic()?; - // Get additional configs from AXL_CONFIG environment variable - let env_configs = parse_axl_config_env().await.into_diagnostic()?; - // Enter a tracing span for evaluation of scripts and configs. let espan = info_span!("eval"); @@ -314,28 +309,6 @@ async fn main() -> miette::Result { scoped_configs.push((root_scope.clone(), path.clone(), "config".to_string())); } - // Append environment configs, each with scope derived from parent directory - if debug_mode() && !env_configs.is_empty() { - eprintln!("AXL_CONFIG configs:"); - for path in &env_configs { - eprintln!( - " - {} (scope: {})", - path.display(), - path.parent() - .map_or("repo root".to_string(), |p| p.display().to_string()) - ); - } - } - - for config_path in env_configs.iter() { - let parent = config_path.parent().unwrap_or(&repo_root); - let scope = ModuleScope { - name: "".to_string(), - path: parent.to_path_buf(), - }; - scoped_configs.push((scope, config_path.clone(), "config".to_string())); - } - // Run all config functions, passing in vector of tasks for configuration let tasks = config_eval .run_all(scoped_configs, tasks) diff --git a/crates/axl-proto/Cargo.toml b/crates/axl-proto/Cargo.toml index cac41303a..793149b7c 100644 --- a/crates/axl-proto/Cargo.toml +++ b/crates/axl-proto/Cargo.toml @@ -12,7 +12,6 @@ rust-version.workspace = true [dependencies] allocative = "0.3.4" anyhow = "1.0.98" -derive_more = { version = "2.0.1", features = ["full"] } display_container = "0.9.0" prost = "0.14.1" prost-types = "0.14.1" @@ -20,7 +19,7 @@ starbuf-derive = { path = "../starbuf-derive" } starbuf-types = { path = "../starbuf-types" } starlark = "0.13.0" starlark_derive = "0.13.0" -tonic = { version = "0.14.2", features = ["transport", "tls-webpki-roots"] } +tonic = { version = "0.14.2", features = ["transport", "tls-native-roots"] } tonic-prost = "0.14.2" tokio = { version = "1", features = ["rt-multi-thread", "macros"] } diff --git a/crates/axl-proto/build.rs b/crates/axl-proto/build.rs index 41d41095c..01f18c9a4 100644 --- a/crates/axl-proto/build.rs +++ b/crates/axl-proto/build.rs @@ -75,20 +75,15 @@ fn main() -> Result<(), std::io::Error> { } config.type_attribute( format!("{}.{}", prefix, desc.name()), - format!( - r#" + r#" #[derive( ::starlark::values::ProvidesStaticType, - ::derive_more::Display, ::starlark::values::Trace, ::starlark::values::NoSerialize, ::allocative::Allocative, ::starbuf_derive::Message )] -#[display("{}")] "#, - desc.name() - ), ); for oneof in &desc.oneof_decl { @@ -184,9 +179,7 @@ pub mod protos {{ ), )?; - let v2 = fs::read_to_string(format!( - "{out_dir}/build.bazel.remote.execution.v2.rs" - ))?; + let v2 = fs::read_to_string(format!("{out_dir}/build.bazel.remote.execution.v2.rs"))?; fs::write( format!("{out_dir}/build.bazel.remote.execution.v2.rs"), diff --git a/crates/axl-proto/descriptor.bin b/crates/axl-proto/descriptor.bin index 8092429aee6c649e5f7fdf3fb24284f030c47136..711036b013f7da3edd275610d6d7a09ad44c8cd9 100644 GIT binary patch delta 15433 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 diff --git a/crates/starbuf-derive/src/lib.rs b/crates/starbuf-derive/src/lib.rs index 9e288a95e..889a074f3 100644 --- a/crates/starbuf-derive/src/lib.rs +++ b/crates/starbuf-derive/src/lib.rs @@ -102,10 +102,7 @@ fn try_types(input: TokenStream) -> Result { let subpath = quote! {#subpath::#subident}; let sub_key = subpath.to_string(); let subgenerator_fn = Ident::new( - &format!( - "{}_toplevels", - sub_key.replace("::", "_").replace(" ", "") - ), + &format!("{}_toplevels", sub_key.replace("::", "_").replace(" ", "")), Span::call_site(), ); let subidentstr = subident.to_string(); @@ -138,10 +135,8 @@ fn try_types(input: TokenStream) -> Result { starlark::values::starlark_value_as_type::StarlarkValueAsType::new(); }); let ident_snake = snake(ident.to_string()); - let constructor_fn = Ident::new( - &format!("{}_constructor", ident_snake), - ident.span(), - ); + let constructor_fn = + Ident::new(&format!("{}_constructor", ident_snake), ident.span()); defs.entry(subpaths) .or_insert_with(|| (vec![], vec![])) .1 @@ -498,7 +493,8 @@ fn try_message(input: TokenStream) -> Result { } }); - let ident_snake = snake(ident.to_string()); + let ident_str = ident.to_string(); + let ident_snake = snake(ident_str.clone()); let methods_ident = Ident::new(&format!("{}_methods", &ident_snake), ident.span()); let constructor_fn_ident = Ident::new(&format!("{}_constructor", &ident_snake), ident.span()); @@ -633,7 +629,286 @@ fn try_message(input: TokenStream) -> Result { }) .collect(); + let repr_fields: Vec = fields + .iter() + .filter_map(|(field, sattrs, attrs, _)| { + let has_deprecated = field.attrs.iter().any(|v| v.path().is_ident("deprecated")); + if sattrs.skip + || has_deprecated + || sattrs.any + || sattrs.duration + || sattrs.timestamp + || attrs.bytes.is_some() + { + return None; + } + + let field_ident = field.ident.as_ref()?; + let display_name = if let Some(ref rename) = sattrs.rename { + rename.clone() + } else { + field_ident.to_string() + }; + + let value_fmt = if attrs.oneof.is_some() { + quote! { + match &self.#field_ident { + Some(v) => { write!(f, "{:?}", v)?; }, + None => f.write_str("None")?, + } + } + } else if attrs.map.is_some() { + quote! { + f.write_str("{")?; + let mut __map_first = true; + for (k, v) in &self.#field_ident { + if !__map_first { f.write_str(", ")?; } + __map_first = false; + write!(f, "{:?}: {:?}", k, v)?; + } + f.write_str("}")?; + } + } else if attrs.repeated { + let item_fmt = if attrs.string { + quote! { write!(f, "\"{}\"", item)?; } + } else if attrs.bool { + quote! { f.write_str(if *item { "True" } else { "False" })?; } + } else if attrs.message { + quote! { write!(f, "{}", item)?; } + } else { + quote! { write!(f, "{}", item)?; } + }; + quote! { + f.write_str("[")?; + for (i, item) in self.#field_ident.iter().enumerate() { + if i > 0 { f.write_str(", ")?; } + #item_fmt + } + f.write_str("]")?; + } + } else if attrs.optional { + let some_fmt = if attrs.string { + quote! { write!(f, "\"{}\"", v)?; } + } else if attrs.bool { + quote! { f.write_str(if *v { "True" } else { "False" })?; } + } else if attrs.message { + quote! { write!(f, "{}", v)?; } + } else { + quote! { write!(f, "{}", v)?; } + }; + quote! { + match &self.#field_ident { + Some(v) => { #some_fmt }, + None => f.write_str("None")?, + } + } + } else if attrs.string { + quote! { write!(f, "\"{}\"", &self.#field_ident)?; } + } else if attrs.bool { + quote! { f.write_str(if self.#field_ident { "True" } else { "False" })?; } + } else if attrs.int32 || attrs.uint32 || attrs.int64 || attrs.uint64 { + quote! { write!(f, "{}", self.#field_ident)?; } + } else if attrs.enumeration.is_some() { + quote! { write!(f, "{}", self.#field_ident)?; } + } else if attrs.message { + quote! { write!(f, "{}", self.#field_ident)?; } + } else { + return None; + }; + + Some(quote! { + if !__repr_first { f.write_str(", ")?; } + __repr_first = false; + f.write_str(#display_name)?; + f.write_str("=")?; + #value_fmt + }) + }) + .collect(); + + let display_body = if repr_fields.is_empty() { + quote! { + f.write_str(#ident_str)?; + f.write_str("()")?; + Ok(()) + } + } else { + quote! { + f.write_str(#ident_str)?; + f.write_str("(")?; + let mut __repr_first = true; + #(#repr_fields)* + f.write_str(")")?; + Ok(()) + } + }; + + let repr_fields_pretty: Vec = fields + .iter() + .filter_map(|(field, sattrs, attrs, _)| { + let has_deprecated = field.attrs.iter().any(|v| v.path().is_ident("deprecated")); + if sattrs.skip + || has_deprecated + || sattrs.any + || sattrs.duration + || sattrs.timestamp + || attrs.bytes.is_some() + { + return None; + } + + let field_ident = field.ident.as_ref()?; + let display_name = if let Some(ref rename) = sattrs.rename { + rename.clone() + } else { + field_ident.to_string() + }; + + let value_fmt = if attrs.oneof.is_some() { + quote! { + match &self.#field_ident { + Some(v) => { write!(__col, "{:?}", v).unwrap(); }, + None => __col.push_str("None"), + } + } + } else if attrs.map.is_some() { + quote! { + if self.#field_ident.is_empty() { + __col.push_str("{}"); + } else { + __col.push_str("{"); + let mut __map_first = true; + for (k, v) in &self.#field_ident { + if !__map_first { __col.push_str(","); } + __map_first = false; + __col.push_str("\n"); + for _ in 0..(__inner + 2) { __col.push(' '); } + write!(__col, "{:?}: {:?}", k, v).unwrap(); + } + __col.push_str("\n"); + for _ in 0..__inner { __col.push(' '); } + __col.push_str("}"); + } + } + } else if attrs.repeated && attrs.message { + quote! { + if self.#field_ident.is_empty() { + __col.push_str("[]"); + } else { + __col.push_str("["); + for (__i, __item) in self.#field_ident.iter().enumerate() { + if __i > 0 { __col.push_str(","); } + __col.push_str("\n"); + for _ in 0..(__inner + 2) { __col.push(' '); } + __item.__starbuf_pretty(__col, __inner + 2); + } + __col.push_str("\n"); + for _ in 0..__inner { __col.push(' '); } + __col.push_str("]"); + } + } + } else if attrs.repeated { + let item_fmt = if attrs.string { + quote! { write!(__col, "\"{}\"", __item).unwrap(); } + } else if attrs.bool { + quote! { __col.push_str(if *__item { "True" } else { "False" }); } + } else { + quote! { write!(__col, "{}", __item).unwrap(); } + }; + quote! { + __col.push_str("["); + for (__i, __item) in self.#field_ident.iter().enumerate() { + if __i > 0 { __col.push_str(", "); } + #item_fmt + } + __col.push_str("]"); + } + } else if attrs.optional { + let is_real_message = attrs.message && { + let is_scalar = + extract_inner_type(&field.ty, "core::option::Option").map_or(false, |ty| { + let s = ty.to_token_stream().to_string().replace(' ', ""); + matches!( + s.as_str(), + "u32" | "i32" | "u64" | "i64" | "f32" | "f64" | "bool" + ) + }); + !is_scalar + }; + let some_fmt = if is_real_message { + quote! { v.__starbuf_pretty(__col, __inner); } + } else if attrs.string { + quote! { write!(__col, "\"{}\"", v).unwrap(); } + } else if attrs.bool { + quote! { __col.push_str(if *v { "True" } else { "False" }); } + } else { + quote! { write!(__col, "{}", v).unwrap(); } + }; + quote! { + match &self.#field_ident { + Some(v) => { #some_fmt }, + None => __col.push_str("None"), + } + } + } else if attrs.string { + quote! { write!(__col, "\"{}\"", &self.#field_ident).unwrap(); } + } else if attrs.bool { + quote! { __col.push_str(if self.#field_ident { "True" } else { "False" }); } + } else if attrs.int32 || attrs.uint32 || attrs.int64 || attrs.uint64 { + quote! { write!(__col, "{}", self.#field_ident).unwrap(); } + } else if attrs.enumeration.is_some() { + quote! { write!(__col, "{}", self.#field_ident).unwrap(); } + } else if attrs.message { + quote! { self.#field_ident.__starbuf_pretty(__col, __inner); } + } else { + return None; + }; + + Some(quote! { + if !__repr_first { __col.push_str(","); } + __repr_first = false; + __col.push_str("\n"); + for _ in 0..__inner { __col.push(' '); } + __col.push_str(#display_name); + __col.push_str("="); + #value_fmt + }) + }) + .collect(); + + let pretty_body = if repr_fields_pretty.is_empty() { + quote! { + __col.push_str(#ident_str); + __col.push_str("()"); + } + } else { + quote! { + use ::std::fmt::Write; + let __inner = __indent + 2; + __col.push_str(#ident_str); + __col.push_str("("); + let mut __repr_first = true; + #(#repr_fields_pretty)* + __col.push_str("\n"); + for _ in 0..__indent { __col.push(' '); } + __col.push_str(")"); + } + }; + let expanded = quote! { + impl #ident { + #[doc(hidden)] + pub fn __starbuf_pretty(&self, __col: &mut String, __indent: usize) { + #pretty_body + } + } + + impl ::std::fmt::Display for #ident { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + #display_body + } + } + impl<'v> ::starlark::values::AllocValue<'v> for #ident { fn alloc_value(self, heap: &'v ::starlark::values::Heap) -> ::starlark::values::Value<'v> { heap.alloc_simple(self) @@ -647,6 +922,10 @@ fn try_message(input: TokenStream) -> Result { ::starlark::environment::MethodsStatic::new(); RES.methods(#methods_ident) } + + fn collect_repr(&self, collector: &mut String) { + self.__starbuf_pretty(collector, 0); + } } #[::starlark::starlark_module] @@ -995,7 +1274,7 @@ fn try_service(attr: TokenStream, item: TokenStream) -> Result?zKgI>fp2FJ>UBgR5aL#;(O-# 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Ǡ~QVc8hQKcvahI3DI7-Ex*xnE|uHJPZugNMB6v| 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

R2uH>MHjhvJI= zzZ1DRA?V5oMA1GR6B7nbJ~O*sZ6R4w%pt{Ck#Ew~zO*-~cFmmlps&ykV&BZ}SQDv} zjv@zxz~c#B3IeKh+qXer%XT1^4gs1r3+)IGa(n>NK4w!1E*rG>2}7u(eH9YG0p<=~ zl_&Y4k|LnWIyGwrOq31QItXBdj$~h@OZ^sEk2HU@6buuqkauvXb6R-|?KN6Pp@hzu z%=j0P#h33!U%nlR7z|I_3MwTgtL$_3jkE+yxM@V=$mra7019FR5|Xr^)&Y1)Y&<){ z_k)9KAodEVe~jId^t{XpxbHw?D*n)aphdt?0mX;-2_K>fC6Y~+$0$&Lgz?ia2mBv7 z=juI+=*ilZ)!zx)L>m_+3n+0_NmWZ?1&0CJ-EbV!Eo~q!L4^m4iR!EOFB-=AMsL>7 zHtr%J<1tNNXoPeY;sc=>ePZy#fCOgRgPJP-DbU8cq-h$HbX?X$y>Ahf<8EzQv}Z~W z2-4Q^vFUzU*Dlp~QMhNMR~sX_LJY-7H*l3t>V1oeb~0=lh1e5%HbsteBscHE8_PdN zWlofD2@Q?v5qVBZfFJQiH_5=g1eWqZcK2BY!oh4+xHQ}X>(fmyzNp~D-?pBOXaBrZ9aB=pP2e&Q0@XOyg{jW|#XFb?OS{E6efK7vz-rHct zA?_K3#{S_RB1oUaKJdWG(mTg5%<~M0?VC4(2)2IN(HfwvYssYSYacfhaM%Z_6}|Ap zxHiyWI^?Qlw7#7i(K#3#n;@a!CMz+RR^w=Sirr=-)+ZZ*sf82rHvDaIGuDZb{ZZ7x z*tseqC1+bYUTr(+?UWhk!fSza`^ zvW=1qy}Fbab?*idu$)ZM)shmu{c3JZRujY{7jY$r8^Tz***MSVcN{##?}NGTL!bb) z1{2=#n4P>DX9rHp7B*vF538KZVr+>JG$wqL-_QeuT|NO#0F|m`-J}WhAduzu7MFO7 zk7$e30--a)@|o{>sh2Zf2`iUvhgnf5=|r}D4`FcBSY>uW>TZ$Hf^teZp4U9&ds*(i zJQ4O>Mk7U=d;0fXI!bV&6Kc=lyU*w>Z)2fKctkVINU#hmGl^zO1E&-?zUFwA$1;G# z{)S<68{$XL#XIFiye@$ZkoquE#j_`iT41bWc-BJ&%%?Zmj0KFHkyn6$B^$QP%h`rm zxv&gEro7#=y}Y%n%QhIwYfh48VZ`TpMMFLS90pv}RVo9G>cHd7G4$ecq+#igmZewv zCM$2TU6SE}iab6D?V>jVKJZ7t5Zchb&B>mKLu$<8P=x#i%~-=0k~L5+=S(=p-83lo zC7tw|Bcepox7Bi7@?e3-!w6RvNO;DM(!BOrX>B?uiT(}zrh|`2_)OExEI-nF9fY)b zWhxM__J%%Hm2s#yWF7VZHq?sf=Xz4mqhEuQ& zGr9^b_yo_lo{EuGdky4NCsF-CEZ8lCRhcz|vMExdMVQfA)h02LtID)}&(kDfWhfY1cgM&0~;TTIb$e{8#Ovp~X27Bp`Tn7*Q4wrih( zsYDw%|46EN%66~`gG|7HDhUPh(7DK~J05f)p&PEOgZ>7)1Z8>Z3Q+d4>ad1X0w%q2 z&?I5!^mJwJxN7$7j+EXn_ilz|kQBuP2-IqZETo~y{RNt&oh^^2?X2>4W=cC`H367L zaH)ZqPS}K)Y+E?;?$`1>Z{5~XRKiBvOqjo5PT}@c9$UUAwwxc?bV7b~s+|e~2AL?k z?yeaL1}t%AudYLocWGY5IOp>j%b zA$U{@G{^R)>=1kpR<%RTV#f6~tkZAUh<%BBig}{#sh=$ttPTIX zJ#2yH7ohJeBAEn9vqgHR4+X+(%SV+H2^2}v}Hj7!t_}I+aAyJgB zFB$2A16dfL&;dFU3gK7hAHL@raHgZ#uB)Uszz%9z{?71rI#58%wFts1d_`7hpri`= zu)S~{1VqNLl7Rl;RJ^5PD{HfZ301h5W#yq?6%@2Eb$OL_Bh@NOZOYIV+vSNE$K3Dy zSAd+k1VwS+a?s=owmZ?fv~obDY*$1CTiXd81=6uJ*od%`9c{e^mE|hHsGi{La z!Nm0303g1-&wmQ_FXcBdSf#bO$8D@6+$TM5;aNcPkLzTYqX#lTUXbl!_oMR%FqT7olz|RGyniw#$GEWdMzIE zL_)e_$H3dx?)0H>*+O@V)9wyKcP#=Dvv$4KJIxN~5zq)89*T#YEk;7B93CG+#Em2H ziJjp+O%?VwReDl%2o2CIt|$AgQ#f7R@DpBgrnjhvpgadC>3O-A)1EbgQhUy{X^x%| zG(0KrHgvm6J3q@CJyfQ{m`GV;T@U1BX*Rc1*e-Jwy}G4cUzL^KjE;@h(@M8!Cd)NK zi~fNvjp*POvY#CaX5Q>7Z+28hrva2IgJZFC4O0+jz@*RGn>p8;(a|xrUL2iu%_&kU z!RY|epvcnD^y0_!$DMm68@a~2F^>?*Nxhp|7ZhsolmL+jk9F$nqCzc6H?^Bu7Z+-Y z#+I$_c#L~#p_Xv9?5U0;ysS_QQYhwiamP!AFE7+m^K0i?R~Bli1+a6i4TV}Fk?v-M zR~Kse0mGB~c2n4_&acfQxYkPSqc4Tx|7XB6Zn8M_YD6=L5?}6Z{S=cA^+L zft_w6wcVX?9XhK*fiu-=Q-;%8v&P9u?^`PPjL|qJ;%ELRM1_<1mY+9}VaOSJ`sg5Q zubRCEN1{CCzj56+zI?^Ek=0QIf#0T>ELVO)mr{QOO47dtw$MEHsjqh7lD!cenu?t@(Qud8O5YwTX?cp*Zzt6Iw8ZtW55=jAy)C>F2^(T}aEYyD zx9t$3D=7?rBR0V--s(S_-MF!fBufgsRSQ5=wIsF;_0llyTr-^IX>-zfBi}jt zkWhF!tICvkx|?;gZ#l4}>#07^^fsMB-}+elJ}ptqaj|XyMx8hl=?L=+6Bj4qH^)xc z`SV!+eK>%vTofeFVHE<|=?fP1O9y=L>ipuLB2ETA=L@~x17yMB6swJ(Ull<<&Bo~r zD{XNjvLA?SA}{C^ix;nv9STB+yrD-d-W)7%a!t`OR=ZI6DIcf>(?rO))Cao143yqO zGFuD?{r*aZB+(nQTE^ma*nuh?lCU0v4`FP8pJt`0ng zkeaXmeYAdT;RA70RZpAKgf+`|RD=5nMh$YoCic)Kc*1@(TEI_ff&LZn24cZcY-Ru( zd_NrNuKMbI??yMwo^g~Gf-0OTJV^xF^(9p2;}p4%_` z_gcIUusstMAp8pTEtPi8UYhe|&Gt{Eom;$dlXj-EvFsD;^R*62YJId&YglUC`Q^N{ zlcrn2b;yAP# zkv_9~JI?E_LM@duKhd$)J%w5-XMX76{2Hq3y078Ag<2|S-oG_pD|OHOOre&_nV;!c z>%KxQl{4?@SnK{mEtNCx=veE4LM@duKhd$)gN0fuXWrJa*29HbDrcVG5jMV1sO56z zx0%qly-~9^Uj7gA9z)t;W0OOxc)RwVJg^cI0uZ>3*tRtwVE%4x%Y2b-`3`+0!BeuG z@!Rt6hG*yUo5)hab+YetOw_WV8M``14~dxFB^ut$mR08?)dPb83+L0((&qrY(3`U} zCmxyw<*a`injY0inh2W2X~E(n+Rw6`F%k`mdBMJThL7gEdUAuz z;5)X@P+MBI)4pkrbsl$V%&Ddbf(_q{{Zw{|8#RoddU|R-KFhl?yEA-}x^ZMsj{!rl zx{z^FLgo1tFV!9#>9wac(GiP!;ZTV^GdCD1G$f|uP*sqIHaH%%VWGxpLTov3lP&k{ zINwJ$LpYKe&d0fll77RyX0ql+F;zlj*KcA(wDpwT6BDUHftjMbn+v>~uPdwNDMZ*P z+kgJV&I{wF4J)-iTv%uXeo46vA%EQv3}I&W%;3IMP#H(?p)kp@L+-JSL+Oun}-2+e)^TtXv%6Qvs~ ztESq@Z$1}fMlzRTMwol{MufQ#5>%ymp&JjxdhyxAnaYHWSk!GQeLfX^Az_|Ko2o+^#~&;@4k)rM7wP$d5-r(g9~kF)s{C}MJ=e$f z1zmk)N<}$L6M0i)jbuQxsUnCssGgia`v)&jhlo>=!Vgcy+mC)L2CVhs#;Q;p2V<&=3Xf$kb2� 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%0D-@SpiU&uw05Gh5D+EU}Llow%djtg2 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

3>#z+6a0-{O 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
Vd;SQ`nfAx#ebU-WnO zIzVgPW2WUlTviJw+H0v|{ zwUgFQvJ20cKM*F53foCf0~VTPnb_n3>PtrZI(H`D0!2=$VSxxP-Yh*5Rco@0_p&5T z4lwP-J@K#}C&KYHAcS%%c~_4eK$w%VtEC1F=3YWCP;-!C>9C{)E{v1In-;G(zX7=J zp1OH!<~PgjM&PW_N%VTPh=JR!Q9+9c2mA*84sYZ8`%ao@X@c_S`gl&-Znk^ItGS!+ zPPzl3)6o#pGt!goE+W%2`+Y_*=mgeS37B%(f5X3-cm<(pHlDspxz#VMaV<3w%jCh^ znnyUzZz((_VVu^E<`w#nR_Ft@1*t7t5NGB}bmnd_?Z7aF^KCR)YN4!k32lvA4P`HOlGJ+Kojk~~` z74QkoqlX~WzAD5#Rh&?#{{upMxy8;~xK1syfSXcDQ$Zdq6jH+(gGh};>$P`PhVQyZ zcO9v_mL)0!%nI9I9?)gwy%0v$zMQNAFL7sDsj#E9P1T2+Qji3S08PCF;s88(0Pavz zFO*F|Pvopdt{-l!-f0XBp7dUek?E-MTHA6Wxr9qJ{m`iB5K_)c6e<^a0V%ULIK}fd z#S9@*NMsP@S%_ql%I8KE_$vn??Lw6+%0T195c>jFi3qZN2UO1D9`>C&;glyObVIVk z@S@6r+iZ?Yvz-fG^wHrn*0^1jZW+ip(BSo6c0mUlu~H6p(vH~?2 zVY;MCjFxJ33;z(|Tr6lVWL3*~$b6B0cB7{N0zl6HBpB1+ z7E^ctT}|>3?{!|(vqHp+=NEnftc<2*BO*Dc@RecwK-!By*g-q^M>Vyn}c^)am0k!bz&Dmer#+tNN`H&^}Es{N+wxJ@a3Rq@v=ju490 z|5{;h7Jxtm;^TI9#m}o$J_gFZQL#5G_D03ikn`>$WgSF5~Qu znqOJOveJQuc(m5t&nofQia%EKCu)@!YwDYXJgpjSIXoqs1d@y*Fy;fr=p0Tfo~0KC zSg;k<7NP((hA^N)0)4GkIUZANB9N~jdo+_zM;X1=SE1~WWDx?W2yVypOB7{g-JB>z zTQ8dwCz@W9=@$~KO^NGk4P(3_UNLUyWQdbn&?lvH0W5KP9&Qq27dYq{Y)Uvbha3|5 zxj2WF0>`e1D(A29ZCEpD;jwJkAP9vp2JEl_ z-COtj>)2kNZP?fRx-Os3?b0G;%)GwK@ogq^eOk1i)uQDfav{@B!IFX}q=Z9&;X$4-m--P_4EPD(~OJo9BCzC>JD!TS_dgdiGoW#DY| zsm7ZMZ1A>5Qua+sNpGRH&*18pQ#RrA&G#*2EyCqjaS8Db|%^s}T!#YBq(H>J}O>F3J_bYn+>R!8Q#L?~7 zy?$A*kITo(O(4buw(n1+KU|e|K->3e+um(k(C%d&f|*Y;)4sab^v>VM$+xAffa2v_I%sF=)WNFfr%_zCR=t{;(Kgb^_nQ>sC# zRJ~8KA}g~eqWnu%l(R4!M~??7T|?O#$lyd_S7mA~5hf9*@#{MQ-&iwecp^;$M3^X2 zT`XiA+5s8@Kp?l^W3=#b1ylQ{i!J>#Irwd}=rYk@#b7k3RMngf%4Kcj?W1=Sdzzw zTmJi!F&vrO3w`!{pZ%#XPQ!}wAE?b^62f_t2GFY_de}1T#1XS+!K*sN zKx9Y%GPfhL9xE_QJ(&bfVu>iAd;D;6a!5?HLkeG15W9y5cr@$%#JRTj_O{RVc2UKD zG0#q)7k^c;%OxeAG0)DLmo&W_EB4pz?AcLD%d}TV*_lP8NV-_Mtk)*J4-FXVox`JH zd-4#|Th_C}Yw&J}qDbe{JE+JzSWn(dL#v7Jm{Q~DND2OC?LB z@ay~SrhdDzKfkG;yb5(tgrB?#baXy5eqNj>MJU@I3zWhHDcS%jCjz@@<*g!<18Y>8 z@!Yo5^8I3%UNSo>eN8FZpd{YJ4ih_5kXz@9^u7F?r_U`(XyJImFX+e9W0|5i75(w& zQH*oJXuEL0FBt%fE*)?z+E?`Z)%|w&Scvs2IQ+-@v10+szT>!S31rcp)Gzyu^Qm^e z&RsW-eiO4bjcap{9wZB3EgjA$@p-5<)u(7y=Rhk*4!1!oML2elA-3#!b!?3~dz-rToFWrJ z9J*4syGQvww2eg=41*gWR5P*f>rvU37Rp9pdRKyAt%UK2&oLZ5UW)-jti>tCvDfw; z&x4O1FC!2SdvTD5A2HsJ)7kTe&mN#O+|$P=O?#t68UY_=47w6blt?C+aBPr3Cc`wN zo$%o>{UhOcg@kY|ul4zb>v?b&$p0Zyb|?i4ebefc)Btaa$nu`9`-jU6F}N<3rm>{Vz8YufJVzi z%a8`BZ2~hJ2tUj|ZKRU<7CEm4j07n?8h553Q951*I1t4M0nUf?e*b2`j*^7d)L z-P%!dq3aQ=3n2vRf<~=%iiHD-TAjeq#xwt9-v~d9orhA|mCQ9y9f+T%BH`bhk0e1W z5t_n6>r_dWYH}?x#C$K-sVa!WRq%&gqkGNoS3Lxy$dlXMCPTv?QlNwr_7X9JJ!|%g zDmg371rz=2DZOO5`w#3K63+_5ck5ohlXE_RyfM*srLE0)-H`j4l2FQ!ZbUZDH8}n@ z6>6>E1&;d{wvZO!s{0nPnH02d$nsFZq^hFseMOagG~mFpO0W|tWL}_JV7+)mM{{Q8 zC?c+?T7`+~#Rd?dMN?Md?g+;y+6s5tWMcSXkw6!f{I^9lfi9!63PoX+T7${U>@+Hr zx$0o?KN_&FlcZ;cIzw*?dJWZ|9KlQN^_RBk^g+LMLyoBJY9hYkPUEy?c zj$g!@O#KF}FV?AJqrYsCxzi$+zX9b_+DxAyC~SNWrxhF`qysM$46c9@F&_fTW3AHZ zJOhXUkBZ0NnBOW>)fcgMUTc1XjG1IZh_j0_FqLV7w6^E3Qx2-d-9@-l#sJbQ;?w3} z*5@>#SW$_e8U~kxu^ndzIdKORp&-e?sV0bG7b`+8U0EQ6r zWq$^8#K->9eK#vMdpSmI2j6 zDks8=>PQ2y%h(lWD6g?P&%T@Us!U=5@p4{l+ktHI5W~0MOB(=xo+d&JlfK((f(daa z(hEqaFRj^OHCv>km&Y*xFZ!fJgb_m%W=6$S3wTMCLY!ih@CrCiGt6ia$Hh2Dp=)g{ z`!IqnT~n+D-62p)_jQK@MVYENF9z&?+4t?rw%yi(7W}LIpi9(BnLtSDlG3?O%YaYa zVMfLXE4*5hFwb`y?1FPo2{*vFz{phV{um{Y5pe_v?GSl>mGD%i=hyA>R=ll+ZRLWN z9yuObik;Gb%%#VymO{ zscT>UI>`}g^NE(e#c;d2b2v-bm+I5YvV9-Cr@i%E=6Y|leT3&-_Fs0OsZ7s*`rhW8 z>sN)Drr(nJOW*bV|Je@wXW;wC?-DY>?U$%y83F@5fy=?E>^K|*#fzmjpAO9~*13)5aYtLR|%_EvS{CEH@#+9MLb5Eu!15D*WogFD)V-^%T?Mguz08x(nQG+N8o+ zxQFL)ajrl>0!xQ~PW41iCW2p4fsydKlcO!8_)vK_d`}^(=mFUbaAaK`-In4*`DY># z0b9?Jr3uyV!y-A*#G)5PsuQpO)G)!qssu@rzO8q?QfZ^~4lw|3B4v7sjFm(#GDpL`IZwTL zS-m+Ban4TJm9GcQvqR^_{pZ=jdA{~|@I20YI@+RncGx_7p+b-SYH<{N)^Aqg%N2X2 z;x8u;###QgsNDk!|}M8@sh9rhtL zd>8x8E}+|)c?XkLNaXx|17N+-z%Fur-7l&WcQa_`?PBNd60fM*HS=umU2TD&D6HCh z*KDetw9EfBO#Lazn(VYO{6r!fX{8aVr}GyTyE%~^Vi@ms64thnSef9Kz$XO~>;MzR z9$*WsaHYhsa{oV}+p$ej%1LY1C)2_d!SlTAN=Pk^l(hmxOmayLJZkRg-^7QUZYpUN@nd0~?T#dW5G_{M zre1tpOgVm#L&0LI`}Hd_VvssO^E&eC`g9+sLYFVvl`syQ?y%sKk4L9yJ~XR{F-XHG8{eZ`IO3mPp`bH;FD+6`R>F+6$Xs`;W{B`4aQqBXFPE0l`!ZmXhc|JYuv)NuRvzdr<(i{=(H&tq-G+bY(r&w<+pg_q zu$Ogr1}i-J6lqSns{Ct#ZNz)@I&rn~2JG7tkEN^u=`0&55P>i*{;2LjSJiciXQSw@ zjLQmATuM05j4^n^v#?+Q+p-#l+#`JEDNp4&(m4o(q2w7-Be>w- zfGQ>A&|-!5@!~eC%YVWPNye%SS;LPB6b#?}QD)U)->>RkyT`ziJ!-`~vu(&=5#!f{=iil{({4Q;h~n8!NFI zZjl)uhf=>?)X&6~ktT>MU^daD7$bH^K$#IY$PD#i1E;@HF%UBpvaUW;TY@v`Q{wsZ zu)Q~RtmMxsYG}2}5kFAGTlx^LUhA?)$QVUw*M9vOuWAt?{3;X4B1)#OL2`d_(9m;uSdm2qwSE<%*KBBTjX5YO_;2g1s+c3QWwDbYJDN_)NK zPcrX3`)l;bxfPoF2vUrk{sOc@gU6>r4yQ(bZdKF%TA%Gh()cJl1v%C4uA)3A3^=u~ zGqGp&_+hZqxTqZuYTLoeXe<22QFhZPx_=x|JFQq2;`<0&<@%6#3v(vpVU;jHg5uK5 z33eIuw>L{0UKB9Myf^m9R=AYd+ZoO9f^trU10p;EN>$L|_f0BcA41?)(@-L5T1$Eg zxWTWhe0P2(@V0iRw)*k^mm|q7T;Gpjboed>@ZM?p9hMEBk=gW43bXAaa{X9Vy@gVs z)T7P(iOe3)e063|GW$d&W~D*PpUdo7w0X7;!2E!qnfafz&d)SIiy$4C^R}sk#D+8{ zXM|L7oKyZtZqK0W=l&e-B|9xy^%hlpU+sRkK}R~CX=ghYTsv2#>w8*2p#?P``IoiV zBekNc^57jV!$a2o!L-3I*^83&57t8sVOz-&DJ?*`RQ*YY!LQSiThK>!*FafH%?4F( zeR15T1bTHCOeH7*RvbQ4PDXjY7%?&Bnetc}zP`MxoCZF}z|Np5jIYXI_s94Gietsk zk$LuHFr2fic3!GSa~_#m znXSsSDpuhd^*hK-s8Su)S62P5YCN=NhcFqPqw{%j4c>TZ?w6@}>(_{H5{@Eo3lNpZ za(^PXOKa4aec$o%bbk0~Pf!rTp3MCzk`=V&E1QU+thirZGrjYt$d)6d4o78}5K#%l z`>^?S77R&+SvQ4{HCHlSYhgfql4>leP^vu(R4p}!7m6%~nztVD{`n4r!T9S{IIX_pm*Blp>Ebi2CQr#$OYLiPK3Cnu!`RIk zx>+58ea(b5P*2W}Vi@1_C5q7E7>_hE=IY@xnL!jNbwDFhmxWE-Fz-{P89^U@((TBN z_u%s-mPl4m$wHgM&@28C+tLne_+si5*&B6#lX9^zRO;k$MFESaqwqXTDmDAAzgqJb zYyOhZfMU9Dis^`FTp^1nwnlk1dJ`J3wH=J9V@*f8pf&0TbS7OPl871HtSAPr^(SAq zXrnA73V&YA{*#I66+?D%N~$`c9?5zfu%6R~3U(+W zk#dr3l7EqHR?e7N);NtJB12juPy5%aU`k@ zN+CFoNOWSwBoe35XcSDL7{<-!x4chqD)E+M`RuhlsD?#tLCepq$Fu6TcP`(=FYCUd z-Z`TB)cw4=pNr|2f=g{9{*Wld6IFb7Do`N-7wkj~X0DUil2LyWD`lD_q(v~WgOyBy zXpp?OlJ#pz-0avBewK;44F-TOTHv(0`1%K z{aXH7GxE7*clY`|z47i|yC(A`Qj^yneShqWXwK!?n<&oM^7}eRzp=$Og-I;=sBDxB z5mldZ6eUPCU@3Y6r7#>ICbq^h1i(;Efm`LAIziy+yI5I@>A`L$;RQA(Tr3y)@VKbK zrE&eT&oAPWozdqj&=i?bg+ryM>WPFgaA$Q!+%OME$S24tFz)bXTr4d((I=%gsEUYe z7F%?4IY1sc5o{Ws&H7%olvv+Rh|ZO?XN7t;b&{@8HuJ0M@%6`%rgm9Xgw zPm~>ctJ~gATb{n#jcoFCw?Cuq9MofMgo=5c<|-Ky%*ftEO$v}vhU1)Ze>2|lA=rc! zY2|)$kDbzEC-*3|yl#j0_+sT%8NrMMH*yj%=gAS_agT3~!^m!3yj&|FC-%iaUAsWesU|TO^0ob~P zi?D_R$a8Z;!jq}BQU3_gd~ycC`TRBE2h%akpju-dswNm zrTaM>Z*n#7`$~+Ux+*EAz0`n~b#jIIsYqD1+#>IvwHM4O%~H0XKu*-G`i4_1`3xig z&Yl?N)`lXM`8c^Z+=@mkuWat4L zD?M6Y>9iZ3Q=7k3n^zY8>u5JbyFU7@$SHfoyZ5kr-rG?FS19^Emk#=^g|Hf}hNqX0 zO>~?`!;oZT(F#={TQXcE{oVdyxIZXDjHq}>1$gYCv=g?>K#DO==XlqM(~-}kd&4qV zM*M^N$d(;dtcxw%)XuEXky|SHG&{B8r&sK>isWH78z(-_?Y|sj^@SC`NMSTrRJiqi z3CmnGs87Vd5(}$-%2I>RiceJDVt*V)#Fk+iU7Zl}wO}o?1`82X5Ku8&DXJhT(|~sg0r(}=T5=ACHOS}4kIFBIBfxCH?se#%AtN^vh))56&;)8N?#Z;ny(6>s+Fd(0b7C3 zjmeJeGX|$e%&bYdoLU67!BEKS5By)b_}|Ezudr<*&!;)+!Nk8vVtuz}dgo7?-Fqu&lxk1*PtVrBPj42QFU5BB?@DO~&pkzD5y~80dQRxUXGN(CSPw|XKI;Tt2 zX_ie^E{O7|?|HbqVKd@s@=_w`tfPuSduO&!=6h#;VCDxX(e&IRJ5Tn}i;KucG>Qdb zUgTfArQt_56r6ut!!E%>B#VDJP7%V_)aXKr|Jyr7Tu|{B3;$E$dspIt70w|@6A@A- z$-k`6M|AlK6~eLMfdwV#@G_>cm8^))4=+9mRC2$H77;C_V7M|*5#ZH9m>sfIzzXwN<;RYBy51M%i22*%wm~?wI7j{h4-+mvF58<4@{R zIo6Z9STjQe>ni$Me=_Ei@>4TP1XeLi;1%V11te4;otyc;0lFdFkCjrupojRGDn3CG z4a4e8oAKd21Vb(FVr+uDdIPfiwl!OFICH|?!YwS~DZiObr?ns=RsUIyH&CA(AD)QgjUHS=xmTll%{MHScUWf zHh+yAvD9T{BhQ0cio1Pbk+M(hFap$>IHowS3r8X zcv(@&W&USs%6tMOdu5zSJ($x951|gQXtmZXMe1v%>bQOG{z>U;TY7@A0E;+NP@=4Od5Kfw+04Px6` zwms9HLyhPs4@d5Ho4|G2V+|V za&B1ugxIB9h+jfl2N*-#GdU=6n>%#mL6EKT6B$zoi^}HRpR!2mds9xGgiT{Kqodc( zs0dk$w%Q>%2zWLfRObsi%mzeAs?D$yL8{tOL{bH6M{ISH(^KG*3{+4QF8Z8(HuCBU z*J;w+NXX96Jj{BGI@+hfvg2|bs&&K&0pfy zh0XTuxhhqXpFKY8RPglpIsa@9XzBscwHxf)9xv4H#2oD#;Z-;mw0aJTwqHc-7X0y^ z3-Yvs8=3W&L}$)d#F|p=gPCEcY%-$gxY(f7W%)@@A^^Gk))fd56#ih26+z^^NwTq4;X~ATuw8z<2 zxCXOJ5`aZa6&}i##gu57l$@CmR76~XOnVG&j)(Ef@*mbpvL8Ts5UV}xaV&ia<4?A4<&4n z^=4&ub1cU|&>LgO6tk9IBv>#W&d$g;#D!0dMP`qE7IEdv8P56S6i@GnaNv`OTvgxc zyvPIJH;8=0=Y|b~Px7QnmE;<({}iI9j-Twf*=fHZL$s0lQ3uU3o?k*%cVxV(Q{q%1 zV5S!>>2pK9EO)Nqc)fuvMvLpz?Pi(HB;;oDkZzAghihd7u{N%ce;`m{P!NV`Hge@3)mWQ!C#6dz@?0%?zg4Dj?|RA%KNVaQ$oDLZtsVU_Y=q4rGs{vzVS{* zA#{H?yT!n&Cu)SCDhK+38VJ-)M75I_^mcAbsc?@0JlN7r+I|t*h2kjai<28f+>p^a&D#<0}NV)9J2N0B#*~;|ch;F~L9j|ROuQ#;)j8@sR|t8GN6!HLp2_O<5lDvD&vS$D7`A>+0%Tzv>QGw79Pk?~)0BN3NUVTcLtZAwrFfU>bG@5z!>24vOq7&-}8%c=4cJ zqGP;d&@UEXPECNJ@(krM&Zx!vtMT5dpnGrCpEi3=D+42XQPzZ)3*wi#eUYlhc&t|? zx@_Ojyl{3DFeD8u_di8dqI*HMZ)&;QvsHVp{CrifVa}vIN@N0!h2!mJ&HGKlfEx!@ zh7e6#rWJ7F(!reL1A{r0hH#rmi@jCXJwE7v8nh<|ZMD8VIjH5K**%mk3fUj)9~k&p zXa%Nih-VM{k~NV{CBXU{Xh2!@gM8nvvQC%m!Bg|~Wg-_*qEFBY*%OoX8QvnDUZQ46 zk68Sga`x`xh`}@?^hxnEFOc+hJyRxSUv{1Z6?G8Wn^h=~&3E zYRWt1iIbL`wFuXczK*hl&O@5A(yC!Zif=xYZE=`g3J4B!XRNR2U6SWk+HPT|=HF0p zL6-VFdV`B-8)H1dLYb0UqBR|x{6vj+v-l1ra#5HD;-zD>cNGNXdO7D)VPq{quw+fT zYE9-`%Nb&LUd`ek85p0~>--Pcesz|s*&88O($x}F!n6$7fcJ><^HDisyU|-lzbRsbOpmL{lSft#vx?Bo?YyDLd+OoEqhPg4k9|nQ5_M2 zC?_3Lm_J)(2~ElZwHlyuvQoC4;HphHV%Q7O5PV1^7M7M!Qj*dpW5ZtK!fHCsT!`Z! zmGIX_fu}|Q1*d~O%CdziK$=A_i)7MA&p|j+G>w2<3X^XH!?jsdX z>m3nBdc_uF!d_#`{n*m2LVt*VDI(|iXHZ!X*R^FceH#pWjUpE(3vVJ$sq3`OQvtT# z)z6Lr&+c`hOrX)10_X5GI?BPMAG{v*TG-T|% zR=?h(Z(NrwmN}?A;15}RK&w?KqdQ5{pv*H-wk(;gg-{;?Xel2}{D$ATOnv}{(y?xd zNVA;U6;?$TV|X=n!NXoX;ew(}9OD?vu;qnnV}HC+m^3l#@<3rjYMCH`Kv3t&W~Ug( zxXj>|e!6ZrjT`oAhu>+KSV+t+H;SA2l`MX{N{uBWDKoRSp}ks4%~4+gR00ojITJA{ z?8UkQpg0kb4gGU~CVlJrToDeH5PXL$+-%8$H|*qod$r$R?zbysZYP;?4VEeYhRucj z^AE~!&_E)POrg+)17~FlWWmXZBD?_aH0PBn4uKKR)`a@-lZIr&e*OgI_@5E)~4B<1w7A;N{p zi#B*LT>jJI#c_ArZTQN_)p}*KnVcSRc$G-!%(rZ}bnZ*Oo9_SHHp%U)L zu^TFOeZ_B}_L)bt=D%pD3rOK2(7teXfV#fsH`J(cT7fpKR|` z{62(l&A=7xcjXIfYy|4W4xCf>GwST_#HOIy8WdyedEz|?pV1$U9ODxaFND~uJz8qU zKS49jdcb{5PZ=@X(1`*wwvDXtD!B^2DlG*vA%p=vlDkm6fT^mWtt37RO&=~agy#k+ zyoUlsByk`wR8pZKc3FU5lZuCwq&ATC)JEysQgIwOa@;A*97q#V);EZ0;xttd%kBHp zxAI(XxQ^6x7N*w3PSgu#tP}xILWKgs+^%i-bq&9w5wC36wRO8eOyxoCg!Z<~6A&%Q zoGn|_@*UFR7qKa4O_B=n7`pa$Y+br5RlGtcCbLT>Da@>iId`X^n+6dn133l{Jgsym zi6XKGu>we&(Dz!OF>$b>L=NaM>Vuhl){_=P z>M;`_PD#m%nb@k@B!hm1*H@Voi3;GEEFCGEUv#sKbf2(Jn7OVpVam8pjw=#XK-qc&0tU>Gu;U_UN6j?5cY#T*sit?tCHOrrazQK1l_p4Ps`S~X*DAD z3t4Ms;?2V|lWh_=21VRIIR3*(Js*xAA}aDD)t02P`Ex*JAplb^(Wk2t?rTunbj~~#3C^^P% zCekE2J6^oh)*f7xz#_-Ltw06R{GYN&T0~}VwUqvGL(_3@dR*QBIe*!0E4qo5iI*ri zg$?O$!Nifwxn^@D8BNk7Bk`xDvu7<3bIR7Hz$6&3W}<>1M}ATwKv`7yWhcv{NNIF& zY=k~bR$uI&VnKb!_GsK{{u`_D$#@|FB*HGYeCL-y5(?I)9=oYW1{lUKjwOSC)lMDo zSOmjJrUm*0!%_EVBh6$ZmT70nmkU3zGnMf6s8N3OC_j8uTs+E-((X

06 zW(}>TwD!=C)7m39gkmqfwzQXD4(S($z0!`4H|?n=yKYl3H4S!g)vp*suAGrM2YDak zKdZ)zDsh4z(u!|4?ZF;`vx)jj=zCvDZ>hUlnMR+Y5S!BqGShFmqB^ zf-MT~I*$_}qj|(#ggUnnVBddTi2=h`kDI7rK?SKJ0aDZbxc))J% z!-T5FWe*Y`eLdwJ^|0S$e!g*tJMJF>F;5%fvKxjV zIygY+1@Ax-<*r-{OfaY;U(W0u!_35G=gMluD}e|ulU73d_P$?|#QnZARo(HvGpSD_ z&cvP~yh8sdk*4bYDXhirolIX(VbKiPwL^BpkX<;LF0Y*IzgRCWTF(w!&lj&}H+L?& zWXLWavdf0-3|(}?WHJqqojX6CHDqTF*@_`MK|fwLna7BlE6l;|wa!JWhwRBAduqsj ztBYQlOfuq=ouBR*vb%@uz9GAwpW>>?xb;;otde~>#mur`L>737Bx4XQO;XT3{gUc& zVs}arB@U{5C0+lM9G*w8;Ll6KZO-n6a zKyLEPQZ(vHlQL3Fs)VZ*Q7n`2QBwirim3<++NeYgXvtqZm0{jD)rVkE$LRAVQ{lPq zOySe_!J&oRYfJ#C*@OuM@~?ej*L99d(?K zd{oKIreviggcDdJMpa738U$6D6f{OQg*IV<8jTIRVl@AxPb$)pC^dZ!Z>v(vZ)9tD zsKCsOJw=vg*l$(4`oW0>@fe4A;%V;7+)nj)x-b-W7q`ux%(d|q*%-OeO27TA zu+_Oep8Fb%R$Qe&u>r6*+s)7RxXj~b_JC)<^Wp(*fWa>nqH@_o5C;(TeD0SPfPhT# zD?)d4Hh)%PWro(OnZsSHq3}qYQAz!KOUXW>`c8{ zH~dO9qwO|KFxZcgCL=!O_)==hUykuMkjU>;`8cZ3u|YfdOllV~VP2)KaDf4(0xYU{ zj}utbsSb`|LB{OJ&)`>)WWCs^h(e_`ECoIzo}K-(dRWz3jj3j^>W$`O@TkTzwvD1{ zyJqA}w1R3-u+pd)oR3OoTNXn~mTHv6?eH*xVvF+^L9r{9CH{dxy$tuI3Jzy>1W6;0*?;IOxH^a~?_xqiI@bNx5in?Q}rqF);Q>gZRIsv3>0 zhB1S^gA_<3G80|6!Y!=gpT%vJD=Yqa@u{L=zB*$Fxmlh*7rBxNGdsn{WQl! z=42mZpT<$N*d*e12!4#{TzX|-+{t7kNvt9bg_n?DdGZ4wI31==AqEQ3iZ(93GH-#o z9a_cnFBOyM7InJ=JC+O-R-T84xqo{!8c8byHOi4q&c(M$VUA6&NN zbURXo`hYGw82aE>RO1Cz$jQ2lt&{l!mOw%}Mn?(uO322p5>sU50B|JjFIA6NWj_wP zuEW#hY$GY2o`|w(LP((HCEd6cZr9S1>I_x`UtfSJ%J)W6YceU<)=C0$M3ay4x|*F^ z^9y9dBYLn_W@bjruxHf#tXe#|$)vE!w#M{E7Y4!X!pt5fgGUjTSFi_p(;jKsqs@rW zV2J$}WyMW3D#k>PDkNp_ty`K(hPp{kwXVj|1ZFcpPvCbO6Ip?^xs9h;CzYZ!eYA15+`=f3m<6F4icuy#x^ zP^hz0!cd%q&9+A@aKcd7mFTf}K-^@-(-1bQ2QKsD_ zCrG0JoSGc|!+pelSS*@mS&5mM6y(3yr-V(ix%O?pC2dVbir3ASrO$*{$Sf3d{mQEn z7El_4$CHDT+0BX(gY6$?zR0lEWJjk;`xRMK2u_kIxoQ7l3yt-xBgB#}RUr*>Ou?Gz zTBkpWbBWQ&2hh-xt%Oagn=-6#D-M<5N3KOfZ~2~3Ps-~PUFx=v*?%)KP}avLMXOJH z`9c`$E61WFL=0KQ})HSZ4BGt`*{x2tr!`p?+{)`oZc* z3#=)~h0Cip#9GEVF0q&ns)tZ$#oi{dLjieACEdiH!eqkblMvDoG(?{(EpgNw5Hb{L zkTQ>IfP{>HK!c`vnnexcF!DT?=yB<#>+%F3jGX)+fC!>0=E-`Sgdi-#*%z@Z5;qt# zTRn7EpAE4yv*^-OG2Ru4aBysz#I^ALA%QC0MwkoP zI~?(OQAJfVjSo^7YG+0JGnB?a`!CqG>BWlqZ(+Y2A3w1Fh+mGYEuItO&+>Rg9xnw7 zV63=@h%XXr0*MAl!WW{OM0MezQbsZ$2{hqh64}tGROkrXo3t*;E6SJ3;abwQ#h;R9 zWs`(%>6I!+N*m@B2by>~BOWbRZ@76P02ggR0WyN?O?>!WUvb&(*2LP7Hs z0g>g;KNNPa3^O}eo|cLxPTVA+RXBo2@{yz)8D|oX2|9!jc44#>f7!o@T!{Y~xvm@j z*JNeX?a(eiq|29d`H@{X(W*eEj#fI6p7gUcKa|LP>LT$*AemDp)f1W2aA%JS$hGq3 zPB$VxC0PE2e&8u5f#n0`h#UDP^h(Y%QiC>a zDjK&GXCz6egNmdet~YF24}^~;M#7D>vT3%v?N$V>)OdF^JcFzaF4iRl{Yt;8+;#S3 zwC9F@m8K*i;>l+oEiuoQRDKe{>-CgGtDg}mC3i8q5(y0i%fIeB(#p5|%aF~h zwEkCSw#@z1L=do&ZQ-Bc_gVfCp(Ef@p}{weTtv>kZvL7O>`;Q1Q{?piD3%$|q5`DI z$2MH!cCyY~llhjM*(IGR1K*?VhwvRS%~9AG7XxdUMKM7#g-8|SO}^1wDm#K1*Ffx5 zcf5vZ-6??3QKITf7UHE^7s)58t;#1M@l58vDNb$Q2t_94n~Fa*<}d-UoPy3oq%%k# zOh11_@hBYR(LCOz_f?vsa|sLaJ99f<@6^P_E5W==JH%{}5CANNny$5JL$Z?X213>! zHf3S5g~2jWBd0d-PxxB(zeHoo{u*r`LB2O-BEkIy6`@tR{A9EFlT8bo3ODMhqhJbn z(3PsIrg~F*v+^|i`;r(6nc_lFemGQvN1iLg#qX2@wh=U!NRou#f;fb|lVOpTJTx*5 z0jdmp?E+R|sr=}ysx*Y^i02n!g?>6)&n8U#+{`Y(u5NG0baJ2qHmJ)r=`~`k9eGx$ovg>(44q4yK?Q^m_sezImOP+utNNvGKm)d%YMqOKO*iv z64&!}9MxZC1exvV|6p6PX^v#8cE;ogh@zHJ_4Qc8)WE0t1vYMY{#$7%F0cr?t*D=ZpE2^y;EUQ@SU*ZtPSTJUiQ&lH)VbOEN0;b{uc9yhOqt?2>c zPdc52&2yNtB)~jvH=CQG}fys(|S%^ z0&}Oh@oN<*N&{=S6i^|{WvZJ-{I@JMSq_FlFOwpb*45@UYu%i82VVPy$xB1QvA#nH1Uuku|He!rj1&vmVK^338TnW5qolyUVlGp6NhP=q;H zJ%0ejSZLBmkD|<4Zja~2eu{shIGf_p+0j7z8vI^nTY@I33+1flx~)oVo0{Y6%JBAU znG|nM@_kiiHf)tY@?X(V^gl*BReO{YJaIPLgha!N`wm)0)FWOlY%iyb{!LsTIs2W6 z+;J>B6_t)&L}Q@N+GPcl^<=2%mnawbH_Tx1eu~j!U_gFqmmEuixxS@HUF5Vf_((bK zWl|F60L2VU;FpOuK{JAla%yUH1D{;VSJ@_f|A6SiQVhQDO;4pW4FY?GS6v`3rzim( zJ3ePLG4D;Bu88TX7)}&QqyJ!Gp(tIno&9>j(%7|@q-kw_={KlY6W{sugoMS%MZ8cA ztZp+9j<|#5f=6XHyc;Nx2t`ZM*tYRsxi54<_+sj}Qwl3V_)4)If=vWuran6*!i4+` zZJ&oZ6Mn=;W`~eVz5@IsGs7i;sU%au;2-%xS==XQhl@mOzs1re>qe_Vg}+!tgz^z| zI81MWoi^)~VIkR(OQU*`gdb)_`WR8wpkKMik;=4$ z&4VI1@CCSkh~oz}E9cn`%t{CH%!H+d@cx<5a?(6$xeU+1@VUNlr%2g}hE>ScXfGFX z9uf&*9-cA#gZaB=e>QtnTif`53anUwx9dRlA~BdfOQ8NL`sLAnk=Z=^uFpfp`*+_9 z^jnbuy|ZIHJ=1Tmq+Q5&W+ohhI~sIdA$q0SDUgB++d?SJL8uN;@#;pUIzvtL9LY7q zfbIAxc#2}DOMOqHf`i6Zqv8g;m3`~rJQFMim zdAJDX^D)XyBu#~do2RiG*CAm}44{vG+10I1LDjQ!zZK3Je^ZGiBDf!%+rA|Ul8VB}6Dz;G5-*iGzXJcweI}kR za$Zm+GKqm)QwGP1HJ3&`c81E@xQt;V*4HFoBoCh;okYvDigQB#lWGy3pfgw|Cei?P zVgN6L0YdZqyL^&2x)e6_*bZLkLXxb#y!>WFsN{WBbW(mXL-zWq(U-CJJR&GFNn-g#P_!#!uNE1L)2%!XD-3m{ z4n>AokeIM$T_PeeMskL0b0Vo%Gr45raI79zr({i8alVYurvq4qXCUrR!igcIA&vkP z*CvzwKA}RDt}s!lRHfpk0m>PhMvAkopkzq7PPXS6I0cyS+pVkfUhBM%>b#E*i`yl zdmYC=G54(6ahKic#t@tgMOu&0H+EFd-pyc&`(14j06 zjazsIcR2EkA}5m6PT@ZZxa=zj%XwH3#aNPlq6g`xf8?jH$_R$ulsZmlGkro@&0Bxx zoODR&1vHfX-T?WNM`@YfuGq#oOOzcCQjjLvnx_yI$=zUB!{KGK=m5oOSZLb zWy_I=U~A*-YHFskrH&-qsvVO|N8pGuc!F4iK+3do>6Z$E1@f>7jmd?G6WOx|m}XRM zrb=kV)hjm<*UF}tW? z11-J3nrErblXkYJ6T>De#mBusgW8OXM|oIEO~F|$;^2u4+@5i# z_eOYFT}#vwA^{PjA9vw2?(*_T8O$!br_0k3TrF_*Yq}?jj<>*kCOH8C`j#em&Xh1~ zYPbYVnhvnriRf?=^WC=gk28D`sKoaW_~m8$H-1+|iZ<()bsVU`qR~|C^O8bV`PeXv z9Z0|23{+}lP>Bvq#rJeV!^mIlhgygh$riCO{i@jQa)5NT$i1Sp6AQD(>o_rT!Cmz#LA^Z-iNSSH!wYxUSsRR9WhcSCglaMkz-ef;1e1!E#vf2 zYUj9v`r_g~M3nNvWIY#5w1&HAlObSR?q_T*Lj3*BHp3_{h4Ut>8lBSRTg(Wv*3%>; zYFE`xBTNqwXySlKT2L%>JK;a$8_l`V_IS6i?zZRqp<8SE#cfi{j>Q;xN3w`oATT<0 zX3H>Zov-+pD|(d#m4`tfA+UO+Chj=`CSpCy6wS_!INj(WxrsG@y~ctgB8l^agXkM{ zZvw>h*8@lrs|M_`9$%%(mM;&`nSDmtpLvf5YGZJwoBf-a?Ddr;t2h{mypTrNJ`}Ix z4>3@MU^2mhj*2(vg>xhE1Mvd!1^B~1fudEc&%NRoopb4(Jq<_MAu5MTQB)c~wwWE$ zv_(xjjBg0&M>UP4^kd31OPYRKQ~91xQTQ}jrl0AH6uUj8X@t<|o|Bp+B-nYB zUMat?km20fN;FK*sM$%E6A$1@FoR8$JG7rMRuN4S<(Fz@UF=ICGEQW+hParB`foNq zW*@EaBCi=A9b{#Ia+LC%UuO0_)Ui)O|2Dz^W8Xux`J}j?Z-eHuS)=W|16cl4dQ zI`5+{FhAd7Iu_~J2={5&=b4?0!6a?%d9FpyEl(R@BD6k~PJS|ejB2i2%71Jb!X{+n z|aUn z1cSBTG)#-9D)$3NY+4mbnqpPcT0K09h^ht1@9I*)$?mX5&6a=KQ#6-XV6nw-_&4jK zl(XAmHa};GM1HQvtu-=~VBH`}IT@EK&q)4*Zln%CC~ZO$tY8kU#aL<6U`}JCj42v3 z?8lN%5c?v_aE|X_U*bM#oInc4tvb$Z#LiuDb__^&64}aUeiQW8Wdu8LN$Ym=+aUUw zr$k*_U=aU6=QGpp!UK3-1q;l4idaw-O@+I%gdKY9!@7_6#b^ShTnm682=L|UoZK+H zDguR6oSrWM2r|jv7XDGjP^AizH0RBL0!0K7N)__})j`PD?q@P^iSbLWo1T$3Kh+>}=egw)WGT}?=nC3~8>Ax&C{Rt@CHrh%;PylVlm z9b}|#tL%O^>PV|vgFGuehf%a>xE(NbXBGA-W0|E5&ruChtGbY9(AjJ3OI*1wIqKv> zea=2x;g#{S&-EoV@z0V?B2*G1;1Bj+O^?wxVLOuwQ@J2*8F3}`fwWze|GtQ8l9WL; znTM(pH}v;-uC1hg)m5uTOqfK;Mwv48i%@P!=JzM@LPMcfjOPP%vJkCXmtiq0j0TxP zgG?(8D+uShN{<@NMDpI0ceToX8n)|t#n@YVGrZXuuYO+Zh2`+v?DQSt)3favVgG}( z6*!IzB$6qw#L?f^MET+0XL1vgb6yc3njN$#pTKsN)Ck_wPu`R3m(zxyI@^}b1`Jtt z+Uz(9B)ZZ3Cc@bWG?K?lBxEz+7zQ_B`K*=m;!gj;KE%BSnHib#2{^9Or%oY9r4BsY%I* z(I2+!4JQiTNAJL+kJ^EEbuT|=2NoXts3p?E=qalL5E1pa%L67X5ed+1Y0@>FlL@fd zCan9Gjg1t{iQ}4KIX~0CQMPyP`>-{W{ZWqi1$b_pa)ksh7m8xp8NHv93VtycXL4p2 zDrKOc0JxY8gTq`)AvKJF2$m!-@>uHfj3cE$kqp1h!4w*lf+yadBJ05vdVQYH4%^w* zaVxzd=A%OW{1g*_R$WN5-n!UoAoab$w=A4kAxID_IpEnm zQPhFBJCz~jomYI_?2mXh_(;dG%gYE5p@LYFopMC>m>l*C5VC6fk(1BTr*GRUBY<3? ztVX{P)o4adCH*DkJJ5{c|4F67MO@Sf;{^<2CQ`PR`fg#n`iPO$>Ayzhol)hyS9s-V zbZOjQV!WI9#(m)#Stcc-mVa#VV)0C~vv|IrX)(o3s58EPMn1?P7Squ=9%OcKIm*Le z2T6flZj{MbtHNS&Ih#0n#?fVOC^-8-DX|Z#@bW_ThB13Y)d}JNNT>vs^anV`CuO#f zzBE#qMfm&wQ)HRE!Qn!<%3|lU#)bk2KHSzy&_p) zIfz-2EU=u_Yp>OS?83SPeI8C`Uk&)KQMjIzS1A_oik?*P0z4G!*3*-;Uuh+qnIx}G zvhWmN(vJ+fd}KPtu#Z&4>$RaRC76K#>+1|vX1YmrXz}rAp|R-1Kgyw%;VlV*-C?^1 zJR>jn=w&hchAD89YJ1ut@VPn`WZ^pmF0pulGtqO|B32sFOWQ#+p`4bETI$3*vcTg+ zpOo>UN%r23v-9mYPTj?g1#yR~jf<rD6D z87_l>z!elxCIu0h3@R!b19n=_#6$y%V$v_M)A_ul`@P0l5fK$pabgk`1SjHvL;(>e zRGbwjR8-1)}0V}oiN)c1;C#BiaR=s_(BBS$@t6f%++0Lq5G|)U@zP4&Z`s306!1{ zg2)+VV-ujYL1@d#S^8SFmQ5701269%l zom35|aT&5~Vv5HO)d@S@KQY?w8cmA2Usu*~G2Y9{W)O&TLN)YmS_9V@Bz}(SWUVrW zv<4zky~)NThm|5ql?l8k#ItV6%f!e6l)NofMD(f{P{KEo4hb_&FO{&F71P8cL^K%R z@y*mhe|FBM{_m!puuv@k-p1q|5QB3WVL4x=JebTvr;K(@CI@|LN?NC;tX0;(oDDu= zeexlRe%yCTou6K3_gDKv+TfVD5G_+4XS{mmw|lqJnO_7rh5q0P%7o!BbhEAncx2Eu z_+lZMUoXzUbX`T!3v#<^eMLS{-iR=25Z>R;JD;EC?H-^~<9F8h3Y9EbU2SXCdBEUH zs_h1y6T3$GA7u)}ASvSy1R|jtEJBs-)0BrK%C^bWROTFkMqU^eR}5H`>qQK)fF6Yb zBWkcR*7x5pqu3=Vc0K)X&BynBqT9%pOD`RZ{< z*tdCm zR_iM&Mm>fdBLg?sZ;(_f1JrUYMrs}6F_Ru^hlXL<_s9X`FZtGM**ztm%q34X3O~@l z>H}K~#|?(rW*CTL&iX{9(zWp(N#b$m+0-6v^oJV38Nz29{h3CYt03)K5*nVYX4JP5 zT;4Wsw54tQrZ!Ie-<(DW-$iYFw#@SVp%2uSwsSPEXY2WU+xWT|Ey5yyq>XP-5uwR= z;4D3--lu6VUkoL}iW1oj!z9}&WKORUCB`2g%R|TpQd>=RVWa?J1js(}hCDS20=os~ zh?OWI4u~Q4&oNI4d*f)}(z*lMO!8b~Wpf&7<%eaSQG5hLeOUF-T(Y*U-Rrg%4o=xk zz~R15v|lN5+R-`Z_X{Z~SEu!+uC-uCh*SpFj)c7(PGF#j_*qCcq89t*`~*>@KDEqTWZ4y6{CqDVjc()jZ!KP6#0ixzMOokCaEXVV9Oe8X@f7L zyc1W*p};yP`hWp6lM@6&`E54%t&$NU-3qa&Kt{AHasWXsA5lsy>`;Od)bf|-FITy{ z1eFt|%dpBgLmsGntKeiL`)S0&T1kPKjKMLCuzt1uL%&?INYcTLO@338U*8lKH`$GC zi7BOfWO3uTI7PKOF6?06wf9py=o?2WK{sWz=lU_Wc+3w_o26rNe^#X%@bmVzc1K%y z%u7xFa+5#X6rPhg6buZnx3x|986c6Iy{T8SPHkQXpWngWi@(*|2W{Sb};9H582MKuDyK7x6|1-=fYv9sC)+fZPboAnok@_9$vw+Jo*(Ix?7* z9c?L}(A`@)(w;CIGbF(R)C;wb+lSfhL8xFiBag@igLxz!1hs3ML%T0@uBtDgs%im= zlhfmjPDY!nEFH9{AK{tXQOi2gbDQ$uY%UXwJC+ciBu3@3Fu82vn!S5KF3Igo3%fX_ zuMjeK^WMH|RbQ_33wv z`mm|qUXeJKeSVO`o_Ym|DNF-fCTys)#~^8F5n*$aza!{R-GSvGvh`$pQ0TS}_Ks#} zt!%W<>dGH&c}KgoBNKj8M}M^=^Lr{!@C=bEE8F>H?d%H7-{G!ywx*q}W^ySf+|i!w z=&L&VpWE4nc6e{V=N-aLJJ{tpi^~1HoX=NGs+u{sgHP|^XLJZ>63o-yX2iZSY4=+kId)_f*5P=5~b)KVsxy+OZH{1*}6M9l!WD}@B~$NtrxS;)qL*&2H0*CD%-6P z3oHc%>-Ed;5in@7Z9=c&E}?T(a#&6BekYcZtb772rZtTDBCslCewbv4aOctjdAqe@18bS)!t+4p?%Vi#lsatDwiiuP6)u%y=C?!tG< zKBRbW`*%{fNubj^cuIF&sg_paKmh>8h>$g#keJ9}3)tsicib=k9;S^7 z$)}Sncdl!@X!emo^{pr*TvPcy7#?TT&EnWq#+wiE_HSFH*fai^TvT zwN-J!@f4Iit^CzTP(~0+q>?-vDfhQs?H+lJSG8;T1aSbjKBb&>B=~yXL!1C zls!4ho*MN7r264eP8IS?I|q)-IxD#sjF1cOg{}bRTM7n(EtJRW;+wko^Ie?DLKIA2 z?QEZPCeVS;t>hs2$DM661=RtSgsoZ-fj1+syh@3E-`b59S9ha5%I|D!Z_g_WBDH7Q zD?o;1_!qi{%{ziuq%5$)8i>{Gip-f(A_2z$Q^ER5YjSN>QlVwF$)2u%9xF^()ppcY z<=2$~-B1-KOrd$gN9(hX2O)Xl%rSm$)dZpNrH>QQ9C><7m~m}+UL z61Yh4Oa+w`ps>m&Aq_-A8}=*4d2dgT(hBL-BGYmz@CoN1f_*YuX2}eOVvltQ8?g_F z#=OXZd8282Pko%)?4!6Wb1;yP|NU)8`;-Obt2>4VI@jq(0OH!f3V7z`U^3X(ggnGxU6j2>b5kg5rltzl}rO6-Y@ z5(23}f2SNBvQV_@=3}C@OkNc|NYmL+lM%{f6C;8EOI$)s%#yblwTMS@Q&0M{q`NQc z?n}EH$D;kY*>7u(6uvA^3=A9toVw2c7$Tv@$eMssa%Ge;X-JKw$wSc%#eI=Br{^`> zrOkFpvrVuy-EDPuW7;3@#()`jwO!lOm-VDs4O0+qK%wJpij2?&WEms^q>d;T%OZBn z&Y6W*+4niPFkK9Kuezi^d?&jC$X9mq*LLz(ce1y40z+^t^a!W+^e21yGrd?;OLp=b zc7ptT)yrS&h5EOXJs;0n z!26^6g}eD_`flg$Vl#H}dwSd2-ga+q&|+0@|EM>ZIeRxdzd6io<{0sOI=EsN zH-~Jhh556Z{dool$}R5=DN<3I2JfYL&e%J*#L3MJpG+A_Zxr{ShCzO40{8G0B6#I7 zO=Ve6UR{h)NylKhm8hjrmk2F+cQ>FYAKm%AY-TUxcww(-ZW9VAZ<>liStnRbEeZoQ zO?mXN%#@SMcmnOA0Xm_A-Y9Hp|@!e_YLwSJb?P~LP<&)e1MyI@(5=AAL zXQkT6)50+ZYS$#|`fwX~GSjAS$FCxr#^SE|%J1*{X%x}AqCOlBFN-so-yd5Gzf@*7 z6D8Yb{3>JrI-+-McWv7@36*oP5aQ8HHDU48AjKCBKT zY8y8(?08MpZ9i-U-q^ydP|I)-q+6U>#K_4iJta21cnKJw5K0T!++~TOLO~**W1#* zQFWM63fJ|78pPWc_Vgcf+x^^zQ2%x@yw<~BWdyYFat~k7Ct}sNeX#%J{8+6lya)1s zk!|BWSZto_RfJl#V4CDH`j0&VEmIOkHLFS{mRLsyy@mM#_Zq;t8l@YwL>EcwQ!YAk z31*pmA%>K-S0P|9I1QBV$ag`e$i86$&F|!Gi*2NZ9&-WHU4)_Jb|^xd#9|_iiby8C z0X7qvVZ6$(8Tw_*Ih$Pc1q|2UU(&j}#0GK8`qBBS^b6&`kM{|nB@Ce2mh|%*`eny( zZa<&ik3}`FAJctHKf9n0cfQ@n+d@}T`=GCF?Q0+PWkG+~mtnuv&$sjo-}Low`@-wB zXzuOD6m9MY+(;$1oAqr2-w142pz}34hg9*+7xrW6z0}t>^|e>j;){L#Jl%6cKWOxl z-F+F02K`MQ`RtD=7g@l18`S_apv7bzgo%r(<4;A&^oi++8X8(v09m_lXQngeqe30{ zrAjnl|`?%h+Neb2lU0I7c{0KPj{`UI4+Qtx8i%YEOW89kPyQp2Bw zZ2?*|R`NlS&th`L0AYF`Th%ALwYzQE9r_@wil(si=|1*h49mEsufNe%HnHV>aiA~h zV>gHZxUKGMw^3HpU+7~m>Pjb&wkGX`cRrGMW+c==Hdu?~2h*(fM=ev1u2cji@kXg{ zqIdd)CREhQz#1rtFqNLCAm6zo=osgT-<4m?DMDL&W4l#N-O$`61klo%tLvfq~%K>HUdgqR{66 zpEE#XvZn`tiEj>Ij86~nX9n<|^9R_41MC9*JY#_0GXR`;Mf=Wn3U@KNdk?yYiypj_Q1D=1 zTi-WF{nCE^Z9o64U--PAebd*b3b`|l4%(7Z8;bcs@XrECvpN!3!_Z#jD%+5I362i^ zZVo%tvgFei88R;RxWEyJ=;+RM*_G@l53tM%I%-+-Cz-5ED~YI(0j_T;%spjW1^(yslOJ!qU#B^TeIs7ua!EgvRTZjcPwc5w!KDxa z{%wlshdP^)v#+F<-?}IGw02L{%u#gp9=N^(xrR)vOUqYb`JLp^i=~r9_eqy2(ShW z3Y&te744p1kEbenp)j59YkwI;^N$X)rF$}fGY5j|R}SJe&+Va79K`m7bNBS=dx{;| zt(70Bt)ICFSL?!Jj8V{(GxqW`_aasM>AkdM_M*E^yu>4WamV}FH(k-9>TUl)VDhyC z8Nw$6QwR=2;N;f5eEDAK@5AMT_~B5$Vh~L{KiD@9_Wxtg?&TZzg2ZYC0ja@Z{a{pX zMYX&!*tZO}vj+RL!FJAI|5AIrSOy8SlUKmVAz8uUmXYZxHO3wdlYM1r5 zOHZ;TdznVTza@M5XMOC;KK6y^5hknY1O0_T{^B5idQf;~5O=&Z&^8U^w~WcW)5nlk z-mBbvi+;FSN&p*g4fGcW`qKl$GXwS1p0-I-sHc9!_q?qZWHx1xnWsmt6)@Kg@`>~t zTsYBh+rw|%!*AMyhi)HWDfA)v_+Cb$ozu@pj)6{j70*jt8K$wp{5!sLK)>5yCK&~0OkF;TA>DaTB#;7N_2M^rMw5xUPd-&U1X9hNSI`ZOcHKH zwT=|qSV^`q7-SbgE80hWa0+yMXr5q)+`gRs2;tP7{ipoEFov^3a))vJN%?S&|CAoV zaeR7|A6Zb&1G|%iWBixlSAJ|^Qka-K-jA~re6mgP6aCkAQtn^4=YNHhIsR+-gZ*3n zPY7q(4pRSN|8D=mLi|5I)%-s>g#YwY%}%kx>1L-H(E$8-hUL#TKg;}V3mgeSImb%V zK?1Us@-y{$fu*zbd9nFy<%ZY=KoR zGQTG7{Bn&2!dkA4+pv%AlZg%$GTutei>(9|g=+|Nk@qhK+Ls_NYw3Qi$ys})5BJq# z<>a)z{q((gFQ#+5udhA8^}c`&+}k*iNRR>=XVV>=l5fMf-o2@3|VYiF+foLt1J*CRNVWs*N`yfSrrnA}m;98S- zp&MfkxQaEz0YnW>zCo2y(QE3G!|IbSW23;DX!rOa5qSK1%pNU)0U2+Me7O(0{dWB# zdTc1g4@B#G+hs%P(_)!TDYd}y9AX;%x}lNG*4jLMn-lE1y-|O$-|6dZy1A=;wU2%p zia$Z(vJ#sVDU}9t6rzW>;yHUmrj>^LFJBsQ=mf_$mANsiN>#53#vJurf934By8PTQbD%7=lwbZ|4uO z3x_cBi-y=7KKaGB{L1gzRkz$W#Qr?Q?-*jY4>49zFTZ(+Egu2}ft3%jwL|R2;l6x0 zjkLG(hBLoc9B<$BvTu9Y@`7JI#THEocNS~~!F6`+6k9xnz_--yD`0@K_l7a6(}(lE z_lDTFLu_V$J8z25m}2MmM=6tPcG^C+YKq<2-|m3B@EmdW;k$k|Ro~8;V$-LDGp5*? zQ@r&!ZHlf>o8qVSXHDK%>CX$j?8X17KhI-48BTwe4F@$I?Prg{$7DVMIcNwqt(HiB z_O=9F##lFbidkqCs>C(05wsEaAy=0oKu{;7cdcI0Ep51faffrfd03RmZPOpw-x*&j zKqMMb@gO5AeWSJtC9XB|>`tLqrQ`(#r=`q!Uw}_)D_j(NGriSYVwK5EBVZ1CD#wP_ zhM2gQS`~d#tH!laobMM#+W~PA{}E4m1&^vAmD%FOJA_j~I(TLlRtU-Waj;_h6i&u_ zGc48<4awpWsAGb~v-{Y_eb5L0#QF6@ZN)zHL#|*dm<)r6zCSFm&A|vd{J;piQ=ey# zgbsc@!q$zT*AUZi$IgEH&UmwWA`CsPJKh{&H|*?7cJ^gEhow9F6Me(|k#qca2;mu8 zfLZ5Fv6VyV%<2(L^`;TT@$y>A!jIs!kBzVmdM&%UNXxd9uslOPq8H}?xB-DGSwM%B zB4yx2TNjj4Qawb8DbM1G`4+1!6MoiS<_}^RH3dASDS+BVC6fUuU$wjU;QpRWGD3(m z)vB;iPb@$MtjXIW>C0Io>E)u4GK`9cV09Oz;*l7_w95X8`?vG=NQ*K4>NGu&k<4P~ z!%7u>CdY3z$)_V(wWkgD(}(*v!~EM}RETL%qju3Sn?DTHd108%8D^L1=E53N|ksn)_;~eLd8k9f~dafniX3(Rv^}+}8~EyM~9A!}T2h+N! z2IUnVBj-nDuq{EPEkH@R9=e6DQUJFHPKNU`e*E{CUQS-ym$$z&+}|DUZwwD_4z~;X zDIjdqaJ#6VY#^@<_Ya2I=fmtX9W^3*XNbS6q=_$vgfE9={YR`4EFT?aOE3ieJut5u zZjbE?#&6o!rcrZR6!ag{yzim-ZNIW}dfJWqf-@WT1%v_@W=(J=*smlkSAn2=rWI}{ zdz5t0Oag(DWr&F(SLXh}F0jD7K}gQOZ7>JLnL_P(m{FJ?MsH$p73S)@;s*YaT2Pq! zzG0;8nzH+)0Wb)=ae!^^Z?E_F&Hd4H z3M9uwmxvPii@qDTBG7{6Ohz<=RU$hHb3xbz@RjPb+X22(@f-huSO|YrmC)5X5dXJ> zwjsV&IRXQs$Pb}=F4;Va?!7nC-yi93jSO3$GwBB-?86aUeS8G)+ByPMcztNtJT$Ui z_e+8Ra`y<;I{E>CTuMF6IBP+HcB=8hj$p0+AEuDui2Okd+3c;5tKxeN;_3JCidxaF zOIK4?Os4Gz@?E{J&)wHA+c(VF*RCFE^RstlSVGdZ-iOpn`hJw)GMrY0&&B)2_JvGv zYe8smW>qXk!yX|RppJYH+oMgIEZ+|*#(U`ixPK6l@lH_O_O1HTs~?h^#CX^#FMtEh%k2+eE`D|HlqvNHmnVSHw${ zn4s(E@zQ+QzvN5xT~G0q9KCn>s{MpERX%Y}_5c)7D*2&ECC7L9{%9JwaWvF*)o8nV zf4ca&x_IvXF>Ywf0ru7bKx6X(e(`9C=uMTDdUmH8_qSBzmfRoTr4`Yi|gk^{pH2SRji9c{};>$q+- z{min=RKsp3n!0net<+WRekOvcC=PT#t#go+H)T`>>j0tR6m&?|W0lD|AYA9A@?sQ{ zw|TKYJ=&fbo%`Ep`<&ueUYou*+TI^c#)3kzP{+a7NTOJcnfaeVN^;62pO0bXy)oL} zq$_G1aRnllxl={1BCh3#38D7u_oL#N${B~yqsPXGlaHals}BO(CfNFexGKNU(t{$- zO&eq9jA8I+j`7>aFi+2LFTWB`&wwhJ*ISrZgm=g4%o==jxvJNHhkv;W{*ep;Ss*KU zhZgj!$U$8BVF{>kNH|n{^dCtWt^GZU(Go0IE3C_aG3z;0Stf(=Mekk5W9A`B(_fu@#buj7>PU`fCB1w!J&55p?1wa6r%M-hkAFr=dkeFVRp`; z*6eQ|g81>uA+|}2QlrY-Uk~-S5B1j%4Vw?;I{_;wsP~TXbz`7~XB}$O54C51VjF)F z;e3}Uh(Sl>k$(zOiiJ9=Vk)tylJG@pr0fKZQs@!^kQkB>T(kVes*1Mag|@N=L=<7W zOp-VQx{F9FVIqWm6iG-`wE-khqI?OnC+$w|wpGPW$zh$7PzE zWCnUE7i)=$RxX;tZzLNW$6QtBM~hx^faqct#w6J%yO!yR+rGn_Faro5L=dugk$m#$ zSX(es3eVOb+chIK5nF#uUj)m%KhVYQ?_wNV3XR#aAM@4kk)5d<+`P_K|5%=fC%f1a zS==ON9+q{sC7tbt&i28Hw)I5&=tTSEMF03i`}9Qnn~u=@YdhO@|M>T-N#M87#zHdA z9_P!t_!%eJ*(U+08@u=o+rANWhZ|=stNiP+elULDnSzFM@xb#Qzr$J z4I*3PCNf@F`3)?{)KX+5N#fZP+pe~O=;HE@TU$}4%bS@U%XKFOim+@&bMAW}j55MF z<~EM-lYlaimfo&85((D#VzPc5tvB1btWGH*Vz`Mu<{RN^KfP- zJFSzQ-s!(Vx)?V64}bq`2T1H8`dO3tF z%3cy|56&h>=qXffAt8}@eD7LjerjMDrOCnxkO_9}KC3o;_@}Juus}t0zGf@w!Vkmv z(O>x&HU50O_p&Dc^dH{okN(R3MsWkb@uzmvPbC+{A(M;90+#V<-gsXK7;JZ#*kBbW z7Oj+536>q%TU_of0G2}$k_Kh2jR4yY_&}hBfT*ShB7xK7r^RHWevGv)^oi_?c!!9W zj?b+0*#gfeTPE=H#p7-Ec!qo#2VOgCJi4$5=dBaKp|umZbkPLx6JhT+BAWceCjY33 zpW*8^m(7uE?{HtcAm^RjVqMuOyTs9m2J9oD&%h5nWHOAjBl^BQ)pbaUwB2A^JLl_F zgt&o7vrH&d_oae^-jH)9qk?Ezi3NaPu7#S)!maHvpgxtPJZoP>NKqP6o%T4{k?267 zPBVbrDHl1N^@ectERlf1f-q`=^<{FiN;)e1w`Yn|BkhgAR1TQ`6fu;qrp%ID9i%Mf z_d-~z4ucSWTEcPk0#v%60j+A9I^#$`^GN@0LYR7_oiV}A)+z#Ql5Hze8L$u$ketjj z0qeRP8Z80b)Y$ns4hxFpV1#Z=ubE(rCK$(NJ99$TAWs4&RfVkwlyUl_Il2UbtyZ}>T_Jb$EbJkp;$GCXypJwL%-q~rdV z33j(WV-;2<1<6_qWzXnU%Lv4A8HL)CjGzVCm~7T49-m+vCxqK4*lmy-{1|VkU5q-a zfuP;osQ{C83&277)IGOuxOpo|Y_`~wGmoZ!_x~J(e@;EsB3b%#5PrQX5Mcvr(R#9& z-#{Cy*o->5S__Ex8RdvVqX5kn@d*AZ0emSja}|4gd|{Td(vZ=cS(*?XkT-*|0@#6&5RK)u=r?uR&9QIbf~ijb++Z`KmahJ zA?b_1;QQQPfJWbuDXw%|}nt zcm2}t{-sv7^jioR|FNrMJd4LF$alf+o5-j)PxQWF7r*Qnn|q8#EQ^=!&+bmshIfv! z_m9Cvr?AT%?XpQcbH^mGoj^C-zrhdT0m8+|L2g@hN)$sDvyD+6q{U^+ zC1dB(pxKS;IL7_hBw)B{5~BAlCP&f@_CGk@DG8U|d5=ce*&mu@59;jgNrVF2sIx~W z!HX!|n|?9Lznm2L$S^JXAuWquXeo}ZaY?@wPHJC?-gm2Lq-b@Jlzypg5EF%KdsF5t?7QJU!5 zg2$bKh-{o<3x#Go!Rb{s{+f8#B?X(EQ3H^vfNMNS+7QMfmVnNjy)7!616JnFBm`q!h8IA(=KzbHKOJi;#6ValqX+hK{FY=%S0J~;#Sj4mb)+F09$=;ge zTPD%WNZa4AZE)O=<0$))?{Cjew2c$(`HA-8L_2G;Pn!&UK{s%8pcX1~MEbt!)=<JS?YEjeXLGqpJ3liv@<8g!Jje7rcGiI zyfWF}oeb2p8~h*X+yCaw?f=^U@&C>I-Zk0po=jZKDN=ZuCaUugLtX8vG=!alJLxjh zM$cFp+j>P0l{%CYFcnV|l1EPv>OhqWcH?n=%W+J)1aMesZSvs>tXEMaVT9~e(Jv;+ zihp9;;wTvkEjy7*`@qB$HF3f5cJ}dh*6}v&c%IW^F}kWG9}Bja3PwTG>i5k|x-I!z z8A?`S88Ys}8?@{y;l2r>12{(fuH$XR@pMYt5@EoRvyB!~IVCW0S z`^(4MOR=E(xl>q}1j9^?dv5*r!7!(iSb8EWkHD27K)0H_QEU?8&ebd}O?L)VhOC$Y z1%@%sOfOWQwp)bST9zdz^`QUoY_I~D7E(rwB`dTH5c5;AX-X8mzdPPepKPa1wlgR5 z7B*ylg9yXPT4uKgiv{haKeFj^2U~;W;y?i6QyJr0vPIMXf$pqhW3VZtwQQKeq)<*> zB(=%AYnC-o8iyWJ*RXXF%9=nnfCefbkUqB`Xr27em>4xikLqU}S+ejX;8pZ{Ci|+% z{>Wt8Fd0Qa3dXCGZS!PsD+?Ua3-WPf|IeKy%YpX{GawzH>%^C~-a{=f9-&zKS}cV5;HJWv#N+0Hn@ zt~-vtXOKuY^BG7U#az}yA8LgJsOR>ZYTDUM%RU_TVK zLUH`EpX9xAc?}P z4)*#9zWD@N{P+a_jXoM)2kD?6cq5=fC6Ev-lMfShTNyXJ7n|U$AL> z^Scn;bpFimLU+buc9JL^yF=*Sh|R+22L9^!D;5#;WFA-JLU(cS5_Gw}9L`m_n1G1i z)$>tgsj9}oRw^WGESwj2LvA^S8QZRKp2q9>WR>P*F=g`D4aEIgwnHM;mX{&yT@V^&0`ycWORkp^q=IH)e5?^l)FAk^@1Z|cw|awSv0 zLsqRj{aQZHEk&*RixJL zjLM$UK&y2ee@I@`i`&^*IkrF{hkzCITpFHDZKJetY?1=UD|vq{PbvHbIUi`+1c*JD zZ7RjrT$`u?N}#P~E}=v%)HU^+6qnErREc|mQLUD-(N}?BXNYL5=SOhu9>M}jnrNMB zntIullozviRo+~y-fdLag(F@BJ0))yvU_P^Hx^9;Vuwoisis~?hv-Iiib{680dMg| zIiIDS*i@F)1O$Y}CNN%GRS-WGdguFKScucYQ}I#loYGqRTzjP`bTy+ZROXabo$8!~ zN!DU)t3xy5UzbL-=>E;#J?0=m!LD+@TKjXnY^6bAud2#)N1%CGX`c0D7iBSR+H!`)ADI~Ckho2Sy6L^@fb(O`wkNT3Li?UL!z zGlo-he7RBlC>>(&>odC+l6`qt{b|g*tuT6{!C-Ie#Dp*tsuP<+F~QYrl#-+sBu_TkGF*Jr0|aq69RwEd6Ca_d^({zAx+DDBegu)(@;CGJ*(CGsLq~D{V6s@@`?wNk zD&`lmz4n$D{bH4vh^v^@PQIsvga~*#7lUwilDNYvkZa+##?Fs@ISt^@UF;Z*rgPebx^KWti$7wVu%cv}Nmi_5mfAxyKvPBvi zHC8Dx$X(i8hQgjqoT!if%KU3N&qY&uy&t5BMib=89a+M=(w&*mf(tEwbofR2X#Yhq zxhiixXkE8_&93MEM}Q|x*1vgqhwHG7yt=`h3Ce;qvbU^rAQ`|ZgF_-qbA1X8cO=v1 z@|bVK#&r?YX*|}(>mi{im3SFzOWZQ%%RyCGY6p3k82hk+W>RW$`ZWp4$mo zTZ>Nx0Cw}8NzgT$B3`F}8#eUh*hoMqm25f!df|g!Cw#A!KmnvAJIa16MDCIxZM~@x zV25q=WF^rBvpl?F_KQGgo}_xUK3_54q|gQEnG@q$4A&OncT+K3`2zNDqF_<#Jpi@j zK(LVRBSUG1IP&H^ZKhC>;r^6`%4d3tS7^tnSe&xo_{=5q>2Q$6>GzECK*+$KK$2;} z&SGmt>T(9^U3K!`TNh0xhC70yqjW;_-a8TuGBw#qu_W;a_;*^^z7`FnlS>Lmba!WQW_Y&G6=Ax zE2mfpEdaNXaWdZ~D?G8tb95E*+7ShVn%yD!T+pN;(bYS|%xC8OJcUA zxV>inlEu*fFN1#;@^$v2`SYaJA&`aZ!}c(U&OF!XflDK*8#7S(R!GEj6|d=y1Co>y7e*t&ELqZJfdQ2g_OjLMGr3Zw z$Pv)_VQ<7f35AW?TSJ~dloR^#b8bxSX!VD_#sBzK-$biK|7c1$%db*|Rf+(U7;RQ&4(IgmV3KK2I3X(_rsX5x%rU6F1iEYgi^5^5w+Aggks%{P0{woZ*`#ko`mOq3`j+YBlzPTlIrA?s!RK*^Z?O9 z+%lY(cS~+7XexMK!_aeaN@$yX#EH0+O4FI(<@f)`+t6_OA={0`h&TmRfbvQ)MwYEQQRnk;e~Z|F zOW;+kD5KKf5P8`ac|q0=WVUZI*5a-t`DSF4&Yb7HGa;Cvp?fZ&T;p>&dpc)#!#8t( zDTEh{b*o*QE=jdpHrjHypUvLT2U!`42PlzfQ}C4q$RgUge0p7Bb~GpUCv`+~pT!~5 zt7L5G%eotZZ--k7Iw7 zE-PeQOvdJ7D@MApUR#Xc^2vJk)Zi(!Il>+Z5lDSL)mj6^q5-$u(A9QIO541fa9G+d zP<@AwjMUO)#Id-YOeH+vw;d{duTSF}1hG_`$*RKN^=j!BA^Kf<-+G;q`2-N&3bsYE zUru$mDg%(YxdM_X#`zzUvF&4{&cp=%vRCB0hvs~A1Ira`UFzdK5rFj?ZWwMON_3+> zna|$TU|uZmW_#HJcFv5;iXjAt0?8;aUweMMK)40FUHkkdo7WULUMZEb!2aJ1;7th| zk{@pnL5vIMF%G*Ib1>%}`A#Y9ct$ZkLsltsZH}&PIFHL=!&?y>ux#~88+`_!1m^)1qKn_d@ zpXChlhj7D^`dq_n$2Mm^GZ(&L-^HBvW?B~f6Z1dFK%tqtN*|AFtAp1HAlA*=>fkBG z{O?BXXZNc@xSysq7tp$kb>AW`+uyV$1osW+H*Q!*YBWzjn71e3^Lcwzh8Gzhe#{)0 zK!p!N^U#J=nXYKbyA-PmIOIe>>x)dQ#iWh zRMW3SQ{~J7+srRJrQ{zLNX>KplwG#L1}9@{umXyO8K0qYUajvaZnen+5@9I>tC&oY zTR{4klC3I9;QS2Glq*tCM5Q-EM5NplK-G%nel z6ltmnr3Gd-JFm`IWKNdRnLa2PyH~Q9@gi%A2zSPWL2^gL?_W}r3(-JkgS?$9Dok7K z4ndV$|ElOzopOIihs!-6XkFuB5n(%G03!Ti)DX?KdNnDiY>tB6OJrPsP|KZ?ugm_H zhb?X#-L`o8k!v&bcl51fpW>#^&e${c1D$P^K2Ec79GPUwdV}9{l;J3v4360|8C%U7 z>Jo7~(voBYzy-j{m_<4ZtE>HnYEZMQxNwnCqOu(Rkc=&`km|&JkhXUj;|I&Ww7a%ZBwUdN zbvuQ{)DcMnN*MMV3@>uCy<~p3`B!E8x@-%|__Bdce>m71mSVr0Rp}$b^I5TwHcM$? z4glFwLFS5_Uz4-zayE~MAYGU%iq*~@R55$b%ug%Z>1A1ckztKu4;LAdEWg~!K>QgC z_e<#Glqn`mt%!ulm)Vktd&bCRvp>jAu#fj(VIjsAXjFB6B-znyWsfvAx#K#3k$tW# zA|}f}8!zTknHFnC=xVBL zz~Q@#?DBhW!C8A(#MYV$+9J)1-GO=&_d1`2WJVoQz|Cd5rJO@q0}bwUn7(g_y1=7s z-JTEG{z@}*b`ez@G%YURW&)gQPVQ*;mczQT-B*rzhwHR8LSIsi8C!eyFJoqj31Zod z#gZsP;fwvl3;h}ISHZT5jcENK*MMBQOU>^JpD)4;a``Uwe+V$Vi(LY0sL7+C3{IBn zYZZhL{`eNq0j_7}&_bk(q@AkxdPeZG*=d5H08j5K+udb<784Vug-G*&A~@Rxvua!H zeeKB6$(PDi#Zs}VrqmvkXvbdBxftielzX{7)DX0ZqLd^MK$Z%_vxyC*8gxE%816{R zyDJWzsqI~vRHA`7Yoc+U%5`Ugn+Wni>*-WT#!_j5Tw%g=>zLIomV3)=i-osP3}0*j zR#!J5vn-@!8aqw;T(%9=<|v9C1*Y8N)~zQ}P-Qj6&p6vDa#mq@F8QPZ;h@^iueU4e z?cO?8%@y_DE?iS*i|PH0Ggm?(Zk*k} zAAN7dt_Ev&y} z(lv56x4uU_n1fy!}#qSDs9Ju{!Xj&C>uZ1ZR^>(d&M3O?Sf5es~ekrmw zvvgO{r`OpzbvCU|TarT-mg3`SZE8u;Z_tfseMN5JMi$jg@loJV!r;$;wBCenM{u4X zNZ+ZE7*|zhn)==ftB;lyFBe%yXje+46QPI%G!RNj#T>5I=4Do06_y(iPT2vi1y&iv zauHUc1(HA>7;y7vp=^@44x3IO+&g1uPPGI{SQma*FA*4yRvc7jc|+4c5Ooo%i2kLrAD9jJMp z9LmDtt@ZX+y=|#CTw>?r*zjg9vOrm;D}^A6UhizrDrh|`aJIbOZe(W`J>bulZGN4d zRmVQRepa2Ity>r9RwUi9I@p?^5Z089h3>7fwKX1(oHNyHYV463d$h*mk#mq~eGQT2 z_GyjBBj?=rNsXOWYp2(GJaW!`iwnXq(1Z{y$aE8#A23<|VXO!wJ5$=R8jD1}#CfBa zWne^ghW2P-0=f|Ww$K`pX}N}TP#`E2zs3DsurN^OgBr&XjTjD@;2=`PQ&hlPRut*R zTPDI?tBoxn+HfZ-Whpw3WPLtsD;ye_bdnR3#XgjPpWBRRhd+AjMf(cFRmLMEXJGLt$LojIBUuK$+AFHKBHN@O z(Eb)PSjW5O?{I&lY;EYUfTDfnus6~ofp#PW5P6*oomvLHr?f~E(fE3*xC=jR z;vAfg=VLo@SLftwzM>5ZS>y(nsl@};Q3_Jg;kp2uee~2@{b9`HB!8ZV8D4!cB$1o& zh#&!Aw~=2)W}N~JcSx>~1R%Y=jgKa#S#c)HgrayA1Xp^9_AIAQWB1_pJ(F9o;P60O z+NkAI^#;U?c`5%;7nt@=d@s`p^kAq3)dDJKzXH&r)k1e^Y&G1Mr(^BY&a|&BJeOf_ zTcZZ|LEktCc@ENz#Tf^`HVftYEv|h`x%)$W(aAwOzH8d(sK0)%XS*{)_cIV<9`LU&>epI6!WWm{hDw-TidZ)yk3 zdjPpF%l1|o1OEGEd#7ygmi?WwZ!MD$3S6%e7rG1x5KykwDoZM+3D2ifAtOKv$d#aW zZCF;r`R#nOvn@Tu4znNoh2`(RZv?$Kwcbvt=NL|@_k)E(s8J+q#ace3;Cou=Rz&)j zLRH7S(mtv?mfKQh?-%g0Di}Mk=&I2g(`?CQLbVkdu$-~PLVGgz*pHHlNZTd{H6_mo zEb{8tfp*%`o_1NGmHn16LrSv+t$AXq_f8IKY=c0Dm+}$gnHA=DA~4Mnc)87p6G3cC z9i#5ILXD(`-LaDS$Y7@Zr-yYEMw9sWwc0} zsDf#skq6aY>e$ZiD%i?`-(Ijg3LeibJHNdU?kI51R`PAZssqt?^~{03fBZa{r>Pf^ z!v}>>TLT7+ihMTGLK_$67wpz(_j3GNw-yv6#&?3_@hho;Hf@B&$RSY7_Uz+{fQtS_ zJdlbI(BLlhXah3D8?-!tE0olOS>fp<=-@a zgBI9V4Pd6IWG@3(oFI~Hn5N8P0GZl3IcVpE{i#orSB#o_6iSuyye99fWhSSfa~j?@ zLpG|Y6S3ip>c`F@Jqhk?ZyBN$QBgYL?3?gABnO2t;b7;li0Wu#@&`9C>HYa`{H4!W z`m|Iwf7(LjcZf>cNiFBex1tyggrbCvk~7#g*8SyN*wyw5-R-WN!Za=b&lu2REO_qq z;o+$EJRn=lBdr?HZMpDjwZB&Fcjl0##G_Z{?4H)2@6P#OGQDIg0twUM|AzO5l{QH> zBJO^QJt11}-XMK650t{@yuHrbeY5uAd!-sXJR#hI_p2zqwi1@9-#^J~!%+3{6R4d% zR^uCL!a!BC!ZJjH2;q*|Tb6T|-5FmfG+C4f1*!}8ZM-J%7A(D!;Gfb0MSbovY9?L+>jW02}pKcMHiuwUB3n zOgAJm8|;GA;NTo*$-Y~QC8Ox`G+kI;=gG=|j0-QsM2(n9FHkH|NlZ^Hq;k(h_o{1SujgY0X z-qIqV3AyB;>f~{!_S{Y|})qv(sV!r%L;?_6B?-FKG ztk*y!{4=<8JYCU0qF5M=1~dwPHf9_@f~(awk>hw&)<5vXhFl=(>}@RDHl^}vM)K)QhN>Gm7mL2ypXUA3(P z%Ey$<5S`{X=*|ujlhL+%$NmlG2!$sbm$$JH!qvDsA`_4kik`AEB)qn;6;=V90H=zo zVJS$sTVq1--4faO(s&F@EZ~7iCeZTRF6$?g<^GbU`ZW(P!RJxbnH`}Of+Vv-NLMl{ zD6^NvNl^Q6?oHOB?)y<#IF9mvX3J!{c%dGRJTWumsK)>v_8pSvaE}nji{o1xX=C2| zMvmJnC+aqkK-T{59fFf7!%osSQ$1s2)ado5n#?Q*sOwGR0x+UDvEG8epV&5g6vf70H0o74ZMyyIh)V#!>hUi zr?m3ff}`2Hy|yO8&k2yn%c1Ve4S#*n7bB>Rx~8s%Zh%5lrn5MQ>m#{@TtXcUQF4!xZsx-(rN^plkE^YwAf?=kc}@Y*{l*r zpT%zPP;E~i%Mp7AHj*GnGG56~DcPxP1z7R7RF~Ol?A$Y1zdXk6LWQlteANgy>J+n<_j=uNFiPNk-Y&@DnV?KM8#1$=WJJ zc%|{!6o1SAg!)@mc48p8#!f}f3{x2fP)z;yyxoz*CG~9Bd0)xaQO~*L>!izlTcB!5RBk9=$YgJJ~5U zHoeBqt??O{nwg;ZA1gqpA{BF24I{0*hbg@h7{Xne57d-w ztfgqjk{w=<@Jd-Xuj>p`E{F}bj5gGgbx;dOy1mBls4xYEK01m2otE8AFWP*KRcx7J^*1C8MgohZ;@ECv{A85606S|H-+vHmlYys`Xj5;2HgiL}W`HTt}P!W~)y-0raxd zb73ACgUlY0Qp`G}5i?#~SQ)SNLJi`X_|S(oDH&Cc?+vv=(-vqqW_+R2qY~f5gRAuk z<9U=)3K%9DfwPJ#5O`2;%j#`uec-5Iu5ar7Ta3Tq&U(AM-u_bWch`e)Fh3TgLb#j| z>~T2aA8%mdHa9q)r5hS-NrNM!wiUA4lMOKtawD!Mh@qaqnk*_Bu4|;G!bk#mM%o=z zyJCH^MGODR63G;4B;rULtx1)Q;;xcLagKSJ+--ih8Zw?V%T1*YfWBqecx70rN~F6` zwmMXs2E%>zaf5%|;9s#BbpvIn!q>RKz+P&3Kvg1K!5`jzIK{J8~ZaigI$ zUEJuGHZuNi8vI+bFMxxZ0Up~LQordB3|YcXJceYQy#43Ni*!{R-l)=!r^t&mzYYBW z+>jr|@yxVd36a=mEB-;W7{jGff5Gl3(gDaUio1ZxBV0nD9ns3buU(3}s7r*IP+~6O z5To`^R;U$G7PUj%C=(6JiY6wC@PdX6>1R?igRW_n zvyWsOd$Wzb(Z=7TlXhiecFW2pyS~Y9XbMZ3?1rXD@-&hzltdPxV;fIk$bOQNAmRiO z@0P7l7MCV0CiNr8;&=O&w{wNwj_sR_%I2g{!IKWjOpqFQQU;k|Nk>kCJ)jy~$ljOicnmwPl7q#FnaWW(D9bo5X)x2J?Uxo*Y z{tiWgeOeXn+gyxENQp$p8W9H$6M-K`#-T_mW>r3FWaFxqPE4?gJ_!@+aGwxl+9d2m zHg|%cqkd!eODue|81X)r95ko60Gnv5N~1U! z!_uTe^1h6NV(Yp`J%aWVVYH$w|28L*HM4F8wn)`~Sj;rH6+O*yuWPOZ>4`aZL<#XPP41}0 z`fx@`TkOSSdRn!LKKSX?A)dXcMQ~>x+_^>0G$~Zj3U!*dWWH}Ce67Ql4boEHRZ3=~ zmI+F6ND>?Pr$yPIUdLHxo3n^FGtiF1lS&DDn~G0JBb*ZhP3kJS0Lo>71V|oa6bM6# z3R(}_3Ir$+s)>NaES*7}4PRIvpFld`30c3|C9^&Ms@ZEXM1p)ioF{8U1UrVl)@*~Y z5B9Mw3i|Y)P}4z(WAFj!o(4$gqbU=z84(8>O{>2pgC8S<;XI=-oEn>x50}Xi6*Clo zi>5}N#Yk==rN4dF;QAxt9SDoCM&?JH?nnx z7cwszZ^>>|er22jZkS31=GjCwU*Qaj!j43@^gw8D!|&RSH!r%Gbw@x{(*QLgrd~o( zY!6_CeUdrW1`B3-mb^O62{Lz@Hq#$jni_DVU;*dp9`!^`3(?_a^(iN4RK?_V%2+r!V&uTF2U48qY=YBq zrDS?3T$P3^Q=4yUIlYT;6C$Lz9kS0MK?E67zXG=v0Uw4W^Q-I$z0)=noi{&I zq$W(XW*2Q;(eEqzdR=){sF2aP0$;~~gnNelajr`DB$p!XpPt0kW=I@f5We?LkK=o1 z$j2ZE#87NRUsc(+RRon>TxDNZ`5@cNxpGy(UJF$DJtf$gq!|D#x80DvShGCV$NSnC zhNqe97@HMLcv7PTfkwsSPCcz1X5OUxsb2U zms3eBwfP!-68J&39M;!5KvKl5Bzh;%D>4oRgLElS5d_E;+vbU52Gsmj1K_%3J!Tc| zR4r_(Vnp_fgf4=-N$z22EzL!xia1w3$crFD4?+B*|rtr6Q{Qm691U8n{id z6M67LDyQgvhLW*Wgm%Ws(v74tGXnif<@s#Uhr`R`ijf$K02KIZxgNlS9Ph}FYfk23 z#}7Zpj=d@MS5kiy>qC?`*iHKX;?1b6t5eCgZlP|cyRXany}1JO=tct9Z}oYqBhv$J z?vzaVFZPAHJA=;J3HF=(IdBH3U>=*h{S^tk^_#bR6FVi_!)1UK_0Q%l5HA?lZL8Nv zUj71|#%vgm1a2!v+(Sc-naekp1S9+tv4xxf^I>5afGHhk$BTWIE1%&Iq{rhiS9bK{ z+a(_Y>>}o{r%Lu@$)719Mz}v;GM4Z2C4adT)}<=iHNDDKQLC)hr<2agz)up6z&8eJ zTEKwqm7r?x!Dy&&kWqGxM=3X2cK8%3<>=vHDZ{Bi8cAk&-wTWnxJA8N0q&}ia zN4dIQt3?35whRvgHe(3&!kC5f`BNC{9+Z5@y-{Ot*7)@`c0-LVVSDavAs)7Zkl!q@ zDKIbebt3KyJF(xfZ6IpC-OP z)m-lY-VkPmfoRVfErDGzCm%wN1qEmc_!Kr@m&1s5v)c`xUyymKe;A)15t%k)st~6d z{YN~jc&I|?RV-5{$4f)2Dr*-;6IAsBWC94HQbH46Nr(nOfi!{Upmm6L?U2=T#H1wU zRrYQrszftWrTzkHS52FCl?BsYN<~^JOs&0EQQP?2p)-r6OFc1V`5oh8$)U1H6rhgm z96~R!q$%%6iGE<*2J6k$D$qbwq=wIoI$;X}L79R-S85Jj8Fn)g09=BT13~E zMY)m1*e#}(6-ySy4`F29-i^O5sUh;}FUjeq&Sgl*`wGH>^^Mlb|hDdBZ> z$PnXhR*m;Pf~ zm)ZQ_3KBbJk-!*R7VTgjn8~@Q1qeF{vEHeyoy29+128@65U_Oa87ppllCBdYo?mbC>TO}YtUfd+A%)S-e&y zp4G}WsY$Z45_afQT!-96oIz$Z`?+2e`GrS*Q8+86@W*3*k@+4VUjzOdbE4EvBL#YZe1>1LFx;Z1rdGjd+k=(8Hx^G6{z7p2bei?->PZBc%; z1~5?w*_f4z;w6)lf^8(ewNKV};PoBYy`8r#=xsc)Ez5!gF+~dY0k8tc%Ai z!KWda+7S$v%FgATDrZU6W4+PH>qz$qHp&%o^qfsU zmmxg+eVKdzlodmgG^NfG&v48WYarPS)yWv6>@IUZmNgf&|KwL5{Er+2#huu9`wWp< zll(9t8a5-<5cP6VL(mbBCR0vMcyzrqyO`#{Ns11wdK%~WxQ--KLrBblm$FS;%Qd76 zcE`zz4a|sW#zSf9^Xpm-qJKvwaK9uJ$z)H+T8{T+P={Ee7$Uu$)=PlQWL*hQZY0lc z?aX)N(6?fn6^HUpiWbr`CvaUTtqo_k?aZ;=uwVWU+dj{B^_Kvr1;WVUyyyeJ(pc*W zzU$;D3OSGh8$DW9%3NW)m#bNimS$Xw?Jl$J<+lB(Sij63I7A0>4s|#N1jX9GlpT|l z4>UPsWWkY<(=aG?f00YCH_c}fWuBE$X_oicCWpoAu1AXTQiee0ANgAYyJXnf@MP#; z!c%{9ECyd`dP%5WB;g^s@PlxT3`?&*mb+TiqyQPPrxz{`B9gT5WxSoZ))`k>ZowOd zSeMW~iPIIiM-rmUG0SQRb^sAaMS0lkx4XNCyL)O6*SbH8rCxkqMVyglc8}i&VmesPCOy-cmzE_PXF69( z{SP_+q;R6=i(5F8T1yfF8$EuIEvOB_g*KFfU$9+vyy>s2zfP=4tNy=#v)b(R3-+e^ zT^63DX{PJS?Gk$j$Ysh!3Z|T_3~?j*`A*wiWZR1|W0iq>lkMIp_UGI5&6mhgvV@4V z^f*?wDZal$mh(pX+vG^v=w5mBo>fyR&LCj*f0$3DcPIJv_t4E7!h7ZIpG&nZ^?Bfw zGke8?7HP*wea?`gw6IBslzOB>eo2G;lKS{1?Pc{(QyYf=G;4?Hjt5z#M`)%kwm3+n z4RH9&;bf8R9FDGw(W;Yb=S8TTcO{|GXy*fqL=)vC$;Ud0@q&uf;r3zJvKiCgURL$c zFy+lMOGuAWyxXgZGayHg>HgFzX#b*+IFiH1DDcq;3(ti_U2hoXH9%9^xl0CMUddt~ zrZZS7X^J8#ESSS*bcKOa(o*CwCNP<_ak6ENPkA4l(AOgA%1RN*kTN+5BW}#X2v@9i zSL8a2ffmR4P%Etav*hf7_Z{aQl8{u)(i)T6RU$+Kf%i%qq0TP1o@OJjY$oDVGk)cG zI=1ezA%)@p_@2$Y+{>0;{mptt5-o9{fBniN@kD59M|Rx^2eN*#Cd>Xwyz*np{wC#8 zMp2D)*%Wd#G#^jPBn<1UA4ogRX*$`jW!bN1Ij_<`Bjw1qmZvd<>2Q`H=V%>lGZoY# zi^)kK(oR{KvY$-Zttn?23zO5%rRngzC1(PQnuj@M9P+oBjMozd8~{dZg%j4PD`}RK zVWpeLngmz~N1MeRxO6$LQC$$c2i{JIuB0Y{d+$*BI}P6g*R$=l`Nk>|2F@6CCRFyL*UWx1>@ zPcfB%t&NFPCN6P2&es$Ywpy`AUskJ2*5yj3lW8k!mP5jItVc)`v$CykCB?|LC&@38 zBgzY{S*%7LB_cbQBvZMPu|hn|#w0z8Lm4Nr5`nrY?cR_kHei{Tmi_xTJM={z`l5r` z$K_C4eQP^kVM^=DIoGvuw#*sQIQ)W9Dpp+Ga045t&0}Ce`Klkt};jmVI~lW_C8nSU9T` zDXs}%UZ(kvx)x_N(aW4g&ywo-A&L71j=D%i|vVa zseKybLuboo2Kmt^)9eNcvmWIjewVUPC%h_Bc)(gk6GQBE2}ATvq8v-66C4_upQ&!X z{H111O!m!k^s8n}7>~f;QK3eQb3~SPJ27rwZ|v&~zmERO3XLvp((*gcb?T)dF<*L) zvWZnZML~^95}SBN3u}T!N+ZgerILmux!~hN`dVzvNIQ?(_T#)4t6?*UJQNl!eM4($ ztV$rJE#_({glzl$(7GOb(rLRNxXy<%>LueU{j_YtIZ`&Ik?=_=n}Qy?K32UXv)PV) zuBH#Xd4UY!YU5hgRm&M!kt>9xk9D`$=XjfIsINI1PW}RASjdAGD>#2!XA+MQ87st? zmCf4fr=(curXJ8!TIDn;nKcR{KP*2b*Dzxw#fbE>hFY^^ZUs79j#cY#v4EFXkv8}O z1i6G07&tqYy)kVv?4)r|mZemYfM5G0`ue7sF^7e7ciN{1Qx$rJFleDUvV%3vx;n`Njq#9(rrTyzf_X7((b%a zR;OjNY?vB4iVR$k))xNSK}AYkiY|sE#U)W<5X)g|CCJrlU&_XTH(i;oT#&MFk}mhn z9NrlJhNskuH<_djy(t_L5tKoi86~YtUL^K7rjq)WxH+E!HpTW8c`#Sfw}g%KsX7=| z)bxWZNI$)XNfh+1&lU_8!8zZj>@_I{aW2Rrbe3nO-_CYF%(g$swm;3y*^iPVC&7hb#fyJ0th8;#EDd4yHT9vm-k}_#P;<0%&mfaj zlQ(5K^Rft9_+*urByN1jFSWp|WWg`@WO~_58pp45ON!-NkEWc*Woq@Al)ZvrQ*vV)l1SJS?_d?Za^^{k&UkyD{$1-OL9@<9pu7`=#2s z&(^&{*QcCoCDthWrPZ{K{@waR(htkmXDIPlG$CnAx^(+dR0mF>Gzq0nLkMV13z8}j z>Ju%AIDjD>!lBpVgkuh2k5A5dHd(9!p(ofUiylmx(@yx8m6O&{2S~z^2OT_2`^265 zlb!mRGX8o^Q>-AxS97%LmCQp~BWYjS98yVY@!)~PH4QR4u zx|>K~;U4BPR!)fIgj5GRX zO=*dfl?qSfU=Fn^L(4nb>qfCEMZ@~KAk0naq78dvt4fYnOmUosy&*;2`|K=mj+A8bb(Jt}$QbG%{VR>OX`p@AKz^OO z2Br+(d~_EK#LH4g43Sl(@oowlLsU#vscoIfX=^^w$Q&|9jfwa>Y z#GB)~-#hjiDMx7;)-fWKC?;7u$+oZ?T>B>0UJ|Dgu(TZ8T=zZKe&2ODqS0Y}?l4v? za$?<1edW-lKF%hT5A0LbZE?EaPfM(Dd{q0Yv@aQ9Nsf&&n8N%bvoZr13Dt6mYDof3 z2F4`iX`oY{JnO{%%ZfwEYQiEX)c1GhP(X52!!W0cP-k3|n53b>8JBagApV7pUKHy;`=Z3IJO?&e<5A_cbzO9MwfFkrBbHeg@v^ZQt453LhKS(J5n~w zuSH^Kp)XFU#cH?}l<)pfDQ|&ZKF>w-MmiD0P^PYSIEpuoH}n)=M}OVtZTC5d_n^Fg zCGEUS3xHIA7HjLya?Z5R)1hvOg*n(EIU311njEFfAv5>X$4$;9Hg6#@!O7_g|NWbt z&~s0~x_@&2%=(x=|HfqP)9J($p?lZ5JuCLji05${1A%x}7U7bjE_CgSB=kv5H@Plz zmu%Ez)tuz6L|Q|CjhZr>nbd3V&|T%YZ&3JgfVcQQPK#L-@D%f|{{Bi&@qdNuGQ+&Q zC*{s_?N?m)Kd$|m>pUT6EZX|(yet(Oi)+%(g@RITFDEsxH^g1U(p{=$0+QrpvqRp< z39WR!G(U$`vQ*1d#))c~sQ|S>&r!}p2@|?j$}$bWHYS}0V5LE{>Od=JqX}OtWvQ04 ztl`F*L?|+B^rS?vBm=rk#JMi#6P3(J6_r@>^=FE18Ir&sOy`Cu_tJ;Zp^AjgNi&Ux zpO{kRgS094!W0V;m#3UZQx5Oii`Cw_Y*MFVC*3=~$?;msq2ghq@bf9gfiB2$+Ea4U z(1$69l}%5loTpOG?O6_=4cUq!f*~Ms4J~dy{^a~3?sb^|vbK~hhZIGcJc%dukMzRj zR{sPgcM+~@by8|_NTzmZ>sZY*e2_(hZ~!Bh?CRE%OyWwK>*476cnXPZW)G!MAD*&m zMK7i5U~9U)Z8o1ON>h}(*5ZLSo0sGy6^UrsZQy>;kA)mU$zcuu>PHD-F`&Wgv$ZNp z%Qz2zwlQlrd??|$o<$qNw`bU=vcy*oa>X6g{sSoHhBKtc&P;nMD^<62CsA=6YR`23 zLLD`L0l5M~hDD$5u9%DOHYR)qvw(%FjS_`FqyC(+^)MhzLI`&70|@*x)nujDx1^HTPWDd`-MYA|ON49Q{y zGpykXOqY$#vJFTAO4sHSE^PZ5WexY^m+{I`)?A6J0XpC)Upol{t3R!>Gs73M7|3CH z5iexJ!LMKD>&tRehWO=WUh-v({*A(S4IDQyyssYS;Es0_FCJ3Z$9hW|Jw30!TTcnT zM!Zhzf}@C;0Sevltb`a-cIt?w{E_f+Uwb~M$S|rRM=DA7<$!{|5(ARxlq;Mc!6QWQhRB07-KsZ8y5kZLV{>ly2Mbkt)_UN#W&4eMt$& z*&@ps8V!&AB$BS`v3Ik}a1OO4-x6~;O-;g&9DtK(Ch!8{N)DjR=H-&LaX_>az2Dx} z@N}U&ei!R~TtJFT+0{II29HXm>We$wk)%czK(Om<(34DY?YE zQkqF9yXkWMJ1f1Z#(;2fazf&s127q~q1lz9;h;m73^Gv7aJcB@u5*R!TC@%;tn93FWwou066tI< z#$rjVF!L>)#cXX2XHyQ0F&8xmfzAQX33Q=VTA&$nqhap?IszyhK8gO@R!3LKm(Rl4-H`cQint_*Pbkfxiw@9?`F--W!I^*agk8|k_(IcWa z#L?c-`Fk|1xp!$qbBdX4=yy2S`J8N5PrrB~Z8OHr@7B)GY3EwDAM|nV$*~!oyeG%u zcTtWjXDjgBU9tp}PiafzOExr+AjDk~vC^-Sh6T5}2!p6#$RnD{)opuK+wi?;Jq3_z zo{pUeb=T0rbX$$pakPE$ezG`g)e-ik`^k{psw12q_H};T*ZF2&=i7blH;%xF+Jd5! zp7K2v_Wc#41-X}Q3CmPu98@atfK6dU1u0r90d6R;L~xutn9|%>3pFzLO6~0KWUDYe zw;glG@&V3$MVH=*(T=tEu64_H5Pme#{bZv3@kG2B;%wPs__NeEGV1ciWFqXmKJM2O z?XR#y3hJ0>zYr-qC)yu{$}cC`dOahlP5LiQ%v4PsXwBg`J{{p8tuXaqRlCR7$EK`L#1@@5RywHds-e~lXCpi{ z)ZW+`O{Fv1MdY4|BD8esq+GdJlHyHi*6_%RK0fnkI~U2A$q=5Cm}i`ne1H#Vlu~6eTaytQBOv zk~D*Pi99ZY#WJPhTF1IPBhT4_^6k8o^BD8OlnQHyQyEmn=aK?AD^Uu0+8a7!mE!fx z^*C0;Fv=BcoSubMNx5H{J}zbPG5fUhsb{bD+*kYA-TmzEq=C!Wyi5kmnGZOIw?wI& z3f~%+EAb-fOjkl;NzRBI#~k!_&Y&#)b*(u8u6az()m_Pfc=iH0Yj-&xz?vV$;<&!n z99pa_&XD|tV~JQ7w^@&{v4RG$Yi;68wRe!idOGEiC4nrbI#AB*r4u4U(fCkYfQ20$ zYcXFsV!V_&bCy?aW^c}vHi^OAJlon4>VLbOYD3`LugPgWPPc7;gC98|oVg5Xi87KM zdyx>5w8_Z^i+RZ@`U+`}rLFU{VB@eP>#u=ziM*VRV}wyY$!I7qDP-(dchRy<_yM$XbFCS?h#`KM7(}Mr*ptvYjK3!kRqF@k65b?uA{XQ9I6|AV$4QQq#pvWXszR-Fr94eJ zv#C=w1#swQ*r*+DeKu5@>aqie9XEs*(*#;cNL?too|G*?I@CHWHOH}MJN6vMo$WYt z9A`E;d#QW_CG9L2W-lCOFBs-79Ohgns`>ojGxqpE=E)Hx5>>(|d1ZjrE#}t9=+!wg zVBwtQp6Sw!Wv-qt7H`c)M`xKULq$)>+LnH@mqW@%?MTCcw{Y3WlvO8-BN-~`vR%!z zeL3M%9A&d@mhA4+zTFs4v%+6$Kk04v#coQ@g%TD#SJ4kee`~Q!yiI0Jg!F#oD4tPl znhK|dvapb4vCB}?zdTbuhMwYBdz`KH8T+i5z31<=vyp?=v$_KNiN1DgU;A3w({NQE z=NvgFpTV;nSI#N0>wWu|{<5F7-gg%Dvlp{PgSSePuD?x#^H~Y4yBwQS>c`@Sz+o|v z`d)pGLy0kXrQ<@parA;7IiIpNA1p0giS0fVmNJe`BLhQOa3I;o79tt9bwwDSaBBt$%BGvq|#-*Ge5t)|DM-GNU4$?(!*AeDdLLk>6C< zDXF9fII2zWq&5=OHs2^L!V`;%oW(`%1x3zWnN*lJ#%&y9-#UiZ+&;#>ZH%pz_#|=6)m0{i9SdMS-r4?SXG$X3;gVx7nCdK?>RdO~y?&~_ zV2XXq6#HiRW~1q15#>yf8j z`v6vPjdZqhWEEG4n@Fk3V^SdUi^F6IpJSJ7#hLO2^W}q+4)cN6Qdr$B!$s0hAaA(= zFXNncyFb0|G{^^`ZI(KG{CS9poIUzntVoe}~iDeyw!}rT zE!9^~`xrnGz%r6fnIucu6P*`nkfrFLt`(+B`{DDCX?2n(WWwCCE|kJoDpPsYreR{{ zUYn39ri*Dz$|p`3QX-qFr1&-wT8;%mtMkaRoW{+lHlP#d%89&)w8f*1Z+wVMo*701 z%;k5uJFMSGd&BJEeX{wN)kiWV)%FI~E40P+U&=m#F|#V7=0uXQtnZ=v4v)oTu`4YP z$Ijo(Dhu|q_hi&&&tcX|nQ=OqEPfKmEY-QL%vcFow}VTT^|zPzcOI2rH%-pRhm?d_ zO#M=z_an=&eS+43O$cl#ZE|W>4Fzd#kjnA6o#m$(S+mNFe7xh$l>M$0W4wUnuaY=C ztzH>))-*nZqf6N~=dNbNQ4SAhCOfs7y%DT=r1AbSpIz{rk3FZ$V;lEBWC1zfYz;^G zahBvI+JsU%NRE?M0kyZJ5L)ytG#6*ednwCsC+(u;j&qPRL#(>iR+!LodRRWZ!g6~4 zNPlcgzxxvTzP5dobF_1meRLoGx?C5CvSNw8eo9+0&bU4iW@U+=(;*KTQ_kZYEEs-k3-cwqM!4Q_n#d%CxD4c;Bj?y~ z#>y%D6|T$VcWdVpUG$={r6+iEj<=lVy(rsVEN!&`u*tu)J(MITu@(K28v8gM`fb#{ zWCYR@P7$sLvz-=>qePQosg={2Z9hB6d3X>@tr!yF00ZYD+5UT_?cT}P281xgJNe!j z&&Y7s`8h6j#`D@6*V=;oJ6Vs#C+x`nE;-9*^$6*f)HQ(Nkb#Vs^kqYU(|-dqXyA5X z@0Kc?vWV}5N#xQz4EL?1`{5IIMTVPU`_NL5FGgfVrz0lU5j(^BZGZzuWRvUdk=%{S zrdMy%!{;1ez8dC+C;TuZl$Itne$v~`Ps{s5wHO^)iZxiq8BAK zwyY+$SU+jaac!Bkv6x)68jxF%*QK1s>_?aCL}tmgA81>QyjrZ;wmuB|23C8vZFL|- zmc>aD7H2hEH8`Rc;nWSQ9ck&q_e+ouk#V-QiEa6|Rb*R#wylM>Evq6drm1E0PDbr0 ziq?KA(3QiC*H6pAauPN(O5Z)$g&it*(hbk2D2-A%fW=x4CPQfaYJ(g|ab|wT;xvC! z5@rmqSPY?H-`UVgF^3b7zOZF8^JoDBwsaAANt76LJZ6x|EQ>mCX&5DedG2n*-Ou1qoQ?J<9bSUPUg3)5$&r~V) zH_eIzjKwT1V_l|9(U>|#&$KK0Cci+;15>G(F-?ktj5SvDgH5^O5L2(1XF3$uGX>+s ze5k2X9A=sonW<%^IH%8;GQ|x{o#F`7u9$D~S;$2tWGWR$nkL0jrdx3%Q^IHEENf#^ zt2o-UDULCDn~1)^R49%$jf&$;m*RL+Ox4EGai&Ibf@xLU#F!${Z)&D17MTXc%}l4_ z=B8*fF`sCv6}K>rid&j?#jQ-v=3>6JDOM~tHHzDqHpNLMf1;RgYpN6{n-<0GjM+l; z+nWl-9ZZvAiLtg6eW@u|+|e{B?qs?YcQ&+;xu%#p#i^!4aTimxwdl)CjpDARO>sAq z&zP%a?QW_R_b@Grdm6Ki==U-eihG+z#d6c7xQ{8BBi+;MPR6NKuE6y+$MW|&RY|0f6F|~?^ns&v*Ou_bIez>VttS~K#N0=Pu z!Y%7aQ?7WFsaHJObSNHU3QENMSW~5VoM~39G*+qT|76M(|7_|N|6)27XPV+2#r$|v zt2oQFE1qETb`pJ+sZ>1CG%22Bter)FvMERSZ!Jr&oFsY zMgLb*sd%PoRy@n(>>~QVnKH${n|j5wO{ZdwDJ~Q9*``Kuj%iao$CzD3f3B%e{D)~$ zJkMCWiT-?3u2^dt6fZDcigQiz?qYtSsa3qlv@2e03ic5FC8k>OQq!VXXUv|W|EH-? zyv#HyUT&|RC|+f{6z7@Zy~VuV)GA(W+7+)c1?8f@)>JFbH_eLInVfw@ zf4!Nmc!OzFY%tx5H=442#r!5yueiW;DlRm|`-%Q$Q>l21X;Qq^bSpNRvT0(z$kZz? zHl2#Mnd1FLf4iwwyu-9B-f0RB5dB@ITCvHrDlRd32a5h~Q>l25X;!?~;!@MD_%Bm1L-Y@sYQ=|5tKuUj?_kj{GnI-hrdjb(lXHmZ zmz(K|kC{fr$4$556Q=A?F<)Wo6`wSnimj&jFws9{Y89V0?TXKsg2P4stf^Lf&a^5% zZ}KWc|AMJhY%|S@FBers}Oiure@T(R5KDSmI-6xW#i&&bFYg4=J6?sN>oqCT0I3pvmRGKr_UaY0y$;13ujoWE@8i`d_VwBn zbG`hNMBmS=Qta=wC=T$<$)X?VRVW&-NzwDHQ$+83<%)qiX*(7YSHI=<%%164T>YZF2zw^ z$r)n4kyodLOwo_?suah2EsBMnIZN~tymG}&yavTh zy)MNfujFrHzL{62xVhJ%IMFNmyXd#@Y81Eh+7!3)^3N9i)?SrjvDc!wjb~~^Kgp|5 z+}3MSoa|Y%MZcX_rntRVuegKPu2|v~%n|cauUc_OuT^m;FYg@D@9b45PVpKQr+VFr zyLe^iig}q=ueht%skob0{14IZ?$s*p;k7I7=@pzO`n|kr#l5{|#d0s_e9`aYO;_C4 zYgF9N>sFlRmDP&*{$9P}0bZx#fnM7DjwvuE6(r==8FDcuUhdCuT}9-FYiLp zALdmm9_}?OR(LrViT((0y5f;uqvBCsx8l)W*~Mahj90ICtki{dGsxlHt@ zdKHSNc}nB760KC%oF{2UbW)+UaMlQmscyyx!|nyumBFLG%q?wc?FltKv;wUW4ctc$JC^ zy=KLmy__3Ge~UL=@m8-RT;!GAB<72~dd1tkPQ}~3;sv6=!>d)i(`#3}%PUwY z`X;Yhaf#Qec(<2#v*_>fDi!bbnicQ!a&8g*{oZuN2fRkbX0KcEL9gsqF<r#Bl zE4fR|S9*1dFMAz|uXsgGqJPz^QEd0x6kqf5mx%s#uS)R^uSIc{XYLmLn_ijXTVB25 z+g_()hgW=$n7`xID!%KrDZc0B-7EU{y-LLoyk^A@J?lQvf8>=bc6tqpAA4PjpLiwr zi}|Nso#JY*Me#pgm*Qt${sUtExmT{(<<%&D;Wa6K>2)Z6<(X!&_qA7|_>EVm_^sEW z_??&kpqO`i6^h?`4T@{LPQ@R*qNQT~qgSK&lh>yBvzPxb(f{IADO!GuqV1c9MDO?& zimuK67R6lOEE9b{zg)4u-=H|a?@}D- z7q^JH@oN=5zg^My3mz4H;8!VT{1(MQe$H~y5BAFxhxql1d49X%dVaxUVm{QbRvhNH zC=U0{oDw=0hG^IAne-k+{m=r<}(@VgZ^@ynhP^G*GF#Uj5`aWlX8Y0+=)*D6l* z+ZDI)3!V}EmVUM3R(`AE)_&fzqA&I<6u0r~6({-airf16&x!eDzd~_4zfo~}ze{lk zzvOu_FY)UXOZ^VT9sT?lM8A_?p}4c(s5r&%R-EdWwTbyIeyw7e->$f;U+|*nck`n2%VIv=uTwn8?@*lK7ri3-gZ&!CL;M!SL;ajrMSqxIrg*qtr&!^4C?4S#wTt)wTgfC+ZF%f7rY_*nSPbx@qVM? zEWcav1ix&Rm{<9AiYNLViYNI6Z;Jk8zgqDWzeVv>Kj$scpXN_jJl$_ptoFMV&+tp$ z7W2RQb&6;D?TTml1s$UQn_s2)cfUpPY~Q>i`WnANakk&2ILEi%75zDWx#GEggW^B@ zF2(cw;`hY-e7{z))^At5z%O`T^mF}c#S8sr#f$uI#f$yo55)Wuzee#=zg4l$&-qaF z|MbfgFZ1gaFZbIOukZ^#67wtlD#fe(X2p4aPN(SW{ppHV`}K;~_??Q^`b8g$`Fy`d z@jAav@p?c16Vcz`S1C65O^P@AU5YpPC7+7<0>4Iaq2H!>v!B0O^tbpGinscWij97^ z;v&E7KVrVvuUEXy?@+wmFZfLKclcF`cls@gclkM=i@wR9uDHZ+RJ_~oR=meA>k{*O z{d&dw{7%LD{o*e~|A1es*zC6}KIj*GDf*>;wc@}0R>g<>yst$6uwSY8h~KQZ%+L8+ z^ez5$#Yg={#pQmt;$wcJC5FaB2aPx>{At$v&0Q-0oeqJP@2P<+O3 zQhe68x<&t-U#|GP-=O${-=Wy%7kn?~FZz{=|Mr^{U-G*ZSNdgZ#QbHyPVp7LRq<6n z?+4Mh`xT0>`Av$i`__-5f5R_PT;wD-#5RA{sX^4@k75!@gtuxbM&2lx#GuugW@NCm*S^>2~!D{wc2OB6!;&%L-8}e zh*=Hlf4@et%WqZu!e@dA{g-~Z;#a=Rgi!zcU5elM#SH3O*0+9*;&*F{V#qQGbLO>y`mk+EDH61P{fQ0vkQUDqA=?a zv?^u=dCZ=$IxDDD%nq6qa{{Zc==%iaihY9y#oU0+`sn)wCAotA1HMfK4hT9F2L?s` zY#(4bmzSkS6C zJji3hgZe+HRNNqFR2&g>E9M7fo|tbK)GLk*Iu%C+#Y_@W{|B{-8wc%*ql1D#^kaf* z#e$$!acq#65&gKJQgM9HtXLRWgG4_eC|BGhXi(fV=u#{SN(PJhWJ)bhIuv&fikL}a{6DBsoEo$#?h@p$FZ!~eN^#eqMRB*lY#{pG zg9^nxf+od118aon_X^4t_YN8q%Y!b(eS(sFG2b_+Q`|4;P@EPNZ7BNvgG$8%f@Z}7 zgPf6~pB|Jc9u(9o&Imdc4-Se)iTNQxt>U3UyW(L%!A7D#Jg8Qz2wD}72+YQ!KQgFL zJSu2XJUXyOi~g9PT=CeTLGietOR+L286)O@3hEU99JDL`B`7Em{mh_B@%W%caaLf) zivEOPx?)w(sCZ(~t$0#UGEU4-4(b$72|5%{4T{E#{P^b8hphNMz zpr}an=La>4wE@fN`1^t&e>1_kL6zc#L5t!=f!SR27Y7xJmjq3Umj>2E(bom#ivJ86 z6fX<96fX}-wh;3xf;z=3gAT>3f}$-&KQE|JtPk20uMYCJ68$wnmEyHQv*P?9XKT@4 z7fe^YK4?_DA?Q|Y2+E4Z{KlYO@ur|taY0bLjp!E!wTd?f?TWVq1(QU7Yf!D&7_=%b z3i7rU{o1>!Nl>kLchIVMPms60=GDf-T!Qt{)US@Dw~XD`uz8cbJQ9W*NbC+JrEEGXMs%s&t6 z6}y5?#V>;5a?yVo)GB@zv@3oc6zn7VZ-Q#YZ-W-a?*eOI(RT-Bir)uyife*4#UFya z{lxsopi=Rtpjq+fAZMEBe+i~5TA4;gJJYS`WXkpzb2n43n96i0W@U;F5PdpRqnMp( zQq0M8EB48h94O{}GqsAjnKs3KnY`(u@1Lnq9FS>L9GK}+G@0Uq#N5l&DEgUJ#UNv5 zh(42E4bg-D`WvUg|%d{vC&Ey;+`eB)3#o?Js#q~4wiW_8F6-Q*c z74tI%hl>3TGt(7EW@;5jWttT?%5*AjoGCg??2XP;D~`#uC>CUL4j28{Ou6E?OpW6B zOsisH##D&;gv@lsO)?FNn`Sx{i!wz=i1}ujYQ@bnt%?&fc}I$Vi%g~BmYHV7tui@B ziGJ(Mbj9LKqvAH1ZpBHNlB30Z+f1$E65cA30mM8AEeQgMe&vtmicI#%?hnKH#4 zGj)nPW!e>Y&g35_=2J42ic>Sqio0ZTDn(zGDOcPzQ?IyNrbBV}Owpgje2+|x;+~l{ z#l155e-{1TnM%d-Oq1e18S5{i-#1gHxL>ATaayKBasN!wOff$oQ=xcZra^Ifrc?2t zO!4tzJ|k15cyOjs@sLc1;-Q(mSuA|94$WXmF6QmquPw|?{laCHe!}f8HXA=kQED8v z?$g}&L7Yf;QHbe5;83J9#RxL56_WUxY?UsZUzqz#U&m~O6%#&UjQ~d?8zXL{n;r6| zx8v^;WC}8kch*OgnZl6zdh|SH&fqt8-T~Yngd8F!h+J1ke6zVf7r6jwPw=hYEy{c^nUtnodMcLBw6+ z#U*ObO0Poq4$_U};g*8PJzGTautM$Sm{KthpJ9IyNd)PKpteX6vHQ{k(Mj?UiQOa^ zx~q?o91**VJzAD*7GhVZKA#0o7!Fo?7`kM-h`B=ZzUG2ncs5Az>>j#x9Xz?_)?Ro< zCV1wpgXao0?`IzGg{L6FbKM`}>2ErE;n^g?Bk7gvcl~v#8V@i(_QJD8g6B51w=SN6 zW(d#xHohh$cpm*jJjN9F!c&sqd1)OyVK{r{K%U7D?OId0-xb*-!Qn=Z9Vm)}aEKFF-XM(nDXO-f$=E1R~@*TFW|D!r_c zLcRZB-SZjK#hLa3xFn3kaT5@(-%XUECx@5~DSdv+b5Vk4VuB}GNd7wW=b0UP;kh)y zvrmGjw}1-Wvz|E&o;VT2{<=KDbKp97!pt_*oY@PHR7`RB9KH^ouy7n^uIYv6h6K-X ze~4$ed88Mfn-e@Itb-@?*ZSs-UU+Ux@SMI5p3q+#m^HodEJ^U3|A%-+7>?1g@!d`6mTc;a*z z7e>z{cs_`De$QWFVKmBI-Ankql;HV%9Xw(9Y-E=9;+{7WJm0T_Cv?xo=9OOD^In3d zzhn@~joSgv)H z^M&SFc;fUNm#gd)TFbNhI(WkPnqWTbg-5;w9J@!m_y5B^VSKUvoQ6Og?}K<=BoC2G z`a0Qild{rHq_eoLiLu5iz2^SH+=b4jW+F7Pw|?6OmS7HjWoaAu_uJ-0X2$;)p3Tf0 zc=E;RT*L6r28dL#;*P#Ze=#6<3eYv66p6hh7zWSgWZ_Wexg~H zwn|%@3v-9YVayIxz54OHf!w9&c4DDm3-c83Tu%+d=#WP^1w${fF3}>^uXzybTbkFg z?x|sq^(_H;yI)pX`y%Ch6q<7y%s?^ z=8vwBISamgx#ju=ySmMoG|H{=NnOE}{yVyJkhw^04xEuY&0$HtNu~g^Vts^8A9g=N zenw)x`y#%{yuTD-`@1!n*w~2Js2pus6~E%!)(k}-`}YX!9*3+zVm>~|r0%;I_gseD zh%}RfS`p!UmU+}3|4ufYq}n*24#4jLvI!FNaqx@s9f0m&qyo7YH?$zaGcD@0h6#H+ zb0~uwG2fZkosG;#V!r7S-&^S3Lq0<~h>I?yY78^gk$*$J?ag`c#s2L>Sn{nHYkwr> zyGETC#_x;hUqQ;E)GYq(w<2`sGQx-yV(w4yjl~a}B4tR-7p3_0Bj_GO+K_g_t`n&~ zltGj8LcY(@TULqLfp-mx)1_qE7FXc0Pr2;OT-YjM{i6PhVP-DlYD!ay%T)%uy-BOg~WWP zM((?wG`aw}9hr&Ssu9h;M1*9MFum+)j)X5ie8$SAvK@ddL1Mnpo|Wz&kMFFY^( zPo8q~Av~0@)+Wd+*jk8Fj+WTjXn{&J?G+Z`!K8XyyqK%X9!b#gD)bnMICzH=e%Op+d)Al+dd zq?NxRJw!?OGj~AR@=RgwxZ@y`QfekBrIdJkC$(hBF+A33=p$E_e#ry#>}lpjvQeB3 z&cwV1IUf<9<|A7nTc$x#&R@X*KM?$iCvmSjnZ2DzTZt|Wkwo(l62lFg`xAd(YGFG zZh|jPwQ=WqBF_+S>bz~$Uf2okE!DoE=F`o?37&0vz7*LRiQRQo#4`)s$w)O)LB&!+ z4i<0LN2PDbcaZ6ZkE=$0;zs8@o{@`8s4aNfsOdIJ^*ESfY^Kfm0waAhOhEY+`|cW^ zz5%%jk-(>zQC|Y-o6#*sdh?--^tCZBbgzy#aZ*!~{*35nUleD%Kv zLSg#^wvW<>nG>MP*Y^`s8_+UAh9MGb;;DGNSeoP~qCX3fCPW<~j+3pjf^(JQaC1w- zdD2(95c`)RaUjKAWa%sQHdPk#RG8)jkEBZR=H&^VG9e_;WN4)KI1}R|%+tN_%uDdZ zUG4wPbEILhz}j>ayXV>jkIv+;(>+I-u3mU8@<_xs^vYetrl1#|`w~1lL%&X*H7L zdf|CE!Bg>v($AmFAqgI7;y((<6G)uhbcP-GNE81V^u335>Fe!e-anh;dtqx!u<88z zy4e=L2HRguO)qS(C)jkBeBEqoU|VR~FFS&;6eP}*LzCz-npehQoJ|k$(AOVtW z;a5kM@iJvN-rSPl8;ac#$XF!itBLqZ(M?5mN0NNCzv7!^?$21Ijc-t?OY>u2EbouR z@j%m4E=MZSBhWWMj+DO61Jh10PvDlg4n7v+zaX_p?3VrIhM;;1-Sfz+h%|*7qn=gy z;bAcsR+?32&p}pc^Qyw!*>)E;zd=&@J#3eRY^mYsHbh1vk%P3byj`pO6U`GeL1?4t zwIy~YA=@Ldr)Xo!mEJXB(CLeO2g$O^Ez~KnXo_B4@S;HVo$~mjdpZzBArMJ z<@mEvS-u(zJ!SdHW|XwYt?z5@KPc@$orj7S@VeTdNnb@d7E7J$4o%_au09g&k3_3f()%CrCTt^*+*stGc!iT@`kb zPd6imu!y9CMEV^Te?)#k99|`r>65m+)N-Vz&mOhbL8WuwkqE3dlW^Fe`3Dlar#5tt_SgT3UdC2p zF5#1FnN_;@U5cB(nxlJRt52|9`N!DSz&7nnb2@C|bh#G7vKX;x*SY*He!V_oYeaVk zvJ_cK;JlAWz^{HU>DRMNw*>rq|JQ(jAD{irbc?T~zmry@jRuOTW=!)!Ch9FMCSKKeh#-oJTZo_&s~#WDQX zYdSAF6q$v@p87a)%v^MrB3B{O^JpX@B#9U95n|Z(JlEWi;ET(>MLZ)kguK;Xhzas_ zMBta5g}Dd*!`us7oVf0SFUBJzy$Yn?z zXb*-)>B(d1xFXXKnNTr^IBRBgZGd^_SBM-{#)a&GV5 zyyiay+C}Es1ltza-WJ&biP>_+yF}@g=&nUd$VKHyej*A8v`>WXV)IdgZ8f&PM7}{{ zwn-6NedKS!zA(jzG3R;&9soE=D0!k|54N&O;+;Uxwod)DBB<8_0a;0yee7PC96Upz-@Dn28e^Fj?sIAT{ zg^zTo*G?0txsYi{%(qi$ls*mJnMjS8C*t7tC_d+^y?>gO@Wt_YHFmE@T9BCUPZ8g0 zbYCFfB1t|uAxhjC@?B=WPWZP!<8MAP42k*v67iLyn~Lm?WU_m*!bI+=y=;y7|Z=q`W_)4~WzP&A3PSwo!Xm7*6Y4>)&SVK8&nDV!lNY zpA;f;df7LK%p}D{=GT$?LjPWA{tRD!_>7g>l#di4MqeLr9n6 zuDse1uTXnenRkcLxcf@l*YmM?BXTbivqggvsa5FSLFAk?X|3lIg2L8yxX{cqeQEf` zspJRjSewCt#5qA0q;hHdx(|BkeZ+Gq!Xp>$pQpbjU)7uZ1e?LOunkJE>EiK-Z3Ozf zUh9qvA4kA+jkFhun&g z%-Is%B&30mL`v82!1?Zc^C6Bgkz;nid}pK_i5(NgO8NwJryyq|UHz~ZIcD`9p<}}I zb)Bi89ToFkhTVC{4M@xvc|6^W?qTF{L@Lp^HM>RRxiI}-Z%&6VCvx8l*jxhF3$x5E}^(`s!04XHz7*BuzKEk(Bs zS%D-OJARcD7Miw%>ty8kW$d>ja!LE`WV$pz7Uu48vw1)9W*J3Wg{`*{DHp`%JcLU} z(Rv%L45R-R^W*wfY0XcCxi8wE^Yquq4@m6(Q^R5=wJX807qTA`Wf;wQorEsi$IMo^ zAc_fV26m1>u0mp-xnZVD&)CwkDv-Y+IqMO2h=gkO86k$#$&E(F72^`23A^_p%}5+e zr9zDFmZN(T`7u#J#<4{4_xjJ0h!zp8#yMiL;m%`jv-P?>eqQ|$@SpPe+42hk$ zTPpPJNn3MNA|i)W)==E!L`Ba0tHRKGPOaT;&Q0(=huxQuoZ=q74=o*oGkR+cR zP9@F^`R*|HB>29@?iyq>!XkE`EGpqjzl5$G`2eXKL=YmvlXpRq?@seYg0El_vwXO-DNHnf#J_S;UA}(K1XAA;b4h*=-NslS zhirqy&XZoW&`F7XDEecO_CyUJtwW()rq=E@EAx9&v-J5-#eOvsJ8yQxCw>0&&`U~| z86Dw>FG|=o=Zf?0F`q*hS5Pv~bRmyihQ!XhHlovcCiHh9$xcBxWq{Cz72dsO+=e}T zGR<>8_8&xI=Pil&;`Q$B{4E(IcA6m0yXL$JxgXj0naR+_k+BS#$B~zi*m-=vN3L|% z_H-r@4@r(on381Z-EWRgIIjr1TO#`+G2hsTPuh=ior_trEGXPFFU~0||%t|3`2w_ML)_eEsnPCa}#Mtm}ezY_fi$aLINiAX#=8&wivVt(8lLng{s zHr7?_OyWn5LtJzeyw-OS-=pYOATJ;babFW6e5)h(g?vw#+KqZj^#O$Q8ti9H>ET&8I-%}=k^BofL$qK}~&_9F}!?iNvn;9jSFgl($%M*MuCHoQfKSAQ) zTNv@ll&rNYNxyH;IIp-*F3S4FS53&BZ@*wxK^LdKK3MOE3`An*JsQz{i0)(LGbC9$ zuX-W$Zdf|EnGvIVa@%IRkvouGk(lp*Fsf2g`kjFO6hxv!a)^vd6_DE~L(Ig{R%zS3 z3Ayj2&d0_@$O0s0nI5soc;(~hpFyHZTO*;PLM;5-oC;%HF}{nPPUJfz=D8x|(dBO2 z?#{RyB9&~WZ|JKlCPb+AUNVc}%MYKi_Q&qQ$Sfr0TNUvwMt2v|j3nK4dlZ?^slAov zgG6XOgWVSqISD=HOW_u-wD7r%fAmF?e8s;in_kv$+vn&bwAZjZ7#WMieDT&w8MxmM z{R||@cW>n1uxxt8>^`O^{Eo-&$;b^z%(qYYuJjIj()L1*K$>xLZB(|;yg3ZNkndIV zT!L>tc5g&(Mq<8aBfclmJ&U}EBs1&E3CYyfZvKu6pUU^W3M zLgHt4h@O>B^(6F>D@vF0zyr=3My6Qe7LD|JcfihWNE|9;Il0oOp*s_qgXEJ!gd0JLGUX1;DNX$pcC6~_eE=0cwNp`i$e%0c7(@5((=4k2`k=VO*fR!$P@9<_6n4~N^BAG}#%u5NrN!Z;1*#(LD;zYj)-JQri zNOJ6Hk0r@O`i}WA!6!>YzQ%r<7Ff*J5IQTp0lHDh=zNB@(>)DL@r!sn%tY^+fn$4u zPe$6t@yz4|Ut`2K1Kr`su}IQ=g}h(*=BmB-%!csA(JPBvPsRTENbJ5iQ{IejF>(*G zGtpa)2+z!4@x5=hf)6j~wH&)oBJUtEUtCD8Pe6`D#v?5W|5ndRy6*!c6K^Ks+Y!6F zAO|5aU!Tw{EtSD+^yeYT_|0sR48IS}5%3Wudd@9<|8@CmHrsrXUKQRA^0_( zeXWVoOIX8yWUfo__1%~16A6$wIY(Jr*OP99{-W%#_>i!RFStsdzM1Ye`4CkTBTi3Zhs^XABW6B;t*RBlBE8M?rh{-Br4=Ig;Z*#{;7EzlIB|}B`?H6 z9dbDm2h&p_i8DN(x*olhu=UwA^mrh(+H~=3H@Bs?W3~jjH}ULqJUf^ITgCzst7!D) zu}@;$gN4A2Q2xjC8Als~+qIO<2}()zf0VME;9fK#ceVYQ89A<}{qqoXk0L9PIH(FG z;F%r$8r}EE&qy+;wji;x=GW{5Prlr8_1}-#LS$nk=9wYEMk1BfX$PaPK$1MSN11Xv zZNGJy8u%oWuRu=5?q88U(|Y($jrd0F&wG%q5UI&mk76ieSLz4Lwsz#%knan#*?1QI z-$qnEjK#;06-XSFBgK{cx#i|Oj9#LWiMZ0`Jdpa*?838c^6aaaNmQ;%Jo|F!kpCKs znR7eOeq|1o_j0?5R2=W~+((FnDeYLRHhOkf%p@?R6rj8{C-YD%4{iTBmcKzZrx_ZD z$m1*NZN&D11yX}HbG*NhawW`IqrdeA4EtNQea5xt=4SxokByXX{elvUMldyzASaWYeMd{?@ehT z(Wo{U!NK?+$mr=k?*Actb^88;=*A!)AT3aoj3F&;i=PIEGxjI<6_PdPXWY^S_5aB& zH#OmpAIz8uR%sKrYtzsrGkU_HKJ4@T*P^<2<=G$2E})G1)UAnWoO1 z3fdWnq|O?$lz6i32=Q6kyAqO4NbbxYjg3NN7bIrs8|L%W`RFb}u0+I1@53%E^%q!N z*<|Gh=)#qjK-HC20yJSw@j1+aP;UghJUVd)W## zmh3xa?1N}5m83|7LXw?Ikt8CiBo(dy=lh=X?sG=^fBW6X8QAmu$}dD1kdVV{HC#jyu1Z*1t7)2rt2G`{5y?*%75De24O zyO4>O=(TrvALIWSD%w64-)ok)3ENh52yLhNAF^GbWf9yk$8(-TL!!zwAw>Qq=jmLKinuC z(farv-=9#PPBGqQ%j<{jDKr$hyw)@T$*+me_a@#>*MFO?f3gP0w>a-X8eC;l5D9V} zB3EY)F;F^xKn`*Qa;T>`1l~~~r-6JFR}PO#s0xbbw_<33H~}q`#2kY|khwR4_kJcz z+9YK6*chL-NTV1oZd9QZ(bL$UMQ)bz(8VPhGurY#E~-Y0NS?>=JpQjbyakpg&tu5j zg(i(IGSbRx(q-YUbPeGh5B>6ata?e=zNr*T{AK>FI^OppjqW2uOOW}pVb~`i8M|{s z6G}Ov;}%G-2~pAZ!)*>e3s449PIg;yav-!0`$m+SEjF-a*oJRT0SkDYiR#$qQi(_7 zw&A%G#dVF*iWyphy!)*U>WpNF)GJ75w@Dz^db5ctw+SjT8=nPe8`7w1*{I}M1eG3T zwi0FJV%W2LrUJA}$)#zY1-)0{WrvrBdf?j^ZAHpkYzFOAYZL?gaFziE@^#$4~7a5bwCo0NGQ2G5NhNGZw66GvC1|OpCM=qQqISg zQ=tdZpcEtwT`I71ucS=!jyRmr_)J8fA?1W$=xPJ#*n`nfCOEISoXWP#SsFY2EF1Z)oy+i?_&$ zuP45J(HNw>_bhKzTlQSo4Z(-C9X?$fZ?*g_e*6jELn%R7bbEcy${a9HSS!>KsPd@hnQjojug*4M5H`<^e9`j&S0tNL%Cz$^C*-5xbU<0<<&NO)DNO=!hp3DY*gZ*bDJ3^hJFWJP6ue^8A;pI=I%b;pVd0j0}t`k0veF$=g z&hD9bcX}5co}4&M$A6{6d)o5kR{xK%e}>u;pY#gJZ!?a|HFo%JF7Cpx@smbV|<$LKhcI}5Y>CN4Sg zk@yU+k~h+cFUK(MeMW_mV5Ijqv%4NylT#aeL*&MHI@8cu*<0?!*Bsy0Xf;yaGRwPe zIBgDZ;un7EIk~I|9F&zUnM?Ws4An=3)q((#% z#5nm4Cn}21p2k%P-)g8Pis!FMTz48?yj&V;j@=%0r_B1K zRN|KS>RxNoYrA-a-#enGP!^m19ve?Ow#DdWI-C~` zCtS%VXV9-*#%bBx#VX=n~|TSx14hG%+b1Ftr`?54~kd+vc(hCO~v=J-}LapP;~^@6AM>*1RZ-GY=?!}8?D{8rf8BR9WiGw~XE6P);D zIrG;>+*(#@W;Oo(4{VQ+S}BmOzWkL z{YqAlH}e{U)8hL9%+DytgjjebEKV-{-HJUK$;v%F7u;mKz6tLEFT)A17QXe-<4Ci6 zr{$f(b{74J-0T+M?@O5GfT6k9sz$826rX6CZYe%ByWK5Mnr>C>Znx6xvgZ5OQ>7B$ z%i6+w3S1J=%O(@8wMo(xX?TMyPG%8@U>|WAvKdt=Sd-nB-i8{nkz^XaY3N0yyyq-W zdg@l}JCGY=&t7v3*Fg8f{uFZaThHeAu;3zXymuVlv-plh6OhJN-t76qYjTUQ zXCRl?G86A%FIqF!dtbx%4YV04?-9%U3!7~5lQZ+uY;!j4$^$@a}-RIJ9pq?HfAB80^x~*3)^@opD`O(%q!xk?3`~drYgW|Cf%4=&qg(L5-Ql&hJh_##HTHJM4YA~XhG+V2C$Fu;8;I`^G#Y7qW=M;K_x+}0 zUyR)NF4*`Cud_GA;mI1|mH2<)@D|$mKIb!TD&r7xdEM_b@!c1;(Jo$^!_)YRkVfNs z+w$bTvXbuHIXI6L++*w&M92Ln-Va1Y zvkbRs;)C8q8kN3RAYmH&9F!YLF7@8`^{d^e9`oXA$3}QLlPiyZMWl^RAAToiat*M% zJ0ERyEJI&)p;Y3exNcq%a2noyxVJ!kk%kw(C5@wOnakaQeIIhOnch)y*4=C7aO4E% zJN$k?8rJ)^FPtsKIz3v7+t4&Dy6TRfSn$%r>jO=Pkvw=`haP(_7S#`yc2^oFET}W8 zScIzrB_fd;G^Miz&4L$_vGw#my_?6C{mc>F)|q4j?Lrz_AxfJqUiM*MVz=2#`IH0+ zy}WDcaH{oxO*`us()RXhlQx5|Kg7%A%vs>SAuZd_B?8J;CTFgl#Y6^j%jIm?g!*`0 z>cr}(6h3#L&PX{8;&c=p+_6aZDiBImTyMTY~J_`(Xo0IpSR1&?I65U(Qt>>C(K18Dm#(I|3ag~ zoQGDgzb7}wB$*VE6?m^guRF9CElmd1&#=pbI`mjlW8=~3DewG7a05KKVMeRs4DR2f z^A2vO#mQY8x##|CR;T_hd$@sK{<^W2k{|a%s0h-U{mtU!d9?RnzaP1!H?WXf6Hj_& z9o~cZK8)HSt%)RB1zWfRc*tce%`Lrp)gLU0eadU-&_>`r7A;2_U0Xv-xMm)w66ks) z?f6(WdiTvt*1jlzY>@XfD zQ1KS_O~{Qe10IWky|3VC%j#8w5f8t;NXtpzpHL`?nQg94xD2Q2&Zm}6Oi1;9rpQx= zmgegJaTuqBGe1^lTWw60u~kR4k;@xBSYjILHL4ejNm_dc{01W}`-8TuGO)dbRw0*j z5st)GMR1W}Ui*5C{=-TqmiPciDX6`CY6cG*SiBU}aqK#*?;t_l;oj3uET{PSEc)I_ zo=Z5igBy#p!%AmRV=s9cHK8GD`7kWZ8eW>y{t@032Uh_1>rru}S=(=M?XY!5-H@BL za|~*NtrU^%S?>jS{Izf!pU$KpN<+#!V|lXgcpLk>$mOjqZ7;L%pNrzL6+;`dgg=JQdDDgFatGg9YFBu&apJIS zB+Ye<*R(!sMESZP+hQ2Y(P|_JVQrBw?001nURGCqz;Cv7gsgKZ^7B})w-eJx_#8$@ zQ5Jp`&N2BynSF=tM|2Unb+Fym!LHD4oVU#3WqE=6MTtl-!qe;e<*`*p)sf39XAe-# z$<}ypi^IDY-)5)`wYQ80=fA-WaHZyx=rv-z|$dP9KMs$Y^1yg6AVwf z#JkvcAmJrtGj(t}Q=6OUML7~n3X|~M7krPPri){|nF)rMx`ca2(0sHVUJbpt!U>tw ztGQl3$!i6VKOJrbX+Jlh%1Gnunbq+2V*3ysLvq~0O6ri)dXxD~p$(EdZ>$sFEg4*w zM$M4&~c(tP8kI{DN z#Ercca_gf2ha#pOi{Dgly~BGL-;QV$()gNMUeRUDU7=*;@=9)YdDFZ<9G*;W^us?D zDQ~Ie$>hd!*k>WP{WY`g&$O56UeGYsUSyj7Mf{f`?X&M&o=nrfa~VtWDH}uR@d*sb z&v|7W+Ix8KM0*_CaZ8gkh%f)0wrXPO#0zoHdkw*556hcDqO=*`Pm@eDTOnKcV^rSH zlXE#^JaRMJ*JjoX$TPeSSKt*Ujq%_{x>^H?VI; zvdE&GZG4Ap<1>THOpiNWQ&vu9$cvYwn&Wu?f;75GrYQb(iB*kG63Q%3?t#@IV0=2W zxhrT|NI7vi!jPkKOIls*O^|zrS@M3jOU(9ufTvyJ5qvwM_mT1{TAr*zeCj2RThIt9 zTAHymk1A33S%Y)Dtc_wkxux#}{-=;OxrvrnC@HqeQfgILy3yo5omx7v*<7y}G|lZL zD1V`XFUO*rXK8XnT5Ig>klRMmCK$45BlEmU+~Tx$TIs|cacA3bWP|rOhj!Y~5?;c# z3avpdtvhAMAn3IqDs8#j@c958MOtQmT8^BsL|>uhBDdSieG!noK5&xcE1Pg`!mk+8 zvMNitu!Sc+Rk3f+X@*NJC;61CB4eK`&GSSSc;lS1uY-Rh)D&r4oh(llrKe+Girls_ znKmX&Gkh%c7CZUejqd?;8YyqR<>g+<3RP4H$;pa5Yi2KbAK1q&{YBm$C%|>M`$Z(rWo&e{;naKDd>)`2xH|7;yC+tDwO(baAGJivt1Jac`F)S=0=j0E zS;e{Dt|ck-mYd(j-duRv7dqnmDC&)r*TM4SQp9NN6OemycG2!$&xL<>iMQE_Z#urS z(ITY0QI@y=H5Rs`@6k?TJA!gkevM9<_{N637rh7WjrE4ntNHsV4Jq#(%ac>v)!5&X z-zigFO}o0R;r$ZwGQ589lEUw_KYVwhJxF=F)2kfp0YeyW?38iJ*ef? zjM+%yJ80|oVCeU<_qM~6n^Pagza5fhQp}2v@Y;*4xo~3>o@|W8XXY}zWO>E=#KH9h z(+8y@4bKd+yd4IcY#DsI$m|?t7^M8V(#zE(Rvl~b-GF{Z%A@vWi*|aGxkdB@av!U@ z)(!`zd%Wu10xu~{LN+-vT#bK@bur!m^IKG2Ah-_udq{TJy>0Q$Icnmo6#A|5zJgc4 z@+vY^R7EwA##h+#WU197*gGOOzXfc5P4&L!U3XuM*9+giXaG`PJdHlLM&b_`i&_dLOeqIUA5mS1v28TmIqd#*PK06Mso~-FpaJZj0LiW*0h( zG&~xJY|$F)&6iqyy2w=9noaS&;XMUUd+)>eO7V5zQ+cNiCVZOB5bVP)<5kR*-8J5; z4sQy+)6pWNJl-!RTl6G0*-rE6#&@Btsa{hZYrXvruQ~pI;a_k=jHkEw3=L_p_|4_z zq1vSw4ew3wM|j#?!dt=df6U=6v+>m_#GVoRGswNVR_}V3x6Uh1kJb7ZiSIb{JktDb zGjT%TMfgn~fLQr5Ue`>#O`hENUeRVZ1>bsTio**muQ9Fb0n`;$ycRzsadp3BKEKH? zkj-9;rcAUgEzNB<^6;4V@jihxx6c?_cyDB$P0W2E_rRdQM4`Onb!!@HA{FteifSX} zOtDePoK|P--H=_^aGM&r>)UVM=D zxZ#l%wk_T#ttM)Sq>yy-~6Ms*_y>#Y)5<_MT3#@@=9QgN3!N>DfX4fE%fQO zu*_u9dtPC9$zc+T4&V3DA*8%k@&%rpUdO+~#1uN4lOtp#P2%kR=JVIENo@Bj!_)p= z5Z@cnO(-4+tu(TiLT3wK##9=+J9Y?9HhR?gmrC;l?)SZi!Rc^*2ksS7H>BZxYHb554ciA^@&nu<_zG>~85~ETQ7E3DB(FCaSa|#XIPA0wQObT2%!u3RwICSnj+6QQ zd9(m!vFS(JV5H%1z`hMlr;(;331Xn_-VYTaL1dRV$jMy!BreM0e-LRrH;NmXtDnS0 zDC{<#kR?3X7#q*8l%~7en*uI-n1X}R;Y=QotWr7bm5|%qMrRrw_j%`> z_+*J$4g6~%Extc3PwoL}jQz@wXGvN0niSuDFOl85hSv=D2T^OJ#g{{3CcCnxe+2e1 z$PF*ehG(*Sz`Gk>QkaATHG1Q8{AW14J1tLo>RZ^~xr~>QiFeTJ?ZmeW-vj6)r13Se zyhdBO)d#gk?s-%3XH4}j3%k~b-br|F^$x=SX{5!s+45us!bI% zx3l*_El^ALdtH(6j_@j6`82Khkaredc3T}g@ZF29em}BPxY7yEQCM zj+0Wb*F$cNtj*L~4tu>EUWazf@ZjId;SIDrxwXFs_Q#RinlEG;432o*%barT&C-c| za*)9xIHw|E6hn5gO1!)>CLN=QA$Sw9`o!lz?-1`ciHVIi-b;AdY??`#Y zEKg=iI%0nmxgnP1SV2NGP3)L=Rjb$tG7R6*XgN~ea?6uD(7(Zc4!OKE+e3GS+4#aM z2~XqmDXMFCGJA&pF80um_0|05awI0%OkBskTCLdWZIHvhn@D{NDvdO%C5Dm^t~A2l z7-=O6B@el0s^076MDs8{9nmsxhcqep zH$%!>X?e29VKDZg$UQPTR@3kfhJGi#MdWhyMwvOEj^|9Y0V(ZMLrXZ1?HBYrl3eOd z#j+xn%RSzHqDnHpk?VJJOn_=3<$M=5ZO(rhGFoDP7P+HrciScohm2F+DTgO-NnC>e zn+~tB?E>%f+qc-yquhxk&S7#_j?$M}Fc-y6dw;^yQTr82ChHztkzk}N(u8D-%IxFy z*xi~Gj%<@S+}&I{@!hzuy*#aBP3$Jzi=&cAvpde>WLaBB?2jTB+02G#n%WufPI$T# z9f|LFv=S-rEz8Tdm(^gXG?Hs^Tdp?QEHKG@8s0Zv9Vb3{?}WT_qKd%SB)dGTVc5H+ z6N{YnnmT`3J?lf4O+4=;)8hH9*YOITjU3O)T+0&A@4P{HCJBH|neyff*@Rh*`%$;x z`Mo#w3e3h1vnET0#PgiD`7K<)-v_&UxyLj! zc@9a+exd#3Wor{_XZ`UWj8YxiOO_^k%kkLVHm0=dkKs8 zL2+CmTm0A9zC&{9xKJW>N`i{Nc*Te$w{eO5#m|zjgnhAm*`vnrB*1;x=)&zJzvxwP zGNQ?^c9L_UEBxzn(CH>WPV$6HUVS1z$Jc5FNOL_ZfwXhvGGQgi^gs&sI>;@E+_l8v zSMO0EYu_)OI4n-q$3B2pYoru8u?xtPjORVD_eJiwxt&pi1&rP}a-v;Tf*yq5(?~10 zqPQ`VNR`Op_?0U7*96-24r=&!Z@yEmiW}wN8iceM?n*nXZSG z$N%LDuvZ<}v;Qr${lMzR`QF2^#;wKnrbE-={C|YDa5uDgzr+=2n;qJe{}$VMp=I%F zUxD_%L!0^EXz%QSmf$~h1=>D`HvhlTrtXE7)$el!+9wWe@qeQo7h2RGcLmxP4sG*) zqpjMK(p2ib>X4V{n#Hwa;0Ri-IphKcK78u{W9%hyn*;W zjW!_V-DD4i${t{EjZ%=ju<(fGWlwc^iGGcCoRSU{}Jr*bDTkd?c zj(q0m=^B5Y!;u=i2qTf>Wi9bi@`WK@4rWuZ*Fkcpj9i)*R^L0!=f==2xBrI2dl27; zQ9C5z$nnramL~_Z)3D2XEOQ}^OFm`#{bLHv^Y=q@_r%gZ=Qy-QmL|JWd5Dx0+C?Ih z<+MtKb_QC4?|(;YxX9O!;xb^oj9y2Y)1`)$AXm*k!G07;lSrU}3+oUS!*0{h-9C2A zbrPR5=++NooP9Q?UD)=ckI`9TT1{-iX_RI@*MuD>kN-S8t;rG}nf+KPKKavOiJiB+ z^4JPwHTyB)=w@m%ubyULZY(&@jw|0o-aq%MR3cs2T=W6~wTlhfh=Ga>yDR8-$xh-*JFYM;AkY9zU zj(tW{3GMOhih3c9DzBl1%V39MAB*Ias;Dio0?;_t^dE4dnu5>sXc1D5eLPcwJX7T` z_T$LSUGG}LDeON6CrQ4teUHyiDBqzNr?1VOEH&zJ&(zq7e{N42lO%dIVgr!$p2Bu0RN&b9?GZ>#?XaZ8sEu>+K)~UlqeeC;@oEzx7 zDq23_mimo;wT`i_`-gCtLa2_E_h^XY%FQgg3ikJr`+m&sGhNhs zX#(ZN+xTvz1>A|fDsszhx*d!Mgym7hf21P=-WPPkn`zdKaBhOM8ZTs!`y_1u+s!e-cRgSHP|9xzoa)t!Wiuog)a*^etPm**L(tI$& z$`(G=VFmUz$j!%!rlwqO4D)fbKbu&#f5|D4Om*zQ`H%xkF|dR}Nu11K{}H*3ay4m~ z((n@I>^eAUk{S@agz73`H(%UbD`_+0a40?CzG5JT1o#ehc*Pt zFf`JkJ!xq&?Ya}YTe3oujs5hxQ_xEJey3PBkcPI86dyXY&6bvz&;Et3OyfLp>}hDF z{ac`EPCtY4B|7EMwpyB;Qp?)@e~Il=p_TC~IW#S|OAd{LRoTKh54ocBFSKP}LreA> zIJ9h^adiNBNE-m)kS6`?R_y;m`&DRV{ZluRy!gq5a^{oXg~yT8JFUeIplt?(m-lr(;_+Fw)>^^Qj&1CyUcVx#s*P0m^}9 zauxR4w&QFI{mS_-!Yg3XMB3ro89nCkE?J)36f_X~Ge|R>{bu&=nL1*5f1Se{i|=H# z5@~$8D(J?etffO`(PU;|br$w?su?KEKI=|jo+~Tc5cDv<9nq6WdDF1_OwQi&In$}A zDw2J2GW+E1#J6*){GRgZw{-Oie#y>sb-q@UXY>xlbr4e2F8Mo*U2=_N8um01C|$1E zvatMI(XS3<<#(kMOE1D911(3=!HS{U@`aXH{`OciF?NWxow+Gx%EVWDQP{NOurv)J;v=@L{_-k8vV^q<#NA-Odh>10#Ra z^~{F>`8$A;IBEco{YwA~&k;Zs{|U)4UuVY4+MRMFybEargKY$I0(cMh`;ptjx`yRe z)gRM2HiA5e&m(9&QqC^Rxq$5wihjZFo~BU_uJo&xLnCa}{CN)N4ty%1$B}Y=j1xa| zxRB*IyM81GwpC~n!r4C5d{zqGs{5}wyj!R?snWWn(ZVSvU*JiVRz^~?l0RYTMi1S8 zp8j6L-*N@oJr3>G|3+K*BPE~WePK__0M32KE6=@OIi4Th;LEZ>1 z>m}rk;BJ)<46D4hU%5-H%Eyy_3d(ReZ44*8;p#B<6G&bur*BfPILxi8yZxD6V?24# za@H@IaYh=~bMawZ(I(g)K&_FCR{Cs!wNJRbI{s34I+_l^SE_z6pMsIzyvp$Yep9@y z`jj0%%fwAxf4virJS=A#HGfi@!d8rIpSZanq;T@G(Iz6a2!D2wIU z2mgjoo%{D950*n(OF7B$J`a)9%vR)UT!)%Tl5mPKhagExd805(?i0`7-l}r zUag5g@i8vi{$83_TvWre7HW=^R@TrG)??d@wjsCFyDyVJcAvkNsI=7nz$gA|W-5_# zdfBL&Vrz*yAUBtLYniD26kOzf|D2P{0_oh+g#Q$zym6K%Z{XUDecNTcNNtzb)GyX8 z7T;(1eu+w+iSd?N-hON!qvJ?AP$QbW%)tD<+2u9!TXbVe_)mt=>%ZX&H7bU*iS0A6 zczKO=DeShuQqGeg;Q^oLf2XAWMOtYNxAS{>C+%{ZR+>XqC+#W{OwZEXAJZ+C5m`)L z6Q8C?3&x!IM8doA24WwA+=4D=o73^Ipj-Gyy2W_1M(TO|UqZ?&nKg6_S2KQ${U~yI z$(aherT=rcSo4(kUjBrC8(l-8&Kn?*Z(H^+8#GN>5 z0F4bKzAL{S#I7xI><9vQ*iY!eYGl414VPJeg2Pdy5wx)p$a!EvbSefgBS{#+BYx2y zu@UzyKIc&db`i?yVK~u^*tVd3NDjs8+2gM6pO~sLRn*qM-Qnds&%_z(iIn%Jm}aZ#zhk(9usP?IFHatGJ2NP=4={fK!oQF(7TeqD zJoqh^J}j1I<>dEH{wg5pqst`j&LXernTOZw4yB`|$n)*K!G00RF+j^ila21pgwol6 zk7CI!U)j8$nTJH>kw$ZW&hV#bKWtB-XOMfrWME&zGnL=P|IXpf!*>yS87Z%~Y z741as_|cc#N##!p|7=%3zGtj)%1O${_#a2gn`C)%l5!FIUzhRL(#T_t=}|uqJl*}~ z{DsphbU#ww7Rwue-wx~t(79ZUSx7j!mYYx03?B1ubmGf*ktT?WBjx>Md2%@37<+Rh z6J8yOSKe4P-R9Rc_HKSkPmb)y(KO__Y#ng!@4y<8h%J1%$P(-?A-Aokc9x&J`;CEY z8c)-RlSOZGda(&lYCk;qZEGm;vgpk=On&L%w<9as6t>~N3)Q$3%SwNfE_(B??0ZpF zl&b*Wkrd5}Gv+g^{Gmuse~42wZ{WKg<^L_l`^fT6U^|22e$U(#<}j)W*Az`Je&V7GJ!kKKNnl8A=6aL2zZy~-*(ZRoBy!UKedzdr- z5S3=_@M=nKQyW{Cg{2bv`c-?yy5C%OoeR;sNaLz~b@&GpMzy6RsrXz-+mytWMk{8& z>fZ||IdtWa3ZFYr6QrEhh7;Y?o~w)4PoTXFqIzjz{45ifDfRyTes~ov?|N1Y6+sn| z@|IYhEH!VBy%)N`E({Q}UBBfn#XyL*q zc`#u5Wwh;u<&O>WYdTTAh|kNYeD)Zpyp3ucEB>dTg{XHv_V7qbt56=dXAkz96V=7% z%J6i!F5KYN9c@4w)pQ$`JdtN?Vq9bfa(87iu5h624<;&xqHy~ipE%|ub0Xzjuu&Dj zc0IZYxl6JR+OirO5}x*_IJvwH-?FG9Qr@qYcLv+{DE=zS|60ZX6y|ca`7~|z8GkRl z+%~?d_|`;ok@AwwkJ08l?WGm!jND0pT#RVKHGMqQzr9baZOG*j8Rrj>M%!#t%ljYm z+2_;Ba9w$*U)#aSZMcU)ok1F2ON;yIcG}xDagnQ#yXU@;si_U~`#3xeuMlZ8yhr|9 zcvEMUVM=DW|Ez;63Z?{Vhcvv-7WX-}6X-{j<}rfU9>0?wC8cL-V}w7`;oZqe#$Bi* zQr@eUw;tPOv=hmQtG#|jrrLehU*3m(?(8y&L*wL;27ln4%Zt&r7+OL}Y-Leph~M1d=nw;lglLYQ#`u>U zUKxDLqqYvOndN*pDajt~U;@ZH zrgs8!4It%L5+scCOObZ;eA3=b8X5m@bJF&+X=VJEN6y+zrK}@C!g#-d{9QNg9ZuR_ z|C07sNjt&sB7ZlXBfh&xQv*GMw1VC+X%o`0%|#25TcB0uNP$oEhXdIwkgYg;fFcaB z3fX8OvYwzL_FhOzQFpFqDMbz`{P{rA7El7R@Npqdi;rLYrKqj9pkJvDp;=z~ixj@rwiwLP+{C()cHsHNVyQ#|&BtOV7P-o&`IxncSf=?oo`}Wr z3On2sk~Tpa%W4~oEQ9Ka{Rt$8hw|)-$sBB)v$1RoOKZAc@(FfrpqIoC!*djxh?Mr0 zp(V)K%RKChkvlA$4tKcE`412kM+f1y9N!iAec*7mS&pACE|MQ5A(yi=Y$nh9PdJ>r z@sal-zlJoP!!~y_^2hNept#6#B;$cTx?wy!ax=t8C^P(xPH9cOo&H{cLp!9rkwF-8 zIIrCpdvmlpN(qx0nU=d~$AjvjTbh5E(#lvu&0U~oWHO{33AEny~cW zPf1XBrvIIjx5OJwBkbuUpJ`)pcZV|Rn?bEfo@8U_T=pXEd6xetk*wwGzPSD{2BBd{ z^EJn?!sQS$%a_J)Znw;SgJfv7pQmqZ_G>;qi_v+9v)sm1q68;%*TzM*q2fh3;Xo44 z&UehGc@obYza~60WOKI8qkZ$Ef=G+#+B~MbWtC(#?2|d*s=@?@uyiAjQA-{#{mwqxida`(h5*z-tnn|v(v-zApG zD~LreL)PH*O7n4J-muR8z80msmUl?-Lfj(%GlJ1NuS2?q=w773d~MQ4-T#bB*%w-wKc_z*)kY=uX$l^YFj&IzXITpT5B`xv0kai_sUyhe4)b%7hfHaaj zOeEnHYSttUsF1CxFoM0Eh5n*Hj2vkR6~U(jT8@F^Tshouyql)}RfvClwq;IG}HSti~x|1(PM^vW`c^WtTRRR-R#IJ5$WmLSLJo3U?0 z>9lW=L{&T-o0j`OI8g~_7k4}hhTHCFFXl;bkD2!{Pmm?{BDR@ffcT>DZ#v+lO|Dur%q{qG%~EQCLR|EEZKH(Q=8_Le8gpXE1q zy1!ng>V4DCJ|H&qmSZ^n5&xf&R!0TPi{2I&Nks0+rKybYpljW_GKs&$t@8_l)7Byj zYx9xhMx^02x45d~`N`J~xIjZSb3h zyp%WBmr2~3^H{n|x-GP+X!1C^MXZhqhKH^I~Pw_*2{7I&}V2M2k#@0#I^Ga^J#{w zZGN^Vnag;m47U*7d&D}?C zqE@*(!5>BLPQP0waa9(1vhZBIUUevA#0iSNynWYYlobrcTvPNHInf-!=Quj=a2RrA z3*Y&dyL?I9x!uC|IOW*mAAO2b4!%}J$cp(g6zuy2z>iewxi0_EUW2is+ zn_{|cc;d7O`${CcpwS$~NVi?dFu=aw-!UlG(Kg`oF8U2A=M%$;4zCy&8I5M6wb!yh z2MOnx9Zr5o5Z*!mtizKl&+p*B6$wVFrBCQb)8;q#s6tq>F(R{l=tl>~s#xyc+y!H= z!^xjDbiC|oIUo52opj^ViHJ1cAq)pBBeDkw6K(iU>||fAnOTI8XZ9v9^LOmwFsXK^fOXUC&P(u$I!Sk zlVr&403}~`qx!_}0Z&hNA-J$Q}zoKMqaPvCzHPxrvz;`<}ItxAmdf%#L>G1w-e*+?!eZnC_cwy+L{exLcj zIfd1w5DS>_-;QWiVUsLq@)tdXO&*)!7QDnK8#89-_ege+`reR8B*}yj8Qp_L(j@yD zY1wo3C0n#A)6)-Bjf=EK^~m}P+w(H);LYR2**^DggQvyU1>YX%Nu<0nmM1e!pJM+4 zO=jmi$L@gh+-Zu>)a5b1E<9};vM~D${@)?Z?x&X5>vsIAnS*C(7bc_TUwP`oKBiQ^ z@H=0DmX}mY`}x1oR_!m7I6eDuf25Py3Sg?B=14Ppvy=&iCwrDj*yo|%>{U|jp5-ii zPzljI$?;474JW*go4HR8|92c7CfUL#L;i~WFXRrU0feq@|@{$;*XSfjV(TT&h*`L7*;Riwavu)%J*CAJLPnCBcYJc^3#YyUAP zzdzyoJ8Drg#(UfHZmbm-xdl~0Yq6!<_A>q_!`l|}&iI4j6%W5NH;?ZEv8Kfv2@U6ceUXp~$b`ATyJg6Ab z_->IeOwouZ2ijMlsaM9C2K>*6j!XX(uZg_%BE6kY=TuJyO|=O|}Dkx<$SA1~)6`{S1e9 z6yGn=pGbL6TAn=D;r9A*kxIxdn)FOv=|}$^c-l3aOJG6gjRzoAGPw^Ug@#1=j+e*$(lTM~_I zat-TqxjgcVUn(^cNsq%QhR zQvVJi@*}>#qSqV6c(}_JU4IWd8*~zNEXsM`ZHCi`BNXA9oxmmk*;GpYSeeBAagU7P z7R-C&BEykJm)(?Ag6slTVSf|J5POUhB{?GP%Mif>tNgUo*!sEM_#8xskaEntP9!SR z(20%d>SzVnNhG)zCENG%;;>1F7%yK4ZwbF$sWX_}TU_vv!`V&x1L$LXjK-0m#G~VS zhBDOibzfZhB$^7GCP+(+fMomE+YT>=Lq|d|lbE_1-$-lHcR=$U&Lifx==_pQAKu5Q zJvwwPHALS`qHVO^U}7_UJ!^31uvp2j!FL1Ngfx#OY>BatiyXneHy`_-64bua&dB4k z)8sK4+&hdDd%pge?Q49$M+x`G@@QY9m>~D~SHNBaX-}8(njZG_Y{6J!q8P*NK73lD z)=10hep~L}VY`5WrsR?MRuY$R&OPepF?;ZWlSg^IK_mPhK+4-AT z&0@T_EwA?j%yFPmD1-d!;-%Jq7~a?6L0MvOC%mNaFLMUgkha-8E>ax{MtW1-gz(4c z{-Hbs276!RJ~wD@9mCrey5$NQz$+ep=UzNU*Gc%NA?3BOJh`uNHTJiVjFeh_tEpG1 zmlv`MhVM?a2Pto?<&EZ&#C0v=B1tHn{ECFL!j_+j@9N-jC%$W#?n=SG zHd5X^%PT_Wn`3Wv8LvQ+;qGRH;xI9o1ut2?vMH~#!&~w{c*T~mUhFa1Aq;E)m58Co;5Ehyj>~ZodSH!-+{||@P%KWY9QR?81 zmW)}*ZGVxvhWk=jAAV3^M65n!IYd+Zdm}Bsn=Mb4L+rXJ0AHn|q-2ZVla&*Ci!tGdJMZh7+fvL~<)Mlz7=ZIfyJOyupEcYCp|37AKKM4}@2Ng+s zjIX=1%;vA8qc@P|j1gM4aDnVT>>r7b)9jO}HYzG;@@%YxBV&biJLxK*_DF*{WP{m>Z67*>+{%=<$w=Qbg>^&F7@l^YYg*HF zP!dvJcDt{Wo7tLRZ-F#(!l`Eq%kYwdZt!Z5582w|+XXE_$}3`dP1`VLp-$*`=issA zP7~jhB0{(^nCry18s9h3F{C`5FsSh`6A7pZk~QqI_EzHS{)(I5n*w=wl;(FRzN65~ zNO|wu_~gZM1s`FO1j*&ki}nQn>|B>uBsc?48}I%2wnPJv@^s%WS2osT{{XdST<(q} zz8a62Pt(|n263ZeW9vD5e?~>x#&|^qOlP>1lgD~vUxOsR?0F1l@I3RmD|9Os6ojYo z$twG^`2Xhc(k)Ler{--J7b%3?&XuQv;hFlqIVcaWc*u@K%HUfbbw!%rwU#H7*I!`& z4#^4zz5HHst()Ilf_t3&%H#EmwU3M3iIjKA^5ht>ANEw_uKt*usr-ru9i05mz;`a% zi-FM18tF1f4MIJ>mxqb{ueH^j#E!BBYGUS#=xI{vRAhKO&-p3411v_%t54o44n^~TT@3vr<6QA&s@vn|FzT<|M zAdlT>gPVxLhc&WA<%n_;_F2f?$rqSra&3A=a&X^h7S0Vz zjt%J>NFXDL4CzlB*guB!cS!I;T-l(X6U(3xvR$nByRGaYf< z9*lQ*D^obl#Qz?oyjLtw_J2dLkGPC?%yuc0xjTZzWbWMXV$RXDedSsy1z9fm9LU-cl#skMM^>P9L0Up5X+&({lGlFN(u<_hliA7gY{Q^1kWJ4fa~q$`=XJwt zxI_6JZ?-TSo3ZakYq1ru!)j_ssSs2e6KjSU2RW9)??;Ez)o{Z1;^yT)g^^t8A6PUJ zNvg`}j&0VaY%2z%i0aVDWabBN!?P@^jx=xmZB%k?y({*9NTMokqdEwUwH(0#|nj^rP1JNzQJz}M@l3G zzq^rUZ-?Q8^D0fT|4ZM0XH0V9dpWBHg&8}u3z_X9+#f-`kY+FH4C!OAPetx7X9X=( zO3l<^wV;Z_lSkbOZ-K)r=J4Kfc-h%63+HSmUiF|AyztD8__pA`108XAZ6$C9Cpq5y zRqT(M@jxfbO13myv&5iAu-xGl#P|3TnZ_6mBo!`x;t`l;-L^CQ%KKt7E+6CfRCy0!X9pbgZ zw;fu9G{3)Fo*eSr)t##lNZPZ$ySl)16JJ*8Tamg!MR?jjM&UaFy@-@2BM@8k7i_;H zuLm*0%VXPf_m+ld`bWLsK8Gi(-HYR25h*X59i3#gdvokSJ`0`7{>_8U`=H)B61p-%F@)&scuDTi!Jss`tV^5S^xeS5W8!38ZCz!~22qq?Uqr z;PEHIZ6?0yXa~~rn{0XVaF}VmI9NgQ97$baxniZ^nf`W9P>2pt!}8=gmvOyme@HNN z*~m%Dlf8vJ=dw3($sR-Us@pcMCQVOHtb1>87ql=?QeF?G2)f0g{b6Zx4?+d(135XX zX!lk!1Go2Cc4ODxc5P)k%qU@hL^7|2fe5Qx=3gjzz=M|g%gfx1p7u-fiw#)z|-oGN6GKR ze=nkh!nX37;l<0N!>>&q(9QXZMM6T350kaUl0J=d3NJK?Q`@ zJZKCr{L23t;M)YvK*}p^d9v)T42MmXk@U|kcY?5yO(iwP}*@dTrVyoBFZpp{62xz7e8H&m?0{w~@=De8cc zmShUqbnpj*xejj!zI)IoNO=!hp6sB%#{M1Zn=RHUGc0dm5i%TkD0sywe7W`YC;Ytu zFk;9YnTZ8{Thi4j5Br4^1^^{i zBf(?v_!HrFC%#os4W#WYTiDqm(Hn`S8TRbdtxg_lA7}7R89P6jtEp{+;qY|K*m51` z^`vbY}^&)*=G!bdN-eu#Gm2aD{Z$)lCyW4u; z_<^l`u-+-RBlt=_k0Z@zG3E={!hHUTU0!cel8mG>E^2(7hMZ4NP8^-3L-3JPZ1Wjk zvOUH6BBbF}w>WugLu2f1Q9br7Em1x8HWzHO+Zg`Uj=_&kc<0!C^um9D!)s%Cqp*!f z(~z6p?MZI6b_%YV9IMt@_|8W!B8{)7<;l>!5&JeI4^NRPlQgn?$nwl_L+79fytZMi zEZ@cV06K+~SKs^=E_!V=h)a?vJF6JWP ze9Q6&g_)~%h7_%inJics_Cj)Ey{^GRa5XGWmc1?nwZy?ONXQnhFpwuVpChZQQE#e3 zaoo+EvL9T+qrv*gT-)I5#JFjsd>PQ&Nb^cn$(A5T4TrGHor`I-Z{01gpy{zRBsk&( z^*Meg&_#zcTiggr)>q9Q%t9yR239iN1ZQru?iO4-g{g+caz1_u&p%O~A+f0Dgs@10 zta_+{y&-a=TH9Y7x(Ah~#5$Hd7p5(K9g&ti!N?Y#!99)rN}Y5g1^*(GRXu_h&~k?f zc>ECFqtSGvW%ZDyO-kXFHP|;Im)P63i?Jc2XE2UD9s|8EPTmNyAMfK1t)cl#3C(E@ zIiF@lCvs_L!;!_8-<(64vU z1D@^_(j}GTa^HX%yR*TRvlX%0>` zUP?}EF(7ypoHmhOHP~;HWH-|As0G==3z?^}|A1s4qt72IXN!*ywt>NLc#Lm9Kz}Z7 zSX?BE`Xl8rZp#+EaEwdG*z*kM#^)j|Iz|%O;1A8G=~zz&i=FsJuVx6we-ct&#}H?3 zh1-UGAChZT`kdkd0}Ri^_f)WLI_lRG-jpLvefBP^dlJHlM}aR84~=;-=*z` z+co&)K~<6Fe!KZ8VKlZ0Xgb=IBb?|BOS5a(`kxLqB*g|#jei5an(to?Co1nDyHbPR z7XJQBkng!zJaP-$W*7&N#*;;W)UHgfUc~+fa(T^cYcagk;5K-Aw3PeVxJW*9JyPEF zmX{akZP=IIYgTyawAbk*Q@dtW%g~^s6JI&}E2D-Euc+n8F0d2!?#P`M>6?&oSnXjbUQT#g8AVB>mC^dYg*SCg za^k2gql0k{PL^<#1a$|}(qmsDTR8I7#oh?H6_Wi%6P_u(F~JHayK>>7DgNyp9!F3i zPx{6P>=TeXQcbsQ&zuR34R$*5&B1pedI@QK<19}Og+IW)AGvM0K&JS{1!oW}CYbqX3DWR(Se(pHyn%fq zlG@b?$ci_*onuOH2wsxpoK1P#9Nzx_!K-I^`NG4hslks9?;|)z&^He6W6P5X&1|E2 zz7mr87#*1p+Tt@4q|<`jX|ecjz_%Exhcv%uEl-w!J%fEDn(U0GE9_yA;Y|8?;ZG7LLHIvu9bE}Zd z=2yw`{(rqq_C!-R%LVeZ;AMDPekb94gDxPAubSn>k7XVSU5(uQcD4C60VK#{*1Fq|DlqoVYfA zZcquH*1|n-nxe;%#>Wm`wy4~f@jUhg$eq$HXX7(}cV6%yytZKyMh$#7pj*brcr5ln9FL)KhB%EsD`y?8UG``*DxA4lreC*3mDg$s5 zy-vz+plu~)Iwn1s3oq63WFPb@{;wk~zvGsdm(TaGC(CHWs3$Dls@%r2_O>M_o{n1( ztajp)Hxch9O=My$zWn@`Eh@8~5!$?{q&M6-Rt$-k0{gB>+hyaE%i^=KFGTJrm1cRSe`Ew3o%rOKZz=w39o|Ql zC(j9zW4?Wt@tRdO@fqIIAc46s9S`LE8*}i8y zShkZHmSsWF*(~VcYl%eS{vOVc4vQ+4?H@~?&X8b6-14A-6U(opi%emO64J6SZ_KcB5ln%nb(z6PEqTi^HI}yrEKl;5AG?(MK?MP#5VOZhRWL@l+PfeC=B@QnKhlz>i9B%i@-$b1qPGj>^ z_`eZ{WyTSduhW2-fCcatPqYT4N z1l?MrLaN1{L+)fN{cSCl|A6s6g53(JSD-h3o4vwnNJN^a3z}NGmL?{Tdd>!%srW5` z*^W?jGb>B@W;iukF+CIUJ_Oz9XJ#4c63<1zL%SE(An*=FScPCJAM+8qie}8jS~kL5 zgc)$+Z3rYLO2e=td0hSHxPz# zKH`&y!#GgZS*LMzVAXTYyD;1*J?rnpt|tBzuca6W_Q4v|)e@>ho1D6?SLwF=r#yQh zN}1$wjX=6Ogv$`jqG6CtSJ6bo(KQ*r`Y7;0SQu4-9Q8i!Ib;r7+HK&SgK#f`iMLXq zxQgge@2?R56T&sg zHKZz|KXJ_j&m9OAvl(Z<#3}me4y@SSiIoV1erIB2b|Jhnd`NVolxmqkSmv2<7uGmG zfXUK(Ub|u*ei(vj{bvg%SI76fB0<4&&)rD7R!@7Rme!Xe?Szd;yTY@K^2MLx<=e+1 z-HBRSl$Wj!O=Tq#)UNb=2$hA`J;wLE3borbP)no zDLL|9aAde_E6y)_M&FHh{s3Zg9zCWs0x6mhOv_p*Ekc|?pN{w&5p<0Vo=Bjtcv4#K z3&FD(VFQAR^KY^W_@ATi!f`5uGZ1K2W-h868k3eK`^(jy>omL(;2njKL@@ErkprHh zhY|M}!V3uceC4eF(eYmO%ttBLZdR5`FUsG91g51Pc9amVgQZUR7+ZL2JWDlM=sDw0 zkhB{buqn&PLuA?LIpa$a-++MTY;AY`JWrS9HP1T8(hg|r?a0?5fho)L!eMr7H8-`R zmS6Ym(qy4pz8OhxI047NAOh9$AX#6wT7JXhZbRn+2w|tUBGK(yp6Z)<9qe@K7TEZk zo@0@A7XIur7isQCSg56KCBgA(Qd+Kf7EOzcgI;w-Q*C?`!PA#AM&b+U3nfdDa0P;? zxyOkI8^ttUq0fdb3uljeR`($CTF-w0q-|@j(g}HQA@w?h?=+PAWSI*tSb=AbkpF22 zBnAa)t=(@Sl(#)iZ7x?C{fR3d{&m}QyoLr$rs|{M$0g>}^eR>TTPcJ?7oFr-_(`wQ zNAlnCT-U~ZTDf!2cFrKj5La^Q>=U9I}yhU|Nqr$;n3G)akO>$a|ij+c+J)TjbG^_$Z2& z?oH`I#M{jDVW8BEc{1gF&#`k^FXU6U0An|Tsh1lHMgC$g-)$})Swzrv{dm@}a=oW7 z@Jzjo#XRC9@Sloc)|+ZF;wVIK#FK1~BajKQY}H#ogEepPTrw9AMBvX0X++rxw8P9&(^=$Wk*=au6y+(FXIwdAcN z49w7cC9SintC#LTaX$1s21!=q&oi$C#J><)H7NDyfO`_+h>l92P`w`s?stFWc~uhy zB-a%1+=O7Nqqi(c!99pO2J{7tAvBv57PrZ>6F6m{(?u5d82Fwji>jbUwy4q3 zhNSrnt|=aN5O?mPlfm0OcWC0#XBYPZ>Q@9)yl?3bz|oVc=K}kDgx9+u27%x<^w7oo z)bk+l%&FJ=_qbfm7vQ)((wKNpLL9>T3bZ=JUxJ{IuXiXsX#t;kUI(688)5K95w1co z@jg;`w25;c;uj)Nktuugf#dO>ibFInIGrSu}t-mUzbSNqlIC;{~jf+-%{2wmc-h|dxK6~bkjczd!M#^;`YKrLk=30|KA(ev)b z%R3NE@oFW_dg087VlJvF9!z=7HzeLpPaJTj_Gs1RU_c#-V2X!n2wmb0jb|d>hoHBP zl9OcZE)#5Dc&^s)NPB(3e?EdK9)|67S>owfns__E#o4znJ@bLqOQvuQ0Ll=Ap&FVu zPomKdSP=0)!{*GjDie(kvMl`$4R@F4dBB;bN1t7~97*CD+#&@>8zi~T?VxI>?xF3- zuRQBD>Ba-*UkI}i@*xy8w7trAj`#$xpGEwa2yMuM0!i0%lCHb2Jv%k==mVXHVR+<4 zF!9Ve9_n$Kue3QgbqvM)uF*8^Jp9?xi? zl?gd<3^|B$0qIl(v#jucbQK*F!cl3&HzAOlH@99N{2y7?)8S)r5Zu#vFZ%j@7`j{w z#_0&F5KOSsX$J$NLwa|>IrpQzAdnTCUs$|TG_D^!8Gy|A5d(&CpTNvNhU)~QsjY|5 z8{q0N6IzJ`1$#YHkajKpT$=Z9B$`M$Aea*T@ou6*IuP{rD z!}odSKrQBYZrStj&)|z7m^f_$#w8vK-Fi3Hc0eOPTLvd2EdC^7_|daa!=bNm%_Keq zvoKFdoDSo#n||t5x~y=&XO))zE~J}_a36vx$04$M#MdDS>Uq#~>#l?;;%u4c1K^kr zVJ&#xL-kn4tm3{ATo~tyx zpNRKCEb}6mcoF&o`Wue8dW63r==IPxM9L@eT;A2d>noDroLeRKy1+jU!NiLdNId$e z0)1HJ2GHo4al)kXUZUiaJK}lXjlk=t@NNa~od`=byc$UppRnJ6_)Q4(vbPY7oE{0Q zS1wDQw{d&-0Iy8p(KvDs`1c{W5qByArk-?(ab(^@*>fY3kFF1~HQDMbZO_a1y61Cs z(EA08kmPU#v$!;H$5n78X#Ym2o0RROGs27uyvG5@Y?eKcz9+(F4d*XV53Zs=KY|$q zLI`04;zAd?T$f?_=KRCuSB22haTR)fz(eW9br}4>2`JxD_%(|;Kvje3nQ036U^i@; zo*}D&ib-48D<}9$dlq@C0f(!V{^)$op@gnDt|#yoaqtx<~<}>n=cPg=`Z_2D&F3A0@OX~~M7s{r zph3K;AO<@?6k;qj6%bx;B_I~yPfLnM4dQJDF~h+?%JDJ-q^ml@JLrBkd0M}qaJh!E zL80_=Ksf=kr)d!6NN)oKc^ZHE=ov@~DGg#DAi9#JI+Udd-UR8Yj`C(82(DK8$E@86 z8VY(5VI!9~pcKQKOot%dz1KmI)%erW$RrJ-Cz84$NYA2E8E&V)v-46v~Gh zO40#kF|-bpf}Y;b;G#F+Ppi$XRuCTn0!_`8Pi@YjIBs;AGf@*~cz<$GN(GIsaBV^; zp+8X1E5TlHruX0nFiFCnR*tW!95F3&6-(Zt@eVm23q*26424 zXmx<-3I|RQXL-*7M7s|0wg%BhK}>dl=mz_~6%c28`vYPD{V9KL!q* zAj-X?0I^$#_&|fW*o1J90z=G&xA{shJjZK1Ky0p7`o}b;O&ZGIh=4lm?%+3J*8r*N z<^87v$QBI*vlszV;sA0a?0S|Dix)oc^?)%=@3YORbD%0w!J){y5EsWi~(TMQ^;_hoz+6-c=gh zAHZIYa2|qPyupa0LuY@*uP)yBEb%J6TQ$6GsI7~^f2ji=tpPV8eq=kI_tc6zIScPx z?{69&9bX!Ra*jbddvR$ykT&3SEUma}?(mh?_VFIKkUbu){LmOQ?to^_FZ3z5hBo_7 zp#9N%KG4jnr4?3M5V*pIh8huHcFrI^s+H43!!p-SLhI|T)6i(k>WyQujftR_l+Z|X z|ICfHbPg)keV#X=!I{HtDk|BBX(t3n-x+ci3{=;jyi+wC`U(Jr2@W{)6@WH?Q!ooh zzf%du^=I!~4ab~B(EFb4^3YRWPWwF)=X~#S4M(?sJ5CcKa+m7@?QR=pzY1C@^)RsmPIa)0y!;v zA+JK5GZYA}e%@0woC6s_Zk%dwm4%))haFwG+nN6Y6q(AM1NE4|xY>vcWI#`K?8-eB*s{|6jrkw{rXyys~+=JaY7 z6l_;Iy<#Re&R@L$rQsY%P1|?pGN|fr?}yU=>b?B`fJPs|a+a)mec;H!61n*a9hK$?A&=9S-(X5OPn^FQ7_NV6D!{;o6|!B};v*ZnYC zzV7Ksye%wVk@NVfy6r_@X^%XVfr>#vR5$)H@BjJr^LsaAnhd_t(iEtmV6;YjuEp2y zhW+9)jY|HuHXSTt`-y+C_#c$_B@ObIa-a)3TmF)-^jeZaTo?#A{+_7f;XB18X1Mt4 zNOga>`jzJ_#cRPtOcxbD*oa0GWsRvstSr-Hltp5Ja3mhcL=y3`ae;KKES3m0M~xn? z>Mg5$rNu%T$W;9^?z-SEPh76*dtUaHmMCFCehjxo;ubfnaD$YJa~tl|dD{P0x{0gb zkK_)j>l7t)U-f(5;jZerulP!9WNw}P>&~P9^4<9q3JQzzii-*h@(YXIU5X1!@((J; zQo~iNeWk5=c|VYHb-g|Z9RgUW%arNre%jc`;ZC#btb?&)+ zaQ%_4zI>f$U4IhSpKaIqw(A1AF667qy81a@)lOG`zG@C|VR89&n1y@BFV{D}yL5h4 zch9T)e+WKVwXJ32^h>5MubTe;Pv;%8d{xz~FCRbqA8)OxI=IRG%#qK%RrROhZi|Ws zyi+yx*f;((n7P zxu#5>405aM_*brQg&P}PgO0k?h4e1qBEFyNhEMvskeBP8Y2`?FrVE&eFLSNF;yBl} zf$rcv!nO5EuWRBDD8Sf{l zahboDeTB8wd)|RF7CscR<3(dn-)aa8{LbQa7rZC^0_jXi&bG= z^W^<3v+(M^Bqa;qs`$%hD(L$p|JqyR{bgI_{h^Bg5>?2>V(zhDdo_r3t+-0wo89>f%3gdjTi1An*JjIaxw>yt;|eUdi0gDb46wmhdRY7a zO8IEDm97gg-k|uljEv{uMs+*ImyMJ0rkvOzZ2bUM_s_7DuLQWbKkTwAC7&GoU||Ee zi0|E|^kY_LzZEjy<*ViIQ!Nt59IhPP+!cr$QMo^)CB+=T6cD8ylrHp^S-P<5z7O~L zeMOoNk>+YkDv7>4LurVzYm7`&DhaNah|=~ED4T7XFBAC?1Ih$<0RKdA`MYa zwR9koy4ppWc2EX4$~0ov1jKD34N(e}Z!z;J5qjGK$~0Om#3g+bCYeG9M5(dqV28+O zD=3HA(7qJ;fTG*RKHTS5ihMpnn%*|4k0Z)*Q1V()Px$TfhijxHN1<+UpTAq=w+(5( zS4~GbLcBzm>Xs-oZPM=%X+8xdKPu78THhyRB+5`*xqcRDJ_F@LTitp^KA?1=w-wVx zc8B}?UZPyvk!BV)2Iw*u!@G+#pmf<~p;do_d$&lk14&lfs`gNk1e7zn*@QkhBf-sv z@Q791>bB3pPv1YF%dEU(ZADve8D4ce_^S`I(SN$aES7+AZLl@G78^c!-<`hFDQ@w; zG^CMFg5fm2df3LCn%M9A+vt1n{3~5$;$OUF#CGq+^Q3f@iGT4;4cqbESe=<2sk{kE&$vV@|m-!}Ezu71msimra!)Ni}`ExSU|)o+{nZCAf#DMeSmZR)pO z{g$N_UH!JH-*)v|hR&+GZ8zCqwWTwug1i1H>%=2(U5EXzyvGyd;@WOA?gir{UClsU zmra)U=5+ecQ{}xn5a{Y+`2dOcj4l1Cw#K#9YJ8Ia92@2AOo zv!A7xkkWnT@Hc`6FfsWmVU$RwT?Uj<>93Z@<cjb5xOz#JiTwcUGc_kC>gUtqf* zV7uQLkqR-pgSpBA%~8w+HhHeH$ve?@zs6SKTW$K9W4rHf!#~f(KK;XKLw^`(GRu?Skf3u~ZV=JJ&MSN(N$L0ch zC#5`c;(+0st!KBl5PJ){)P`4R>+eU~T!y^`jIpKn+R`6pYe8Sy%JZnL#pT;t)Gs#v z9k%kFY{R#==zvXryNf>8mVT(MK99D^)6M3g_Sxil+E$--4{@%|KKj|}FKM%nfK8qg zt^BKZ|KclsrnpvFylK&YRV~t-d!A}D;3=wwnI7dn+xUNxt2J2(&$8Xu z*c5V>O`bV6{@ynFMYiA@JLTa_ zkM^i7{ZLzdJZYmpY18j68~!)8`xQ2R?qZ~TyKDpKpiMuI+Uj?WwTTt+Un|(OkvL>Xr$8al4u|v zZVrTvJa=uPB%JV-S5%hwIv5N=Bb_!vXE(Iub*oL31!JLef{9o%5;ZI?*NwZcYQ+l& z0x=_R68*Wkr1YS0!r#ywiH0JfgS$uK86y=BME!w=NcmqQ@lbhPCKZW?yB?iI83usz zA?f}QWlXmtJCcZg$Ppdm>jU9KkIjnq`zaT{%I2_RGA&8NUv6Acp2an!KG1MDCk!T= z%T;-YCuv(K?K!<;!c=oS6NwrAbW6H?SRykdKG+B(y(e10COwcz#3I4+ixPoQb?}NK zj_-`2?~%vlB3H*leUD-pZRo>OeY@u*BI(h`l-7*APdqJ`0Dk|Fc&2v+)i7i&J3TkwD3JP8D#ji;^-Niw zl(RfUO`e>yJVfqOc}h<3O9G+LsX0>!e&o z1W_r`my<_GDa5EaAWxsl-lycsOW>&7Ds$GWY2~Qbb92@VF$szK9Ehb)Kt zz6WCIQ+ZzJMNbY(jPC!Z({ejT<@knBv-@)=4pi~U_IZBCYL5jnP31$Iqr?CeUC^=G zO^!a57j}smG2@DcM5v|eP~{`bMO1Sj+V3cPjDKt(6*c13MPLawrTTN`4J{cX5Dk|P ziHD5w{c$5Zs+x}NE*40l12D!74I~F}w_^HdLG}AV^n;kr1fo%NHc_K48I5EHo`oXG z4$+A}Y-C19GEILqTIym*H|UH`xs%PAx@aOJSZjNB${J23#?>bT=iuMNDI^|pPN$f9 z_JaaxwBWz==`?{VU7|T-6%fgw=D+spG@U&oq`0V~zY}_o8{>rNLpwH5RWBK;3x9da zNE?}9ISZ(`n&ZJHBRIwgjgYDyerhg3E!d_&x@p9La!->j{8vZ!kS!xs+Q_3V3l1a$ zK^l?y{Eb4}bsb3+id5fSPnAwb!f{0zb&O8Y@Y0#o#aV!y3Z&78cSu%o$zgh&VE@}m zxt)V3+t5Jr@24DqN2v0@J9an5cr=YfVodqS=J@|~G-91x9x@t@)VNe2S#jy_<@Eid zV|`>{Ho_Wwes+<;rU3r$n+jl1>-X1X0vXuVka#3>8CSm}&q$*&5{(89$dxvXPy-L+ zbSxNeb28{GOG7jf9ODlgaU&H8hMdz29^>SWHKAuBiqv?pS<4X=EzEXc#K_cr6@8m5 zCksQNxIu7T4T0d8h}TStx<`{Am`Wv56_>NwkmH7z?lq=ERNttck>K+6iFJtUT@mjP z*QYY!vGP?pK+2@mIW+dJ5P(;3OrJ^-ld@uhDkg1776gW1%2-S&u83*2WDwp##Em_| zlp!98a`d=E%xI%A5HyS{##<2)8PU?sQ_qy^7^WN`|rIUfUzZ{i6Ds7~yQ${>c z)6^UvQ=b?VXpUz7dCu=c8|EvmP5#NM7%LUPGc^G*HLM@W_Y6hXHR*H~9sX!!tO`fG>N;M#o zGJ=_j9EsbpGICNLOB+q3MFFnOJJFKOjLXh=a$Z-H!-yp_EmJfU$UyMEsd-t2rnqS= zFNsP~vLMsB&=h$c7h3RS75e&YkYpe=2J`G#By&TaRY7SZiUP+QsPHrLEcfpBj|)UH zSNP%Zu4p!zjT>3Sa030U5g&U~-pOXk{Qi2(hO05DPthb-v`2rr__;aHa{dN2(>gIr zm$aFjUowii5D6sd7EacXXpV={8tv9Rs|_SE<6=} z6`GTGJZmh1?x>!|45T`Lc_Re6D~}s3sMVp+-Fe65Oo8!t8`lcKQ6Djv%R^C^0Yx(N zw6c?~LWvBiWZ*q)=D|dKY<)a|LGis@c;Q~id(@4KWP(li<@GRy5z8<`XvE3n8uVJm zd{$61td=@56mh754mNZ@Bm4c)MvP$5os=h=(@hK5P<2Wo`2Z85jqyatxHu4vgwP=_ zW@s_9Zjy2)U zXfbdfmPiK!@u#_Vv#52T4NG7}DrBUdVH5AbBRQ6`shJ!X1yW(-S*@w3jG;nR;otzH zp*j2I|b1_2(mK8JbF=$maDI*lgyuc2KCSB2#5HmR562<+U*z^|qex%n z88k(p1Q-EtU=@;7B3bOsx|y3K0U*4>$4=xFMkIkWd}6dcOPvZhiIHR=Wx#yu#=&E6$*TMy znq~@{0_B3a4n6wTtQKL>G36qkNgSVKi*F*(BzYS*ee_nTObt!iV;DxIKV?6MffL7n z#-0VEX)As^chqJ_u!DOfM3LM6oSD#?QT{}5C-;A5)UZS?B>RF>gFvajWV11|7+$xF zD_CVRyzVPaM5_lHUiURC60F%BQ(Z%9%x>;+)42VHB@+Wgj9<_-UumSi)z#S;882#^ zR;(hK@7Rd^ekKWyJ)2QsQ5glhk`cPEy6yZfi8B113@f(J)2`H(*TZfmg8fmYtA!}OWtwq{8VtZ0h8uRRb)#pDBV_@=n6v2r-rKTL`f z)gtRMJ=J}RS=UZvWi7sGZfmw_vPppH9pNQGsH);Rw>7wuWh7$t*gzyo=6Su_8jniq z4Q^|w4_hHeHbbu}YJM0Ai4tUt8{O6%H3;9BN+uG~^i6JSI@%b^46Cb753Re|U2c}q z?+*uSMvS^Bg6W=tS(jKu5>BkPrXItZbc8H@rdylZJ0w7>j-;FP6t}pwS)W6S<|GZz zZ*^;{3pu$i!dTh}-R3^MQ=zdq*&J(*0(I7b@)kq=+udh&iYHcRYiQ9kl4+Uk)}~}p zsjPux(Fb6}PHp-QHapBrvgnvHrJG~Moop9&4ov@&bL>rMWFnEl@P_)ZyWG}1Q(6Vl zM4xdti)Et-YxA|atrY|6j#5ZBmkrm9lDzZW)^yn<^heh+<{q|KGoJd9TG&c(O#0rA zsi?C|-^cOcpd5{ho@zd$WyQvEwt7D2luK!`ZeGZ_7qDNTen7B~Pu*KPs zV(s%$ZmR?-=Nn77928jt%fYk{&xwvT9&=mkL+K{Wu^#92;gr!L(?6jXc0hA1Ib2L* zo@DXEL8?P*g7Xw-DD8*lf1;k!PqW__J|ck;6Z$^OM^H!ojIBx9c|_BwX@N6ZYHN~q z&Xh4Wk~W@oYolzq13MQDp$P3co7?Ef7sd2Ty4~m9zN}_$=cNUek2I;gFYX`sNCIZSOL z5Ebh%7__|T?$s$j28xMPi|7$()`T1q9H?v)UP?Pnumn2BxTj$YqmbnUN3R% zmSm@R{Q#zyf|z5C>@;t|(l(ch2HPLqDqZ7pf*t)@mS;=aXBfh=L9k%3P#LTh!W zFoG8Ef&p}BsKvM4+RPJvNXEj{Xn%>C{X3m8(CYEKoiU7qe_p3|m-Z~g3fp^n?`-El zm#Uo6APk(0(EHpC`u%ohsB=9#%Z9K?-=HT-VzEs4J@n_Q#2@I!>_C^j=0>(Jv6x(k z)EGAfjSt<{oWbvRNIpDneB`#47HLCHt?q5o?K>Hu>D>S<>B*&Ef~QKV!Ge=m;M}a2 z!W3Ps56HUuxDz@}UE4dMlWW}KRFw)}$hNgJ0E`np(e+>xkk&J5jrcabtFf`b-Urft z$ftU3$lW5+g;>0k>WSjG%4fQta^%8TD`jlA7fOQ>h1y{+l*T|)&Cm70Tr$EPm0Voi znN?;QK|t2HYC$+nFd~!sqB9n3oPgy^y~yZFvry0r$j*Hici|0~a-~}8F!B#J)kDg! zbScv`d8mm7(rJIW>}bB$)vlJGsYYo0W-goT)*)!tI~I%l0P>eN7&x}|4LcscKZ}g6 z`dhcPC}$&5w6)^mEy=MNO8g|^xpp;C9C*J z*O)_YV$<|z-FQ`jFi%LNGJj9R8X`ve7oJMU#qc^&^lK=UYn!ObSKPSkgDHaiTQ@ za3(isOw6}tGPJEoE@4tWPr+4`^vTyUFC-Pblk=^4G@=@tqtPk()?^uy0h1!9G8=9D zCK?;3D)9)|v$=eBR7_Yh5IpAcejq7kOwPjx!Xu z>UF2Gh3}>&k-jb8TGz=&9)=-Pnzk)wf?LL@;Mz#A;zP7ZajlbkNuxJX_F6qO1ooKwW zpL|3wwMG@jhdth~u{d8_?9w=B0EH80*mk46p+|E_OI%BGY`a7d%cNp8Sggmq%iaJZi;?0;Pi-QFW5<|x zlm0Pf9o>H&8*xsq_qcXL31^`9xps50$P%v4=LJN_9Nxe+M#t>PK?%eEKyMjx3N^g3 zk;wk?8roIZ$bw^7FCI0r7_iEPQyY=^hwSh>@X%ugA8}oPZf1@4NnU+ZmINA6w2bCp zaC5%4a<8W*29mTEOFh`l7)XaZKW0nG&I$?J^(L$X1*4cbV7)A{h5KWyETBiOBLk+h zNL$%BbV?%m3HPcRK`a?=%hzT^3QZVKHTed0rsGpxzYa_^2>Fa_-PA9Ji=ld~h76&{ z2S|}Yy4#*_Z77jy%X{z8)d5eBr81hABJWV>a~&0HEb0sk4Md3t)f14@teppBRGaf( z=v9e_+$P|ifGa5zhYm&k-o3>TBQBi0Y)0igsT^A5+?$8 zv$@4F&;bip9q4p2^>g2_yHG@0C~WzbB~#JOap3{Jq}b1D!FkIFhIoYY z6W6pEYeD_Y**1p!;(*F8tnd^~ePV?1D&IFuHl3UaVBwMfi>^LQv_&$k>I2PYiug+#ZH*-TBq2G z$pu#b6Hbhv)S`V%DX?a>di1EN1=hq>#n(k6L97fK@o5Ft#MMq3H9beNU?6#2j$|N> zy1s)HBDelG6!64W3N7PD&2R?mP4eC7oTzurO$F9OSEwu96lu)dY|~aKGBy%2X0o=# z0}Sv1V=*bYh3f$0p8@n}!>ycNaHjA)Kq`J4%RrN5>(Fg_7PD)yw-;!GFi|B`J#}>zt5@NoMU#RVV8^4H@{0q3!g=(dmV-Il2LJ1YOkfp+2FZRc4ALiB&NVmj;*!-rYn~F!+C5SGp zaxq&O=_nP#V&w?3jYnBzVP)hbm#~^eoIKV07-NQo3wxZ!5p3z?6SkOm^hq0h1CCcb z#mW}x8nFtUd73pUBI%*^s4@N-TY7p*b17>^up;VNTU3)V{y7_9QXXA>-WIJM`+UJx zWIQH<2i}+2Bu$fJTh0i`CWIYhtZaqSD+;VmDu&IXm7J7rrP;j5Diqan?n}0aKC8Gw zan2`bgo8~+6l;wyvu0~?q!_2CUt!L$j2Y6{zd7Bqn#EHikGkeiBK#^xt8s>iUc-vR zfk>Ppj7DE$m77r&ue14399k{RJ~$@a>x}|y0W6y!3;ZTKl`Jwn+!lzwRbZ`$ro}0E z%tKRn76~Js;Fz^sVh9z+Q0r}0sT@LM1X%kH7eF11s(qJ>YDSI3s_i;1mrx+pz7+z7^bx}Z18I5_w!apu26VmxQf^}R1S+0}VA5t56(m)v zkF)qyq^PFe?Kw%lEnG){s;y6q#1XeGiK7;sy*WO$1|KvGK_W*$}>F}K#Csv4YQIn7QElGnMr3XV!vZfG!L1254#~`6#JgbNVmQp_?|Q$+shE>h@^e) z<1z{D#(rd7sulj^ein#ugrK3=Ph29AQbqsFwG$4CY=7YxW4sZ>hQqI%lxCzO)#;Mo zIBObA(;h-=p*1YV;{x(L=~ac+*i^JwB)=j(EHPq2p*1QL@%8k48WFCx5$JG0Z4C(5 zFcNLL55uk^@-B_KcE7Af ze{f2nH4UI>e{3oPntmNU;WRF^iuK2)7it4<;nMI%m=uOt{@8Uo2!@q3DDcOw=U5d- z&EN(dT0D~DkIg8wMjDulpl$eWw8!+iiOU!cp+86^T5c}1`aoLanaN6q2=qh~CePHx z+)`-u8rcNtj&ALgTya~cWZ$epYnZF&NpFCGd%isfH5{ae@@5xW6Ba795?4r7aYt^N z@6JMN(5wAy|BrL4kKg4y0@rP`4cn+$G`rU`w?lDi2 z%V>|Vc0`=A>&1oI%m%C~x}3Ue`Q(KZ>(N4MK%*y@N?F1>CEdY`V3Fc6)|9I3e*Gvi(`vMmu98EN!8@&S6xr{NB^wbPC`~son%qkkF7Smmdz$Qvey|blo*0xr0QK#0N6k~<8Ty2Kc zs>L#WpURK8J&Fdgi8X;98}C{pS@4FM^kz;k2ujS4xmeW2jKl+2iMV>iwOy0U$WYga zYE5p@D>XGPhT#!br&H8sx9XLeO_GiD6Ws+dgLHk{xUQ(0TWG*dHTfxPH!D8-ar@6$ z*fd7zvTyQj&x%!!$G3xXq6v$|{y8fH3;l?uWBLAa@tD(2wiunJo|6AUFFB`7B`_H> zE;1T3U+Rs;&M-0(Zp!Rpp=kR?%;tlMWXo4vqZqaZ$Ivq%V(|VoC$I?Q^LKLviFon6 zn|vzo8!n(u5|7<|>y*qdoZENo2SqZG{T^;4B9gNHo@EV$F2^JIYF#7!1J{Ejh!gjF z*(PPISb0qE(MV8!HIZL+|S%W1yvm1lECMsTx5D!Z( zbg5SrS%XWMQD%(L1GZsOVR}JSdIDqE$T)Ri&iAe^(i|^iP-jA-gY%jqYlH+k9wi_T zHnE7OAql9JydgwOPjZg0xYjwo_hjez$|*(G@KhKtz5Xf#T~j7gi>&!YDu6noxJ)cL zt;m{RV9_Mfr*e9cH6;>Wij-1A>l@bw4zJ@Cl<~91Kg70&ZY}-!GPc zvC%aQlhPSQ+CUgp7ODv+B>l!BYoa8-+$FXuZsHQj*bw|R`nE`8i|^(ltpj5!4)wy? z=;e|#Sxt}vkyrx9A?KD`imcg7l3rfXY~0G3Q{v zrvMgHcINZgB(Pyc;~E^zLOTul?kTb+u=1@QDOi#0sqW=OieysmE3&3{Oc4*p(Vpvk zwkL+f;t0|1*QAq@gWh8rdYG-1OH0GUN1QY(z5L=LZH^+Ohm--`j99BfW9dk*0PM4jv&|;zj|Ts7 zc_$E+D>@d41m+C*r6&u zdJD?SHgGT_)_T_W72QYax${%FiR5a%(#W#uDPdtK($HVk{eX=wW=?AuK;&@|EyJeD z>(HN7(<1L{HX$|oAdFXDx7Cg!lRe4D4+O{?TogSM<|3#!xn1Z?wdTnvF&YtYZ*dor zo0A~da^3p<%~m%=7GIrtn?=`&SgS}x@zfP9;bGtA9X4B?i+Zwmxl}p{0}4FrY^GnQ zJ3JO4-4Yv7^PXNgObdo_M3H7k>G!$I6$PcK+=!a=`XXypSZoSbV?wuqvCJXEh=_rO zr$N~K#P}%l0XsF3h{g~!u-M2AR>Whm29u0XL(7NkAF~O*k9a(2iRIhGisDG=6E-{W zSA6WiUm^M1xhx`Qa{;ZM7GX#STi5`c8K`hW;*E)|TxdDrOv@ZT;n7f75w@{X(@lwS zVkG@3>tDnHH3HPnxK1PKf#d1X3WHYh$w_Z#t%Xg?Z4wQ82U9EsC9wUKN`G!^gH%LG zk<#vTP}N|$9s32V$^um+nf6Ov);ck&wOZ6JrU^A-{A#KAD{l9KHau?VAg3pa)VAxe#VSgyHPATijB~hl|%bGy1PbMf-1eQMw4@eGkjf$vblqY0q*_E|EszgjH(HUCs(H@V=H& z@<1wN!x4(RovjR_x1?#f(bfrlAod66I@6^UVrzPyGo8kGqS@W!TnwVq8wBpPsi0o$ zTj8WG?X})#v!yJebc6GYtu-p4dlWi2=6-H^%5{k7dKx4P54M2q%YlK8$vnWWg>FT9 zywxhWki82on?6NnG9e-x!sUV9w% zoWkf(v5yp6^T`f8%7=i9hJlOOUw6X!DC-2hy0D#kIW91BTvDtpj0mJU%$qUUNhg|d zj*HSjz2=E5f$&)IIlPvVGYQ&QsD+l+aQyml7Q?CKBWx#ZmG4SBd-*D+?;585m7Y@ZiX*4g@L>2rt{^reP-HUn%Al z(J|o>So>VfoK$YCNsbWS^9Kefj zU*|qT=b+=1NdJa2yrTNvhlZJV#v*IO#y>4bRh zyT#TjCU1*N&~;p`ymjw;kBvw>G9**H&tQCVPmn6sv#HW#z5HC6VgsiTr<#R|WQq?o zy=EOPmnk=LN`5j#l0IYu6OYtm6d(y7@sI%v(CWn+=HiPGi)PxsO}~q+V)O4}>;3WX zVykRtI|&Ejc(u2@N#VD!KC<6GC&^pcNYsm+_>Fvmqw*8>g*iCNecKL%a_*o z4+~Ah6;QtC#z*dwUI|POrvKoe6al6)?d8TKqOE=Bee4K;hnFnl(RHQB^pEU^X*W(T z9PZ~xv5+h#v_BOeM4K0K&ERL2JS?9;_@&tCOFYn`@D{%oTgR`&GZMcQTib<{9;Yo! zECyOCOq|{|=6UMk(e_)}P|(T``Bb0_hm_4|j34$>s)h(Rfo| zBCbk*H$x;b(-((P+e)m3hmH>k^qR{ltfvy@l~^6J73Ys9f|>D|drGVs5#&)W>Rwi{ zJnVX3iM6_uT|2({xhNI)=c4ppkc(3JKrYI;3v*HWEXqas9OuK3sA{c7z}AV@EYV!quJ(G^dTlCDyV|_SWsACD!tb^jz7mhhM_g4l+5)$GAo4 z4=O!ga;Tr|Tu6g|B1zv9oR(q-M8-bJl}0i3a2>(AryL?jJg76F`%s4>uPCt=iu``t2QRSU?Qe{&EIE?;8}T7cbD}Ax z<1dyR+kqg@S5P~Csf543X(q#TWi0yJL~4}-rk~v9%Oxjtz#Ktyg<+BCKq}iSCC7DO z&`Pzs1AYT)m=UD5Yi=^n*#5%#-B|WXo%sfOt(s4=Q z9fy*Nrb=r_@0J|j0Y`t&?m9hu-gl54Z4zCwkbQm0(H-&>vSWi_ zgG16VC;h-dU1Ef@v7|=_OhFh#o5>+DgZ|K=taz9_9ZW^U$6-Hm$Q!#;BzLIRU%9D- zzpG`cydI4QtEJj^cQ!j@qQA-RW3BN13d=r3qiZkeDjo!E!U%+3->{|RP;rk@u|I|{ z#NmA^TU8V_-*|JZ0o!1olpHR&C<>3rHTfy|wvsL)lK%O$q*O!rtfW*+yuGArR=OQp TyO&0sE*}iMivlfp(Z>G=_)_=4 diff --git a/examples/imagination/main.go b/examples/imagination/main.go deleted file mode 100644 index 77d36d40f..000000000 --- a/examples/imagination/main.go +++ /dev/null @@ -1,41 +0,0 @@ -// Simple WASI-enabled wasm module for exercising the AXL wasm engine. -// -// Build with: -// -// GOOS=wasip1 GOARCH=wasm go build -o imagination.wasm . -package main - -import "unsafe" - -// host_add is provided by the host via WASM imports. -// -//go:wasmimport env host_add -func host_add(a int32, b int32) int32 - -// message is returned to the host via a pointer/length pair. -var message = []byte("Hello from the imagination wasm module!") - -// get_message returns a packed pointer/length pair (lower 32 bits pointer, upper 32 bits length). -// -//go:wasmexport get_message -func get_message() uint64 { - ptr := uint32(uintptr(unsafe.Pointer(&message[0]))) - length := uint32(len(message)) - return uint64(ptr) | (uint64(length) << 32) -} - -// add_numbers adds two integers inside the wasm module. -// -//go:wasmexport add_numbers -func add_numbers(a int32, b int32) int32 { - return a + b -} - -// add_with_host forwards to the host-provided add function. -// -//go:wasmexport add_with_host -func add_with_host(a int32, b int32) int32 { - return host_add(a, b) -} - -func main() {}