diff --git a/.github/actions/just-setup/action.yml b/.github/actions/just-setup/action.yml new file mode 100644 index 000000000..7b97ece53 --- /dev/null +++ b/.github/actions/just-setup/action.yml @@ -0,0 +1,52 @@ +name: Setup tools and cache +inputs: + tools: + description: Extra tools + required: false + default: "" + cache: + description: Enable caches + required: true + default: true + type: boolean + cache-suffix: + description: Suffix for cache key + required: false + default: "" +runs: + using: composite + steps: + - if: inputs.tools == '' + name: Install just + uses: taiki-e/install-action@v2 + with: + tool: just + - if: inputs.tools != '' + name: Install just and tools + uses: taiki-e/install-action@v2 + with: + tool: just,${{ inputs.tools }} + + - if: inputs.cache + name: Configure index cache + uses: actions/cache@v3 + with: + path: | + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}-${{ inputs.cache-suffix }} + restore-keys: | + ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}- + ${{ runner.os }}-cargo-index- + + - if: inputs.cache + name: Configure build cache + uses: actions/cache@v3 + with: + path: | + target/ + key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }}-${{ inputs.cache-suffix }} + restore-keys: | + ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }}- diff --git a/.github/scripts/install-deps.sh b/.github/scripts/install-deps.sh deleted file mode 100755 index 085c32869..000000000 --- a/.github/scripts/install-deps.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -set -euxo pipefail - -apt update -exec apt install -y --no-install-recommends liblzma-dev libzip-dev libzstd-dev diff --git a/.github/scripts/pack-release-archives.sh b/.github/scripts/pack-release-archives.sh deleted file mode 100755 index 8ecb1c486..000000000 --- a/.github/scripts/pack-release-archives.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -set -euxo pipefail - -for o in outputs/*; do - pushd "$o" - - chmod +x cargo-binstall* - - target=$(basename "$o" | cut -d. -f1) - if grep -qE '(apple|windows)' <<< "$target"; then - zip -9 "../cargo-binstall-${target}.zip" * - else - tar cv * | gzip -9 > "../cargo-binstall-${target}.tgz" - fi - - popd -done diff --git a/.github/scripts/tests.sh b/.github/scripts/tests.sh deleted file mode 100755 index 5714932d8..000000000 --- a/.github/scripts/tests.sh +++ /dev/null @@ -1,126 +0,0 @@ -#!/bin/bash - -set -euxo pipefail - -unset CARGO_INSTALL_ROOT - -crates="b3sum cargo-release cargo-binstall cargo-watch miniserve sccache" - -if [ "$2" = "Windows" ]; then - # Install binaries using cargo-binstall - # shellcheck disable=SC2086 - "./$1" --log-level debug --no-confirm $crates -else - export CARGO_HOME=/tmp/cargo-home-for-test - export PATH="$CARGO_HOME/bin:/tmp/t/bin:$PATH" - - mkdir -p "/tmp/t/bin" - # Copy it to bin to test use of env var `CARGO` - cp "./$1" "/tmp/t/bin/cargo-binstall" - - # Install binaries using cargo-binstall - # shellcheck disable=SC2086 - cargo binstall --log-level debug --no-confirm $crates - - rm -r /tmp/t -fi - -# Test that the installed binaries can be run -b3sum --version -cargo-release release --version -cargo-binstall --help >/dev/null -cargo binstall --help >/dev/null -cargo watch -V -miniserve -V - -test_resources=".github/scripts/cargo-tomls" - -# Install binaries using `--manifest-path` -# Also test default github template -"./$1" binstall --force --log-level debug --manifest-path "$test_resources/github-test-Cargo.toml" --no-confirm cargo-binstall -# Test that the installed binaries can be run -cargo binstall --help >/dev/null - -# FIXME: test this some other way that is not dependent on the version being published! -# "./$1" binstall --force --log-level debug --manifest-path crates/bin --no-confirm cargo-binstall - -min_tls=1.3 -[[ "${2:-}" == "Windows" ]] && min_tls=1.2 # WinTLS on GHA doesn't support 1.3 yet - -"./$1" binstall \ - --force \ - --log-level debug \ - --min-tls-version $min_tls \ - --no-confirm \ - cargo-binstall -# Test that the installed binaries can be run -cargo binstall --help >/dev/null - -# Test --version -"./$1" binstall --force --log-level debug --no-confirm --version 0.11.1 cargo-binstall -# Test that the installed binaries can be run -cargo binstall --help >/dev/null - -# Test "$crate_name@$version" -"./$1" binstall --force --log-level debug --no-confirm cargo-binstall@0.11.1 -# Test that the installed binaries can be run -cargo binstall --help >/dev/null - -# Test skip when installed -"./$1" binstall --no-confirm --force cargo-binstall@0.11.1 -"./$1" binstall --no-confirm cargo-binstall@0.11.1 | grep -q 'cargo-binstall v0.11.1 is already installed' - -"./$1" binstall --no-confirm cargo-binstall@0.10.0 | grep -q -v 'cargo-binstall v0.10.0 is already installed' - -## Test When 0.11.0 is installed but can be upgraded. -"./$1" binstall --no-confirm cargo-binstall@0.12.0 -"./$1" binstall --no-confirm cargo-binstall@0.12.0 | grep -q 'cargo-binstall v0.12.0 is already installed' -"./$1" binstall --no-confirm cargo-binstall@^0.12.0 | grep -q -v 'cargo-binstall v0.12.0 is already installed' - -# Test default GitLab pkg-url templates -"./$1" binstall \ - --force \ - --manifest-path "$test_resources/gitlab-test-Cargo.toml" \ - --log-level debug \ - --no-confirm \ - --disable-strategies compile \ - cargo-binstall - -# Test default BitBucket pkg-url templates -"./$1" binstall \ - --force \ - --manifest-path "$test_resources/bitbucket-test-Cargo.toml" \ - --log-level debug \ - --no-confirm \ - --disable-strategies compile \ - cargo-binstall - -# Test default Github pkg-url templates, -# with bin-dir provided -"./$1" binstall \ - --force \ - --manifest-path "$test_resources/github-test-Cargo2.toml" \ - --log-level debug \ - --no-confirm \ - --disable-strategies compile \ - cargo-binstall - -## Test --disable-strategies -set +e - -"./$1" binstall --no-confirm --disable-strategies quick-install,compile cargo-update -exit_code="$?" - -if [ "$exit_code" != 94 ]; then - echo "Expected exit code 94, but actual exit code $exit_code" - exit 1 -fi - -## Test --strategies -"./$1" binstall --no-confirm --strategies crate-meta-data cargo-update -exit_code="$?" - -if [ "$exit_code" != 94 ]; then - echo "Expected exit code 94, but actual exit code $exit_code" - exit 1 -fi diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 3140c9335..000000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,149 +0,0 @@ -name: Build - -on: - workflow_call: - inputs: - for_release: - description: "True if the build is for a release" - required: true - default: false - type: boolean - - workflow_dispatch: - inputs: - for_release: - description: "True if the build is for a release" - required: true - default: false - type: boolean - -env: - CARGO_TERM_COLOR: always - CARGO_UNSTABLE_SPARSE_REGISTRY: "true" - -jobs: - build: - strategy: - fail-fast: false - matrix: - include: - - target: x86_64-unknown-linux-gnu - os: ubuntu-20.04 - debug_features: [ rustls, pkg-config ] - - target: x86_64-apple-darwin - os: macos-latest - - target: aarch64-apple-darwin - os: macos-latest - - target: x86_64-pc-windows-msvc - os: windows-latest - debug_features: [ native-tls ] - - target: x86_64-unknown-linux-musl - os: ubuntu-latest - - target: armv7-unknown-linux-musleabihf - os: ubuntu-20.04 - use-cross: true - - target: armv7-unknown-linux-gnueabihf - os: ubuntu-20.04 - use-cross: true - - target: aarch64-unknown-linux-musl - os: ubuntu-latest - use-cross: true - - target: aarch64-unknown-linux-gnu - os: ubuntu-20.04 - use-cross: true - - runs-on: ${{ matrix.os }} - name: ${{ matrix.target }} - - steps: - - uses: actions/checkout@v3 - - - name: Configure toolchain - run: | - rustup toolchain install --profile minimal --no-self-update nightly - rustup default nightly - - - name: Install cross - if: matrix.use-cross - uses: taiki-e/install-action@v2 - with: - tool: cross - - - name: Install host target - if: "!matrix.use-cross" - run: rustup target add ${{ matrix.target }} - - - name: Install rust-src - if: inputs.for_release - run: rustup component add rust-src - - - name: Select compile settings - shell: bash - run: | - jq \ - --argjson for_release '${{ toJSON(inputs.for_release) }}' \ - --argjson matrix '${{ toJSON(matrix) }}' \ - -nrf .github/scripts/compile-settings.jq \ - | tee -a $GITHUB_ENV - - - name: Configure caching - uses: actions/cache@v3 - with: - path: | - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ runner.os }}-cargo-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }}-${{ env.COUTPUT }} - - - name: Install musl-tools - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' }} - run: sudo apt-get install -y musl-tools - - - name: Install deps - if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' && !startsWith(github.ref, 'refs/tags/v') }} - run: sudo .github/scripts/install-deps.sh - - - name: Build - run: ${{ env.CTOOL }} build ${{ env.CARGS }} - env: - RUSTFLAGS: ${{ env.RUSTFLAGS }} - - - name: Get output - shell: bash - run: | - cp target/${{ matrix.target }}/${{ env.COUTPUT }}/${{ env.CBIN }} ${{ env.CBIN }} - chmod +x ${{ env.CBIN }} || true - ls -l ${{ env.CBIN }} - - - name: Upload output - uses: actions/upload-artifact@v3 - with: - retention-days: 1 - name: "${{ matrix.target }}.${{ env.CBIN }}" - path: "${{ env.CBIN }}" - macos_universal_bin: - needs: build - runs-on: macos-latest - env: - aarch64: aarch64-apple-darwin.cargo-binstall - x86_64: x86_64-apple-darwin.cargo-binstall - steps: - - name: Download aarch64 artifact - uses: actions/download-artifact@v3 - with: - name: ${{ env.aarch64 }} - path: ${{ env.aarch64 }} - - name: Download x86-64 artifact - uses: actions/download-artifact@v3 - with: - name: ${{ env.x86_64 }} - path: ${{ env.x86_64 }} - - name: Create universal binary for MacOS - run: lipo -create -output cargo-binstall $aarch64/cargo-binstall $x86_64/cargo-binstall - - name: Upload output - uses: actions/upload-artifact@v3 - with: - retention-days: 1 - name: universal-apple-darwin.cargo-binstall - path: cargo-binstall diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..d3e29bfe1 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,119 @@ +name: CI + +on: + workflow_dispatch: + pull_request: + push: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true + +env: + CARGO_TERM_COLOR: always + CARGO_UNSTABLE_SPARSE_REGISTRY: "true" + +jobs: + test: + strategy: + fail-fast: false + matrix: + include: + - target: x86_64-apple-darwin + os: macos-latest + - target: x86_64-unknown-linux-gnu + os: ubuntu-latest + - target: x86_64-unknown-linux-musl + os: ubuntu-latest + - target: x86_64-pc-windows-msvc + os: windows-latest + + runs-on: ${{ matrix.os }} + env: + CARGO_BUILD_TARGET: ${{ matrix.target }} + + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/just-setup + with: + cache-suffix: ${{ env.CARGO_BUILD_TARGET }} + + - run: just toolchain + - run: just ci-install-deps + - run: just test + + linux-cross-check: + strategy: + fail-fast: false + matrix: + target: + - armv7-unknown-linux-musleabihf + - armv7-unknown-linux-gnueabihf + - aarch64-unknown-linux-musl + - aarch64-unknown-linux-gnu + + runs-on: ubuntu-latest + env: + CARGO_BUILD_TARGET: ${{ matrix.target }} + JUST_USE_CROSS: true + + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/just-setup + with: + tools: cross + cache-suffix: ${{ env.CARGO_BUILD_TARGET }} + + - run: just toolchain + - run: just ci-install-deps + - run: just check + + apple-m1-check: + runs-on: macos-latest + env: + CARGO_BUILD_TARGET: aarch64-apple-darwin + + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/just-setup + with: + cache-suffix: ${{ env.CARGO_BUILD_TARGET }} + + - run: just toolchain + - run: just check + + lint: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/just-setup + + - run: just toolchain rustfmt,clippy + - run: just ci-install-deps + - run: just lint + + # Dummy job to have a stable name for the "all tests pass" requirement + tests-pass: + name: Tests pass + needs: + - test + - linux-cross-check + - apple-m1-check + - lint + runs-on: ubuntu-latest + steps: + - run: echo "Tests pass" + + # if everything succeeds and PR is ready for review, test the release/package process + release-builds: + if: (github.event_name == 'pull_request' && github.event.pull_request.draft == false) || github.event_name == 'workflow_dispatch' + needs: + - tests-pass + uses: ./.github/workflows/release-build.yml diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml deleted file mode 100644 index a5740149d..000000000 --- a/.github/workflows/integration.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Integration - -on: - workflow_dispatch: - pull_request: - push: - branches: - - main - -env: - CARGO_TERM_COLOR: always - -jobs: - build: - uses: ./.github/workflows/build.yml - with: - for_release: false - - test: - needs: build - - strategy: - fail-fast: false - matrix: - include: - - target: x86_64-apple-darwin - os: macos-latest - bin: cargo-binstall - - target: x86_64-unknown-linux-gnu - os: ubuntu-latest - bin: cargo-binstall - - target: x86_64-unknown-linux-musl - os: ubuntu-latest - bin: cargo-binstall - - target: x86_64-pc-windows-msvc - os: windows-latest - bin: cargo-binstall.exe - - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v3 - - - name: Download build - uses: actions/download-artifact@v3 - with: - name: "${{ matrix.target }}.${{ matrix.bin }}" - - - run: chmod +x ${{ matrix.bin }} - if: matrix.os != 'windows-latest' - - - name: Test - shell: bash - run: .github/scripts/tests.sh ${{ matrix.bin }} ${{ runner.os }} - diff --git a/.github/workflows/release-build.yml b/.github/workflows/release-build.yml new file mode 100644 index 000000000..fe408e98d --- /dev/null +++ b/.github/workflows/release-build.yml @@ -0,0 +1,119 @@ +name: Build for release + +on: + workflow_dispatch: # can't publish from dispatch + workflow_call: + inputs: + publish: + description: "Set to the release metadata JSON to publish the release" + required: false + type: string + +env: + CARGO_TERM_COLOR: always + CARGO_UNSTABLE_SPARSE_REGISTRY: "true" + +jobs: + build: + strategy: + fail-fast: false + matrix: + include: + - { o: macos-latest, t: x86_64-apple-darwin } + - { o: macos-latest, t: aarch64-apple-darwin } + - { o: ubuntu-20.04, t: x86_64-unknown-linux-gnu } + - { o: ubuntu-20.04, t: armv7-unknown-linux-gnueabihf, c: true } + - { o: ubuntu-20.04, t: aarch64-unknown-linux-gnu, c: true } + - { o: ubuntu-latest, t: x86_64-unknown-linux-musl } + - { o: ubuntu-latest, t: armv7-unknown-linux-musleabihf, c: true } + - { o: ubuntu-latest, t: aarch64-unknown-linux-musl, c: true } + - { o: windows-latest, t: x86_64-pc-windows-msvc } + - { o: windows-latest, t: aarch64-pc-windows-msvc } + + name: ${{ matrix.t }} + runs-on: ${{ matrix.o }} + env: + CARGO_BUILD_TARGET: ${{ matrix.t }} + JUST_USE_CROSS: ${{ matrix.c }} + JUST_FOR_RELEASE: true + + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/just-setup + with: + tools: cross + cache-suffix: release-${{ matrix.t }} + + - run: just toolchain rust-src + - run: just ci-install-deps + - run: just package + - if: runner.os == 'Windows' + run: Get-ChildItem packages/ + - if: runner.os != 'Windows' + run: ls -shal packages/ + + - if: ${{ inputs.publish }} + name: Publish release + uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 + with: + tag_name: ${{ fromJSON(inputs.publish).version }} + name: ${{ fromJSON(inputs.publish).version }} + body: ${{ fromJSON(inputs.publish).notes }} + append_body: false + files: | + packages/cargo-binstall-* + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - if: ${{ !inputs.publish || runner.os == 'macOS' }} + name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: ${{ matrix.t }} + path: packages/cargo-binstall-* + retention-days: 1 + + lipo: + needs: build + name: universal-apple-darwin + runs-on: macos-latest + env: + JUST_FOR_RELEASE: true + + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/just-setup + with: + cache: false + + - uses: actions/download-artifact@v3 + with: + name: x86_64-apple-darwin + path: packages/ + - uses: actions/download-artifact@v3 + with: + name: aarch64-apple-darwin + path: packages/ + + - run: ls -shalr packages/ + - run: just repackage-lipo + - run: ls -shal packages/ + + - if: ${{ inputs.publish }} + name: Publish release + uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 + with: + tag_name: ${{ fromJSON(inputs.publish).version }} + name: ${{ fromJSON(inputs.publish).version }} + body: ${{ fromJSON(inputs.publish).notes }} + append_body: false + files: | + packages/cargo-binstall-universal-* + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - if: ${{ !inputs.publish }} + name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: universal-apple-darwin + path: packages/cargo-binstall-universal-* + retention-days: 1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2e3a5310a..f47f9710e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -49,40 +49,11 @@ jobs: custom_tag: ${{ needs.info.outputs.version }} tag_prefix: '' - build: - if: "startsWith(github.event.head_commit.message, 'release: cargo-binstall v')" - needs: info # not really, but just so it fails fast - uses: ./.github/workflows/build.yml - with: - for_release: true - - release: + package: if: "startsWith(github.event.head_commit.message, 'release: cargo-binstall v')" needs: - - info - - tag - - build - name: Package and release - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Get outputs - uses: actions/download-artifact@v3 - with: - path: outputs/ - - - name: Pack archives - run: .github/scripts/pack-release-archives.sh - - - name: Publish release - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 - with: - tag_name: ${{ needs.info.outputs.version }} - name: ${{ needs.info.outputs.version }} - body: ${{ needs.info.outputs.notes }} - append_body: true - files: | - outputs/cargo-binstall-*.zip - outputs/cargo-binstall-*.tgz - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - info + - tag + uses: ./.github/workflows/release-build.yml + with: + publish: ${{ toJSON(needs.info.outputs) }} diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml deleted file mode 100644 index 57e10fffe..000000000 --- a/.github/workflows/unit-tests.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Unit tests - -on: - pull_request: - push: - branches: - - main - -env: - CARGO_TERM_COLOR: always - CARGO_UNSTABLE_SPARSE_REGISTRY: "true" - -jobs: - test: - strategy: - fail-fast: false - matrix: - os: - - macos - - ubuntu - - windows - - runs-on: ${{ matrix.os }}-latest - name: unit tests on ${{ matrix.os }} - - steps: - - uses: actions/checkout@v3 - - name: Configure toolchain - run: | - rustup toolchain install nightly --component rustfmt,clippy --no-self-update --profile minimal - rustup default nightly - - - name: Configure caching - uses: actions/cache@v3 - with: - path: | - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ runner.os }}-unit-tests-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-unit-tests - - - name: Install deps - if: matrix.os == 'ubuntu' - run: sudo .github/scripts/install-deps.sh - - - name: Test (Unix) - if: matrix.os != 'windows' - run: cargo test --no-default-features --features pkg-config,native-tls - - - name: Test (Windows) - if: matrix.os == 'windows' - run: cargo test --no-default-features --features native-tls - - - name: fmt - run: cargo fmt --all --check - - - name: clippy - run: cargo clippy --no-deps -- -D clippy::all diff --git a/.gitignore b/.gitignore index 05923927f..b8aaf2b20 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /target .DS_Store +/packages +/e2e-tests/cargo-binstall* diff --git a/README.md b/README.md index 9fb698693..6739e2b24 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ We recommend using the pre-compiled ones because we optimize those more than a s | macos | universal | https://github.com/cargo-bins/cargo-binstall/releases/latest/download/cargo-binstall-universal-apple-darwin.zip | | windows | x86\_64 | https://github.com/cargo-bins/cargo-binstall/releases/latest/download/cargo-binstall-x86_64-pc-windows-msvc.zip | -To upgrade, use `cargo binstall cargo-binstall`! +To upgrade cargo-binstall, use `cargo binstall cargo-binstall`! ## Usage @@ -90,6 +90,8 @@ Supported crates such as `cargo-binstall` itself can also be updated with `cargo - You can find a full description of errors including exit codes here: - Can I use it in CI? - Yes! For GitHub Actions, we recommend the excellent [taiki-e/install-action](https://github.com/marketplace/actions/install-development-tools), which has explicit support for selected tools and uses `cargo-binstall` for everything else. +- Are debug symbols available? + - Yes! Extra pre-built packages with a `.full` suffix are available and contain split debuginfo (for Windows and macOS, Linux coming soon), documentation files, and extra binaries like the `detect-wasi` utility. --- diff --git a/crates/bin/src/args.rs b/crates/bin/src/args.rs index 30c41fc5a..107c452c9 100644 --- a/crates/bin/src/args.rs +++ b/crates/bin/src/args.rs @@ -1,4 +1,5 @@ use std::{ + env, ffi::OsString, fmt, num::{NonZeroU64, ParseIntError}, @@ -225,13 +226,8 @@ pub struct Args { /// /// Set to `off` to disable logging completely, this will also /// disable output from `cargo-install`. - #[clap( - help_heading = "Meta", - long, - default_value = "info", - value_name = "LEVEL" - )] - pub log_level: LevelFilter, + #[clap(help_heading = "Meta", long, value_name = "LEVEL")] + pub log_level: Option, /// Equivalent to setting `log_level` to `off`. /// @@ -331,8 +327,16 @@ pub fn parse() -> Args { // Load options let mut opts = Args::parse_from(args); - if opts.quiet { - opts.log_level = LevelFilter::Off; + + if let (true, Some(log)) = ( + opts.log_level.is_none(), + env::var("BINSTALL_LOG_LEVEL") + .ok() + .and_then(|s| s.parse().ok()), + ) { + opts.log_level = Some(log); + } else if opts.quiet { + opts.log_level = Some(LevelFilter::Off); } // Ensure no conflict diff --git a/crates/bin/src/entry.rs b/crates/bin/src/entry.rs index f1490f6c9..020fedb2e 100644 --- a/crates/bin/src/entry.rs +++ b/crates/bin/src/entry.rs @@ -85,7 +85,7 @@ pub async fn install_crates(args: Args, jobserver_client: LazyJobserverClient) - no_symlinks: args.no_symlinks, dry_run: args.dry_run, force: args.force, - quiet: args.log_level == LevelFilter::Off, + quiet: args.log_level == Some(LevelFilter::Off), version_req: args.version_req, manifest_path: args.manifest_path, diff --git a/crates/bin/src/main.rs b/crates/bin/src/main.rs index ecf0f41b9..721ba51f4 100644 --- a/crates/bin/src/main.rs +++ b/crates/bin/src/main.rs @@ -1,6 +1,7 @@ use std::time::Instant; use binstalk::helpers::jobserver_client::LazyJobserverClient; +use log::LevelFilter; use tracing::debug; use cargo_binstall::{ @@ -24,7 +25,10 @@ fn main() -> MainExit { println!("{}", env!("CARGO_PKG_VERSION")); MainExit::Success(None) } else { - logging(args.log_level, args.json_output); + logging( + args.log_level.unwrap_or(LevelFilter::Info), + args.json_output, + ); let start = Instant::now(); diff --git a/crates/detect-targets/src/detect.rs b/crates/detect-targets/src/detect.rs index 2ef978c84..0216d4ade 100644 --- a/crates/detect-targets/src/detect.rs +++ b/crates/detect-targets/src/detect.rs @@ -9,8 +9,6 @@ use std::{ use cfg_if::cfg_if; use tokio::process::Command; -use crate::TARGET; - cfg_if! { if #[cfg(target_os = "linux")] { mod linux; @@ -56,7 +54,7 @@ pub async fn detect_targets() -> Vec { { let target = get_target_from_rustc().await.unwrap_or_else(|| { guess_host_triple::guess_host_triple() - .unwrap_or(TARGET) + .unwrap_or(crate::TARGET) .to_string() }); diff --git a/crates/detect-wasi/Cargo.toml b/crates/detect-wasi/Cargo.toml index e9d4241cc..01df98a6b 100644 --- a/crates/detect-wasi/Cargo.toml +++ b/crates/detect-wasi/Cargo.toml @@ -11,3 +11,6 @@ license = "Apache-2.0 OR MIT" [dependencies] tempfile = "3.3.0" + +[package.metadata.binstall] +pkg-url = "{ repo }/releases/download/v{ version }/cargo-binstall-{ target }.full.{ archive-format }" diff --git a/.github/scripts/fake-cargo/cargo b/e2e-tests/fake-cargo/cargo similarity index 100% rename from .github/scripts/fake-cargo/cargo rename to e2e-tests/fake-cargo/cargo diff --git a/e2e-tests/live.sh b/e2e-tests/live.sh new file mode 100755 index 000000000..fd9107fee --- /dev/null +++ b/e2e-tests/live.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +set -euxo pipefail + +unset CARGO_INSTALL_ROOT + +crates="b3sum cargo-release cargo-binstall cargo-watch miniserve sccache" + +export CARGO_HOME=$(mktemp -d 2>/dev/null || mktemp -d -t 'cargo-home') +othertmpdir=$(mktemp -d 2>/dev/null || mktemp -d -t 'cargo-test') +export PATH="$CARGO_HOME/bin:$othertmpdir/bin:$PATH" + +mkdir -p "$othertmpdir/bin" +# Copy it to bin to test use of env var `CARGO` +cp "./$1" "$othertmpdir/bin/" + +# Install binaries using cargo-binstall +# shellcheck disable=SC2086 +cargo binstall --no-confirm $crates + +rm -r "$othertmpdir" + +# Test that the installed binaries can be run +b3sum --version +cargo-release release --version +cargo-binstall --help >/dev/null +cargo binstall --help >/dev/null +cargo watch -V +miniserve -V diff --git a/e2e-tests/manifest-path.sh b/e2e-tests/manifest-path.sh new file mode 100755 index 000000000..9818eef1c --- /dev/null +++ b/e2e-tests/manifest-path.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -euxo pipefail + +unset CARGO_INSTALL_ROOT + +export CARGO_HOME=$(mktemp -d 2>/dev/null || mktemp -d -t 'cargo-home') +export PATH="$CARGO_HOME/bin:$PATH" + +# Install binaries using `--manifest-path` +# Also test default github template +"./$1" binstall --force --manifest-path "manifests/github-test-Cargo.toml" --no-confirm cargo-binstall +# Test that the installed binaries can be run +cargo binstall --help >/dev/null diff --git a/.github/scripts/cargo-tomls/bitbucket-test-Cargo.toml b/e2e-tests/manifests/bitbucket-test-Cargo.toml similarity index 100% rename from .github/scripts/cargo-tomls/bitbucket-test-Cargo.toml rename to e2e-tests/manifests/bitbucket-test-Cargo.toml diff --git a/.github/scripts/cargo-tomls/github-test-Cargo.toml b/e2e-tests/manifests/github-test-Cargo.toml similarity index 100% rename from .github/scripts/cargo-tomls/github-test-Cargo.toml rename to e2e-tests/manifests/github-test-Cargo.toml diff --git a/.github/scripts/cargo-tomls/github-test-Cargo2.toml b/e2e-tests/manifests/github-test-Cargo2.toml similarity index 100% rename from .github/scripts/cargo-tomls/github-test-Cargo2.toml rename to e2e-tests/manifests/github-test-Cargo2.toml diff --git a/.github/scripts/cargo-tomls/gitlab-test-Cargo.toml b/e2e-tests/manifests/gitlab-test-Cargo.toml similarity index 100% rename from .github/scripts/cargo-tomls/gitlab-test-Cargo.toml rename to e2e-tests/manifests/gitlab-test-Cargo.toml diff --git a/e2e-tests/other-repos.sh b/e2e-tests/other-repos.sh new file mode 100755 index 000000000..2097da438 --- /dev/null +++ b/e2e-tests/other-repos.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +set -euxo pipefail + +unset CARGO_INSTALL_ROOT + +export CARGO_HOME=$(mktemp -d 2>/dev/null || mktemp -d -t 'cargo-home') +export PATH="$CARGO_HOME/bin:$PATH" + +# Test default GitLab pkg-url templates +"./$1" binstall \ + --force \ + --manifest-path "manifests/gitlab-test-Cargo.toml" \ + --no-confirm \ + --disable-strategies compile \ + cargo-binstall + +# Test default BitBucket pkg-url templates +"./$1" binstall \ + --force \ + --manifest-path "manifests/bitbucket-test-Cargo.toml" \ + --no-confirm \ + --disable-strategies compile \ + cargo-binstall + +# Test default Github pkg-url templates, +# with bin-dir provided +"./$1" binstall \ + --force \ + --manifest-path "manifests/github-test-Cargo2.toml" \ + --no-confirm \ + --disable-strategies compile \ + cargo-binstall diff --git a/e2e-tests/strategies.sh b/e2e-tests/strategies.sh new file mode 100755 index 000000000..741cdddd2 --- /dev/null +++ b/e2e-tests/strategies.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +set -uxo pipefail + +unset CARGO_INSTALL_ROOT + +export CARGO_HOME=$(mktemp -d 2>/dev/null || mktemp -d -t 'cargo-home') +export PATH="$CARGO_HOME/bin:$PATH" + +## Test --disable-strategies +"./$1" binstall --no-confirm --disable-strategies quick-install,compile cargo-update +exit_code="$?" + +if [ "$exit_code" != 94 ]; then + echo "Expected exit code 94, but actual exit code $exit_code" + exit 1 +fi + +## Test --strategies +"./$1" binstall --no-confirm --strategies crate-meta-data cargo-update +exit_code="$?" + +if [ "$exit_code" != 94 ]; then + echo "Expected exit code 94, but actual exit code $exit_code" + exit 1 +fi diff --git a/e2e-tests/tls.sh b/e2e-tests/tls.sh new file mode 100755 index 000000000..e603e1975 --- /dev/null +++ b/e2e-tests/tls.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -euxo pipefail + +unset CARGO_INSTALL_ROOT + +export CARGO_HOME=$(mktemp -d 2>/dev/null || mktemp -d -t 'cargo-home') +export PATH="$CARGO_HOME/bin:$PATH" + +"./$1" binstall \ + --force \ + --min-tls-version "${2:-1.3}" \ + --no-confirm \ + cargo-binstall +# Test that the installed binaries can be run +cargo binstall --help >/dev/null diff --git a/e2e-tests/upgrade.sh b/e2e-tests/upgrade.sh new file mode 100755 index 000000000..dd5919054 --- /dev/null +++ b/e2e-tests/upgrade.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +set -euxo pipefail + +unset CARGO_INSTALL_ROOT + +export CARGO_HOME=$(mktemp -d 2>/dev/null || mktemp -d -t 'cargo-home') +export PATH="$CARGO_HOME/bin:$PATH" + +# Test skip when installed +"./$1" binstall --no-confirm --force cargo-binstall@0.11.1 +"./$1" binstall --log-level=info --no-confirm cargo-binstall@0.11.1 | grep -q 'cargo-binstall v0.11.1 is already installed' + +"./$1" binstall --log-level=info --no-confirm cargo-binstall@0.10.0 | grep -q -v 'cargo-binstall v0.10.0 is already installed' + +## Test When 0.11.0 is installed but can be upgraded. +"./$1" binstall --no-confirm cargo-binstall@0.12.0 +"./$1" binstall --log-level=info --no-confirm cargo-binstall@0.12.0 | grep -q 'cargo-binstall v0.12.0 is already installed' +"./$1" binstall --log-level=info --no-confirm cargo-binstall@^0.12.0 | grep -q -v 'cargo-binstall v0.12.0 is already installed' diff --git a/e2e-tests/version-syntax.sh b/e2e-tests/version-syntax.sh new file mode 100755 index 000000000..e4096dab0 --- /dev/null +++ b/e2e-tests/version-syntax.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -euxo pipefail + +unset CARGO_INSTALL_ROOT + +export CARGO_HOME=$(mktemp -d 2>/dev/null || mktemp -d -t 'cargo-home') +export PATH="$CARGO_HOME/bin:$PATH" + +# Test --version +"./$1" binstall --force --no-confirm --version 0.11.1 cargo-binstall +# Test that the installed binaries can be run +cargo binstall --help >/dev/null + +# Test "$crate_name@$version" +"./$1" binstall --force --no-confirm cargo-binstall@0.11.1 +# Test that the installed binaries can be run +cargo binstall --help >/dev/null diff --git a/justfile b/justfile new file mode 100644 index 000000000..92ed4389a --- /dev/null +++ b/justfile @@ -0,0 +1,238 @@ +# input variables +ci := env_var_or_default("CI", "") +for-release := env_var_or_default("JUST_FOR_RELEASE", "") +use-cross := env_var_or_default("JUST_USE_CROSS", "") +extra-build-args := env_var_or_default("JUST_EXTRA_BUILD_ARGS", "") +extra-features := env_var_or_default("JUST_EXTRA_FEATURES", "") +default-features := env_var_or_default("JUST_DEFAULT_FEATURES", "") +override-features := env_var_or_default("JUST_OVERRIDE_FEATURES", "") + +export BINSTALL_LOG_LEVEL := if env_var_or_default("RUNNER_DEBUG", "0") == "1" { "debug" } else { "info" } + +# target information +target-host := `rustc -vV | grep host: | cut -d ' ' -f 2` +target := env_var_or_default("CARGO_BUILD_TARGET", target-host) +target-os := if target =~ "-windows-" { "windows" + } else if target =~ "darwin" { "macos" + } else if target =~ "linux" { "linux" + } else { "unknown" } +target-arch := if target =~ "x86_64" { "x64" + } else if target =~ "i[56]86" { "x86" + } else if target =~ "aarch64" { "arm64" + } else if target =~ "armv7" { "arm32" + } else { "unknown" } +target-libc := if target =~ "gnu" { "gnu" + } else if target =~ "musl" { "musl" + } else { "unknown" } + +# build output location +output-ext := if target-os == "windows" { ".exe" } else { "" } +output-filename := "cargo-binstall" + output-ext +output-profile-folder := if for-release != "" { "release" } else { "debug" } +output-folder := if target != target-host { "target" / target / output-profile-folder + } else if env_var_or_default("CARGO_BUILD_TARGET", "") != "" { "target" / target / output-profile-folder + } else if cargo-buildstd != "" { "target" / target / output-profile-folder + } else { "target" / output-profile-folder } +output-path := output-folder / output-filename + +# which tool to use for compiling +cargo-bin := if use-cross != "" { "cross" } else { "cargo +nightly" } + +# cargo compile options +cargo-profile := if for-release != "" { "release" } else { "dev" } + + +ci-or-no := if ci != "" { "ci" } else { "noci" } + +# In release builds in CI, build the std library ourselves so it uses our +# compile profile, and optimise panic messages out with immediate abort. +# +# explicitly disabled on aarch64-unknown-linux-gnu due to a failing build +cargo-buildstd := if (cargo-profile / ci-or-no) == "release/ci" { + if target == "aarch64-unknown-linux-gnu" { "" + } else { " -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort" } +} else { "" } + +# In musl release builds in CI, statically link gcclibs. +cargo-gcclibs := if (cargo-profile / ci-or-no / target-libc) == "release/ci/musl" { + " -C link-arg=-lgcc -C link-arg=-static-libgcc" +} else { "" } + +# disable default features in CI for debug builds, for speed +cargo-no-default-features := if default-features == "false" { " --no-default-features" + } else if default-features == "true" { "" + } else if (cargo-profile / ci-or-no) == "dev/ci" { " --no-default-features" + } else { "" } + +cargo-features := trim_end_match(if override-features != "" { override-features + } else if (cargo-profile / ci-or-no) == "dev/ci" { "rustls,fancy-with-backtrace," + extra-features + } else if (cargo-profile / ci-or-no / target-libc) == "release/ci/musl" { "rustls,fancy-with-backtrace,zstd-thin," + extra-features + } else if (cargo-profile / ci-or-no) == "release/ci" { "rustls,fancy-with-backtrace," + extra-features + } else { extra-features +}, ",") + +# it seems we can't split debuginfo for non-buildstd builds +# errors with: "Found a record with an unknown abbreviation code" +cargo-split-debuginfo := if cargo-buildstd != "" { " --config='profile.release.split-debuginfo=\"packed\"' --config=profile.release.debug=2" } else { "" } + +# for ARM64 Windows, use a patched version of ring +# this should be unnecessary once ring 0.17 is released +win-arm64-ring16 := if target == "aarch64-pc-windows-msvc" { " --config='patch.crates-io.ring.git=\"https://github.com/awakecoding/ring\"' --config='patch.crates-io.ring.branch=\"0.16.20_alpha\"'" } else { "" } + +cargo-build-args := (if for-release != "" { " --release" } else { "" }) + (if target != target-host { " --target " + target } else if cargo-buildstd != "" { " --target " + target } else { "" }) + (cargo-buildstd) + (if extra-build-args != "" { " " + extra-build-args } else { "" }) + (cargo-no-default-features) + (cargo-split-debuginfo) + (if cargo-features != "" { " --features " + cargo-features } else { "" }) + (win-arm64-ring16) +export RUSTFLAGS := (cargo-gcclibs) + + +ci-apt-deps := if target == "x86_64-unknown-linux-gnu" { "liblzma-dev libzip-dev libzstd-dev" + } else if target == "x86_64-unknown-linux-musl" { "musl-tools" + } else { "" } + +[linux] +ci-install-deps: + {{ if ci-apt-deps == "" { "exit" } else { "" } }} + sudo apt update && sudo apt install -y --no-install-recommends {{ci-apt-deps}} + +[macos] +[windows] +ci-install-deps: + +toolchain components="": + rustup toolchain install nightly {{ if components != "" { "--component " + components } else { "" } }} --no-self-update --profile minimal + {{ if ci != "" { "rustup default nightly" } else { "rustup override set nightly" } }} + {{ if target != "" { "rustup target add " + target } else { "" } }} + + +build: + {{cargo-bin}} build {{cargo-build-args}} + +check: + {{cargo-bin}} check {{cargo-build-args}} + +get-output file outdir=".": + test -d "{{outdir}}" || mkdir -p {{outdir}} + cp -r {{ output-folder / file }} {{outdir}}/{{ file_name(file) }} + -ls -l {{outdir}}/{{ file_name(file) }} + +get-binary outdir=".": (get-output output-filename outdir) + -chmod +x {{ outdir / output-filename }} + +e2e-test file *arguments: (get-binary "e2e-tests") + cd e2e-tests && bash {{file}}.sh {{output-filename}} {{arguments}} + +e2e-test-live: (e2e-test "live") +e2e-test-manifest-path: (e2e-test "manifest-path") +e2e-test-other-repos: (e2e-test "other-repos") +e2e-test-strategies: (e2e-test "strategies") +e2e-test-version-syntax: (e2e-test "version-syntax") +e2e-test-upgrade: (e2e-test "upgrade") + +# WinTLS (Windows in CI) does not have TLS 1.3 support +[windows] +e2e-test-tls: (e2e-test "tls" "1.2") +[linux] +[macos] +e2e-test-tls: (e2e-test "tls" "1.2") (e2e-test "tls" "1.3") + +e2e-tests: e2e-test-live e2e-test-manifest-path e2e-test-other-repos e2e-test-strategies e2e-test-version-syntax e2e-test-upgrade e2e-test-tls + +unit-tests: + {{cargo-bin}} test {{cargo-build-args}} + +test: unit-tests build e2e-tests + +clippy: + {{cargo-bin}} clippy --no-deps -- -D clippy::all + +fmt: + cargo fmt --all -- --check + +fmt-check: + cargo fmt --all -- --check + +lint: clippy fmt-check + +package-dir: + rm -rf packages/prep + mkdir -p packages/prep + cp crates/bin/LICENSE packages/prep + cp README.md packages/prep + +[macos] +package-prepare: build package-dir + just get-binary packages/prep + -just get-output cargo-binstall.dSYM packages/prep + + just get-output detect-wasi{{output-ext}} packages/prep + -just get-output detect-wasi.dSYM packages/prep + +# when https://github.com/rust-lang/cargo/pull/11384 lands, we can use +# -just get-output cargo_binstall.dwp packages/prep +# underscored dwp name needs to remain for debuggers to find the file properly +[linux] +package-prepare: build package-dir + just get-binary packages/prep + -cp {{output-folder}}/deps/cargo_binstall-*.dwp packages/prep/cargo_binstall.dwp + + just get-output detect-wasi packages/prep + -cp {{output-folder}}/deps/detect_wasi-*.dwp packages/prep/detect_wasi.dwp + +# underscored pdb name needs to remain for debuggers to find the file properly +# read from deps because sometimes cargo doesn't copy the pdb to the output folder +[windows] +package-prepare: build package-dir + just get-binary packages/prep + -just get-output deps/cargo_binstall.pdb packages/prep + + just get-output detect-wasi.exe packages/prep + -just get-output deps/detect_wasi.pdb packages/prep + +# we don't get dSYM bundles for universal binaries; unsure if it's even a thing +[macos] +lipo-prepare: package-dir + just target=aarch64-apple-darwin build get-binary packages/prep/arm64 + just target=x86_64-apple-darwin build get-binary packages/prep/x64 + + just target=aarch64-apple-darwin get-binary packages/prep/arm64 + just target=x86_64-apple-darwin get-binary packages/prep/x64 + lipo -create -output packages/prep/{{output-filename}} packages/prep/{arm64,x64}/{{output-filename}} + + just target=aarch64-apple-darwin get-output detect-wasi{{output-ext}} packages/prep/arm64 + just target=x86_64-apple-darwin get-output detect-wasi{{output-ext}} packages/prep/x64 + lipo -create -output packages/prep/detect-wasi{{output-ext}} packages/prep/{arm64,x64}/detect-wasi{{output-ext}} + + rm -rf packages/prep/{arm64,x64} + + +[linux] +package: package-prepare + cd packages/prep && tar cv {{output-filename}} | gzip -9 > "../cargo-binstall-{{target}}.tgz" + cd packages/prep && tar cv * | gzip -9 > "../cargo-binstall-{{target}}.full.tgz" + +[macos] +package: package-prepare + cd packages/prep && zip -9 "../cargo-binstall-{{target}}.zip" {{output-filename}} + cd packages/prep && zip -9 "../cargo-binstall-{{target}}.full.zip" * + +[windows] +package: package-prepare + cd packages/prep && 7z a -mx9 "../cargo-binstall-{{target}}.zip" {{output-filename}} + cd packages/prep && 7z a -mx9 "../cargo-binstall-{{target}}.full.zip" * + +[macos] +package-lipo: lipo-prepare + cd packages/prep && zip -9 "../cargo-binstall-universal-apple-darwin.zip" {{output-filename}} + cd packages/prep && zip -9 "../cargo-binstall-universal-apple-darwin.full.zip" * + +# assuming x64 and arm64 packages are already built, extract and lipo them +[macos] +repackage-lipo: package-dir + mkdir -p packages/prep/{arm64,x64} + cd packages/prep/x64 && unzip -o "../../cargo-binstall-x86_64-apple-darwin.full.zip" + cd packages/prep/arm64 && unzip -o "../../cargo-binstall-aarch64-apple-darwin.full.zip" + + lipo -create -output packages/prep/{{output-filename}} packages/prep/{arm64,x64}/{{output-filename}} + lipo -create -output packages/prep/detect-wasi packages/prep/{arm64,x64}/detect-wasi + + rm -rf packages/prep/{arm64,x64} + cd packages/prep && zip -9 "../cargo-binstall-universal-apple-darwin.zip" {{output-filename}} + cd packages/prep && zip -9 "../cargo-binstall-universal-apple-darwin.full.zip" *