├── .github ├── dependabot.yaml └── workflows │ ├── audit.yaml │ ├── benchmark.yaml │ ├── ci.yaml │ ├── dependabot-auto-merge.yaml │ └── release.yaml ├── .gitignore ├── .goreleaser.yaml ├── .octocov.yml ├── CLAUDE.md ├── Cargo.lock ├── Cargo.toml ├── Cargo.toml.template ├── LICENSE ├── README.md ├── benches └── example.rs ├── cargo-generate.toml ├── pre-script.rhai ├── rust-toolchain.toml └── src ├── lib.rs └── main.rs /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: / 5 | schedule: 6 | interval: weekly 7 | time: "07:00" 8 | timezone: "Asia/Tokyo" 9 | - package-ecosystem: cargo 10 | directory: / 11 | schedule: 12 | interval: weekly 13 | time: "07:00" 14 | timezone: "Asia/Tokyo" 15 | -------------------------------------------------------------------------------- /.github/workflows/audit.yaml: -------------------------------------------------------------------------------- 1 | name: Security audit 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 */3 * *" 6 | 7 | push: 8 | branches: [main] 9 | paths: 10 | - "**/Cargo.toml" 11 | - "**/Cargo.lock" 12 | 13 | pull_request: 14 | paths: 15 | - "**/Cargo.toml" 16 | - "**/Cargo.lock" 17 | 18 | jobs: 19 | audit: 20 | name: Audit 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v5 24 | 25 | - name: Install cargo-audit 26 | uses: taiki-e/install-action@v2 27 | with: 28 | tool: cargo-audit 29 | 30 | - name: Run audit 31 | run: cargo audit 32 | -------------------------------------------------------------------------------- /.github/workflows/benchmark.yaml: -------------------------------------------------------------------------------- 1 | name: Benchmark 2 | on: 3 | push: 4 | branches: 5 | - main 6 | paths: 7 | - '**/*.rs' 8 | - '**/Cargo.toml' 9 | - '**/Cargo.lock' 10 | - '.github/workflows/benchmark.yaml' 11 | 12 | permissions: 13 | contents: write 14 | deployments: write 15 | 16 | jobs: 17 | benchmark: 18 | name: Run Rust benchmark example 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@v5 22 | - name: Toolchain setup 23 | run: rustup toolchain update nightly && rustup default nightly 24 | - name: Run benchmark 25 | run: cargo +nightly bench | tee output.txt 26 | 27 | - name: Store benchmark result 28 | uses: benchmark-action/github-action-benchmark@v1 29 | with: 30 | name: Rust Benchmark 31 | tool: 'cargo' 32 | output-file-path: output.txt 33 | github-token: ${{ secrets.GITHUB_TOKEN }} 34 | auto-push: true 35 | # Show alert with commit comment on detecting possible performance regression 36 | alert-threshold: '200%' 37 | comment-on-alert: true 38 | fail-on-alert: true 39 | benchmark-data-dir-path: docs 40 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: Rust CI 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | paths: 7 | - '**/*.rs' 8 | - '**/Cargo.toml' 9 | - '**/Cargo.lock' 10 | - '.github/workflows/ci.yaml' 11 | 12 | pull_request: 13 | paths: 14 | - '**/*.rs' 15 | - '**/Cargo.toml' 16 | - '**/Cargo.lock' 17 | - '.github/workflows/ci.yaml' 18 | 19 | env: 20 | CARGO_TERM_COLOR: always 21 | 22 | concurrency: 23 | group: ${{ github.workflow }}-${{ github.ref }} 24 | cancel-in-progress: true 25 | 26 | jobs: 27 | check: 28 | name: Check 29 | strategy: 30 | matrix: 31 | os: [ubuntu-latest, macos-latest, windows-latest] 32 | runs-on: ${{ matrix.os }} 33 | steps: 34 | - uses: actions/checkout@v5 35 | with: 36 | fetch-depth: 0 37 | 38 | - uses: actions-rust-lang/setup-rust-toolchain@v1 39 | with: 40 | components: rustfmt, clippy 41 | cache-shared-key: setup-rust-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/Cargo.lock') }} 42 | 43 | - name: Install reviewdog 44 | uses: reviewdog/action-setup@v1 45 | 46 | - name: Check format 47 | run: | 48 | cargo fmt --all -- --check 49 | 50 | - uses: giraffate/clippy-action@v1 51 | with: 52 | reporter: 'github-pr-review' 53 | github_token: ${{ secrets.GITHUB_TOKEN }} 54 | fail_on_error: true 55 | filter_mode: nofilter 56 | 57 | - name: Build 58 | run: cargo build 59 | 60 | test: 61 | name: Test 62 | strategy: 63 | matrix: 64 | os: [ubuntu-latest, macos-latest, windows-latest] 65 | runs-on: ${{ matrix.os }} 66 | permissions: 67 | contents: write 68 | pull-requests: write 69 | steps: 70 | - uses: actions/checkout@v5 71 | with: 72 | fetch-depth: 0 73 | 74 | - uses: actions-rust-lang/setup-rust-toolchain@v1 75 | with: 76 | components: llvm-tools-preview 77 | cache-shared-key: setup-rust-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/Cargo.lock') }} 78 | 79 | - name: Install tools 80 | uses: taiki-e/install-action@v2 81 | with: 82 | tool: cargo-llvm-cov, cargo-nextest 83 | 84 | - name: Run test 85 | if: runner.os != 'Linux' 86 | run: | 87 | cargo nextest run 88 | 89 | - name: Generate coverage 90 | if: runner.os == 'Linux' 91 | run: cargo llvm-cov nextest --lcov --output-path lcov.info 92 | 93 | - name: Upload coverage 94 | if: runner.os == 'Linux' 95 | uses: k1LoW/octocov-action@v1 96 | with: 97 | github-token: ${{ secrets.GITHUB_TOKEN }} 98 | -------------------------------------------------------------------------------- /.github/workflows/dependabot-auto-merge.yaml: -------------------------------------------------------------------------------- 1 | name: Dependabot Auto-merge 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened 7 | - synchronize 8 | - reopened 9 | 10 | permissions: 11 | contents: write 12 | pull-requests: write 13 | 14 | jobs: 15 | dependabot-automation: 16 | runs-on: ubuntu-latest 17 | if: ${{ github.actor == 'dependabot[bot]' }} 18 | timeout-minutes: 13 19 | steps: 20 | - name: Dependabot metadata 21 | id: metadata 22 | uses: dependabot/fetch-metadata@v2.4.0 23 | with: 24 | github-token: ${{ secrets.GITHUB_TOKEN }} 25 | - name: Approve & enable auto-merge for Dependabot PR 26 | if: | 27 | steps.metadata.outputs.update-type == 'version-update:semver-patch' || 28 | steps.metadata.outputs.update-type == 'version-update:semver-minor' 29 | run: | 30 | gh pr merge --auto -s "$PR_URL" 31 | env: 32 | PR_URL: ${{ github.event.pull_request.html_url }} 33 | PR_TITLE: ${{ github.event.pull_request.title }} 34 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 35 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | workflow_dispatch: 8 | 9 | permissions: 10 | # for goreleaser 11 | contents: write 12 | 13 | jobs: 14 | release: 15 | name: Release 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v5 20 | with: 21 | fetch-depth: 0 22 | 23 | - name: (setup) sccache 24 | uses: mozilla-actions/sccache-action@v0.0.9 25 | 26 | - name: (setup) environment variables for sccache 27 | shell: bash 28 | run: | 29 | echo "SCCACHE_GHA_ENABLED=true" >> "$GITHUB_ENV" 30 | echo "RUSTC_WRAPPER=sccache" >> "$GITHUB_ENV" 31 | 32 | - uses: actions-rust-lang/setup-rust-toolchain@v1 33 | with: 34 | cache-shared-key: setup-rust-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/Cargo.lock') }} 35 | target: "x86_64-unknown-linux-gnu, x86_64-apple-darwin, x86_64-pc-windows-gnu, aarch64-unknown-linux-gnu, aarch64-apple-darwin" 36 | rustflags: "" # override default rustflags 37 | 38 | - uses: actions-rust-lang/setup-rust-toolchain@v1 39 | with: 40 | cache: true 41 | 42 | - name: Install zig 43 | uses: mlugg/setup-zig@v2 44 | 45 | - name: Install cargo-zigbuild 46 | run: | 47 | cargo install cargo-zigbuild 48 | 49 | - name: Run GoReleaser 50 | uses: goreleaser/goreleaser-action@v6 51 | with: 52 | distribution: goreleaser 53 | version: '~> v2' 54 | args: release --clean 55 | env: 56 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 57 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /.goreleaser.yaml: -------------------------------------------------------------------------------- 1 | # This is an example .goreleaser.yml file with some sensible defaults. 2 | # Make sure to check the documentation at https://goreleaser.com 3 | 4 | # The lines below are called `modelines`. See `:help modeline` 5 | # Feel free to remove those if you don't want/need to use them. 6 | # yaml-language-server: $schema=https://goreleaser.com/static/schema.json 7 | # vim: set ts=2 sw=2 tw=0 fo=cnqoj 8 | 9 | version: 2 10 | 11 | before: 12 | hooks: 13 | # if you don't do these things before calling goreleaser, it might be a 14 | # good idea to do them here: 15 | - cargo fetch --locked 16 | 17 | builds: 18 | - builder: rust 19 | flags: 20 | - --release 21 | targets: 22 | - x86_64-unknown-linux-gnu 23 | - x86_64-apple-darwin 24 | - x86_64-pc-windows-gnu 25 | - aarch64-unknown-linux-gnu 26 | - aarch64-apple-darwin 27 | 28 | archives: 29 | - formats: tar.gz 30 | # this name template makes the OS and Arch compatible with the results of `uname`. 31 | name_template: >- 32 | {{ .ProjectName }}_ 33 | {{- title .Os }}_ 34 | {{- if eq .Arch "amd64" }}x86_64 35 | {{- else if eq .Arch "386" }}i386 36 | {{- else }}{{ .Arch }}{{ end }} 37 | # use zip for windows archives 38 | format_overrides: 39 | - goos: windows 40 | formats: zip 41 | 42 | changelog: 43 | sort: asc 44 | filters: 45 | exclude: 46 | - "^docs:" 47 | - "^test:" 48 | 49 | release: 50 | footer: >- 51 | 52 | --- 53 | 54 | Released by [GoReleaser](https://github.com/goreleaser/goreleaser). 55 | -------------------------------------------------------------------------------- /.octocov.yml: -------------------------------------------------------------------------------- 1 | # generated by octocov init 2 | coverage: 3 | if: true 4 | testExecutionTime: 5 | if: true 6 | diff: 7 | datastores: 8 | - artifact://${GITHUB_REPOSITORY} 9 | comment: 10 | if: is_pull_request 11 | summary: 12 | if: true 13 | report: 14 | if: is_default_branch 15 | datastores: 16 | - artifact://${GITHUB_REPOSITORY} 17 | -------------------------------------------------------------------------------- /CLAUDE.md: -------------------------------------------------------------------------------- 1 | # CLAUDE.md 2 | 3 | This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. 4 | 5 | ## Commands 6 | 7 | ### Build & Run 8 | ```bash 9 | # Build 10 | cargo build 11 | 12 | # Release build 13 | cargo build --release 14 | 15 | # Run (example) 16 | cargo run -- --name "World" 17 | ``` 18 | 19 | ### Testing 20 | ```bash 21 | # Run all tests 22 | cargo test 23 | 24 | # Fast test execution with cargo-nextest (recommended) 25 | cargo nextest run 26 | 27 | # Run a single test 28 | cargo test test_name 29 | 30 | # Generate coverage (requires cargo-llvm-cov) 31 | cargo llvm-cov nextest --lcov --output-path lcov.info 32 | ``` 33 | 34 | ### Quality Checks 35 | ```bash 36 | # Format check 37 | cargo fmt -- --check 38 | 39 | # Apply formatting 40 | cargo fmt 41 | 42 | # Static analysis with Clippy 43 | cargo clippy 44 | ``` 45 | 46 | ### Benchmarks 47 | ```bash 48 | # Requires nightly toolchain 49 | cargo +nightly bench 50 | ``` 51 | 52 | ## Architecture 53 | 54 | ### Project Structure 55 | - **cargo-generate template**: This repository is a template for generating new Rust CLI projects 56 | - **CLI parser**: Uses clap v4 derive macros for command-line argument processing 57 | - **Benchmarks**: Located in `benches/` directory, uses nightly compiler's test crate 58 | 59 | ### CI/CD Configuration 60 | - **ci.yaml**: Main CI workflow 61 | - Runs formatting, Clippy, build, and tests 62 | - Generates coverage on Linux with octocov reporting 63 | - Automatic PR feedback via reviewdog 64 | - **benchmark.yaml**: Auto-deploys benchmark results to GitHub Pages 65 | - **audit.yaml**: Security audit for dependencies 66 | - **release.yaml**: Automated release on tag push (cross-platform builds via GoReleaser) 67 | 68 | ### Key Settings 69 | - **Rust version**: Fixed to 1.87 in `rust-toolchain.toml` 70 | - **Edition**: Uses Rust 2024 edition 71 | - **Test tools**: cargo-nextest and cargo-llvm-cov recommended -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "anstream" 7 | version = "0.6.18" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" 10 | dependencies = [ 11 | "anstyle", 12 | "anstyle-parse", 13 | "anstyle-query", 14 | "anstyle-wincon", 15 | "colorchoice", 16 | "is_terminal_polyfill", 17 | "utf8parse", 18 | ] 19 | 20 | [[package]] 21 | name = "anstyle" 22 | version = "1.0.10" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" 25 | 26 | [[package]] 27 | name = "anstyle-parse" 28 | version = "0.2.6" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" 31 | dependencies = [ 32 | "utf8parse", 33 | ] 34 | 35 | [[package]] 36 | name = "anstyle-query" 37 | version = "1.1.2" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" 40 | dependencies = [ 41 | "windows-sys", 42 | ] 43 | 44 | [[package]] 45 | name = "anstyle-wincon" 46 | version = "3.0.7" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" 49 | dependencies = [ 50 | "anstyle", 51 | "once_cell", 52 | "windows-sys", 53 | ] 54 | 55 | [[package]] 56 | name = "clap" 57 | version = "4.5.48" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" 60 | dependencies = [ 61 | "clap_builder", 62 | "clap_derive", 63 | ] 64 | 65 | [[package]] 66 | name = "clap_builder" 67 | version = "4.5.48" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" 70 | dependencies = [ 71 | "anstream", 72 | "anstyle", 73 | "clap_lex", 74 | "strsim", 75 | ] 76 | 77 | [[package]] 78 | name = "clap_derive" 79 | version = "4.5.47" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" 82 | dependencies = [ 83 | "heck", 84 | "proc-macro2", 85 | "quote", 86 | "syn", 87 | ] 88 | 89 | [[package]] 90 | name = "clap_lex" 91 | version = "0.7.4" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" 94 | 95 | [[package]] 96 | name = "colorchoice" 97 | version = "1.0.3" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" 100 | 101 | [[package]] 102 | name = "heck" 103 | version = "0.5.0" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 106 | 107 | [[package]] 108 | name = "is_terminal_polyfill" 109 | version = "1.70.1" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 112 | 113 | [[package]] 114 | name = "once_cell" 115 | version = "1.20.3" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" 118 | 119 | [[package]] 120 | name = "proc-macro2" 121 | version = "1.0.93" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" 124 | dependencies = [ 125 | "unicode-ident", 126 | ] 127 | 128 | [[package]] 129 | name = "quote" 130 | version = "1.0.38" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" 133 | dependencies = [ 134 | "proc-macro2", 135 | ] 136 | 137 | [[package]] 138 | name = "rust-cli-template" 139 | version = "0.0.1" 140 | dependencies = [ 141 | "clap", 142 | ] 143 | 144 | [[package]] 145 | name = "strsim" 146 | version = "0.11.1" 147 | source = "registry+https://github.com/rust-lang/crates.io-index" 148 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 149 | 150 | [[package]] 151 | name = "syn" 152 | version = "2.0.98" 153 | source = "registry+https://github.com/rust-lang/crates.io-index" 154 | checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" 155 | dependencies = [ 156 | "proc-macro2", 157 | "quote", 158 | "unicode-ident", 159 | ] 160 | 161 | [[package]] 162 | name = "unicode-ident" 163 | version = "1.0.17" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" 166 | 167 | [[package]] 168 | name = "utf8parse" 169 | version = "0.2.2" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 172 | 173 | [[package]] 174 | name = "windows-sys" 175 | version = "0.59.0" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 178 | dependencies = [ 179 | "windows-targets", 180 | ] 181 | 182 | [[package]] 183 | name = "windows-targets" 184 | version = "0.52.6" 185 | source = "registry+https://github.com/rust-lang/crates.io-index" 186 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 187 | dependencies = [ 188 | "windows_aarch64_gnullvm", 189 | "windows_aarch64_msvc", 190 | "windows_i686_gnu", 191 | "windows_i686_gnullvm", 192 | "windows_i686_msvc", 193 | "windows_x86_64_gnu", 194 | "windows_x86_64_gnullvm", 195 | "windows_x86_64_msvc", 196 | ] 197 | 198 | [[package]] 199 | name = "windows_aarch64_gnullvm" 200 | version = "0.52.6" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 203 | 204 | [[package]] 205 | name = "windows_aarch64_msvc" 206 | version = "0.52.6" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 209 | 210 | [[package]] 211 | name = "windows_i686_gnu" 212 | version = "0.52.6" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 215 | 216 | [[package]] 217 | name = "windows_i686_gnullvm" 218 | version = "0.52.6" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 221 | 222 | [[package]] 223 | name = "windows_i686_msvc" 224 | version = "0.52.6" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 227 | 228 | [[package]] 229 | name = "windows_x86_64_gnu" 230 | version = "0.52.6" 231 | source = "registry+https://github.com/rust-lang/crates.io-index" 232 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 233 | 234 | [[package]] 235 | name = "windows_x86_64_gnullvm" 236 | version = "0.52.6" 237 | source = "registry+https://github.com/rust-lang/crates.io-index" 238 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 239 | 240 | [[package]] 241 | name = "windows_x86_64_msvc" 242 | version = "0.52.6" 243 | source = "registry+https://github.com/rust-lang/crates.io-index" 244 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 245 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-cli-template" 3 | version = "0.0.1" 4 | authors = ["skanehira"] 5 | edition = "2024" 6 | 7 | [dependencies] 8 | clap = { version = "4.5.48", features = ["derive"] } 9 | -------------------------------------------------------------------------------- /Cargo.toml.template: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "{{project-name}}" 3 | version = "0.0.1" 4 | authors = ["{{author}}"] 5 | edition = "2024" 6 | 7 | [dependencies] 8 | clap = { version = "4.5.42", features = ["derive"] } 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 skanehira 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![GitHub Repo stars](https://img.shields.io/github/stars/skanehira/rust-cli-template?style=social) 2 | ![GitHub](https://img.shields.io/github/license/skanehira/rust-cli-template) 3 | ![GitHub all releases](https://img.shields.io/github/downloads/skanehira/rust-cli-template/total) 4 | ![GitHub CI Status](https://img.shields.io/github/actions/workflow/status/skanehira/rust-cli-template/ci.yaml?branch=main) 5 | ![GitHub Release Status](https://img.shields.io/github/v/release/skanehira/rust-cli-template) 6 | 7 | # Rust CLI Template 8 | 9 | A ready-to-use template for creating Rust CLI applications. 10 | 11 | ## Overview 12 | 13 | This repository serves as a template for quickly bootstrapping Rust command-line 14 | interface (CLI) applications using `cargo-generate`. It provides a minimal yet 15 | comprehensive foundation with the following features: 16 | 17 | - CLI argument parsing using [clap](https://github.com/clap-rs/clap) with derive 18 | macros 19 | - GitHub Actions workflow for CI/CD 20 | - Code coverage reporting with [octocov](https://github.com/k1LoW/octocov) 21 | - Automatic benchmark result visualization and deployment with 22 | [github-action-benchmark](https://github.com/benchmark-action/github-action-benchmark) 23 | - Security audit checks for dependencies 24 | - Automated release workflow for publishing 25 | - Automated dependency updates with Dependabot 26 | 27 | ## Project Structure 28 | 29 | Generated projects will have the following structure: 30 | 31 | ``` 32 | . 33 | ├── .github/ # GitHub Actions workflows 34 | │ ├── workflows/ # CI/CD workflows for testing, benchmarking, and releasing 35 | │ │ ├── ci.yml # Main CI workflow (tests, linting, coverage) 36 | │ │ ├── audit.yml # Security audit workflow 37 | │ │ └── release.yml # Release automation workflow 38 | │ └── dependabot.yaml # Automated dependency update configuration file 39 | ├── benches/ # Benchmark code (requires nightly Rust) 40 | ├── src/ # Source code 41 | ├── .gitignore # Git ignore file 42 | ├── .octocov.yml # Code coverage configuration 43 | ├── goreleasser.yaml # GoReleaser configuration file for cross-platform builds and distribution 44 | ├── Cargo.toml # Project manifest 45 | ├── Cargo.lock # Dependency lock file 46 | └── rust-toolchain.toml # Rust toolchain configuration 47 | ``` 48 | 49 | ## Benchmark visualization 50 | 51 | The benchmark results are automatically deployed to GitHub Pages for easy 52 | visualization and performance tracking. You need to create a `gh-pages` branch 53 | in your repository before first push. 54 | 55 | image 56 | 57 | image 58 | 59 | ## Coverage 60 | 61 | This project uses [octocov](https://github.com/k1LoW/octocov) to measure code 62 | coverage. During CI execution, coverage reports are automatically generated and 63 | displayed as comments on PRs or commits. The coverage history is also tracked, 64 | allowing you to see changes over time. 65 | 66 | The coverage reports are deployed to GitHub Pages for easy visualization. 67 | Coverage information can also be displayed in the README as a badge. 68 | 69 | image 70 | 71 | The detailed configuration for octocov is managed in the `.octocov.yml` file. 72 | 73 | ## Usage 74 | 75 | ### Prerequisites 76 | 77 | - [cargo-generate](https://github.com/cargo-generate/cargo-generate) 78 | - [gh](https://github.com/cli/cli) 79 | 80 | ### Creating a New Project 81 | 82 | Create a new project using this template: 83 | 84 | ```bash 85 | cargo generate --git https://github.com/skanehira/rust-cli-template.git 86 | ``` 87 | 88 | Follow the prompts to customize your project. 89 | 90 | ### Running Tests 91 | 92 | ```bash 93 | cargo test 94 | ``` 95 | 96 | ### Running Benchmarks 97 | 98 | Benchmarks require the nightly Rust channel: 99 | 100 | ```bash 101 | cargo +nightly bench 102 | ``` 103 | 104 | ### Release Process 105 | 106 | This template includes an automated release workflow. Follow these steps to 107 | create a release: 108 | 109 | 1. Push a tag with your changes: 110 | ```bash 111 | git tag v0.1.0 # Replace with the appropriate version number 112 | git push origin v0.1.0 113 | ``` 114 | 115 | 2. When the tag is pushed, the GitHub Actions `release.yml` workflow will 116 | automatically execute. This workflow: 117 | - Builds cross-platform binaries (Linux, macOS, Windows) 118 | - Creates a GitHub Release 119 | - Uploads binaries and changelog 120 | 121 | The release configuration is managed in the `.github/workflows/release.yml` and 122 | `goreleasser.yaml` files. 123 | 124 | --- 125 | 126 | Feel free to customize this template to fit your specific needs! 127 | -------------------------------------------------------------------------------- /benches/example.rs: -------------------------------------------------------------------------------- 1 | #![feature(test)] 2 | extern crate test; 3 | 4 | #[cfg(test)] 5 | mod tests { 6 | use test::Bencher; 7 | 8 | fn fib(n: u32) -> u32 { 9 | if n == 0 { 10 | return 0; 11 | } 12 | if n == 1 { 13 | return 1; 14 | } 15 | let mut a = 0; 16 | let mut b = 1; 17 | for _ in 2..=n { 18 | let c = a + b; 19 | a = b; 20 | b = c; 21 | } 22 | b 23 | } 24 | 25 | #[bench] 26 | fn bench_fib(b: &mut Bencher) { 27 | b.iter(|| fib(30)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /cargo-generate.toml: -------------------------------------------------------------------------------- 1 | [template] 2 | name = "rust-cli-template" 3 | description = "A template for creating Rust CLI applications" 4 | version = "0.0.1" 5 | ignore = [ 6 | "target", 7 | "pre-script.rhai", 8 | "cargo-generate.toml", 9 | ".git", 10 | ".DS_Store", 11 | "init.sh", 12 | ] 13 | exclude = [ 14 | ".github/workflows/ci.yaml", 15 | ".github/workflows/release.yaml", 16 | ".github/workflows/dependabot-auto-merge.yaml", 17 | ".goreleaser.yaml", 18 | ] 19 | 20 | [placeholders] 21 | author = { prompt = "author name", type = "string" } 22 | 23 | [hooks] 24 | pre = ["pre-script.rhai"] 25 | -------------------------------------------------------------------------------- /pre-script.rhai: -------------------------------------------------------------------------------- 1 | file::rename("Cargo.toml.template", "Cargo.toml"); 2 | -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "1.90" 3 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod tests { 3 | #[test] 4 | fn it_works() { 5 | assert_eq!(2 + 2, 4); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser, Debug)] 4 | #[command(author, version, about, long_about = None)] 5 | struct Args { 6 | #[arg(short, long)] 7 | name: String, 8 | } 9 | 10 | fn main() { 11 | let args = Args::parse(); 12 | println!("Hello, {}!", args.name); 13 | } 14 | --------------------------------------------------------------------------------