diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 994a5f3..95b7359 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,6 @@ env: CARGO_TERM_COLOR: always permissions: contents: read - jobs: ci: name: ${{ matrix.os }} @@ -22,41 +21,34 @@ jobs: - uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: actions-rs/toolchain@v1 if: ${{ matrix.os == 'windows-latest' }} with: components: clippy profile: minimal toolchain: stable - - uses: actions-rs/toolchain@v1 if: ${{ matrix.os == 'windows-latest' }} with: components: rustfmt profile: minimal toolchain: nightly - - uses: cachix/install-nix-action@v20 if: ${{ matrix.os != 'windows-latest' }} with: nix_path: nixpkgs=channel:nixos-unstable - - uses: cachix/cachix-action@v12 if: ${{ matrix.os != 'windows-latest' && env.CACHIX_AUTH_TOKEN != '' }} with: authToken: ${{ env.CACHIX_AUTH_TOKEN }} name: zoxide - - name: Setup cache uses: Swatinem/rust-cache@v2 with: key: ${{ matrix.os }} - - name: Install just uses: taiki-e/install-action@v2 with: tool: just - - name: Run lints + tests run: just lint test diff --git a/.github/workflows/no-response.yml b/.github/workflows/no-response.yml index b73a46c..a23313f 100644 --- a/.github/workflows/no-response.yml +++ b/.github/workflows/no-response.yml @@ -17,6 +17,6 @@ jobs: daysUntilClose: 30 responseRequiredLabel: waiting-for-response closeComment: > - This issue has been automatically closed due to inactivity. If you - feel this is still relevant, please comment here or create a fresh - issue. + This issue has been automatically closed due to inactivity. If you feel + this is still relevant, please comment here or create a fresh issue. + diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8e81859..efa9466 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,6 @@ env: CARGO_INCREMENTAL: 0 permissions: contents: write - jobs: release: name: ${{ matrix.target }} @@ -27,12 +26,10 @@ jobs: - os: ubuntu-latest target: aarch64-unknown-linux-musl deb: true - - os: macos-11 target: x86_64-apple-darwin - os: macos-11 target: aarch64-apple-darwin - - os: windows-latest target: x86_64-pc-windows-msvc - os: windows-latest @@ -42,14 +39,12 @@ jobs: uses: actions/checkout@v3 with: fetch-depth: 0 - - name: Get version id: get_version uses: SebRollen/toml-action@v1.0.2 with: file: Cargo.toml field: package.version - - name: Install Rust uses: actions-rs/toolchain@v1 with: @@ -57,51 +52,41 @@ jobs: profile: minimal override: true target: ${{ matrix.target }} - - name: Setup cache uses: Swatinem/rust-cache@v1.0.2 with: key: ${{ matrix.target }} - - name: Build binary uses: actions-rs/cargo@v1 with: command: build args: --release --locked --target=${{ matrix.target }} --color=always --verbose use-cross: ${{ runner.os == 'Linux' }} - - name: Install cargo-deb if: ${{ matrix.deb == true }} uses: actions-rs/install@v0.1 with: crate: cargo-deb - - name: Build deb if: ${{ matrix.deb == true }} uses: actions-rs/cargo@v1 with: command: deb args: --no-build --no-strip --output=. --target=${{ matrix.target }} - - name: Package (*nix) if: runner.os != 'Windows' - run: > - tar -cv - CHANGELOG.md LICENSE README.md - man/ - -C contrib/ completions/ -C ../ - -C target/${{ matrix.target }}/release/ zoxide - | gzip --best - > 'zoxide-${{ steps.get_version.outputs.value }}-${{ matrix.target }}.tar.gz' + run: | + tar -cv CHANGELOG.md LICENSE README.md man/ \ + -C contrib/ completions/ -C ../ \ + -C target/${{ matrix.target }}/release/ zoxide | + gzip --best > \ + zoxide-${{ steps.get_version.outputs.value }}-${{ matrix.target }}.tar.gz - name: Package (Windows) if: runner.os == 'Windows' - run: > - 7z a 'zoxide-${{ steps.get_version.outputs.value }}-${{ matrix.target }}.zip' - CHANGELOG.md LICENSE README.md - ./man/ - ./contrib/completions/ - ./target/${{ matrix.target }}/release/zoxide.exe - + run: | + 7z a zoxide-${{ steps.get_version.outputs.value }}-${{ matrix.target }}.zip ` + CHANGELOG.md LICENSE README.md ./man/ ./contrib/completions/ ` + ./target/${{ matrix.target }}/release/zoxide.exe - name: Upload artifact uses: actions/upload-artifact@v3 with: @@ -110,9 +95,9 @@ jobs: *.deb *.tar.gz *.zip - - name: Create release - if: ${{ github.ref == 'refs/heads/main' && startsWith(github.event.head_commit.message, 'chore(release)') }} + if: | + ${{ github.ref == 'refs/heads/main' && startsWith(github.event.head_commit.message, 'chore(release)') }} uses: softprops/action-gh-release@v1 with: draft: true diff --git a/install.sh b/install.sh index 2ba77bb..796c4d9 100755 --- a/install.sh +++ b/install.sh @@ -7,7 +7,7 @@ # extension. Note: Most shells limit `local` to 1 var per line, contra bash. main() { - if [ "$KSH_VERSION" = 'Version JM 93t+ 2010-03-05' ]; then + if [ "${KSH_VERSION-}" = 'Version JM 93t+ 2010-03-05' ]; then # The version of ksh93 that ships with many illumos systems does not # support the "local" extension. Print a message rather than fail in # subtle ways later on: @@ -18,57 +18,57 @@ main() { # Detect and print host target triple. ensure get_architecture - local _arch="$RETVAL" - assert_nz "$_arch" "arch" - echo "Detected architecture: $_arch" + local _arch="${RETVAL}" + assert_nz "${_arch}" "arch" + echo "Detected architecture: ${_arch}" # Create and enter a temporary directory. local _tmp_dir _tmp_dir="$(mktemp -d)" || err "mktemp: could not create temporary directory" - cd "$_tmp_dir" || err "cd: failed to enter directory: $_tmp_dir" + cd "${_tmp_dir}" || err "cd: failed to enter directory: ${_tmp_dir}" # Download and extract zoxide. - ensure download_zoxide "$_arch" - local _package="$RETVAL" - assert_nz "$_package" "package" - echo "Downloaded package: $_package" - case "$_package" in + ensure download_zoxide "${_arch}" + local _package="${RETVAL}" + assert_nz "${_package}" "package" + echo "Downloaded package: ${_package}" + case "${_package}" in *.tar.gz) need_cmd tar - ensure tar -xf "$_package" + ensure tar -xf "${_package}" ;; *.zip) need_cmd unzip - ensure unzip -oq "$_package" + ensure unzip -oq "${_package}" ;; *) - err "unsupported package format: $_package" + err "unsupported package format: ${_package}" ;; esac # Install binary. - local _bin_dir="$HOME/.local/bin" + local _bin_dir="${HOME}/.local/bin" local _bin_name - case "$_arch" in + case "${_arch}" in *windows*) _bin_name="zoxide.exe" ;; *) _bin_name="zoxide" ;; esac - ensure mkdir -p "$_bin_dir" - ensure cp "$_bin_name" "$_bin_dir" - ensure chmod +x "$_bin_dir/$_bin_name" - echo "Installed zoxide to $_bin_dir" + ensure mkdir -p "${_bin_dir}" + ensure cp "${_bin_name}" "${_bin_dir}" + ensure chmod +x "${_bin_dir}/${_bin_name}" + echo "Installed zoxide to ${_bin_dir}" # Install manpages. - local _man_dir="$HOME/.local/share/man" - ensure mkdir -p "$_man_dir/man1" - ensure cp "man/man1/"* "$_man_dir/man1/" - echo "Installed manpages to $_man_dir" + local _man_dir="${HOME}/.local/share/man" + ensure mkdir -p "${_man_dir}/man1" + ensure cp "man/man1/"* "${_man_dir}/man1/" + echo "Installed manpages to ${_man_dir}" # Print success message and check $PATH. echo "" echo "zoxide is installed!" - if ! echo ":$PATH:" | grep -Fq ":$_bin_dir:"; then - echo "NOTE: $_bin_dir is not on your \$PATH. zoxide will not work unless it is added to \$PATH." + if ! echo ":${PATH}:" | grep -Fq ":${_bin_dir}:"; then + echo "NOTE: ${_bin_dir} is not on your \$PATH. zoxide will not work unless it is added to \$PATH." fi } @@ -86,33 +86,35 @@ download_zoxide() { local _releases_url="https://api.github.com/repos/ajeetdsouza/zoxide/releases/latest" local _releases - case "$_dld" in - curl) _releases="$(curl -sL "$_releases_url")" || - err "curl: failed to download $_releases_url" ;; - wget) _releases="$(wget -qO- "$_releases_url")" || - err "wget: failed to download $_releases_url" ;; + case "${_dld}" in + curl) _releases="$(curl -sL "${_releases_url}")" || + err "curl: failed to download ${_releases_url}" ;; + wget) _releases="$(wget -qO- "${_releases_url}")" || + err "wget: failed to download ${_releases_url}" ;; + *) err "unsupported downloader: ${_dld}" ;; esac - (echo "$_releases" | grep -q 'API rate limit exceeded') && + (echo "${_releases}" | grep -q 'API rate limit exceeded') && err "you have exceeded GitHub's API rate limit. Please try again later, or use a different installation method: https://github.com/ajeetdsouza/zoxide/#installation" local _package_url - _package_url="$(echo "$_releases" | grep "browser_download_url" | cut -d '"' -f 4 | grep "$_arch")" || - err "zoxide has not yet been packaged for your architecture ($_arch), please file an issue: https://github.com/ajeetdsouza/zoxide/issues" + _package_url="$(echo "${_releases}" | grep "browser_download_url" | cut -d '"' -f 4 | grep "${_arch}")" || + err "zoxide has not yet been packaged for your architecture (${_arch}), please file an issue: https://github.com/ajeetdsouza/zoxide/issues" local _ext - case "$_package_url" in + case "${_package_url}" in *.tar.gz) _ext="tar.gz" ;; *.zip) _ext="zip" ;; - *) err "unsupported package format: $_package_url" ;; + *) err "unsupported package format: ${_package_url}" ;; esac - local _package="zoxide.$_ext" - case "$_dld" in - curl) _releases="$(curl -sLo "$_package" "$_package_url")" || err "curl: failed to download $_package_url" ;; - wget) _releases="$(wget -qO "$_package" "$_package_url")" || err "wget: failed to download $_package_url" ;; + local _package="zoxide.${_ext}" + case "${_dld}" in + curl) _releases="$(curl -sLo "${_package}" "${_package_url}")" || err "curl: failed to download ${_package_url}" ;; + wget) _releases="$(wget -qO "${_package}" "${_package_url}")" || err "wget: failed to download ${_package_url}" ;; + *) err "unsupported downloader: ${_dld}" ;; esac - RETVAL="$_package" + RETVAL="${_package}" } # The below functions have been extracted with minor modifications from the @@ -126,25 +128,25 @@ get_architecture() { _cputype="$(uname -m)" _clibtype="musl" - if [ "$_ostype" = Linux ]; then - if [ "$(uname -o)" = Android ]; then + if [ "${_ostype}" = Linux ]; then + if [ "$(uname -o || true)" = Android ]; then _ostype=Android fi fi - if [ "$_ostype" = Darwin ] && [ "$_cputype" = i386 ]; then + if [ "${_ostype}" = Darwin ] && [ "${_cputype}" = i386 ]; then # Darwin `uname -m` lies if sysctl hw.optional.x86_64 | grep -q ': 1'; then _cputype=x86_64 fi fi - if [ "$_ostype" = SunOS ]; then + if [ "${_ostype}" = SunOS ]; then # Both Solaris and illumos presently announce as "SunOS" in "uname -s" # so use "uname -o" to disambiguate. We use the full path to the # system uname in case the user has coreutils uname first in PATH, # which has historically sometimes printed the wrong value here. - if [ "$(/usr/bin/uname -o)" = illumos ]; then + if [ "$(/usr/bin/uname -o || true)" = illumos ]; then _ostype=illumos fi @@ -152,18 +154,18 @@ get_architecture() { # machine hardware name; e.g., "i86pc" on both 32- and 64-bit x86 # systems. Check for the native (widest) instruction set on the # running kernel: - if [ "$_cputype" = i86pc ]; then + if [ "${_cputype}" = i86pc ]; then _cputype="$(isainfo -n)" fi fi - case "$_ostype" in + case "${_ostype}" in Android) _ostype=linux-android ;; Linux) check_proc - _ostype=unknown-linux-$_clibtype + _ostype=unknown-linux-${_clibtype} _bitness=$(get_bitness) ;; FreeBSD) @@ -185,23 +187,23 @@ get_architecture() { _ostype=pc-windows-msvc ;; *) - err "unrecognized OS type: $_ostype" + err "unrecognized OS type: ${_ostype}" ;; esac - case "$_cputype" in + case "${_cputype}" in i386 | i486 | i686 | i786 | x86) _cputype=i686 ;; xscale | arm) _cputype=arm - if [ "$_ostype" = "linux-android" ]; then + if [ "${_ostype}" = "linux-android" ]; then _ostype=linux-androideabi fi ;; armv6l) _cputype=arm - if [ "$_ostype" = "linux-android" ]; then + if [ "${_ostype}" = "linux-android" ]; then _ostype=linux-androideabi else _ostype="${_ostype}eabihf" @@ -209,7 +211,7 @@ get_architecture() { ;; armv7l | armv8l) _cputype=armv7 - if [ "$_ostype" = "linux-android" ]; then + if [ "${_ostype}" = "linux-android" ]; then _ostype=linux-androideabi else _ostype="${_ostype}eabihf" @@ -225,7 +227,7 @@ get_architecture() { _cputype=$(get_endianness mips '' el) ;; mips64) - if [ "$_bitness" -eq 64 ]; then + if [ "${_bitness}" -eq 64 ]; then # only n64 ABI is supported for now _ostype="${_ostype}abi64" _cputype=$(get_endianness mips64 '' el) @@ -247,13 +249,13 @@ get_architecture() { _cputype=riscv64gc ;; *) - err "unknown CPU type: $_cputype" + err "unknown CPU type: ${_cputype}" ;; esac # Detect 64-bit linux with 32-bit userland if [ "${_ostype}" = unknown-linux-musl ] && [ "${_bitness}" -eq 32 ]; then - case $_cputype in + case ${_cputype} in x86_64) # 32-bit executable for amd64 = x32 if is_host_amd64_elf; then { @@ -271,7 +273,7 @@ get_architecture() { ;; aarch64) _cputype=armv7 - if [ "$_ostype" = "linux-android" ]; then + if [ "${_ostype}" = "linux-android" ]; then _ostype=linux-androideabi else _ostype="${_ostype}eabihf" @@ -280,13 +282,14 @@ get_architecture() { riscv64gc) err "riscv64 with 32-bit userland unsupported" ;; + *) ;; esac fi # Detect armv7 but without the CPU features Rust needs in that build, # and fall back to arm. # See https://github.com/rust-lang/rustup.rs/issues/587. - if [ "$_ostype" = "unknown-linux-musleabihf" ] && [ "$_cputype" = armv7 ]; then + if [ "${_ostype}" = "unknown-linux-musleabihf" ] && [ "${_cputype}" = armv7 ]; then if ensure grep '^Features' /proc/cpuinfo | grep -q -v neon; then # At least one processor does not have NEON. _cputype=arm @@ -294,7 +297,7 @@ get_architecture() { fi _arch="${_cputype}-${_ostype}" - RETVAL="$_arch" + RETVAL="${_arch}" } get_bitness() { @@ -307,9 +310,9 @@ get_bitness() { # escape sequences, so we use those. local _current_exe_head _current_exe_head=$(head -c 5 /proc/self/exe) - if [ "$_current_exe_head" = "$(printf '\177ELF\001')" ]; then + if [ "${_current_exe_head}" = "$(printf '\177ELF\001')" ]; then echo 32 - elif [ "$_current_exe_head" = "$(printf '\177ELF\002')" ]; then + elif [ "${_current_exe_head}" = "$(printf '\177ELF\002')" ]; then echo 64 else err "unknown platform bitness" @@ -327,9 +330,9 @@ get_endianness() { local _current_exe_endianness _current_exe_endianness="$(head -c 6 /proc/self/exe | tail -c 1)" - if [ "$_current_exe_endianness" = "$(printf '\001')" ]; then + if [ "${_current_exe_endianness}" = "$(printf '\001')" ]; then echo "${cputype}${suffix_el}" - elif [ "$_current_exe_endianness" = "$(printf '\002')" ]; then + elif [ "${_current_exe_endianness}" = "$(printf '\002')" ]; then echo "${cputype}${suffix_eb}" else err "unknown platform endianness" @@ -344,7 +347,7 @@ is_host_amd64_elf() { # but we're interested in it being 0x3E to indicate amd64, or not that. local _current_exe_machine _current_exe_machine=$(head -c 19 /proc/self/exe | tail -c 1) - [ "$_current_exe_machine" = "$(printf '\076')" ] + [ "${_current_exe_machine}" = "$(printf '\076')" ] } check_proc() { diff --git a/justfile b/justfile index be68681..18309da 100644 --- a/justfile +++ b/justfile @@ -5,6 +5,8 @@ default: fmt: nix-shell --cores 0 --pure --run 'cargo-fmt --all' nix-shell --cores 0 --pure --run 'nixfmt -- *.nix' + nix-shell --cores 0 --pure --run 'shfmt --indent=4 --language-dialect=posix --simplify --write *.sh' + nix-shell --cores 0 --pure --run 'yamlfmt -- .github/workflows/*.yml' [windows] fmt: @@ -14,11 +16,14 @@ fmt: lint: nix-shell --cores 0 --pure --run 'cargo-fmt --all --check' nix-shell --cores 0 --pure --run 'cargo clippy --all-features --all-targets -- -Dwarnings' - nix-shell --cores 0 --pure --run 'nixfmt --check -- ./*.nix' - nix-shell --cores 0 --pure --run 'markdownlint ./*.md' - nix-shell --cores 0 --pure --run 'mandoc -man -Wall -Tlint -- ./man/man1/*.1' nix-shell --cores 0 --pure --run 'cargo msrv verify' nix-shell --cores 0 --pure --run 'cargo udeps --all-features --all-targets --workspace' + nix-shell --cores 0 --pure --run 'mandoc -man -Wall -Tlint -- man/man1/*.1' + nix-shell --cores 0 --pure --run 'markdownlint *.md' + nix-shell --cores 0 --pure --run 'nixfmt --check -- *.nix' + # nix-shell --cores 0 --pure --run 'shellcheck --enable all *.sh' + nix-shell --cores 0 --pure --run 'shfmt --diff --indent=4 --language-dialect=posix --simplify *.sh' + nix-shell --cores 0 --pure --run 'yamlfmt -lint -- .github/workflows/*.yml' [windows] lint: diff --git a/shell.nix b/shell.nix index f825912..2059f4f 100644 --- a/shell.nix +++ b/shell.nix @@ -1,10 +1,10 @@ let - rust = import (builtins.fetchTarball - "https://github.com/oxalica/rust-overlay/archive/9096306d4a1c3adcc8d20f2c9dcaee3dee30d1ad.tar.gz"); pkgs = import (builtins.fetchTarball - "https://github.com/NixOS/nixpkgs/archive/5f902ae769594aaeaf326e8623a48482eeacfe89.tar.gz") { + "https://github.com/NixOS/nixpkgs/archive/22a6958f46fd8e14830d02856ff63b1d0e5cc3e4.tar.gz") { overlays = [ rust ]; }; + rust = import (builtins.fetchTarball + "https://github.com/oxalica/rust-overlay/archive/a61fcd9910229d097ffef92b5a2440065e3b64d5.tar.gz"); rust-nightly = pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.minimal); @@ -43,6 +43,7 @@ in pkgs.mkShell { pkgs.python3Packages.pylint pkgs.shellcheck pkgs.shfmt + pkgs.yamlfmt # Dependencies pkgs.cacert diff --git a/src/shell.rs b/src/shell.rs index 8321546..6237f76 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -85,7 +85,7 @@ mod tests { source.push('\n'); Command::new("shfmt") - .args(["-d", "-s", "-ln", "bash", "-i", "4", "-ci", "-"]) + .args(["--diff", "--indent=4", "--language-dialect=bash", "--simplify", "-"]) .write_stdin(source) .assert() .success() @@ -218,7 +218,7 @@ mod tests { source.push('\n'); Command::new("shfmt") - .args(["-d", "-s", "-ln", "posix", "-i", "4", "-ci", "-"]) + .args(["--diff", "--indent=4", "--language-dialect=posix", "--simplify", "-"]) .write_stdin(source) .assert() .success()