@ifi/oh-pi-skills 0.2.8 → 0.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/package.json +1 -1
  2. package/skills/btw/SKILL.md +149 -0
  3. package/skills/flutter-serverpod-mvp/SKILL.md +199 -0
  4. package/skills/rust-workspace-bootstrap/SKILL.md +86 -0
  5. package/skills/rust-workspace-bootstrap/scaffold.js +222 -0
  6. package/skills/rust-workspace-bootstrap/template/.cargo/config.toml +7 -0
  7. package/skills/rust-workspace-bootstrap/template/.changeset/.gitkeep +0 -0
  8. package/skills/rust-workspace-bootstrap/template/.envrc +7 -0
  9. package/skills/rust-workspace-bootstrap/template/.github/actions/devenv/action.yml +42 -0
  10. package/skills/rust-workspace-bootstrap/template/.github/workflows/ci.yml +130 -0
  11. package/skills/rust-workspace-bootstrap/template/.github/workflows/coverage.yml +45 -0
  12. package/skills/rust-workspace-bootstrap/template/.github/workflows/docs-pages.yml +60 -0
  13. package/skills/rust-workspace-bootstrap/template/.github/workflows/release-preview.yml +52 -0
  14. package/skills/rust-workspace-bootstrap/template/.github/workflows/release.yml +87 -0
  15. package/skills/rust-workspace-bootstrap/template/.github/workflows/semver.yml +63 -0
  16. package/skills/rust-workspace-bootstrap/template/Cargo.toml +64 -0
  17. package/skills/rust-workspace-bootstrap/template/changelog.md +3 -0
  18. package/skills/rust-workspace-bootstrap/template/clippy.toml +1 -0
  19. package/skills/rust-workspace-bootstrap/template/crates/__CLI_CRATE__/Cargo.toml +20 -0
  20. package/skills/rust-workspace-bootstrap/template/crates/__CLI_CRATE__/src/main.rs +21 -0
  21. package/skills/rust-workspace-bootstrap/template/crates/__CORE_CRATE__/Cargo.toml +15 -0
  22. package/skills/rust-workspace-bootstrap/template/crates/__CORE_CRATE__/src/lib.rs +32 -0
  23. package/skills/rust-workspace-bootstrap/template/deny.toml +18 -0
  24. package/skills/rust-workspace-bootstrap/template/devenv.nix +214 -0
  25. package/skills/rust-workspace-bootstrap/template/devenv.yaml +10 -0
  26. package/skills/rust-workspace-bootstrap/template/docs/book.toml +6 -0
  27. package/skills/rust-workspace-bootstrap/template/docs/src/SUMMARY.md +3 -0
  28. package/skills/rust-workspace-bootstrap/template/docs/src/index.md +3 -0
  29. package/skills/rust-workspace-bootstrap/template/dprint.json +40 -0
  30. package/skills/rust-workspace-bootstrap/template/knope.toml +73 -0
  31. package/skills/rust-workspace-bootstrap/template/readme.md +77 -0
  32. package/skills/rust-workspace-bootstrap/template/rust-toolchain.toml +4 -0
  33. package/skills/rust-workspace-bootstrap/template/rustfmt.toml +21 -0
  34. package/skills/rust-workspace-bootstrap/template/scripts/release.sh +61 -0
