diff --git a/.agents/skills/code-test/SKILL.md b/.agents/skills/code-test/SKILL.md
index 55d28d2a1..7d380a57d 100644
--- a/.agents/skills/code-test/SKILL.md
+++ b/.agents/skills/code-test/SKILL.md
@@ -62,7 +62,7 @@ Examples:
```bash
just test-unit [EXTRA_FLAGS]
```
-Runs only unit tests, excluding integration tests and ampup package. Uses `cargo nextest run --workspace --exclude tests --exclude ampup`.
+Runs only unit tests, excluding integration tests. Uses `cargo nextest run --workspace --exclude tests`.
**⚠️ WARNING**: Some unit tests may require external dependencies (e.g., PostgreSQL for metadata-db tests).
@@ -86,17 +86,6 @@ Examples:
- `just test-it` - run all integration tests
- `just test-it test_name` - run specific integration test
-### Run Ampup Tests (REQUIRES EXTERNAL DEPENDENCIES)
-```bash
-just test-ampup [EXTRA_FLAGS]
-```
-Runs tests for the ampup package. Uses `cargo nextest run --package ampup`.
-
-**⚠️ WARNING**: May require external dependencies.
-
-Examples:
-- `just test-ampup` - run ampup tests
-
## Important Guidelines
### Cargo Nextest vs Cargo Test
@@ -120,7 +109,7 @@ This test command is pre-approved and can be run without user permission:
1. **During local development**: Prefer targeted tests first; use `just test-local` only for broader confidence
2. **Before commits (local)**: Run the smallest relevant test scope; broaden only if the change is risky or cross-cutting
3. **In CI environments**: The CI system will run `just test` or other commands
-4. **Local development**: Never run `just test`, `just test-unit`, `just test-it`, or `just test-ampup` locally. Those are for CI
+4. **Local development**: Never run `just test`, `just test-unit`, or `just test-it` locally. Those are for CI
5. **Codex sandbox**: Run tests only when warranted; prefer targeted scope. If running `just test-local`, request escalation (outside the sandbox)
### External Dependencies Required by Non-Local Tests
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 53ecec9e7..7d95abced 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -122,12 +122,12 @@ jobs:
- name: Build binaries
run: |
export RUSTFLAGS="-C link-arg=-fuse-ld=mold ${RUSTFLAGS}"
- cargo build --target ${{ matrix.target }} --release -v -p ampd -p ampctl -p ampup -p ampsync
+ cargo build --target ${{ matrix.target }} --release -v -p ampd -p ampctl -p ampsync
- name: Compress debug sections (Linux only)
if: contains(matrix.target, 'linux')
run: |
- for binary in ampd ampctl ampup ampsync; do
+ for binary in ampd ampctl ampsync; do
path="target/${{ matrix.target }}/release/$binary"
size_before=$(stat -c%s "$path")
objcopy --compress-debug-sections=zlib-gnu "$path"
@@ -142,7 +142,6 @@ jobs:
path: |
target/${{ matrix.target }}/release/ampd
target/${{ matrix.target }}/release/ampctl
- target/${{ matrix.target }}/release/ampup
target/${{ matrix.target }}/release/ampsync
compression-level: 0
retention-days: 30
@@ -173,7 +172,7 @@ jobs:
rustflags: ""
- name: Build binaries
- run: cargo build --target ${{ matrix.target }} --release -v -p ampd -p ampctl -p ampup -p ampsync
+ run: cargo build --target ${{ matrix.target }} --release -v -p ampd -p ampctl -p ampsync
- name: Upload artifacts
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
@@ -182,7 +181,6 @@ jobs:
path: |
target/${{ matrix.target }}/release/ampd
target/${{ matrix.target }}/release/ampctl
- target/${{ matrix.target }}/release/ampup
target/${{ matrix.target }}/release/ampsync
compression-level: 0
retention-days: 30
@@ -196,7 +194,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- binary: [ampd, ampctl, ampup, ampsync]
+ binary: [ampd, ampctl, ampsync]
target: [x86_64-apple-darwin, aarch64-apple-darwin]
steps:
@@ -297,12 +295,6 @@ jobs:
cp artifacts/x86_64-apple-darwin-ampctl-notarized/ampctl release/ampctl-darwin-x86_64
cp artifacts/aarch64-apple-darwin-ampctl-notarized/ampctl release/ampctl-darwin-aarch64
- # Copy and rename ampup binaries
- cp artifacts/x86_64-unknown-linux-gnu/ampup release/ampup-linux-x86_64
- cp artifacts/aarch64-unknown-linux-gnu/ampup release/ampup-linux-aarch64
- cp artifacts/x86_64-apple-darwin-ampup-notarized/ampup release/ampup-darwin-x86_64
- cp artifacts/aarch64-apple-darwin-ampup-notarized/ampup release/ampup-darwin-aarch64
-
# Copy and rename ampsync binaries
cp artifacts/x86_64-unknown-linux-gnu/ampsync release/ampsync-linux-x86_64
cp artifacts/aarch64-unknown-linux-gnu/ampsync release/ampsync-linux-aarch64
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7ef85ed1f..85ee12fa2 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -113,32 +113,6 @@ jobs:
RPC_ETH_BASE_URL: ${{ secrets.RPC_ETH_BASE_URL }}
SOLANA_MAINNET_HTTP_URL: ${{ secrets.SOLANA_MAINNET_HTTP_URL }}
- ampup-tests:
- name: Test ampup
- runs-on: ubuntu-latest
- timeout-minutes: 10
- steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
-
- - uses: actions-rust-lang/setup-rust-toolchain@1780873c7b576612439a134613cc4cc74ce5538c # v1
- with:
- cache: true
- rustflags: ""
-
- - name: Setup just
- uses: extractions/setup-just@e33e0265a09d6d736e2ee1e0eb685ef1de4669ff # v3
-
- - name: Install cargo-nextest
- uses: baptiste0928/cargo-install@b687c656bda5733207e629b50a22bf68974a0305 # v3
- with:
- crate: cargo-nextest
- version: ^0.9
-
- - name: Run ampup tests
- run: just test-ampup --verbose
- env:
- GITHUB_TOKEN: ${{ github.token }}
-
rustfmt:
name: Check rustfmt style
runs-on: ubuntu-latest
diff --git a/Cargo.lock b/Cargo.lock
index 443263dcc..f1b00ad14 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1310,25 +1310,6 @@ dependencies = [
"uuid",
]
-[[package]]
-name = "ampup"
-version = "0.1.0"
-dependencies = [
- "anyhow",
- "clap",
- "console",
- "dialoguer",
- "fs-err",
- "futures",
- "indicatif",
- "reqwest 0.13.2",
- "semver 1.0.27",
- "serde",
- "tempfile",
- "tokio",
- "vergen-gitcl",
-]
-
[[package]]
name = "android_system_properties"
version = "0.1.5"
@@ -4482,18 +4463,6 @@ dependencies = [
"unicode-xid",
]
-[[package]]
-name = "dialoguer"
-version = "0.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25f104b501bf2364e78d0d3974cbc774f738f5865306ed128e1e0d7499c0ad96"
-dependencies = [
- "console",
- "shell-words",
- "tempfile",
- "zeroize",
-]
-
[[package]]
name = "diff"
version = "0.1.13"
@@ -9867,12 +9836,6 @@ dependencies = [
"lazy_static",
]
-[[package]]
-name = "shell-words"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77"
-
[[package]]
name = "shlex"
version = "1.3.0"
diff --git a/Cargo.toml b/Cargo.toml
index c0e21d0ab..1a3b647c8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,7 +7,6 @@ members = [
"crates/bin/ampcc",
"crates/bin/ampd",
"crates/bin/ampsync",
- "crates/bin/ampup",
"crates/clients/flight",
"crates/config",
"crates/config/gen",
diff --git a/README.md b/README.md
index 0e8d78779..3f3feaa03 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,7 @@ ampup build --pr 123
ampup build --branch develop
```
-For more details and advanced options, see the [ampup README](crates/bin/ampup/README.md).
+For more details and advanced options, see the [ampup README](https://github.com/edgeandnode/ampup?tab=readme-ov-file#ampup).
### Installation via Nix
diff --git a/crates/bin/ampup/Cargo.toml b/crates/bin/ampup/Cargo.toml
deleted file mode 100644
index 8af2a9447..000000000
--- a/crates/bin/ampup/Cargo.toml
+++ /dev/null
@@ -1,31 +0,0 @@
-[package]
-name = "ampup"
-version.workspace = true
-license-file.workspace = true
-edition.workspace = true
-build = "build.rs"
-
-[lib]
-name = "ampup"
-path = "src/lib.rs"
-
-[[bin]]
-name = "ampup"
-path = "src/main.rs"
-
-[dependencies]
-anyhow.workspace = true
-clap.workspace = true
-fs-err.workspace = true
-futures.workspace = true
-reqwest.workspace = true
-semver.workspace = true
-serde.workspace = true
-tempfile.workspace = true
-tokio.workspace = true
-indicatif = "0.18"
-console = "0.16"
-dialoguer = "0.12"
-
-[build-dependencies]
-vergen-gitcl = { version = "9.0.0", features = ["build"] }
diff --git a/crates/bin/ampup/README.md b/crates/bin/ampup/README.md
deleted file mode 100644
index 49019f0e3..000000000
--- a/crates/bin/ampup/README.md
+++ /dev/null
@@ -1,214 +0,0 @@
-# ampup
-
-The official version manager and installer for amp.
-
-## Installation
-
-### Quick Install
-
-```sh
-# Install ampup
-curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/edgeandnode/amp/refs/heads/main/install.sh | sh
-```
-
-Once installed, you can conveniently manage your `ampd` versions through `ampup`.
-
-### Customizing Installation
-
-The installer script accepts options to customize the installation process:
-
-```sh
-# Skip automatic PATH modification
-curl ... | sh -s -- --no-modify-path
-
-# Skip installing the latest ampd version
-curl ... | sh -s -- --no-install-latest
-
-# Use a custom installation directory
-curl ... | sh -s -- --install-dir /custom/path
-
-# Combine multiple options
-curl ... | sh -s -- --no-modify-path --no-install-latest --install-dir ~/.custom/amp
-```
-
-**Available Options:**
-
-- `--install-dir
`: Install to a custom directory (default: `$XDG_CONFIG_HOME/.amp` or `$HOME/.amp`)
-- `--no-modify-path`: Don't automatically add `ampup` to your PATH
-- `--no-install-latest`: Don't automatically install the latest `ampd` version
-
-## Usage
-
-### Install Latest Version
-
-> NOTE: By default, the `ampup` installer will also install the latest version of `ampd`.
-
-```sh
-ampup
-```
-
-or
-
-```sh
-ampup install
-```
-
-### Install Specific Version
-
-```sh
-ampup install v0.1.0
-```
-
-### List Installed Versions
-
-```sh
-ampup list
-```
-
-### Switch Between Versions
-
-```sh
-ampup use v0.1.0
-```
-
-### Uninstall a Version
-
-```sh
-ampup uninstall v0.1.0
-```
-
-### Build from Source
-
-Build from the default repository's main branch:
-
-```sh
-ampup build
-```
-
-Build from a specific branch:
-
-```sh
-ampup build --branch main
-```
-
-Build from a specific commit:
-
-```sh
-ampup build --commit abc123
-```
-
-Build from a Pull Request:
-
-```sh
-ampup build --pr 123
-```
-
-Build from a local repository:
-
-```sh
-ampup build --path /path/to/amp
-```
-
-Build from a custom repository:
-
-```sh
-ampup build --repo username/fork
-```
-
-Combine options (e.g., custom repo + branch):
-
-```sh
-ampup build --repo username/fork --branch develop
-```
-
-Build with a custom version name:
-
-```sh
-ampup build --path . --name my-custom-build
-```
-
-Build with specific number of jobs:
-
-```sh
-ampup build --branch main --jobs 8
-```
-
-### Update ampup Itself
-
-```sh
-ampup update
-```
-
-## How It Works
-
-`ampup` is a Rust-based version manager with a minimal bootstrap script for installation.
-
-### Installation Methods
-
-1. **Precompiled Binaries** (default): Downloads signed binaries from [GitHub releases](https://github.com/edgeandnode/amp/releases)
-2. **Build from Source**: Clones and compiles the repository using Cargo
-
-### Directory Structure
-
-```
-~/.amp/
-├── bin/
-│ ├── ampup # Version manager binary
-│ └── ampd # Symlink to active version
-├── versions/
-│ ├── v0.1.0/
-│ │ └── ampd # Binary for v0.1.0
-│ └── v0.2.0/
-│ └── ampd # Binary for v0.2.0
-└── .version # Tracks active version
-```
-
-## Supported Platforms
-
-- Linux (x86_64, aarch64)
-- macOS (aarch64/Apple Silicon)
-
-## Environment Variables
-
-- `GITHUB_TOKEN`: GitHub personal access token for private repository access
-- `AMP_REPO`: Override repository (default: `edgeandnode/amp`)
-- `AMP_DIR`: Override installation directory (default: `$XDG_CONFIG_HOME/.amp` or `$HOME/.amp`)
-
-## Security
-
-- macOS binaries are code-signed and notarized
-- Private repository access uses GitHub's OAuth token mechanism
-
-## Troubleshooting
-
-### Command not found: ampup
-
-Make sure the `ampup` binary is in your PATH. You may need to restart your terminal or run:
-
-```sh
-source ~/.bashrc # or ~/.zshenv for zsh, or ~/.config/fish/config.fish for fish
-```
-
-### Download failed
-
-- Check your internet connection
-- Verify the release exists on GitHub
-- For private repos, ensure `GITHUB_TOKEN` is set correctly
-
-### Building from source requires Rust
-
-If you're building from source (using the `build` command), you need:
-
-- Rust toolchain (install from https://rustup.rs)
-- Git
-- Build dependencies (see main project documentation)
-
-## Uninstalling
-
-To uninstall ampd and ampup, simply delete you `.amp` directory (default: `$XDG_CONFIG_HOME/.amp` or `$HOME/.amp`):
-
-```sh
-rm -rf ~/.amp # or $XDG_CONFIG_HOME/.amp
-```
-
-Then remove the PATH entry from your shell configuration file.
diff --git a/crates/bin/ampup/build.rs b/crates/bin/ampup/build.rs
deleted file mode 100644
index 08991ae48..000000000
--- a/crates/bin/ampup/build.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-use vergen_gitcl::{BuildBuilder, Emitter, GitclBuilder};
-
-type BoxError = Box;
-
-fn main() -> Result<(), BoxError> {
- let build = BuildBuilder::all_build()?;
- let gitcl = GitclBuilder::default().describe(true, true, None).build()?;
- Emitter::new()
- .add_instructions(&build)?
- .add_instructions(&gitcl)?
- .emit()?;
- Ok(())
-}
diff --git a/crates/bin/ampup/src/builder.rs b/crates/bin/ampup/src/builder.rs
deleted file mode 100644
index d7872e987..000000000
--- a/crates/bin/ampup/src/builder.rs
+++ /dev/null
@@ -1,623 +0,0 @@
-use std::{
- fmt,
- path::{Path, PathBuf},
- process::{Command, Stdio},
-};
-
-use anyhow::{Context, Result};
-use fs_err as fs;
-
-use crate::{DEFAULT_REPO, ui, version_manager::VersionManager};
-
-#[derive(Debug)]
-pub enum BuildError {
- LocalPathNotFound {
- path: PathBuf,
- },
- LocalPathNotDirectory {
- path: PathBuf,
- },
- LocalPathNotGitRepo {
- path: PathBuf,
- },
- GitCloneFailed {
- repo: String,
- branch: Option,
- },
- GitCheckoutFailed {
- target: String,
- },
- GitFetchPrFailed {
- pr: u32,
- },
- CargoBuildFailed,
- BinaryNotFound {
- path: PathBuf,
- },
- CommandNotFound {
- command: String,
- },
-}
-
-impl std::fmt::Display for BuildError {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- match self {
- Self::LocalPathNotFound { path } => {
- writeln!(f, "Local path does not exist")?;
- writeln!(f, " Path: {}", path.display())?;
- writeln!(f)?;
- writeln!(f, " Check that the path is correct and accessible.")?;
- }
- Self::LocalPathNotDirectory { path } => {
- writeln!(f, "Local path is not a directory")?;
- writeln!(f, " Path: {}", path.display())?;
- writeln!(f)?;
- writeln!(
- f,
- " The build command requires a directory containing a Cargo workspace."
- )?;
- }
- Self::LocalPathNotGitRepo { path } => {
- writeln!(f, "Local path is not a git repository")?;
- writeln!(f, " Path: {}", path.display())?;
- writeln!(f)?;
- writeln!(
- f,
- " Use --name flag to specify a version name for non-git builds."
- )?;
- writeln!(
- f,
- " Example: ampup build --path {} --name my-version",
- path.display()
- )?;
- }
- Self::GitCloneFailed { repo, branch } => {
- writeln!(f, "Failed to clone repository")?;
- writeln!(f, " Repository: {}", repo)?;
- if let Some(b) = branch {
- writeln!(f, " Branch: {}", b)?;
- }
- writeln!(f)?;
- writeln!(f, " Ensure the repository exists and is accessible.")?;
- writeln!(f, " Check your network connection and GitHub permissions.")?;
- }
- Self::GitCheckoutFailed { target } => {
- writeln!(f, "Failed to checkout git reference")?;
- writeln!(f, " Target: {}", target)?;
- writeln!(f)?;
- writeln!(f, " The commit/branch may not exist in the repository.")?;
- }
- Self::GitFetchPrFailed { pr } => {
- writeln!(f, "Failed to fetch pull request")?;
- writeln!(f, " PR: #{}", pr)?;
- writeln!(f)?;
- writeln!(f, " Ensure the pull request exists and is accessible.")?;
- }
- Self::CargoBuildFailed => {
- writeln!(f, "Cargo build failed")?;
- writeln!(f)?;
- writeln!(f, " Check the build output above for compilation errors.")?;
- writeln!(
- f,
- " Ensure all dependencies are installed and the code compiles."
- )?;
- }
- Self::BinaryNotFound { path } => {
- writeln!(f, "Binary not found after build")?;
- writeln!(f, " Expected: {}", path.display())?;
- writeln!(f)?;
- writeln!(f, " Build succeeded but the ampd binary was not created.")?;
- writeln!(
- f,
- " This may indicate an issue with the build configuration."
- )?;
- }
- Self::CommandNotFound { command } => {
- writeln!(f, "Required command not found")?;
- writeln!(f, " Command: {}", command)?;
- writeln!(f)?;
- match command.as_str() {
- "git" => {
- writeln!(f, " Install git:")?;
- writeln!(f, " macOS: brew install git")?;
- writeln!(f, " Ubuntu/Debian: sudo apt install git")?;
- }
- "cargo" => {
- writeln!(f, " Install Rust toolchain:")?;
- writeln!(
- f,
- " curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh"
- )?;
- }
- _ => {
- writeln!(
- f,
- " Please install {} and ensure it's in your PATH.",
- command
- )?;
- }
- }
- }
- }
- Ok(())
- }
-}
-
-impl std::error::Error for BuildError {}
-
-/// Represents the source from which to build ampd
-pub enum BuildSource {
- /// Build from a local repository path
- Local { path: PathBuf },
- /// Build from a specific branch
- Branch { repo: String, branch: String },
- /// Build from a specific commit
- Commit { repo: String, commit: String },
- /// Build from a pull request
- Pr { repo: String, number: u32 },
- /// Build from main branch
- Main { repo: String },
-}
-
-impl BuildSource {
- /// Generate version label for this build source
- fn generate_version_label(&self, git_hash: Option<&str>, name: Option<&str>) -> String {
- // Custom name always takes precedence
- if let Some(name) = name {
- return name.to_string();
- }
-
- // Generate base label
- let base = match self {
- Self::Local { .. } => "local".to_string(),
- Self::Branch { repo, branch } => {
- if repo != DEFAULT_REPO {
- let slug = repo.replace('/', "-");
- format!("{}-branch-{}", slug, branch)
- } else {
- format!("branch-{}", branch)
- }
- }
- Self::Commit { repo, commit } => {
- // Commit already has hash in it, don't append git hash later
- let commit_hash = &commit[..8.min(commit.len())];
- if repo != DEFAULT_REPO {
- let slug = repo.replace('/', "-");
- return format!("{}-commit-{}", slug, commit_hash);
- } else {
- return format!("commit-{}", commit_hash);
- }
- }
- Self::Pr { repo, number } => {
- if repo != DEFAULT_REPO {
- let slug = repo.replace('/', "-");
- format!("{}-pr-{}", slug, number)
- } else {
- format!("pr-{}", number)
- }
- }
- Self::Main { repo } => {
- if repo != DEFAULT_REPO {
- let slug = repo.replace('/', "-");
- format!("{}-main", slug)
- } else {
- "main".to_string()
- }
- }
- };
-
- // Append git hash if available
- if let Some(hash) = git_hash {
- format!("{}-{}", base, hash)
- } else {
- base
- }
- }
-}
-
-impl fmt::Display for BuildSource {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Self::Local { path } => write!(f, "local path: {}", path.display()),
- Self::Branch { repo, branch } => {
- if repo != DEFAULT_REPO {
- write!(f, "repository: {}, branch: {}", repo, branch)
- } else {
- write!(f, "branch: {}", branch)
- }
- }
- Self::Commit { repo, commit } => {
- if repo != DEFAULT_REPO {
- write!(f, "repository: {}, commit: {}", repo, commit)
- } else {
- write!(f, "commit: {}", commit)
- }
- }
- Self::Pr { repo, number } => {
- if repo != DEFAULT_REPO {
- write!(f, "repository: {}, pull request #{}", repo, number)
- } else {
- write!(f, "pull request #{}", number)
- }
- }
- Self::Main { repo } => {
- if repo != DEFAULT_REPO {
- write!(f, "repository: {} (main branch)", repo)
- } else {
- write!(f, "default repository (main branch)")
- }
- }
- }
- }
-}
-
-/// Options for building ampd
-pub struct BuildOptions {
- /// Custom version name
- pub name: Option,
- /// Number of CPU cores to use
- pub jobs: Option,
-}
-
-/// Builder for ampd from source
-pub struct Builder {
- version_manager: VersionManager,
-}
-
-impl Builder {
- pub fn new(version_manager: VersionManager) -> Self {
- Self { version_manager }
- }
-
- /// Execute the build for a given source
- pub async fn build(&self, source: BuildSource, options: BuildOptions) -> Result<()> {
- match &source {
- BuildSource::Local { path } => {
- // Validate path exists and is a directory
- if !path.exists() {
- return Err(BuildError::LocalPathNotFound { path: path.clone() }.into());
- }
- if !path.is_dir() {
- return Err(BuildError::LocalPathNotDirectory { path: path.clone() }.into());
- }
-
- // Check for git repository and extract commit hash
- let git = GitRepo::new(path);
- let git_hash = git.get_commit_hash()?;
-
- // If not a git repo and no custom name provided, error out
- if git_hash.is_none() && options.name.is_none() {
- return Err(BuildError::LocalPathNotGitRepo { path: path.clone() }.into());
- }
-
- // Generate version label and build
- let version_label =
- source.generate_version_label(git_hash.as_deref(), options.name.as_deref());
- build_and_install(&self.version_manager, path, &version_label, options.jobs)?;
-
- Ok(())
- }
- BuildSource::Branch { repo, branch } => {
- let temp_dir =
- tempfile::tempdir().context("Failed to create temporary directory")?;
-
- // Clone repository with specific branch
- let git = GitRepo::clone(repo, temp_dir.path(), Some(branch.as_str())).await?;
-
- // Extract git commit hash, generate version label, and build
- let git_hash = git.get_commit_hash()?;
- let version_label =
- source.generate_version_label(git_hash.as_deref(), options.name.as_deref());
- build_and_install(
- &self.version_manager,
- temp_dir.path(),
- &version_label,
- options.jobs,
- )?;
-
- Ok(())
- }
- BuildSource::Commit { repo, commit } => {
- let temp_dir =
- tempfile::tempdir().context("Failed to create temporary directory")?;
-
- // Clone repository and checkout specific commit
- let git = GitRepo::clone(repo, temp_dir.path(), None).await?;
- git.checkout_commit(commit)?;
-
- // Extract git commit hash, generate version label, and build
- let git_hash = git.get_commit_hash()?;
- let version_label =
- source.generate_version_label(git_hash.as_deref(), options.name.as_deref());
- build_and_install(
- &self.version_manager,
- temp_dir.path(),
- &version_label,
- options.jobs,
- )?;
-
- Ok(())
- }
- BuildSource::Pr { repo, number } => {
- let temp_dir =
- tempfile::tempdir().context("Failed to create temporary directory")?;
-
- // Clone repository and checkout pull request
- let git = GitRepo::clone(repo, temp_dir.path(), None).await?;
- git.fetch_and_checkout_pr(*number)?;
-
- // Extract git commit hash, generate version label, and build
- let git_hash = git.get_commit_hash()?;
- let version_label =
- source.generate_version_label(git_hash.as_deref(), options.name.as_deref());
- build_and_install(
- &self.version_manager,
- temp_dir.path(),
- &version_label,
- options.jobs,
- )?;
-
- Ok(())
- }
- BuildSource::Main { repo } => {
- let temp_dir =
- tempfile::tempdir().context("Failed to create temporary directory")?;
-
- // Clone repository (main branch)
- let git = GitRepo::clone(repo, temp_dir.path(), None).await?;
-
- // Extract git commit hash, generate version label, and build
- let git_hash = git.get_commit_hash()?;
- let version_label =
- source.generate_version_label(git_hash.as_deref(), options.name.as_deref());
- build_and_install(
- &self.version_manager,
- temp_dir.path(),
- &version_label,
- options.jobs,
- )?;
-
- Ok(())
- }
- }
- }
-}
-
-/// Git repository operations
-pub struct GitRepo<'a> {
- path: &'a Path,
- remote: String,
-}
-
-impl<'a> GitRepo<'a> {
- /// Create a new GitRepo instance for an existing repository
- pub fn new(path: &'a Path) -> Self {
- Self {
- path,
- remote: "origin".to_string(),
- }
- }
-
- /// Clone a repository from GitHub and create a GitRepo instance
- pub async fn clone(repo: &str, destination: &'a Path, branch: Option<&str>) -> Result {
- check_command_exists("git")?;
-
- let repo_url = format!("https://github.com/{}.git", repo);
-
- ui::info!("Cloning {}", repo_url);
-
- let mut args = vec!["clone"];
-
- if let Some(branch) = branch {
- args.extend(["--branch", branch]);
- }
-
- args.push(&repo_url);
- args.push(destination.to_str().unwrap());
-
- let status = Command::new("git")
- .args(&args)
- .status()
- .context("Failed to execute git clone")?;
-
- if !status.success() {
- return Err(BuildError::GitCloneFailed {
- repo: repo.to_string(),
- branch: branch.map(|s| s.to_string()),
- }
- .into());
- }
-
- Ok(Self::new(destination))
- }
-
- /// Get the commit hash from this repository
- /// Returns None if the path is not a git repository
- pub fn get_commit_hash(&self) -> Result