diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 64c3f5a..e388f35 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,10 +1,10 @@ name: CI on: - push: - branches: - - master pull_request: + branches: + - '*' + push: branches: - master @@ -12,48 +12,70 @@ defaults: run: shell: bash +env: + RUSTFLAGS: --deny warnings + jobs: - all: - name: All + lint: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: Swatinem/rust-cache@v2 + + - name: Clippy + run: cargo clippy --all --all-targets + + - name: Format + run: cargo fmt --all -- --check + + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install ripgrep shellcheck + + - name: Check for Forbidden Words + run: ./bin/forbid + - name: Check /bin scripts + run: shellcheck bin/* + + msrv: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions-rust-lang/setup-rust-toolchain@v1 + + - uses: Swatinem/rust-cache@v2 + + - name: Check + run: cargo check + + test: strategy: matrix: os: - ubuntu-latest - macos-latest + - windows-latest runs-on: ${{matrix.os}} - env: - RUSTFLAGS: --deny warnings - steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - name: Install Rust Toolchain Components - uses: actions-rs/toolchain@v1 - with: - components: clippy, rustfmt - override: true - toolchain: stable + - name: Remove Broken WSL bash executable + if: ${{ matrix.os == 'windows-latest' }} + shell: cmd + run: | + takeown /F C:\Windows\System32\bash.exe + icacls C:\Windows\System32\bash.exe /grant administrators:F + del C:\Windows\System32\bash.exe - - uses: Swatinem/rust-cache@v1 + - uses: Swatinem/rust-cache@v2 - - name: Check Lockfile - run: | - cargo update --locked --package present - name: Test run: cargo test --all - - - name: Clippy - run: cargo clippy --all --all-targets - - - name: Format - run: cargo fmt --all -- --check - - - name: Check for Forbidden Words - if: ${{ matrix.os == 'ubuntu-latest' }} - run: | - sudo apt-get update - sudo apt-get install ripgrep - ./bin/forbid diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a30bdf1..f491e96 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -9,54 +9,87 @@ defaults: run: shell: bash +env: + RUSTFLAGS: --deny warnings + jobs: - all: - name: All + prerelease: + runs-on: ubuntu-latest + + outputs: + value: ${{ steps.prerelease.outputs.value }} + + steps: + - name: Prerelease Check + id: prerelease + run: | + if [[ ${{ github.ref_name }} =~ ^[0-9]+[.][0-9]+[.][0-9]+$ ]]; then + echo value=false >> "$GITHUB_OUTPUT" + else + echo value=true >> "$GITHUB_OUTPUT" + fi + package: strategy: - fail-fast: false matrix: target: + - aarch64-apple-darwin + - aarch64-unknown-linux-musl + - arm-unknown-linux-musleabihf + - armv7-unknown-linux-musleabihf - x86_64-apple-darwin - x86_64-pc-windows-msvc - - x86_64-unknown-linux-gnu + - aarch64-pc-windows-msvc + - x86_64-unknown-linux-musl include: + - target: aarch64-apple-darwin + os: macos-latest + target_rustflags: '' + - target: aarch64-unknown-linux-musl + os: ubuntu-latest + target_rustflags: '--codegen linker=aarch64-linux-gnu-gcc' + - target: arm-unknown-linux-musleabihf + os: ubuntu-latest + target_rustflags: '--codegen linker=arm-linux-gnueabihf-gcc' + - target: armv7-unknown-linux-musleabihf + os: ubuntu-latest + target_rustflags: '--codegen linker=arm-linux-gnueabihf-gcc' - target: x86_64-apple-darwin os: macos-latest target_rustflags: '' - target: x86_64-pc-windows-msvc os: windows-latest + - target: aarch64-pc-windows-msvc + os: windows-latest target_rustflags: '' - - target: x86_64-unknown-linux-gnu + - target: x86_64-unknown-linux-musl os: ubuntu-latest target_rustflags: '' runs-on: ${{matrix.os}} + needs: + - prerelease + steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - name: Install Rust Toolchain Components - uses: actions-rs/toolchain@v1 - with: - override: true - target: ${{ matrix.target }} - toolchain: stable + - name: Install AArch64 Toolchain + if: ${{ matrix.target == 'aarch64-unknown-linux-musl' }} + run: | + sudo apt-get update + sudo apt-get install gcc-aarch64-linux-gnu libc6-dev-i386 - - name: Install Linux Dependencies - if: ${{ matrix.os == 'ubuntu-latest' }} + - name: Install ARM Toolchain + if: ${{ matrix.target == 'arm-unknown-linux-musleabihf' || matrix.target == 'armv7-unknown-linux-musleabihf' }} run: | sudo apt-get update - sudo apt-get install musl-tools libssl-dev pkg-config + sudo apt-get install gcc-arm-linux-gnueabihf - - name: Release Type - id: release-type + - name: Install AArch64 Toolchain (Windows) + if: ${{ matrix.target == 'aarch64-pc-windows-msvc' }} run: | - if [[ ${{ github.ref }} =~ ^refs/tags/[0-9]+[.][0-9]+[.][0-9]+$ ]]; then - echo ::set-output name=value::release - else - echo ::set-output name=value::prerelease - fi + rustup target add aarch64-pc-windows-msvc - name: Package id: package @@ -69,11 +102,43 @@ jobs: shell: bash - name: Publish Archive - uses: softprops/action-gh-release@v0.1.5 + uses: softprops/action-gh-release@v2.2.1 if: ${{ startsWith(github.ref, 'refs/tags/') }} with: draft: false files: ${{ steps.package.outputs.archive }} - prerelease: ${{ steps.release-type.outputs.value == 'prerelease' }} + prerelease: ${{ needs.prerelease.outputs.value }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + checksum: + runs-on: ubuntu-latest + + needs: + - package + - prerelease + + steps: + - name: Download Release Archives + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: >- + gh release download + --repo casey/just + --pattern '*' + --dir release + ${{ github.ref_name }} + + - name: Create Checksums + run: | + cd release + shasum -a 256 ./* > ../SHA256SUMS + + - name: Publish Checksums + uses: softprops/action-gh-release@v2.2.1 + with: + draft: false + files: SHA256SUMS + prerelease: ${{ needs.prerelease.outputs.value }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/Cargo.lock b/Cargo.lock index c39e13d..c229f19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,12 +1,12 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -19,36 +19,37 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "once_cell", + "windows-sys 0.59.0", ] [[package]] @@ -65,9 +66,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "cfg-if" @@ -77,9 +78,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.19" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" +checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" dependencies = [ "clap_builder", "clap_derive", @@ -87,9 +88,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.19" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" +checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" dependencies = [ "anstream", "anstyle", @@ -99,39 +100,39 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.18" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "console" -version = "0.15.8" +version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" dependencies = [ "encode_unicode", - "lazy_static", "libc", - "unicode-width", - "windows-sys 0.52.0", + "once_cell", + "unicode-width 0.2.0", + "windows-sys 0.59.0", ] [[package]] @@ -158,18 +159,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -186,18 +187,18 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crossterm" @@ -238,9 +239,9 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "encode_unicode" -version = "0.3.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "executable-path" @@ -272,17 +273,11 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - [[package]] name = "libc" -version = "0.2.159" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "lock_api" @@ -296,9 +291,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.22" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "memchr" @@ -329,12 +324,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.1" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" -dependencies = [ - "portable-atomic", -] +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "parking_lot" @@ -359,12 +351,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "portable-atomic" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" - [[package]] name = "present" version = "0.2.3" @@ -396,9 +382,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] @@ -409,16 +395,16 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "memchr", "unicase", ] [[package]] name = "quote" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -462,11 +448,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", ] [[package]] @@ -535,15 +521,15 @@ dependencies = [ [[package]] name = "similar" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" [[package]] name = "smallvec" -version = "1.13.2" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" [[package]] name = "snafu" @@ -569,9 +555,9 @@ dependencies = [ [[package]] name = "str_indices" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9557cb6521e8d009c51a8666f09356f4b817ba9ba0981a305bd86aee47bd35c" +checksum = "d08889ec5408683408db66ad89e0e1f93dff55c73a4ccc71c427d5b277ee47e6" [[package]] name = "strsim" @@ -592,9 +578,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -622,43 +608,40 @@ dependencies = [ "crossterm", "minimad", "thiserror", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.100", ] [[package]] name = "unicase" -version = "2.7.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-segmentation" @@ -672,6 +655,12 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "unindent" version = "0.1.11" @@ -684,12 +673,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - [[package]] name = "walkdir" version = "2.5.0" @@ -728,7 +711,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] @@ -746,15 +729,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.59.0" diff --git a/Cargo.toml b/Cargo.toml index b7f4c1a..964f3b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,11 +12,11 @@ keywords = ["command-line", "productivity", "utility", "markdown", "bash"] resolver = "2" [dependencies] -clap = { version = "4.5.19", features = ["derive"] } -console = "0.15.8" +clap = { version = "4.5.35", features = ["derive"] } +console = "0.15.11" pulldown-cmark = { version = "0.9.6", default-features = false, features = ["simd"] } ropey = "1.6.1" -similar = "2.6.0" +similar = "2.7.0" snafu = { version = "0.7.5", default-features = false, features = ["std"] } termimad = "0.20.6" unicode-segmentation = "1.12.0" diff --git a/README.md b/README.md index de5140b..958b30b 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![CI](https://github.com/terror/present/actions/workflows/ci.yaml/badge.svg)](https://github.com/terror/present/actions/workflows/ci.yaml) [![crates.io](https://shields.io/crates/v/present.svg)](https://crates.io/crates/present) [![docs.rs](https://img.shields.io/docsrs/present)](https://docs.rs/present) +[![dependency status](https://deps.rs/repo/github/terror/present/status.svg)](https://deps.rs/repo/github/terror/present) **present** is a tool that lets you interpolate the standard output of arbitrary scripts that get interpreted by the shell into your markdown documents. @@ -11,11 +12,15 @@ Its aim is to provide a nice way to automatically update sections of your markdown documents that might be the standard output of a command, such as command-line utility help outputs or benchmarks. -### Demo +## Demo Below is a short demo showcasing the main functionality of the program. -[![asciicast](https://asciinema.org/a/6AO2ME0abbvn93dr4Dh4lenM0.svg)](https://asciinema.org/a/6AO2ME0abbvn93dr4Dh4lenM0) +[![asciicast](https://asciinema.org/a/499682.svg)](https://asciinema.org/a/499682) + +## Usage + +You can use `present` from the command-line interface (CLI) or library. ### CLI @@ -26,6 +31,9 @@ You can install the `present` command-line utility with the rust package manager $ cargo install present ``` +In addition, pre-built binaries can be found on the +[releases](https://github.com/terror/present/releases) page. + Below is the standard output of `present --help`, interpolated by the `present` binary itself! @@ -80,7 +88,7 @@ means that when running `cargo test`, the README gets automatically updated. You can read more about using the library on [docs.rs](https://docs.rs/present). -### Examples +## Examples Below are a few examples showcasing what kind of command result interpolations `present` is currently able to handle. @@ -133,7 +141,7 @@ Below are a few examples showcasing what kind of command result interpolations -### Prior Art +## Prior Art This project is loosely inspired by [`Cog`](https://github.com/nedbat/cog), the code generation tool. However, as mentioned above, this project's main target is diff --git a/bin/get_version b/bin/get_version index 3071e5b..a4ef6bb 100755 --- a/bin/get_version +++ b/bin/get_version @@ -1,4 +1,5 @@ #!/bin/bash -version=$(cat Cargo.toml | grep -E 'version\s*=\s*"[^"]+"' | sed '1!d') -echo $(echo "$version" | sed -E 's/[^"]+"([^"]+)"/present = "\1"/') +version=$(grep -E 'version\s*=\s*"[^"]+"' Cargo.toml | sed '1!d') + +echo "${version}" | sed -E 's/[^"]+"([^"]+)"/present = "\1"/' diff --git a/bin/package b/bin/package index 3cffd67..9bf9c85 100755 --- a/bin/package +++ b/bin/package @@ -2,41 +2,56 @@ set -euxo pipefail -VERSION=`basename $REF` -DIST=`pwd`/dist -BIN=present +VERSION=${REF#"refs/tags/"} +DIST=$(pwd)/dist -echo "Packaging $BIN $VERSION for $TARGET..." +echo "Packaging present $VERSION for $TARGET..." -echo "Building $BIN..." -RUSTFLAGS="$TARGET_RUSTFLAGS" cargo build --bin $BIN --target $TARGET --release -EXECUTABLE=target/$TARGET/release/$BIN +test -f Cargo.lock || cargo generate-lockfile + +echo "Installing rust toolchain for $TARGET..." +rustup target add "$TARGET" + +if [[ $TARGET == aarch64-unknown-linux-musl ]]; then + export CC=aarch64-linux-gnu-gcc +fi + +echo "Building present..." + +RUSTFLAGS="--deny warnings --codegen target-feature=+crt-static $TARGET_RUSTFLAGS" \ + cargo build --bin present --target "$TARGET" --release + +EXECUTABLE=target/$TARGET/release/present if [[ $OS == windows-latest ]]; then EXECUTABLE=$EXECUTABLE.exe fi echo "Copying release files..." -mkdir $DIST -cp \ - $EXECUTABLE \ + +mkdir dist + +cp -r \ + "$EXECUTABLE" \ Cargo.lock \ Cargo.toml \ LICENSE \ README.md \ - $DIST + "$DIST" + +cd "$DIST" -cd $DIST echo "Creating release archive..." + case $OS in ubuntu-latest | macos-latest) - ARCHIVE=$DIST/$BIN-$VERSION-$TARGET.tar.gz - tar czf $ARCHIVE * - echo "::set-output name=archive::$ARCHIVE" + ARCHIVE=present-$VERSION-$TARGET.tar.gz + tar czf "$ARCHIVE" ./* + echo "archive=$DIST/$ARCHIVE" >> "$GITHUB_OUTPUT" ;; windows-latest) - ARCHIVE=$DIST/$BIN-$VERSION-$TARGET.zip - 7z a $ARCHIVE * - echo "::set-output name=archive::`pwd -W`/$BIN-$VERSION-$TARGET.zip" + ARCHIVE=present-$VERSION-$TARGET.zip + 7z a "$ARCHIVE" ./* + echo "archive=$(pwd -W)/$ARCHIVE" >> "$GITHUB_OUTPUT" ;; esac diff --git a/bin/publish b/bin/publish deleted file mode 100755 index 115e97b..0000000 --- a/bin/publish +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -rm -rf tmp/release - -git clone https://github.com/terror/present.git tmp/release - -VERSION=$(sed -En 's/version[[:space:]]*=[[:space:]]*"([^"]+)"/\1/p' Cargo.toml | head -1) -echo "Releasing $VERSION..." -cd tmp/release - -if git rev-parse "$VERSION" >/dev/null 2>&1; then - echo "Tag $VERSION already exists. Skipping tag creation." -else - git tag -a "$VERSION" -m "Release $VERSION" - git push origin "$VERSION" -fi - -cargo publish - -cd ../.. -rm -rf tmp/release diff --git a/justfile b/justfile index fbd07bc..2304134 100644 --- a/justfile +++ b/justfile @@ -6,39 +6,64 @@ all: build test clippy fmt-check forbid readme alias f := fmt alias r := run +[group: 'misc'] build: cargo build +[group: 'check'] check: cargo check +[group: 'check'] clippy: cargo clippy --all-targets --all-features +[group: 'format'] fmt: cargo +nightly fmt +[group: 'check'] fmt-check: cargo +nightly fmt --all -- --check @echo formatting check done +[group: 'check'] forbid: ./bin/forbid +[group: 'release'] publish: - ./bin/publish + #!/usr/bin/env bash + set -euxo pipefail + rm -rf tmp/release + gh repo clone https://github.com/terror/just-lsp tmp/release + cd tmp/release + VERSION=`sed -En 's/version[[:space:]]*=[[:space:]]*"([^"]+)"/\1/p' Cargo.toml | head -1` + git tag -a $VERSION -m "Release $VERSION" + git push origin $VERSION + cargo publish + cd ../.. + rm -rf tmp/release +[group: 'dev'] run *args: cargo run -- {{args}} +[group: 'misc'] readme: cargo run -- README.md --in-place +[group: 'test'] test *args: cargo test --all-targets {{args}} -usage: - cargo run -- --help | pbcopy +[group: 'test'] +test-release-workflow: + -git tag -d test-release + -git push origin :test-release + git tag test-release + git push origin test-release +[group: 'dev'] watch +COMMAND='test': cargo watch --clear --exec "{{COMMAND}}" diff --git a/src/command.rs b/src/command.rs index 2b12892..30cb916 100644 --- a/src/command.rs +++ b/src/command.rs @@ -13,15 +13,15 @@ impl Command { Ok(match &*command { [prefix, program, arguments @ ..] if prefix == PREFIX => Some(Self { program: program.to_string(), - arguments: Lexer::lex(&arguments.join(" "))?, + arguments: Lexer::lex(&arguments.join(" ").replace("\r\n", "\n"))?, }), _ => None, }) } pub(crate) fn execute(&self) -> Result { - let output = process::Command::new(self.program.clone()) - .args(self.arguments.clone()) + let output = process::Command::new(&self.program) + .args(&self.arguments) .output(); if let Err(error) = output { diff --git a/src/lexer.rs b/src/lexer.rs index dd24cb8..5fe85f9 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -11,7 +11,7 @@ impl<'a> Lexer<'a> { } pub(crate) fn lex(src: &'a str) -> Result> { - Lexer::new(src).tokenize() + Lexer::new(&src.replace("\r\n", "\n")).tokenize() } fn tokenize(&self) -> Result> { @@ -32,7 +32,7 @@ impl<'a> Lexer<'a> { tokens.push(quoted_string); } - ' ' | '\t' => { + ' ' | '\t' | '\r' => { if !current_token.is_empty() { tokens.push(current_token); current_token = String::new(); @@ -53,7 +53,12 @@ impl<'a> Lexer<'a> { tokens.push(current_token); } - Ok(tokens) + let normalized_tokens = tokens + .into_iter() + .map(|token| token.replace("\r\n", "\n")) + .collect(); + + Ok(normalized_tokens) } fn parse_quoted_string( @@ -80,7 +85,7 @@ impl<'a> Lexer<'a> { escaped = false; } '\\' => escaped = true, - ch if ch == quote => return Ok(result), + ch if ch == quote => return Ok(result.replace("\r\n", "\n")), _ => result.push(ch), } } @@ -96,7 +101,7 @@ mod tests { use super::*; fn lex(src: &str) -> Result> { - Lexer::new(src).tokenize() + Lexer::lex(src) } #[test] @@ -164,4 +169,12 @@ mod tests { vec!["echo", "Hello\nWorld\t\"\\", "Single'Quote"] ); } + + #[test] + fn windows_line_endings() { + assert_eq!( + lex("echo \"hello\r\nworld\"").unwrap(), + vec!["echo", "hello\nworld"] + ); + } } diff --git a/src/parser.rs b/src/parser.rs index 79f996f..54c36b4 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -14,7 +14,11 @@ impl<'a> Parser<'a> { } pub(crate) fn parse(&self) -> Result> { - let ranges = MarkdownParser::new(self.src) + let normalized_src = self.src.replace("\r\n", "\n"); + + let parser = MarkdownParser::new(&normalized_src); + + let ranges = parser .into_offset_iter() .filter(|event| { matches!( diff --git a/tests/integration.rs b/tests/integration.rs index 8dbe7c2..fc8deb6 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -182,6 +182,7 @@ fn codeblock_end_with_superfluous_characters() -> Result { } #[test] +#[cfg(not(target_os = "windows"))] fn invalid_command() -> Result { Test::new()? .markdown( @@ -199,6 +200,25 @@ fn invalid_command() -> Result { .run() } +#[test] +#[cfg(target_os = "windows")] +fn invalid_command() -> Result { + Test::new()? + .markdown( + " + ```present foobarbaz + ```test + ", + ) + .expected_status(1) + .expected_stderr( + " + error: Program foobarbaz failed to execute with message: program not found + ", + ) + .run() +} + #[test] fn simple_with_exterior_content() -> Result { Test::new()? @@ -614,6 +634,7 @@ fn grapheme_handling() -> Result { } #[test] +#[cfg(not(target_os = "windows"))] fn large_output_handling() -> Result { Test::new()? .markdown(