From aa7098502e5054ae68bb6383c91d934ff67f7151 Mon Sep 17 00:00:00 2001 From: thomasschafer Date: Mon, 18 Nov 2024 19:42:32 +0000 Subject: [PATCH 1/4] Add build workflow --- .github/workflows/build.yml | 118 ++++++++++++++++++++++++++++++++++++ README.md | 13 ++++ src/main.rs | 10 +-- 3 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..96bc864 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,118 @@ +name: Build and upload release binaries + +on: + # push: + # tags: + # - "v*" + workflow_dispatch: + pull_request: + branches: + - '**' # TODO: remove + +permissions: + contents: write + +jobs: + build-and-upload: + name: ${{ matrix.target }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + target: x86_64-unknown-linux-musl + use-cross: true + - os: ubuntu-latest + target: aarch64-unknown-linux-musl + use-cross: true + - os: macos-13 + target: x86_64-apple-darwin + use-cross: false + - os: macos-latest + target: aarch64-apple-darwin + use-cross: false + - os: windows-latest + target: x86_64-pc-windows-msvc + use-cross: false + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get latest tag + shell: bash + run: | + git fetch --tags + LATEST_TAG=$(git tag --sort=committerdate | tail -1) + echo "LATEST_TAG=$LATEST_TAG" >> $GITHUB_ENV + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.target }} + + - name: Handle Rust dependencies caching + uses: Swatinem/rust-cache@v2 + with: + key: v1-${{ matrix.target }} + + - name: Build binary + uses: clechasseur/rs-cargo@v2 + with: + command: build + args: --release --target ${{ matrix.target }} + use-cross: ${{ matrix.use-cross }} + + - name: Get binary name from Cargo.toml + shell: bash + run: | + BINARY_NAME=$(grep -m1 '^name' Cargo.toml | cut -d'"' -f2 | cut -d"'" -f2) + echo "BINARY_NAME=$BINARY_NAME" >> $GITHUB_ENV + + - name: Create release archive + shell: bash + run: | + cd target/${{ matrix.target }}/release + if [ "${{ runner.os }}" = "Windows" ]; then + ARCHIVE="${{ env.BINARY_NAME }}-${{ env.LATEST_TAG }}-${{ matrix.target }}.zip" + mv "${{ env.BINARY_NAME }}.exe" "${{ env.BINARY_NAME }}-${{ matrix.target }}.exe" + 7z a "$ARCHIVE" "${{ env.BINARY_NAME }}-${{ matrix.target }}.exe" + else + ARCHIVE="${{ env.BINARY_NAME }}-${{ env.LATEST_TAG }}-${{ matrix.target }}.tar.gz" + mv "${{ env.BINARY_NAME }}" "${{ env.BINARY_NAME }}-${{ matrix.target }}" + tar -czvf "$ARCHIVE" "${{ env.BINARY_NAME }}-${{ matrix.target }}" + fi + + # Generate checksums + openssl dgst -r -sha256 -out "$ARCHIVE.sha256" "$ARCHIVE" + openssl dgst -r -sha512 -out "$ARCHIVE.sha512" "$ARCHIVE" + + echo "ASSET=$ARCHIVE" >> $GITHUB_ENV + + - name: Verify binary + shell: bash + run: | + cd target/${{ matrix.target }}/release + case "${{ matrix.target }}" in + *windows*) + 7z x -y "$ASSET" + ./${{ env.BINARY_NAME }}-${{ matrix.target }}.exe --version ;; + aarch64*) + echo "Can't test an ARM binary on a AMD64 runner" ;; + *) + tar -xvzf "$ASSET" + ./${{ env.BINARY_NAME }}-${{ matrix.target }} --version ;; + esac + + - name: Upload to release + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ env.LATEST_TAG }} + files: | + target/${{ matrix.target }}/release/${{ env.ASSET }} + target/${{ matrix.target }}/release/${{ env.ASSET }}.sha256 + target/${{ matrix.target }}/release/${{ env.ASSET }}.sha512 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 2544f28..2912793 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,19 @@ Ensure you have cargo installed (see [here](https://doc.rust-lang.org/cargo/gett cargo install scooter ``` +### Prebuilt binaries + +You can download binaries from the releases page (note that you'll need to unzip after downloading): + +- **Linux** + - Intel/AMD: `*-x86_64-unknown-linux-musl.tar.gz` + - ARM64: `*-aarch64-unknown-linux-musl.tar.gz` +- **macOS** + - Apple Silicon: `*-aarch64-apple-darwin.tar.gz` + - Intel: `*-x86_64-apple-darwin.tar.gz` +- **Windows** + - `*-x86_64-pc-windows-msvc.zip` + ### Building from source Ensure you have cargo installed (see [here](https://doc.rust-lang.org/cargo/getting-started/installation.html)), then run the following commands: diff --git a/src/main.rs b/src/main.rs index 1321ee0..7143f66 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,11 @@ use ratatui::{backend::CrosstermBackend, Terminal}; use std::{io, path::PathBuf, str::FromStr}; use tui::Tui; +use crate::{ + app::App, + event::{Event, EventHandler}, +}; + mod app; mod event; mod fields; @@ -11,13 +16,10 @@ mod logging; mod tui; mod ui; mod utils; -use crate::{ - app::App, - event::{Event, EventHandler}, -}; #[derive(Parser, Debug)] #[command(about = "Interactive find and replace TUI.")] +#[command(version)] struct Args { /// Directory in which to search #[arg(index = 1)] From 7d1b9dccc7a259749a5a79361f7e2e8e2216d28a Mon Sep 17 00:00:00 2001 From: thomasschafer Date: Mon, 18 Nov 2024 21:30:01 +0000 Subject: [PATCH 2/4] Update readme --- README.md | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 2912793..a23f7d9 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,22 @@ Scooter respects both `.gitignore` and `.ignore` files. You can add capture groups to the search regex and use them in the replacement string: for instance, if you use `(\d) - (\w+)` for the search text and `($2) "$1"` as the replacement, then `9 - foo` would be replaced with `(foo) "9"`. +## Usage + +Run + +```sh +scooter +``` + +in a terminal to launch Scooter. By default the current directory is used to search and replace in, but you can pass in a directory as the first argument to override this behaviour: + +```sh +scooter ../foo/bar` +``` + +You can then enter some text to search with and text to replace matches with, toggle on or off fixed strings, and enter a regex pattern that filenames must match. A more extensive set of keymappings will be shown at the bottom of the window: these vary slightly depending on the screen you're on. + ## Installation ### Cargo @@ -26,13 +42,13 @@ cargo install scooter ### Prebuilt binaries -You can download binaries from the releases page (note that you'll need to unzip after downloading): +You can download binaries from the [releases page](https://github.com/thomasschafer/scooter/releases/latest). After downloading, unzip the binary and move it to a directory in your `PATH`. - **Linux** - Intel/AMD: `*-x86_64-unknown-linux-musl.tar.gz` - ARM64: `*-aarch64-unknown-linux-musl.tar.gz` - **macOS** - - Apple Silicon: `*-aarch64-apple-darwin.tar.gz` + - Apple silicon: `*-aarch64-apple-darwin.tar.gz` - Intel: `*-x86_64-apple-darwin.tar.gz` - **Windows** - `*-x86_64-pc-windows-msvc.zip` @@ -47,10 +63,6 @@ cd scooter cargo install --path . ``` -## Usage - -Run `scooter` in a terminal to launch Scooter. You can then enter some text to search with and text to replace matches with, toggle on or off fixed strings, and enter a regex pattern that filenames must match. A more extensive set of keymappings will be shown at the bottom of the window: these vary slightly depending on the screen you're on. - ## Contributing Contributions are very welcome! I'd be especially grateful for any contributions to add scooter to popular package managers. If you'd like to add a new feature, please create an issue first so we can discuss the idea, then create a PR with your changes. From 479126ef69e2ddb9f2436de1ffabbcd2450a25e9 Mon Sep 17 00:00:00 2001 From: thomasschafer Date: Tue, 19 Nov 2024 09:36:45 +0000 Subject: [PATCH 3/4] Combine build and release workflows --- .github/workflows/build.yml | 118 ---------------------------------- .github/workflows/release.yml | 107 ++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 118 deletions(-) delete mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 96bc864..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,118 +0,0 @@ -name: Build and upload release binaries - -on: - # push: - # tags: - # - "v*" - workflow_dispatch: - pull_request: - branches: - - '**' # TODO: remove - -permissions: - contents: write - -jobs: - build-and-upload: - name: ${{ matrix.target }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - os: ubuntu-latest - target: x86_64-unknown-linux-musl - use-cross: true - - os: ubuntu-latest - target: aarch64-unknown-linux-musl - use-cross: true - - os: macos-13 - target: x86_64-apple-darwin - use-cross: false - - os: macos-latest - target: aarch64-apple-darwin - use-cross: false - - os: windows-latest - target: x86_64-pc-windows-msvc - use-cross: false - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Get latest tag - shell: bash - run: | - git fetch --tags - LATEST_TAG=$(git tag --sort=committerdate | tail -1) - echo "LATEST_TAG=$LATEST_TAG" >> $GITHUB_ENV - - - name: Install Rust - uses: dtolnay/rust-toolchain@stable - with: - targets: ${{ matrix.target }} - - - name: Handle Rust dependencies caching - uses: Swatinem/rust-cache@v2 - with: - key: v1-${{ matrix.target }} - - - name: Build binary - uses: clechasseur/rs-cargo@v2 - with: - command: build - args: --release --target ${{ matrix.target }} - use-cross: ${{ matrix.use-cross }} - - - name: Get binary name from Cargo.toml - shell: bash - run: | - BINARY_NAME=$(grep -m1 '^name' Cargo.toml | cut -d'"' -f2 | cut -d"'" -f2) - echo "BINARY_NAME=$BINARY_NAME" >> $GITHUB_ENV - - - name: Create release archive - shell: bash - run: | - cd target/${{ matrix.target }}/release - if [ "${{ runner.os }}" = "Windows" ]; then - ARCHIVE="${{ env.BINARY_NAME }}-${{ env.LATEST_TAG }}-${{ matrix.target }}.zip" - mv "${{ env.BINARY_NAME }}.exe" "${{ env.BINARY_NAME }}-${{ matrix.target }}.exe" - 7z a "$ARCHIVE" "${{ env.BINARY_NAME }}-${{ matrix.target }}.exe" - else - ARCHIVE="${{ env.BINARY_NAME }}-${{ env.LATEST_TAG }}-${{ matrix.target }}.tar.gz" - mv "${{ env.BINARY_NAME }}" "${{ env.BINARY_NAME }}-${{ matrix.target }}" - tar -czvf "$ARCHIVE" "${{ env.BINARY_NAME }}-${{ matrix.target }}" - fi - - # Generate checksums - openssl dgst -r -sha256 -out "$ARCHIVE.sha256" "$ARCHIVE" - openssl dgst -r -sha512 -out "$ARCHIVE.sha512" "$ARCHIVE" - - echo "ASSET=$ARCHIVE" >> $GITHUB_ENV - - - name: Verify binary - shell: bash - run: | - cd target/${{ matrix.target }}/release - case "${{ matrix.target }}" in - *windows*) - 7z x -y "$ASSET" - ./${{ env.BINARY_NAME }}-${{ matrix.target }}.exe --version ;; - aarch64*) - echo "Can't test an ARM binary on a AMD64 runner" ;; - *) - tar -xvzf "$ASSET" - ./${{ env.BINARY_NAME }}-${{ matrix.target }} --version ;; - esac - - - name: Upload to release - uses: softprops/action-gh-release@v1 - with: - tag_name: ${{ env.LATEST_TAG }} - files: | - target/${{ matrix.target }}/release/${{ env.ASSET }} - target/${{ matrix.target }}/release/${{ env.ASSET }}.sha256 - target/${{ matrix.target }}/release/${{ env.ASSET }}.sha512 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 94acb21..d1ff793 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -68,3 +68,110 @@ jobs: env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} run: cargo publish + + name: Build and upload release binaries + + build-and-upload: + name: ${{ matrix.target }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + target: x86_64-unknown-linux-musl + use-cross: true + - os: ubuntu-latest + target: aarch64-unknown-linux-musl + use-cross: true + - os: macos-13 + target: x86_64-apple-darwin + use-cross: false + - os: macos-latest + target: aarch64-apple-darwin + use-cross: false + - os: windows-latest + target: x86_64-pc-windows-msvc + use-cross: false + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get latest tag + shell: bash + run: | + git fetch --tags + LATEST_TAG=$(git tag --sort=committerdate | tail -1) + echo "LATEST_TAG=$LATEST_TAG" >> $GITHUB_ENV + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.target }} + + - name: Handle Rust dependencies caching + uses: Swatinem/rust-cache@v2 + with: + key: v1-${{ matrix.target }} + + - name: Build binary + uses: clechasseur/rs-cargo@v2 + with: + command: build + args: --release --target ${{ matrix.target }} + use-cross: ${{ matrix.use-cross }} + + - name: Get binary name from Cargo.toml + shell: bash + run: | + BINARY_NAME=$(grep -m1 '^name' Cargo.toml | cut -d'"' -f2 | cut -d"'" -f2) + echo "BINARY_NAME=$BINARY_NAME" >> $GITHUB_ENV + + - name: Create release archive + shell: bash + run: | + cd target/${{ matrix.target }}/release + if [ "${{ runner.os }}" = "Windows" ]; then + ARCHIVE="${{ env.BINARY_NAME }}-${{ env.LATEST_TAG }}-${{ matrix.target }}.zip" + mv "${{ env.BINARY_NAME }}.exe" "${{ env.BINARY_NAME }}-${{ matrix.target }}.exe" + 7z a "$ARCHIVE" "${{ env.BINARY_NAME }}-${{ matrix.target }}.exe" + else + ARCHIVE="${{ env.BINARY_NAME }}-${{ env.LATEST_TAG }}-${{ matrix.target }}.tar.gz" + mv "${{ env.BINARY_NAME }}" "${{ env.BINARY_NAME }}-${{ matrix.target }}" + tar -czvf "$ARCHIVE" "${{ env.BINARY_NAME }}-${{ matrix.target }}" + fi + + # Generate checksums + openssl dgst -r -sha256 -out "$ARCHIVE.sha256" "$ARCHIVE" + openssl dgst -r -sha512 -out "$ARCHIVE.sha512" "$ARCHIVE" + + echo "ASSET=$ARCHIVE" >> $GITHUB_ENV + + - name: Verify binary + shell: bash + run: | + cd target/${{ matrix.target }}/release + case "${{ matrix.target }}" in + *windows*) + 7z x -y "$ASSET" + ./${{ env.BINARY_NAME }}-${{ matrix.target }}.exe --version ;; + aarch64*) + echo "Can't test an ARM binary on a AMD64 runner" ;; + *) + tar -xvzf "$ASSET" + ./${{ env.BINARY_NAME }}-${{ matrix.target }} --version ;; + esac + + - name: Upload to release + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ env.LATEST_TAG }} + files: | + target/${{ matrix.target }}/release/${{ env.ASSET }} + target/${{ matrix.target }}/release/${{ env.ASSET }}.sha256 + target/${{ matrix.target }}/release/${{ env.ASSET }}.sha512 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + From 3c8b6a66dc8f38f9293c518225f0f95b46a9fd0f Mon Sep 17 00:00:00 2001 From: thomasschafer Date: Tue, 19 Nov 2024 10:08:42 +0000 Subject: [PATCH 4/4] Refactor workflows --- .github/workflows/release.yml | 68 +++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d1ff793..2672ebe 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,20 +5,22 @@ on: branches: [ "main" ] paths: - 'Cargo.toml' - workflow_dispatch: # Allows manual triggering + workflow_dispatch: permissions: contents: write jobs: - release: - name: Release + prepare-release: + name: Prepare release runs-on: ubuntu-latest + outputs: + version: ${{ steps.get-package-info.outputs.version }} + should_release: ${{ steps.check-version.outputs.exists == 'false' }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} - name: Get package info from Cargo.toml id: get-package-info @@ -53,25 +55,12 @@ jobs: gh release create "v${version}" \ --title "v${version}" \ - --generate-notes - - - name: Install Rust toolchain - if: steps.check-version.outputs.exists == 'false' - uses: dtolnay/rust-toolchain@stable - - - name: Rust cache - if: steps.check-version.outputs.exists == 'false' - uses: Swatinem/rust-cache@v2 - - - name: Publish to crates.io - if: steps.check-version.outputs.exists == 'false' - env: - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - run: cargo publish - - name: Build and upload release binaries + --generate-notes \ + --draft # Make it draft until binaries are uploaded build-and-upload: + needs: prepare-release + if: needs.prepare-release.outputs.should_release == 'true' name: ${{ matrix.target }} runs-on: ${{ matrix.os }} strategy: @@ -99,13 +88,6 @@ jobs: with: fetch-depth: 0 - - name: Get latest tag - shell: bash - run: | - git fetch --tags - LATEST_TAG=$(git tag --sort=committerdate | tail -1) - echo "LATEST_TAG=$LATEST_TAG" >> $GITHUB_ENV - - name: Install Rust uses: dtolnay/rust-toolchain@stable with: @@ -133,12 +115,13 @@ jobs: shell: bash run: | cd target/${{ matrix.target }}/release + VERSION="${{ needs.prepare-release.outputs.version }}" if [ "${{ runner.os }}" = "Windows" ]; then - ARCHIVE="${{ env.BINARY_NAME }}-${{ env.LATEST_TAG }}-${{ matrix.target }}.zip" + ARCHIVE="${{ env.BINARY_NAME }}-v${VERSION}-${{ matrix.target }}.zip" mv "${{ env.BINARY_NAME }}.exe" "${{ env.BINARY_NAME }}-${{ matrix.target }}.exe" 7z a "$ARCHIVE" "${{ env.BINARY_NAME }}-${{ matrix.target }}.exe" else - ARCHIVE="${{ env.BINARY_NAME }}-${{ env.LATEST_TAG }}-${{ matrix.target }}.tar.gz" + ARCHIVE="${{ env.BINARY_NAME }}-v${VERSION}-${{ matrix.target }}.tar.gz" mv "${{ env.BINARY_NAME }}" "${{ env.BINARY_NAME }}-${{ matrix.target }}" tar -czvf "$ARCHIVE" "${{ env.BINARY_NAME }}-${{ matrix.target }}" fi @@ -167,7 +150,7 @@ jobs: - name: Upload to release uses: softprops/action-gh-release@v1 with: - tag_name: ${{ env.LATEST_TAG }} + tag_name: v${{ needs.prepare-release.outputs.version }} files: | target/${{ matrix.target }}/release/${{ env.ASSET }} target/${{ matrix.target }}/release/${{ env.ASSET }}.sha256 @@ -175,3 +158,26 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + publish: + needs: [prepare-release, build-and-upload] + if: needs.prepare-release.outputs.should_release == 'true' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Rust cache + uses: Swatinem/rust-cache@v2 + + - name: Publish to crates.io + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: cargo publish + + - name: Publish release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release edit "v${{ needs.prepare-release.outputs.version }}" --draft=false