What Is the Role of runner.go in the Aqua Project?
The runner.go file in pkg/cli/runner.go implements the core execution logic for Aqua's CLI, bridging shell command invocation with version-managed tool environments by handling temporary PATH setup, lazy installation, and process spawning.
The runner.go component serves as the execution engine within the aquaproj/aqua repository, enabling the aqua exec command functionality. It transforms standard command-line invocations into reproducible executions by ensuring specified tool versions are installed and isolated in a temporary environment before the target process launches.
Core Responsibilities of runner.go
Located in pkg/cli/runner.go, this file implements the “run” sub-command logic that powers Aqua's command execution capabilities. While pkg/cli/exec.go serves as the CLI entry point for argument parsing, the runner handles the actual process lifecycle management and environment orchestration.
Command Execution and Process Spawning
The runner manages command execution by parsing user arguments and spawning child processes after verifying all prerequisites. When a user executes aqua exec go -- version, the runner extracts the tool name and arguments, then launches the process with the correct binary.
It preserves exit code propagation, ensuring that the status codes from executed commands return unchanged to the parent shell. This fidelity is critical for CI/CD pipelines and shell scripts that depend on accurate failure detection from underlying tools.
Environment Preparation and PATH Management
A primary function of runner.go is environment preparation. The component constructs a temporary PATH variable that prioritizes Aqua-managed binary directories over system-wide installations. This isolation prevents version conflicts and eliminates the need for global PATH modifications.
The runner injects these environment variables into the child process context, creating a sandboxed execution environment where the specified tool versions take precedence without affecting the host system configuration.
Dependency Resolution and Lazy Installation
The runner performs dependency resolution by analyzing command arguments to identify required tools. When it detects a missing or outdated binary, it triggers the installation controller in pkg/controller/install.go to fetch the correct version on-the-fly.
This lazy installation mechanism consults pkg/config/config.go to parse the aqua.yml configuration, supporting version-specific overrides via flags such as --file. Users avoid manual installation steps, as the runner resolves and installs dependencies transparently before execution.
Telemetry and Error Handling
Beyond execution, runner.go implements structured logging and telemetry collection. When enabled, it emits usage metrics about tool execution frequency and performance. The runner captures execution errors while preserving visibility into underlying tool output, creating a transparent debugging experience for developers.
Practical Usage Examples
The following patterns demonstrate how runner.go functions in real-world scenarios:
# Running a tool that Aqua installs on-the-fly
# runner.go parses the "go" argument, ensures the version is present,
# then executes "go version" with the Aqua-managed binary on PATH
aqua exec go -- go version
# Using a specific configuration file for version pinning
# runner.go reads aqua.yml, resolves the Terraform version,
# installs it if missing, and launches the command
aqua exec --file aqua.yml terraform -- version
# CI pipeline integration with Node.js
# The runner guarantees the exact Node version defined in config is used,
# then runs npm install with that isolated binary
aqua exec node -- npm install
Key Integration Points
The runner operates within an architecture that includes several critical components:
pkg/cli/runner.go: Contains the primary execution logic, environment setup, and process management.pkg/controller/install.go: Performs binary downloads and installations when the runner detects missing tools.pkg/cli/exec.go: Serves as the CLI entry point that wires theexecsub-command to the runner implementation.pkg/config/config.go: Loadsaqua.ymlconfigurations that inform the runner's version resolution decisions.
Together, these files enable Aqua to function as a runtime-aware version manager, executing commands with precise version control without permanent system modification.
Summary
runner.goimplements the execution logic for Aqua's run command, located atpkg/cli/runner.go.- It constructs temporary PATH environments to isolate tool versions from the global system.
- The component triggers lazy installation via
pkg/controller/install.gowhen required tools are absent. - It propagates exit codes from child processes to maintain compatibility with scripts and CI systems.
- The runner supports configuration-driven execution by parsing
aqua.ymlthroughpkg/config/config.go.
Frequently Asked Questions
Where is runner.go located in the Aqua repository?
The runner.go file resides in pkg/cli/runner.go within the aquaproj/aqua repository. This location places it in the CLI package alongside other command implementations, specifically serving as the backend execution engine while pkg/cli/exec.go handles the command-line interface wiring.
How does runner.go handle missing tool versions?
When runner.go detects that a required tool is not installed, it invokes the installation controller from pkg/controller/install.go to download and install the specific version defined in the aqua.yml configuration. This process occurs transparently before command execution, enabling on-demand tool management without separate installation steps.
Does runner.go modify the system PATH permanently?
No, runner.go creates a temporary PATH environment variable specifically for the child process it spawns. It prepends Aqua's managed binary directories to this temporary PATH, ensuring the correct tool versions are found during execution without altering the user's global shell environment or system configuration.
What is the relationship between runner.go and the exec sub-command?
The runner.go file implements the core "run" logic that powers the exec sub-command. The CLI entry point in pkg/cli/exec.go wires the exec command to the runner's methods, delegating process execution and environment setup to runner.go while handling initial flag parsing and validation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →