pycoati 0.1.0__tar.gz
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.
- pycoati-0.1.0/.claude/settings.json +2 -0
- pycoati-0.1.0/.claude/skills/rust-review/SKILL.md +88 -0
- pycoati-0.1.0/.github/workflows/audit.yml +29 -0
- pycoati-0.1.0/.github/workflows/cargo-deny.yml +35 -0
- pycoati-0.1.0/.github/workflows/codeql.yml +42 -0
- pycoati-0.1.0/.github/workflows/release.yml +114 -0
- pycoati-0.1.0/.github/workflows/review.yml +66 -0
- pycoati-0.1.0/.gitignore +74 -0
- pycoati-0.1.0/CLAUDE.md +84 -0
- pycoati-0.1.0/Cargo.lock +1042 -0
- pycoati-0.1.0/Cargo.toml +78 -0
- pycoati-0.1.0/LICENSE +21 -0
- pycoati-0.1.0/Makefile +60 -0
- pycoati-0.1.0/PKG-INFO +59 -0
- pycoati-0.1.0/README.md +33 -0
- pycoati-0.1.0/WEIGHTS.md +164 -0
- pycoati-0.1.0/clippy.toml +7 -0
- pycoati-0.1.0/deny.toml +28 -0
- pycoati-0.1.0/docs/plans/pycoati-bootstrap.md +249 -0
- pycoati-0.1.0/docs/plans/zorilla-integration.md +60 -0
- pycoati-0.1.0/prek.toml +35 -0
- pycoati-0.1.0/pyproject.toml +41 -0
- pycoati-0.1.0/release.toml +9 -0
- pycoati-0.1.0/rust-toolchain.toml +3 -0
- pycoati-0.1.0/rustfmt.toml +3 -0
- pycoati-0.1.0/src/coverage.rs +323 -0
- pycoati-0.1.0/src/lib.rs +724 -0
- pycoati-0.1.0/src/main.rs +190 -0
- pycoati-0.1.0/src/mock_api.rs +184 -0
- pycoati-0.1.0/src/parser.rs +1631 -0
- pycoati-0.1.0/src/pretty.rs +678 -0
- pycoati-0.1.0/src/pyproject.rs +373 -0
- pycoati-0.1.0/src/pytest.rs +528 -0
- pycoati-0.1.0/src/python_detect.rs +154 -0
- pycoati-0.1.0/src/smells.rs +299 -0
- pycoati-0.1.0/src/suspicion.rs +377 -0
- pycoati-0.1.0/src/sut_calls.rs +430 -0
- pycoati-0.1.0/src/walker.rs +128 -0
- pycoati-0.1.0/tests/cli.rs +108 -0
- pycoati-0.1.0/tests/end_to_end.rs +480 -0
- pycoati-0.1.0/tests/fixtures/hyphen_project/my_pkg/__init__.py +11 -0
- pycoati-0.1.0/tests/fixtures/hyphen_project/pyproject.toml +2 -0
- pycoati-0.1.0/tests/fixtures/hyphen_project/tests/test_greet.py +6 -0
- pycoati-0.1.0/tests/fixtures/project/myproj/__init__.py +9 -0
- pycoati-0.1.0/tests/fixtures/project/myproj/repository.py +4 -0
- pycoati-0.1.0/tests/fixtures/project/pyproject.toml +2 -0
- pycoati-0.1.0/tests/fixtures/project/tests/helpers.py +13 -0
- pycoati-0.1.0/tests/fixtures/project/tests/other_test.py +6 -0
- pycoati-0.1.0/tests/fixtures/project/tests/test_mixed.py +10 -0
- pycoati-0.1.0/tests/fixtures/project/tests/test_mock_only.py +11 -0
- pycoati-0.1.0/tests/fixtures/project/tests/test_no_asserts.py +5 -0
- pycoati-0.1.0/tests/fixtures/project/tests/test_overmocked.py +11 -0
- pycoati-0.1.0/tests/fixtures/project/tests/test_real.py +16 -0
- pycoati-0.1.0/tests/fixtures/project/tests/test_uses_repo.py +14 -0
- pycoati-0.1.0/tests/fixtures/simple/empty.py +6 -0
- pycoati-0.1.0/tests/fixtures/simple/test_basic.py +18 -0
- pycoati-0.1.0/tests/fixtures/stubs_style/test_stubs.py +42 -0
- pycoati-0.1.0/tests/fixtures/unittest_style/test_unittest.py +38 -0
- pycoati-0.1.0/tests/inventory_shape.rs +141 -0
- pycoati-0.1.0/tests/parse_assertions.rs +169 -0
- pycoati-0.1.0/tests/pytest_integration.rs +640 -0
- pycoati-0.1.0/tests/scoring.rs +146 -0
- pycoati-0.1.0/tests/stubs.rs +162 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rust-review
|
|
3
|
+
context: fork
|
|
4
|
+
description: Deep Rust code quality review. Auto-invoke when finishing a task, before marking work complete, when the user asks to review code, or when preparing a PR. Covers error handling, async correctness, duplicated logic, test quality, performance patterns, idiomatic Rust, docs-code alignment, and API design beyond what clippy catches.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Deep Code Review for pycoati
|
|
8
|
+
|
|
9
|
+
Perform a thorough code quality review of the changes in this project. Go beyond what clippy and rustfmt catch. Focus on the areas below and report findings grouped by severity: Must Fix, Should Fix, Suggestion.
|
|
10
|
+
|
|
11
|
+
First, run `cargo fmt --all -- --check` and `cargo clippy --all-targets --all-features -- -D warnings` to confirm the automated checks pass. If they don't, fix those first before proceeding with the deep review.
|
|
12
|
+
|
|
13
|
+
## 1. Error Handling Quality
|
|
14
|
+
|
|
15
|
+
- `.unwrap()` outside tests is forbidden. Flag any instance.
|
|
16
|
+
- Check that `.context("message")` is used when propagating errors from external crates with `?` — bare `?` loses context about what operation failed.
|
|
17
|
+
- Flag `Result` return types where the function never actually returns `Err` (remove the wrapper — clippy catches this as `unnecessary_wraps` but double-check).
|
|
18
|
+
- Flag `.map_err(|_| ...)` that silently discards error information.
|
|
19
|
+
- Verify error types are specific enough — no `String` as error type, no `anyhow::Error` leaking into library-style modules.
|
|
20
|
+
- Check that `thiserror` error variants have `#[from]` or manual `From` impls for their sources.
|
|
21
|
+
|
|
22
|
+
## 2. Async / Tokio Correctness
|
|
23
|
+
|
|
24
|
+
- Flag any `MutexGuard` or `RwLockGuard` held across an `.await` point — this can deadlock or prevent `Send` futures.
|
|
25
|
+
- Flag blocking operations (std::fs, std::process::Command, heavy computation) running directly in async context without `spawn_blocking`.
|
|
26
|
+
- Check that spawned tasks (`tokio::spawn`) have their `JoinHandle` either awaited or explicitly dropped with a comment explaining why.
|
|
27
|
+
- Verify `tokio::select!` branches handle cancellation correctly (partially completed work).
|
|
28
|
+
- Check for unbounded channels or queues that could cause memory issues under load.
|
|
29
|
+
|
|
30
|
+
## 3. Duplicated Logic
|
|
31
|
+
|
|
32
|
+
- Search for functions or code blocks that do substantially the same thing with minor variations. Flag them and suggest extraction into a shared function, trait, or generic.
|
|
33
|
+
- Pay special attention to:
|
|
34
|
+
- Error handling boilerplate that could be a helper
|
|
35
|
+
- Serialization/deserialization patterns
|
|
36
|
+
- Similar match arms across different functions
|
|
37
|
+
- Suggest concrete refactoring: which function to extract, what parameters it should take.
|
|
38
|
+
|
|
39
|
+
## 4. Test Quality
|
|
40
|
+
|
|
41
|
+
- **Tests that don't assert**: Flag any test that just calls code without asserting on the result. Running without panicking is not a test.
|
|
42
|
+
- **Tests that assert too little**: `assert!(result.is_ok())` without checking the value inside is weak. Suggest asserting on the actual content.
|
|
43
|
+
- **Overly verbose tests**: Tests with excessive setup that obscure what's actually being tested. Suggest extracting test helpers or fixtures.
|
|
44
|
+
- **Missing edge cases**: For each public function, check if tests cover: empty input, error paths, boundary conditions.
|
|
45
|
+
- **Test naming**: Test names should describe the behavior being tested, not the implementation (`test_returns_error_on_missing_file` not `test_function_xyz`).
|
|
46
|
+
- **Integration vs unit**: Verify that unit tests (in `#[cfg(test)] mod tests`) test internal logic, while `tests/` tests exercise the public CLI interface.
|
|
47
|
+
- Suggest adding `proptest` for any function that transforms data (roundtrip properties).
|
|
48
|
+
|
|
49
|
+
## 5. Performance Patterns
|
|
50
|
+
|
|
51
|
+
- Flag unnecessary `.clone()` — suggest borrowing or restructuring ownership.
|
|
52
|
+
- Flag `.collect::<Vec<_>>()` immediately followed by `.iter()` — the intermediate collection is usually unnecessary.
|
|
53
|
+
- Prefer `&str` over `String`, `&[T]` over `Vec<T>`, `&Path` over `PathBuf` in function parameters when ownership isn't needed.
|
|
54
|
+
- Flag large structs being passed by value instead of reference.
|
|
55
|
+
- Check for `Arc::clone(&x)` vs `x.clone()` — the former is required by our lint config for clarity.
|
|
56
|
+
- In async code, flag futures that capture large amounts of data across await points.
|
|
57
|
+
|
|
58
|
+
## 6. Idiomatic Rust
|
|
59
|
+
|
|
60
|
+
- Prefer iterator chains over manual `for` loops with `push`.
|
|
61
|
+
- Use `if let` / `let else` instead of `match` with a single interesting arm and a wildcard.
|
|
62
|
+
- Suggest `impl From<X> for Y` instead of standalone conversion functions.
|
|
63
|
+
- Suggest `Display` implementations instead of `to_string()` methods.
|
|
64
|
+
- Flag `&String`, `&Vec<T>`, `&Box<T>` in function signatures — use `&str`, `&[T]`, `&T` instead.
|
|
65
|
+
- Check doc comments on all public types and functions.
|
|
66
|
+
|
|
67
|
+
## 7. Documentation ↔ Code Alignment
|
|
68
|
+
|
|
69
|
+
- **Check that `README.md` and any `docs/` content still match the current CLI and behavior.** Compare documented flags and subcommands against the `clap` definitions in `src/`.
|
|
70
|
+
- Flag any mismatch as Must Fix — stale docs are worse than no docs.
|
|
71
|
+
|
|
72
|
+
## 8. API and Module Design
|
|
73
|
+
|
|
74
|
+
- Is `main.rs` thin? It should just parse args and call into library code.
|
|
75
|
+
- Are module boundaries clean? Each module should have a clear responsibility.
|
|
76
|
+
- Check for any `pub` items that don't need to be public.
|
|
77
|
+
- Flag circular dependencies between modules.
|
|
78
|
+
|
|
79
|
+
## Output Format
|
|
80
|
+
|
|
81
|
+
Group all findings by severity, then by area. For each finding:
|
|
82
|
+
- State **what** the issue is and **where** (file:line or function name)
|
|
83
|
+
- Explain **why** it matters
|
|
84
|
+
- Suggest a **concrete fix** (not just "improve this")
|
|
85
|
+
|
|
86
|
+
End with a summary: X must-fix, Y should-fix, Z suggestions.
|
|
87
|
+
|
|
88
|
+
$ARGUMENTS
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: "Cargo Audit"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
paths:
|
|
6
|
+
- "Cargo.toml"
|
|
7
|
+
- "Cargo.lock"
|
|
8
|
+
pull_request:
|
|
9
|
+
paths:
|
|
10
|
+
- "Cargo.toml"
|
|
11
|
+
- "Cargo.lock"
|
|
12
|
+
schedule:
|
|
13
|
+
- cron: "0 0 * * *" # Daily at midnight UTC
|
|
14
|
+
workflow_dispatch:
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
issues: write
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
audit:
|
|
22
|
+
name: Security Audit
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
steps:
|
|
25
|
+
- name: Checkout repository
|
|
26
|
+
uses: actions/checkout@v6
|
|
27
|
+
|
|
28
|
+
- name: Run cargo-audit
|
|
29
|
+
uses: actions-rust-lang/audit@v1
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: "Cargo Deny"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["main"]
|
|
6
|
+
paths:
|
|
7
|
+
- "Cargo.lock"
|
|
8
|
+
- "Cargo.toml"
|
|
9
|
+
- "deny.toml"
|
|
10
|
+
pull_request:
|
|
11
|
+
paths:
|
|
12
|
+
- "Cargo.lock"
|
|
13
|
+
- "Cargo.toml"
|
|
14
|
+
- "deny.toml"
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
deny:
|
|
21
|
+
name: ${{ matrix.check }}
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
strategy:
|
|
24
|
+
fail-fast: false
|
|
25
|
+
matrix:
|
|
26
|
+
check: [bans, licenses, sources]
|
|
27
|
+
steps:
|
|
28
|
+
- name: Checkout repository
|
|
29
|
+
uses: actions/checkout@v6
|
|
30
|
+
|
|
31
|
+
- name: Run cargo-deny (${{ matrix.check }})
|
|
32
|
+
uses: EmbarkStudios/cargo-deny-action@v2
|
|
33
|
+
with:
|
|
34
|
+
command: check ${{ matrix.check }}
|
|
35
|
+
arguments: --all-features
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: "CodeQL"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["main"]
|
|
6
|
+
paths:
|
|
7
|
+
- "src/**"
|
|
8
|
+
- "Cargo.toml"
|
|
9
|
+
- "Cargo.lock"
|
|
10
|
+
pull_request:
|
|
11
|
+
branches: ["main"]
|
|
12
|
+
paths:
|
|
13
|
+
- "src/**"
|
|
14
|
+
- "Cargo.toml"
|
|
15
|
+
- "Cargo.lock"
|
|
16
|
+
schedule:
|
|
17
|
+
- cron: "0 6 * * 1" # Weekly on Monday at 06:00 UTC
|
|
18
|
+
|
|
19
|
+
permissions:
|
|
20
|
+
security-events: write
|
|
21
|
+
packages: read
|
|
22
|
+
actions: read
|
|
23
|
+
contents: read
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
analyze:
|
|
27
|
+
name: Analyze Rust
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
steps:
|
|
30
|
+
- name: Checkout repository
|
|
31
|
+
uses: actions/checkout@v6
|
|
32
|
+
|
|
33
|
+
- name: Initialize CodeQL
|
|
34
|
+
uses: github/codeql-action/init@v4
|
|
35
|
+
with:
|
|
36
|
+
languages: rust
|
|
37
|
+
build-mode: none
|
|
38
|
+
|
|
39
|
+
- name: Perform CodeQL Analysis
|
|
40
|
+
uses: github/codeql-action/analyze@v4
|
|
41
|
+
with:
|
|
42
|
+
category: "/language:rust"
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build-wheels:
|
|
14
|
+
name: Build wheels on ${{ matrix.os }}
|
|
15
|
+
runs-on: ${{ matrix.os }}
|
|
16
|
+
strategy:
|
|
17
|
+
matrix:
|
|
18
|
+
os: [ubuntu-latest, macos-14, windows-latest]
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v6
|
|
22
|
+
|
|
23
|
+
- name: Build wheels
|
|
24
|
+
uses: PyO3/maturin-action@v1
|
|
25
|
+
with:
|
|
26
|
+
args: --release --strip
|
|
27
|
+
manylinux: 2_28
|
|
28
|
+
|
|
29
|
+
- name: Upload wheels
|
|
30
|
+
uses: actions/upload-artifact@v7
|
|
31
|
+
with:
|
|
32
|
+
name: wheels-${{ matrix.os }}
|
|
33
|
+
path: target/wheels/*.whl
|
|
34
|
+
|
|
35
|
+
build-sdist:
|
|
36
|
+
name: Build source distribution
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v6
|
|
40
|
+
|
|
41
|
+
- name: Set up Rust
|
|
42
|
+
uses: dtolnay/rust-toolchain@stable
|
|
43
|
+
|
|
44
|
+
- name: Set up Python
|
|
45
|
+
uses: actions/setup-python@v6
|
|
46
|
+
with:
|
|
47
|
+
python-version: '3.11'
|
|
48
|
+
|
|
49
|
+
- name: Install maturin
|
|
50
|
+
run: pip install maturin
|
|
51
|
+
|
|
52
|
+
- name: Build sdist
|
|
53
|
+
run: maturin sdist
|
|
54
|
+
|
|
55
|
+
- name: Upload sdist
|
|
56
|
+
uses: actions/upload-artifact@v7
|
|
57
|
+
with:
|
|
58
|
+
name: sdist
|
|
59
|
+
path: target/wheels/*.tar.gz
|
|
60
|
+
|
|
61
|
+
create-release:
|
|
62
|
+
name: Create GitHub Release
|
|
63
|
+
needs: [build-wheels, build-sdist]
|
|
64
|
+
runs-on: ubuntu-latest
|
|
65
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
66
|
+
steps:
|
|
67
|
+
- uses: actions/checkout@v6
|
|
68
|
+
|
|
69
|
+
- name: Download all artifacts
|
|
70
|
+
uses: actions/download-artifact@v8
|
|
71
|
+
with:
|
|
72
|
+
path: dist
|
|
73
|
+
|
|
74
|
+
- name: Flatten artifacts
|
|
75
|
+
run: |
|
|
76
|
+
mkdir -p wheels
|
|
77
|
+
find dist -name '*.whl' -exec cp {} wheels/ \;
|
|
78
|
+
find dist -name '*.tar.gz' -exec cp {} wheels/ \;
|
|
79
|
+
|
|
80
|
+
- name: Create Release
|
|
81
|
+
uses: softprops/action-gh-release@v2
|
|
82
|
+
with:
|
|
83
|
+
files: wheels/*
|
|
84
|
+
generate_release_notes: true
|
|
85
|
+
draft: false
|
|
86
|
+
prerelease: false
|
|
87
|
+
|
|
88
|
+
publish-to-pypi:
|
|
89
|
+
name: Publish to PyPI
|
|
90
|
+
needs: [build-wheels, build-sdist, create-release]
|
|
91
|
+
runs-on: ubuntu-latest
|
|
92
|
+
if: startsWith(github.ref, 'refs/tags/') && github.event_name == 'push'
|
|
93
|
+
environment:
|
|
94
|
+
name: pypi
|
|
95
|
+
url: https://pypi.org/p/pycoati
|
|
96
|
+
permissions:
|
|
97
|
+
id-token: write
|
|
98
|
+
steps:
|
|
99
|
+
- name: Download all artifacts
|
|
100
|
+
uses: actions/download-artifact@v8
|
|
101
|
+
with:
|
|
102
|
+
path: dist
|
|
103
|
+
|
|
104
|
+
- name: Flatten artifacts
|
|
105
|
+
run: |
|
|
106
|
+
mkdir -p wheels
|
|
107
|
+
find dist -name '*.whl' -exec cp {} wheels/ \;
|
|
108
|
+
find dist -name '*.tar.gz' -exec cp {} wheels/ \;
|
|
109
|
+
|
|
110
|
+
- name: Publish to PyPI
|
|
111
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
112
|
+
with:
|
|
113
|
+
packages-dir: wheels/
|
|
114
|
+
skip-existing: true
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
name: Code Review
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths:
|
|
7
|
+
- "src/**"
|
|
8
|
+
- "tests/**"
|
|
9
|
+
- "Cargo.toml"
|
|
10
|
+
- "Cargo.lock"
|
|
11
|
+
- "rust-toolchain.toml"
|
|
12
|
+
- "clippy.toml"
|
|
13
|
+
- "rustfmt.toml"
|
|
14
|
+
pull_request:
|
|
15
|
+
paths:
|
|
16
|
+
- "src/**"
|
|
17
|
+
- "tests/**"
|
|
18
|
+
- "Cargo.toml"
|
|
19
|
+
- "Cargo.lock"
|
|
20
|
+
- "rust-toolchain.toml"
|
|
21
|
+
- "clippy.toml"
|
|
22
|
+
- "rustfmt.toml"
|
|
23
|
+
|
|
24
|
+
concurrency:
|
|
25
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
26
|
+
cancel-in-progress: true
|
|
27
|
+
|
|
28
|
+
env:
|
|
29
|
+
CARGO_TERM_COLOR: always
|
|
30
|
+
|
|
31
|
+
jobs:
|
|
32
|
+
fmt:
|
|
33
|
+
name: Formatting
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/checkout@v6
|
|
37
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
38
|
+
with:
|
|
39
|
+
components: rustfmt
|
|
40
|
+
- run: cargo fmt --all --check
|
|
41
|
+
|
|
42
|
+
clippy:
|
|
43
|
+
name: Clippy
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v6
|
|
47
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
48
|
+
with:
|
|
49
|
+
components: clippy
|
|
50
|
+
- uses: Swatinem/rust-cache@v2
|
|
51
|
+
- run: cargo clippy --all-targets --all-features -- -D warnings
|
|
52
|
+
|
|
53
|
+
test:
|
|
54
|
+
name: Tests
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
steps:
|
|
57
|
+
- uses: actions/checkout@v6
|
|
58
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
59
|
+
- uses: Swatinem/rust-cache@v2
|
|
60
|
+
- name: Set up Python
|
|
61
|
+
uses: actions/setup-python@v6
|
|
62
|
+
with:
|
|
63
|
+
python-version: "3.11"
|
|
64
|
+
- name: Install pytest
|
|
65
|
+
run: pip install pytest
|
|
66
|
+
- run: cargo test --all-features
|
pycoati-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Rust
|
|
2
|
+
/target/
|
|
3
|
+
**/*.rs.bk
|
|
4
|
+
|
|
5
|
+
# Python
|
|
6
|
+
__pycache__/
|
|
7
|
+
*.py[cod]
|
|
8
|
+
*$py.class
|
|
9
|
+
*.so
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
pip-wheel-metadata/
|
|
24
|
+
share/python-wheels/
|
|
25
|
+
*.egg-info/
|
|
26
|
+
.installed.cfg
|
|
27
|
+
*.egg
|
|
28
|
+
MANIFEST
|
|
29
|
+
|
|
30
|
+
# Virtual environments
|
|
31
|
+
.env
|
|
32
|
+
.venv
|
|
33
|
+
env/
|
|
34
|
+
venv/
|
|
35
|
+
ENV/
|
|
36
|
+
env.bak/
|
|
37
|
+
venv.bak/
|
|
38
|
+
|
|
39
|
+
# Claude Code
|
|
40
|
+
.claude/worktrees/
|
|
41
|
+
cf/
|
|
42
|
+
|
|
43
|
+
# IDE
|
|
44
|
+
.vscode/
|
|
45
|
+
.idea/
|
|
46
|
+
*.swp
|
|
47
|
+
*.swo
|
|
48
|
+
*~
|
|
49
|
+
|
|
50
|
+
# OS
|
|
51
|
+
.DS_Store
|
|
52
|
+
.DS_Store?
|
|
53
|
+
._*
|
|
54
|
+
.Spotlight-V100
|
|
55
|
+
.Trashes
|
|
56
|
+
ehthumbs.db
|
|
57
|
+
Thumbs.db
|
|
58
|
+
|
|
59
|
+
# Logs
|
|
60
|
+
*.log
|
|
61
|
+
|
|
62
|
+
# Temporary files
|
|
63
|
+
*.tmp
|
|
64
|
+
*.temp
|
|
65
|
+
.cache/
|
|
66
|
+
|
|
67
|
+
# maturin / PyO3
|
|
68
|
+
*.so
|
|
69
|
+
*.pyd
|
|
70
|
+
|
|
71
|
+
# Testing
|
|
72
|
+
.pytest_cache/
|
|
73
|
+
.coverage
|
|
74
|
+
htmlcov/
|
pycoati-0.1.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
pycoati audits Python test suites for mock smells and suspicious tests. Hybrid Rust/Python project: builds a Rust binary (`pycoati`) and packages it as a Python package via maturin for distribution through pip/uv.
|
|
8
|
+
|
|
9
|
+
## Common Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Pre-commit checks (always run before committing)
|
|
13
|
+
cargo fmt --check && cargo clippy --all-targets --all-features -- -D warnings && cargo test --all-features
|
|
14
|
+
|
|
15
|
+
# Run tests
|
|
16
|
+
cargo test
|
|
17
|
+
|
|
18
|
+
# Build and install locally for testing (puts `pycoati` on PATH at ~/.cargo/bin)
|
|
19
|
+
cargo install --path . --force
|
|
20
|
+
|
|
21
|
+
# Build a Python wheel (only needed when packaging for pip/uv distribution)
|
|
22
|
+
maturin develop
|
|
23
|
+
|
|
24
|
+
# Full review (fmt, clippy, tests, audit, deny)
|
|
25
|
+
make review
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Development Workflow
|
|
29
|
+
|
|
30
|
+
All features and bug fixes follow TDD (red-green-refactor). No implementation code without a failing test first. Bug fixes must include a regression test that fails without the fix.
|
|
31
|
+
|
|
32
|
+
## Test Changes Require Deliberation
|
|
33
|
+
|
|
34
|
+
When a test fails during implementation:
|
|
35
|
+
|
|
36
|
+
1. **Stop and diagnose.** Understand WHY it fails before changing anything.
|
|
37
|
+
2. **Default assumption: the test is right.** Fix the implementation first.
|
|
38
|
+
3. **If the test genuinely needs updating** (requirements changed, API evolved), explain what changed and why the old assertion is no longer correct before modifying it.
|
|
39
|
+
4. **Never weaken an assertion just to make it pass.**
|
|
40
|
+
5. **If uncertain, ask.**
|
|
41
|
+
|
|
42
|
+
## Branch Hygiene
|
|
43
|
+
|
|
44
|
+
**Always merge `main` into your feature branch before creating a PR.** Run:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
git fetch origin main && git merge origin/main
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Then re-run the full check suite to verify the merge didn't introduce breakage.
|
|
51
|
+
|
|
52
|
+
## When Stuck
|
|
53
|
+
|
|
54
|
+
If hitting a wall:
|
|
55
|
+
1. Do not silently work around it — state the problem explicitly.
|
|
56
|
+
2. Do not attempt more than 3 approaches without reporting what was tried and why each failed.
|
|
57
|
+
3. Do not modify unrelated code hoping it fixes the issue.
|
|
58
|
+
4. Revert to last known good state if changes made things worse.
|
|
59
|
+
5. When in doubt, ask.
|
|
60
|
+
|
|
61
|
+
## Review Before Completing Work
|
|
62
|
+
|
|
63
|
+
Before marking any task as complete:
|
|
64
|
+
|
|
65
|
+
1. **Automated checks** (run automatically via prek pre-commit hook on `git commit`):
|
|
66
|
+
- `cargo fmt --all -- --check`
|
|
67
|
+
- `cargo clippy --all-targets --all-features -- -D warnings`
|
|
68
|
+
- `cargo test --all-features --bins`
|
|
69
|
+
|
|
70
|
+
2. **Deep review** (REQUIRED for all significant changes):
|
|
71
|
+
- Run the `rust-review` skill (`/rust-review`) before marking work as complete
|
|
72
|
+
- Address all Must Fix items before completing
|
|
73
|
+
- Address Should Fix items unless there's a documented reason not to
|
|
74
|
+
|
|
75
|
+
3. **Full review** (run before pushing):
|
|
76
|
+
- `make review`
|
|
77
|
+
|
|
78
|
+
### Code Rules
|
|
79
|
+
- No `.unwrap()` outside tests — use `.context()` when propagating errors with `?`
|
|
80
|
+
- No `MutexGuard` held across `.await`
|
|
81
|
+
- Prefer `&str`/`&[T]`/`&Path` over owned types in function parameters when ownership isn't needed
|
|
82
|
+
- Tests must assert on values, not just "runs without panic"
|
|
83
|
+
- Flaky tests need root-cause analysis, not looser assertions
|
|
84
|
+
- No new dependencies without surfacing the choice
|