@@ -0,0 +1,42 @@
1
+ name: devenv
2
+ description: Setup development environment with devenv
3
+ inputs:
4
+ github-token:
5
+ description: Provide a GitHub token
6
+ required: true
7
+ cache-version:
8
+ description: Cache version for dependency keys
9
+ required: false
10
+ default: "v1"
11
+
12
+ runs:
13
+ using: composite
14
+ steps:
15
+ - name: cache rust dependencies
16
+ uses: Swatinem/rust-cache@v2
17
+ with:
18
+ prefix-key: "${{ inputs.cache-version }}"
19
+
20
+ - name: cache cargo binaries
21
+ uses: actions/cache@v4
22
+ with:
23
+ path: ./.bin
24
+ key: ${{ runner.os }}-cargo-bin-${{ inputs.cache-version }}-${{ env.RUSTUP_TOOLCHAIN }}-${{ hashFiles('rust-toolchain.toml', 'Cargo.toml') }}
25
+ restore-keys: |
26
+ ${{ runner.os }}-cargo-bin-${{ inputs.cache-version }}-
27
+
28
+ - name: install nix
29
+ uses: cachix/install-nix-action@v31
30
+ with:
31
+ github_access_token: ${{ inputs.github-token }}
32
+
33
+ - name: setup nix environment
34
+ run: |
35
+ nix profile add --accept-flake-config nixpkgs#cachix
36
+ cachix use devenv
37
+ nix profile add nixpkgs#devenv
38
+ shell: bash
39
+
40
+ - name: install dependencies
41
+ run: install:cargo:bin
42
+ shell: devenv shell -- bash -e {0}
@@ -0,0 +1,130 @@
1
+ name: "ci"
2
+ permissions:
3
+ contents: read
4
+ on:
5
+ push:
6
+ branches:
7
+ - main
8
+ pull_request:
9
+ branches:
10
+ - main
11
+
12
+ concurrency:
13
+ group: ${{ github.workflow }}-${{ github.ref }}
14
+ cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
15
+
16
+ jobs:
17
+ commit-lint:
18
+ timeout-minutes: 15
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - name: checkout repository
22
+ uses: actions/checkout@v4
23
+ with:
24
+ fetch-depth: 0
25
+
26
+ - name: validate commit messages
27
+ run: |
28
+ PATTERN='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?!?: .+'
29
+
30
+ if [ "${{ github.event_name }}" = "pull_request" ]; then
31
+ BASE_SHA='${{ github.event.pull_request.base.sha }}'
32
+ HEAD_SHA='${{ github.event.pull_request.head.sha }}'
33
+ COMMITS=$(git log --format='%s' --no-merges "${BASE_SHA}..${HEAD_SHA}")
34
+ else
35
+ COMMITS=$(git log --format='%s' -1)
36
+ fi
37
+
38
+ FAILED=0
39
+ while IFS= read -r msg; do
40
+ [ -z "$msg" ] && continue
41
+ if ! echo "$msg" | grep -qE "$PATTERN"; then
42
+ echo "::error::Invalid commit message: '$msg'"
43
+ FAILED=1
44
+ fi
45
+ done <<< "$COMMITS"
46
+
47
+ if [ "$FAILED" -eq 1 ]; then
48
+ exit 1
49
+ fi
50
+
51
+ changeset:
52
+ timeout-minutes: 10
53
+ runs-on: ubuntu-latest
54
+ if: github.event_name == 'pull_request' || !startsWith(github.event.head_commit.message, 'chore: prepare releases')
55
+ steps:
56
+ - name: checkout repository
57
+ uses: actions/checkout@v4
58
+
59
+ - name: check for changeset
60
+ run: |
61
+ CHANGESETS=$(find .changeset -name '*.md' ! -name 'README.md' 2>/dev/null | wc -l | tr -d ' ')
62
+ if [ "$CHANGESETS" -eq 0 ]; then
63
+ echo "::error::No changeset found. Run 'knope document-change'."
64
+ exit 1
65
+ fi
66
+ echo "✅ Found $CHANGESETS changeset(s)"
67
+
68
+ lint:
69
+ timeout-minutes: 60
70
+ runs-on: ubuntu-latest
71
+ steps:
72
+ - name: checkout repository
73
+ uses: actions/checkout@v4
74
+
75
+ - name: setup
76
+ uses: ./.github/actions/devenv
77
+ with:
78
+ github-token: ${{ secrets.GITHUB_TOKEN }}
79
+
80
+ - name: lint
81
+ run: lint:all
82
+ shell: devenv shell -c -- bash -e {0}
83
+
84
+ test:
85
+ timeout-minutes: 60
86
+ runs-on: ubuntu-latest
87
+ steps:
88
+ - name: checkout repository
89
+ uses: actions/checkout@v4
90
+
91
+ - name: setup
92
+ uses: ./.github/actions/devenv
93
+ with:
94
+ github-token: ${{ secrets.GITHUB_TOKEN }}
95
+
96
+ - name: run tests
97
+ run: test:all
98
+ shell: devenv shell -c -- bash -e {0}
99
+
100
+ build:
101
+ timeout-minutes: 60
102
+ runs-on: ubuntu-latest
103
+ needs: [commit-lint, changeset, lint, test]
104
+ if: ${{ !failure() && !cancelled() }}
105
+ steps:
106
+ - name: checkout repository
107
+ uses: actions/checkout@v4
108
+
109
+ - name: setup
110
+ uses: ./.github/actions/devenv
111
+ with:
112
+ github-token: ${{ secrets.GITHUB_TOKEN }}
113
+
114
+ - name: build default features
115
+ run: build:default
116
+ shell: devenv shell -c -- bash -e {0}
117
+
118
+ - name: build all features
119
+ run: build:all
120
+ shell: devenv shell -c -- bash -e {0}
121
+
122
+ security:
123
+ timeout-minutes: 30
124
+ runs-on: ubuntu-latest
125
+ steps:
126
+ - name: checkout repository
127
+ uses: actions/checkout@v4
128
+
129
+ - name: run cargo-deny
130
+ uses: EmbarkStudios/cargo-deny-action@v2
@@ -0,0 +1,45 @@
1
+ name: "coverage"
2
+ permissions:
3
+ contents: read
4
+ on:
5
+ push:
6
+ branches:
7
+ - main
8
+ pull_request:
9
+ branches:
10
+ - main
11
+ workflow_dispatch:
12
+
13
+ concurrency:
14
+ group: ${{ github.workflow }}-${{ github.ref }}
15
+ cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
16
+
17
+ jobs:
18
+ coverage:
19
+ timeout-minutes: 90
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - name: checkout repository
23
+ uses: actions/checkout@v4
24
+
25
+ - name: setup
26
+ uses: ./.github/actions/devenv
27
+ with:
28
+ github-token: ${{ secrets.GITHUB_TOKEN }}
29
+
30
+ - name: generate coverage report
31
+ run: coverage:all
32
+ shell: devenv shell -c -- bash -e {0}
33
+
34
+ - name: upload lcov artifact
35
+ uses: actions/upload-artifact@v4
36
+ with:
37
+ name: coverage-lcov
38
+ path: target/coverage/lcov.info
39
+ if-no-files-found: error
40
+
41
+ - name: upload codecov report
42
+ uses: codecov/codecov-action@v5
43
+ with:
44
+ files: target/coverage/lcov.info
45
+ fail_ci_if_error: false
@@ -0,0 +1,60 @@
1
+ name: "docs-pages"
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ paths:
8
+ - "docs/**"
9
+ - "readme.md"
10
+ - "devenv.nix"
11
+ - ".github/workflows/docs-pages.yml"
12
+ release:
13
+ types: [published]
14
+ workflow_dispatch:
15
+
16
+ permissions:
17
+ contents: read
18
+ pages: write
19
+ id-token: write
20
+
21
+ concurrency:
22
+ group: "pages"
23
+ cancel-in-progress: true
24
+
25
+ jobs:
26
+ build:
27
+ if: github.repository == '__GITHUB_OWNER__/__GITHUB_REPO__'
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+ - name: checkout repository
31
+ uses: actions/checkout@v4
32
+
33
+ - name: setup
34
+ uses: ./.github/actions/devenv
35
+ with:
36
+ github-token: ${{ secrets.GITHUB_TOKEN }}
37
+
38
+ - name: configure github pages
39
+ uses: actions/configure-pages@v5
40
+
41
+ - name: build mdbook docs
42
+ run: docs:build
43
+ shell: devenv shell -c -- bash -e {0}
44
+
45
+ - name: upload pages artifact
46
+ uses: actions/upload-pages-artifact@v3
47
+ with:
48
+ path: docs/book
49
+
50
+ deploy:
51
+ if: github.repository == '__GITHUB_OWNER__/__GITHUB_REPO__'
52
+ needs: build
53
+ runs-on: ubuntu-latest
54
+ environment:
55
+ name: github-pages
56
+ url: ${{ steps.deployment.outputs.page_url }}
57
+ steps:
58
+ - name: deploy to github pages
59
+ id: deployment
60
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,52 @@
1
+ name: "release-preview"
2
+ permissions:
3
+ contents: read
4
+ on:
5
+ pull_request:
6
+ branches:
7
+ - main
8
+ workflow_dispatch:
9
+
10
+ concurrency:
11
+ group: ${{ github.workflow }}-${{ github.ref }}
12
+ cancel-in-progress: true
13
+
14
+ jobs:
15
+ preview:
16
+ timeout-minutes: 20
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - name: checkout repository
20
+ uses: actions/checkout@v4
21
+ with:
22
+ fetch-depth: 0
23
+
24
+ - name: setup
25
+ uses: ./.github/actions/devenv
26
+ with:
27
+ github-token: ${{ secrets.GITHUB_TOKEN }}
28
+
29
+ - name: preview release
30
+ run: |
31
+ echo "## Release Preview" >> "$GITHUB_STEP_SUMMARY"
32
+ echo "" >> "$GITHUB_STEP_SUMMARY"
33
+
34
+ if ls .changeset/*.md 1>/dev/null 2>&1; then
35
+ echo "### Changesets" >> "$GITHUB_STEP_SUMMARY"
36
+ echo '```markdown' >> "$GITHUB_STEP_SUMMARY"
37
+ for f in .changeset/*.md; do
38
+ echo "--- $f ---" >> "$GITHUB_STEP_SUMMARY"
39
+ cat "$f" >> "$GITHUB_STEP_SUMMARY"
40
+ echo "" >> "$GITHUB_STEP_SUMMARY"
41
+ done
42
+ echo '```' >> "$GITHUB_STEP_SUMMARY"
43
+ else
44
+ echo "No changesets found in .changeset/." >> "$GITHUB_STEP_SUMMARY"
45
+ fi
46
+
47
+ echo "" >> "$GITHUB_STEP_SUMMARY"
48
+ echo "### knope release --dry-run" >> "$GITHUB_STEP_SUMMARY"
49
+ echo '```' >> "$GITHUB_STEP_SUMMARY"
50
+ knope release --dry-run 2>&1 | tee -a "$GITHUB_STEP_SUMMARY" || true
51
+ echo '```' >> "$GITHUB_STEP_SUMMARY"
52
+ shell: devenv shell -- bash -e {0}
@@ -0,0 +1,87 @@
1
+ name: "release"
2
+
3
+ on:
4
+ release:
5
+ types: [created]
6
+ workflow_dispatch:
7
+ inputs:
8
+ tag:
9
+ description: "Release tag (e.g. v0.3.0). Must start with 'v'."
10
+ required: true
11
+ type: string
12
+
13
+ concurrency:
14
+ group: ${{ github.workflow }}-${{ inputs.tag || github.event.release.tag_name }}
15
+ cancel-in-progress: true
16
+
17
+ jobs:
18
+ upload_assets:
19
+ env:
20
+ CARGO_PROFILE_RELEASE_LTO: true
21
+ CARGO_PROFILE_RELEASE_CODEGEN_UNITS: 1
22
+ CARGO_PROFILE_RELEASE_STRIP: symbols
23
+ RELEASE_TAG: ${{ inputs.tag || github.event.release.tag_name }}
24
+ permissions:
25
+ contents: write
26
+ if: github.repository == '__GITHUB_OWNER__/__GITHUB_REPO__' && startsWith(inputs.tag || github.event.release.tag_name, 'v')
27
+ strategy:
28
+ fail-fast: false
29
+ matrix:
30
+ include:
31
+ - target: aarch64-unknown-linux-gnu
32
+ os: ubuntu-latest
33
+ - target: aarch64-unknown-linux-musl
34
+ os: ubuntu-latest
35
+ - target: aarch64-apple-darwin
36
+ os: macos-14
37
+ - target: x86_64-unknown-linux-gnu
38
+ os: ubuntu-latest
39
+ - target: x86_64-unknown-linux-musl
40
+ os: ubuntu-latest
41
+ - target: x86_64-apple-darwin
42
+ os: macos-latest
43
+ - target: x86_64-pc-windows-msvc
44
+ os: windows-latest
45
+ - target: aarch64-pc-windows-msvc
46
+ os: windows-latest
47
+ runs-on: ${{ matrix.os }}
48
+ timeout-minutes: 60
49
+ steps:
50
+ - name: checkout
51
+ uses: actions/checkout@v4
52
+ with:
53
+ ref: ${{ env.RELEASE_TAG }}
54
+
55
+ - name: install rust toolchain
56
+ uses: dtolnay/rust-toolchain@stable
57
+
58
+ - name: setup cross toolchain
59
+ uses: taiki-e/setup-cross-toolchain-action@v1
60
+ with:
61
+ target: ${{ matrix.target }}
62
+ if: startsWith(matrix.os, 'ubuntu') && !contains(matrix.target, '-musl')
63
+
64
+ - name: install cross
65
+ uses: taiki-e/install-action@v2
66
+ with:
67
+ tool: cross
68
+ if: contains(matrix.target, '-musl')
69
+
70
+ - name: set static crt linkage
71
+ shell: bash
72
+ run: echo "RUSTFLAGS=${RUSTFLAGS} -C target-feature=+crt-static" >> "${GITHUB_ENV}"
73
+ if: endsWith(matrix.target, 'windows-msvc')
74
+
75
+ - name: upload binaries
76
+ uses: taiki-e/upload-rust-binary-action@v1
77
+ with:
78
+ bin: __PROJECT_NAME__
79
+ manifest-path: crates/__CLI_CRATE__/Cargo.toml
80
+ package: __CLI_CRATE__
81
+ ref: refs/tags/${{ env.RELEASE_TAG }}
82
+ archive: $bin-$target-$tag
83
+ target: ${{ matrix.target }}
84
+ tar: all
85
+ zip: windows
86
+ token: ${{ secrets.GITHUB_TOKEN }}
87
+ checksum: sha256,sha512
@@ -0,0 +1,63 @@
1
+ name: "semver"
2
+ permissions:
3
+ contents: read
4
+ on:
5
+ pull_request:
6
+ branches:
7
+ - main
8
+
9
+ concurrency:
10
+ group: ${{ github.workflow }}-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ semver-checks:
15
+ timeout-minutes: 30
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - name: checkout repository
19
+ uses: actions/checkout@v4
20
+ with:
21
+ fetch-depth: 0
22
+
23
+ - name: setup
24
+ uses: ./.github/actions/devenv
25
+ with:
26
+ github-token: ${{ secrets.GITHUB_TOKEN }}
27
+
28
+ - name: run semver-checks
29
+ id: semver
30
+ continue-on-error: true
31
+ run: cargo semver-checks check-release --workspace
32
+ shell: devenv shell -c -- bash -e {0}
33
+
34
+ - name: evaluate semver results
35
+ if: steps.semver.outcome == 'failure'
36
+ env:
37
+ PR_TITLE: ${{ github.event.pull_request.title }}
38
+ run: |
39
+ echo "::warning::semver-checks detected breaking changes"
40
+
41
+ title_acknowledged=false
42
+ if echo "$PR_TITLE" | grep -qE '^[a-zA-Z]+(\(.+\))?!:'; then
43
+ title_acknowledged=true
44
+ echo "PR title contains '!' — breaking change acknowledged via title"
45
+ fi
46
+
47
+ changeset_acknowledged=false
48
+ if ls .changeset/*.md 1>/dev/null 2>&1; then
49
+ if grep -lE '^[a-zA-Z_]+: major$' .changeset/*.md 1>/dev/null 2>&1; then
50
+ changeset_acknowledged=true
51
+ echo "Found major changeset — breaking change acknowledged via changeset"
52
+ fi
53
+ fi
54
+
55
+ if [ "$title_acknowledged" = true ] || [ "$changeset_acknowledged" = true ]; then
56
+ echo "::notice::Breaking changes are acknowledged."
57
+ exit 0
58
+ fi
59
+
60
+ echo "::error::Breaking changes detected but not acknowledged."
61
+ echo "Add '!' to PR title or create a major changeset via 'knope document-change'."
62
+ exit 1
63
+ shell: bash
@@ -0,0 +1,64 @@
1
+ [workspace]
2
+ resolver = "2"
3
+ members = ["crates/__CORE_CRATE__", "crates/__CLI_CRATE__"]
4
+
5
+ [workspace.package]
6
+ version = "0.1.0"
7
+ authors = ["__GITHUB_OWNER__"]
8
+ edition = "2024"
9
+ license = "MIT"
10
+ readme = "readme.md"
11
+ repository = "https://github.com/__GITHUB_OWNER__/__GITHUB_REPO__"
12
+ homepage = "https://github.com/__GITHUB_OWNER__/__GITHUB_REPO__"
13
+ rust-version = "1.86.0"
14
+ description = "__DESCRIPTION__"
15
+
16
+ [workspace.dependencies]
17
+ clap = { default-features = false, version = "^4", features = ["derive", "std"] }
18
+ thiserror = { default-features = false, version = "^2" }
19
+ __CORE_CRATE__ = { path = "crates/__CORE_CRATE__", version = "0.1.0" }
20
+
21
+ [workspace.metadata.bin]
22
+ cargo-deny = { version = "0.19.0" }
23
+ cargo-llvm-cov = { version = "0.8.4" }
24
+ cargo-nextest = { version = "0.9.129" }
25
+ cargo-semver-checks = { version = "0.46.0" }
26
+ cargo-workspaces = { version = "0.4.2" }
27
+ knope = { version = "0.22.3", bins = ["knope"] }
28
+
29
+ [workspace.lints.rust]
30
+ rust_2021_compatibility = { level = "warn", priority = -1 }
31
+ rust_2024_compatibility = { level = "warn", priority = -1 }
32
+ unsafe_code = "deny"
33
+ unstable_features = "deny"
34
+ unused_extern_crates = "warn"
35
+ unused_import_braces = "warn"
36
+ unused_lifetimes = "warn"
37
+ unused_macro_rules = "warn"
38
+ unused_qualifications = "warn"
39
+ variant_size_differences = "warn"
40
+ edition_2024_expr_fragment_specifier = "allow"
41
+
42
+ [workspace.lints.clippy]
43
+ complexity = { level = "warn", priority = -1 }
44
+ correctness = { level = "deny", priority = -1 }
45
+ pedantic = { level = "warn", priority = -1 }
46
+ perf = { level = "warn", priority = -1 }
47
+ style = { level = "warn", priority = -1 }
48
+ suspicious = { level = "warn", priority = -1 }
49
+
50
+ blocks_in_conditions = "allow"
51
+ cargo_common_metadata = "allow"
52
+ cast_possible_truncation = "allow"
53
+ cast_possible_wrap = "allow"
54
+ cast_precision_loss = "allow"
55
+ cast_sign_loss = "allow"
56
+ items_after_statements = "allow"
57
+ missing_errors_doc = "allow"
58
+ missing_panics_doc = "allow"
59
+ module_name_repetitions = "allow"
60
+ must_use_candidate = "allow"
61
+ no_effect_underscore_binding = "allow"
62
+ too_many_lines = "allow"
63
+ wildcard_dependencies = "deny"
64
+ wildcard_imports = "allow"
@@ -0,0 +1,3 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
@@ -0,0 +1 @@
1
+ msrv = "1.86"
@@ -0,0 +1,20 @@
1
+ [package]
2
+ name = "__CLI_CRATE__"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+ readme.workspace = true
7
+ repository.workspace = true
8
+ rust-version.workspace = true
9
+ description = "CLI for __PROJECT_NAME__"
10
+
11
+ [[bin]]
12
+ name = "__PROJECT_NAME__"
13
+ path = "src/main.rs"
14
+
15
+ [lints]
16
+ workspace = true
17
+
18
+ [dependencies]
19
+ clap.workspace = true
20
+ __CORE_CRATE__.workspace = true
@@ -0,0 +1,21 @@
1
+ use clap::Parser;
2
+
3
+ #[derive(Debug, Parser)]
4
+ #[command(name = "__PROJECT_NAME__")]
5
+ #[command(about = "__DESCRIPTION__")]
6
+ struct Args {
7
+ /// Optional name to greet.
8
+ #[arg(short, long, default_value = "world")]
9
+ name: String,
10
+ }
11
+
12
+ fn main() {
13
+ let args = Args::parse();
14
+ match __CORE_CRATE__::greet(&args.name) {
15
+ Ok(message) => println!("{message}"),
16
+ Err(error) => {
17
+ eprintln!("error: {error}");
18
+ std::process::exit(1);
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,15 @@
1
+ [package]
2
+ name = "__CORE_CRATE__"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+ readme.workspace = true
7
+ repository.workspace = true
8
+ rust-version.workspace = true
9
+ description = "Core library for __PROJECT_NAME__"
10
+
11
+ [lints]
12
+ workspace = true
13
+
14
+ [dependencies]
15
+ thiserror.workspace = true
@@ -0,0 +1,32 @@
1
+ use thiserror::Error;
2
+
3
+ #[derive(Debug, Error)]
4
+ pub enum CoreError {
5
+ #[error("name cannot be empty")]
6
+ EmptyName,
7
+ }
8
+
9
+ pub fn greet(name: &str) -> Result<String, CoreError> {
10
+ if name.trim().is_empty() {
11
+ return Err(CoreError::EmptyName);
12
+ }
13
+
14
+ Ok(format!("Hello, {name}!"))
15
+ }
16
+
17
+ #[cfg(test)]
18
+ mod tests {
19
+ use super::greet;
20
+
21
+ #[test]
22
+ fn greets_with_name() {
23
+ let result = greet("world");
24
+ assert_eq!(result.as_deref(), Ok("Hello, world!"));
25
+ }
26
+
27
+ #[test]
28
+ fn rejects_empty_name() {
29
+ let result = greet(" ");
30
+ assert!(result.is_err());
31
+ }
32
+ }
@@ -0,0 +1,18 @@
1
+ [graph]
2
+ all-features = true
3
+
4
+ [advisories]
5
+ version = 2
6
+ yanked = "deny"
7
+
8
+ [licenses]
9
+ version = 2
10
+ allow = ["MIT", "Apache-2.0", "BSD-3-Clause", "ISC", "Unicode-3.0"]
11
+ confidence-threshold = 0.93
12
+
13
+ [bans]
14
+ multiple-versions = "warn"
15
+
16
+ [sources]
17
+ unknown-registry = "deny"
18
+ unknown-git = "warn"