crapkit 0.4.7__tar.gz → 0.4.8__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.
Files changed (72) hide show
  1. {crapkit-0.4.7 → crapkit-0.4.8}/PKG-INFO +121 -3
  2. crapkit-0.4.7/src/crapkit.egg-info/PKG-INFO → crapkit-0.4.8/README.md +1118 -1039
  3. {crapkit-0.4.7 → crapkit-0.4.8}/pyproject.toml +1 -1
  4. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/__init__.py +1 -1
  5. crapkit-0.4.7/README.md → crapkit-0.4.8/src/crapkit.egg-info/PKG-INFO +1157 -1000
  6. {crapkit-0.4.7 → crapkit-0.4.8}/LICENSE +0 -0
  7. {crapkit-0.4.7 → crapkit-0.4.8}/setup.cfg +0 -0
  8. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/__main__.py +0 -0
  9. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/_pygdefer.py +0 -0
  10. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/analyze.py +0 -0
  11. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/cache.py +0 -0
  12. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/churn.py +0 -0
  13. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/churn_cache.py +0 -0
  14. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/churn_log.py +0 -0
  15. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/cli/__init__.py +0 -0
  16. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/cli/_shared.py +0 -0
  17. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/cli/admin.py +0 -0
  18. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/cli/analyses.py +0 -0
  19. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/cli/claude_hook.py +0 -0
  20. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/cli/parser.py +0 -0
  21. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/cli/queue.py +0 -0
  22. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/cli/ratchet_cmds.py +0 -0
  23. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/cli/reports.py +0 -0
  24. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/cli/scoring.py +0 -0
  25. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/cli/verifying.py +0 -0
  26. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/config.py +0 -0
  27. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/coupling.py +0 -0
  28. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/coupling_cache.py +0 -0
  29. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/coverage_istanbul.py +0 -0
  30. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/coverage_py.py +0 -0
  31. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/covstream.py +0 -0
  32. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/diffparse.py +0 -0
  33. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/digest.py +0 -0
  34. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/discover.py +0 -0
  35. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/doctor.py +0 -0
  36. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/dup.py +0 -0
  37. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/errors.py +0 -0
  38. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/gitio.py +0 -0
  39. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/hook.py +0 -0
  40. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/junitparse.py +0 -0
  41. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/keys.py +0 -0
  42. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/lanes.py +0 -0
  43. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/lizardcognitive.py +0 -0
  44. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/lizardpowershell.py +0 -0
  45. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/lizardrust.py +0 -0
  46. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/lizardshell.py +0 -0
  47. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/mcp_server.py +0 -0
  48. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/merge.py +0 -0
  49. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/mutate.py +0 -0
  50. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/mutate_pool.py +0 -0
  51. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/override.py +0 -0
  52. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/packet.py +0 -0
  53. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/procs.py +0 -0
  54. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/ratchet.py +0 -0
  55. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/ratchet_report.py +0 -0
  56. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/report.py +0 -0
  57. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/sarif.py +0 -0
  58. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/sarifio.py +0 -0
  59. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/scaffold.py +0 -0
  60. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/score.py +0 -0
  61. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/snapshot.py +0 -0
  62. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/store.py +0 -0
  63. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/uncovered.py +0 -0
  64. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/universe.py +0 -0
  65. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/verify.py +0 -0
  66. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/watch.py +0 -0
  67. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit/worklist.py +0 -0
  68. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit.egg-info/SOURCES.txt +0 -0
  69. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit.egg-info/dependency_links.txt +0 -0
  70. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit.egg-info/entry_points.txt +0 -0
  71. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit.egg-info/requires.txt +0 -0
  72. {crapkit-0.4.7 → crapkit-0.4.8}/src/crapkit.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crapkit
3
- Version: 0.4.7
3
+ Version: 0.4.8
4
4
  Summary: Scores every function on complexity times uncovered risk, ranks the worst, and blocks commits that add more.
5
5
  Author: Jean-Francois Gagne
6
6
  License: MIT
@@ -44,6 +44,8 @@ Dynamic: license-file
44
44
  [![Python](https://img.shields.io/pypi/pyversions/crapkit)](https://pypi.org/project/crapkit/)
45
45
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
46
46
 
47
+ ![crapkit init, coverage and worklist --top 5 on a small Python repo, then a shell heredoc adding a function at ccn 7: the per-edit advisory reports it and exits 2, and the commit gate refuses the staged file with exit 6](https://raw.githubusercontent.com/JeanFrancoisGagne/crapkit/main/docs/demo.gif)
48
+
47
49
  crapkit scores every function in your repo on complexity times uncovered risk, ranks the
48
50
  worst ones by how often the file changes, and blocks commits that add more. It reads
49
51
  Python, TypeScript, TSX, JavaScript, Swift, Go, Rust, shell, PowerShell, C and C++,
@@ -145,7 +147,7 @@ changing crapkit.
145
147
 
146
148
  ```
147
149
  $ crapkit --version
148
- crapkit 0.4.7
150
+ crapkit 0.4.8
149
151
  ```
150
152
 
151
153
  `python -m crapkit` works identically to the console script and is what to use from a
@@ -373,7 +375,7 @@ crapkit ships a `.pre-commit-hooks.yaml` declaring `id: crapkit-gate`. In your
373
375
  repos:
374
376
  - repo: https://github.com/JeanFrancoisGagne/crapkit
375
377
  # crapkit's release step rewrites this line to the tag it just cut
376
- rev: v0.4.7
378
+ rev: v0.4.8
377
379
  hooks:
378
380
  - id: crapkit-gate
379
381
  ```
@@ -469,6 +471,122 @@ commit, and a row in the override log. All three land or nothing does, and an un
469
471
  `alert_command` refuses the override outright. See
470
472
  [docs/ratchet.md](docs/ratchet.md#overrides-and-the-audit-trail).
471
473
 
474
+ ## The GitHub Action
475
+
476
+ [action.yml](action.yml) at this repository's root is a composite action, so a reviewer
477
+ sees crapkit's numbers on the pull request without installing anything. Four lines add it
478
+ to a workflow, and every input has a default:
479
+
480
+ ```yaml
481
+ - uses: actions/checkout@v4
482
+ with:
483
+ fetch-depth: 0
484
+ - uses: JeanFrancoisGagne/crapkit@v0.4.8
485
+ ```
486
+
487
+ The whole job those four lines sit in:
488
+
489
+ ```yaml
490
+ on: pull_request
491
+ jobs:
492
+ crapkit:
493
+ runs-on: ubuntu-latest
494
+ permissions:
495
+ pull-requests: write # the comment, and nothing else
496
+ steps:
497
+ - uses: actions/checkout@v4
498
+ with:
499
+ fetch-depth: 0 # the diff, and verify's baseline commit
500
+ - run: pip install -e ".[dev]" # whatever your lanes need to run
501
+ - uses: JeanFrancoisGagne/crapkit@v0.4.8
502
+ with:
503
+ gate: "false"
504
+ ```
505
+
506
+ That `pip install` step is the one people leave out, and it is the same one Route 4 above
507
+ names: the action installs crapkit and nothing else, so your lanes still need whatever
508
+ your test command needs. Without it the lane writes no artifact and the comment says so.
509
+
510
+ `fetch-depth: 0` is the other one. `actions/checkout` clones a single commit; the action
511
+ reads the pull request's changed files out of git and `verify` reads the diff against the
512
+ baseline's commit. With a shallow clone the file list comes back empty and the comment
513
+ ranks the whole repository instead of the diff.
514
+
515
+ The action installs crapkit from `$GITHUB_ACTION_PATH`, which is its own checkout of the
516
+ ref you pinned in `uses:`. So `@v0.4.8` scores your tree with 0.4.8's crapkit rather than
517
+ with whatever released last, and pinning a tag is the whole version policy.
518
+
519
+ ### What the comment looks like
520
+
521
+ One comment per pull request, edited in place on every push. A hidden
522
+ `<!-- crapkit-action -->` line is how the next run finds it, so a fifteen-push branch
523
+ carries one comment and not fifteen. On a `push` event there is no pull request to carry
524
+ it, and the same text goes to the job log instead.
525
+
526
+ Rendered against this repository's own store, with a base commit fifteen back standing in
527
+ for a pull request:
528
+
529
+ ```markdown
530
+ <!-- crapkit-action -->
531
+
532
+ ## crapkit
533
+
534
+ 1333 functions in 61 files, 0 over target, CRAP load 3713.89, grade A+.
535
+
536
+ **verify passed.** Run 2 against baseline 1, 7 changed files.
537
+
538
+ ### Worklist: 39 changed files
539
+
540
+ | File | Function | ccn | risk | remedy |
541
+ |---|---|---:|---:|---|
542
+ | `src/crapkit/cli/admin.py:1026` | `_recorded_roots( recorded )` | 6 | 10.9908 | ok |
543
+ | `src/crapkit/lanes.py:646` | `build_retest_command( template : str , tests : set [ str ] )` | 6 | 10.8234 | ok |
544
+ | `src/crapkit/cli/admin.py:80` | `_next_step( scopes : dict , lanes : tuple )` | 5 | 9.159 | ok |
545
+ | `src/crapkit/cli/admin.py:239` | `_pytest_cov_probe( command : str )` | 5 | 9.159 | ok |
546
+ | `src/crapkit/cli/admin.py:505` | `_segment_problems( name : str , cwd : Path , tokens : list [ str ] )` | 5 | 9.159 | ok |
547
+ ```
548
+
549
+ The rows are the ranked worklist for the files the pull request changed, worst first,
550
+ `top` of them. `risk` is ccn times churn weight, the number `crapkit worklist` ranks on,
551
+ and `remedy` is the run's own verdict for that function: `decompose`, `add-tests` or `ok`.
552
+ A pull request that touches no ranked function gets the heading and no table.
553
+
554
+ The two file counts describe two different diffs, and both are wanted. `39 changed files`
555
+ is the pull request's own list, `git diff --name-only` against the base commit, and it is
556
+ what the table is filtered to. `7 changed files` on the verdict line is what `verify`
557
+ measured against its baseline run, which is the section below.
558
+
559
+ ### The inputs
560
+
561
+ | Input | Default | What it does |
562
+ |---|---|---|
563
+ | `gate` | `"false"` | `"true"` exits with `crapkit verify`'s own code, so a finding fails the check. Anything else exits 0 and the comment is the whole output |
564
+ | `top` | `"5"` | worklist rows rendered in the table |
565
+ | `python-version` | `"3.12"` | the interpreter `actions/setup-python` installs crapkit into |
566
+
567
+ `gate: "false"` is the default on purpose. A team adopts the action before it has decided
568
+ which findings should stop a merge, and a check that fails on day one gets turned off on
569
+ day two.
570
+
571
+ ### What the verdict line covers
572
+
573
+ The action runs `crapkit coverage --json` and then `crapkit verify --json
574
+ --reuse-artifacts`, so the baseline is the run written a step earlier, at this same
575
+ commit. On a clean checkout that diff is empty: the verdict line reports the tree's own
576
+ health and the exit code verify returned, not the pull request's delta. The gate that
577
+ judges the delta is the portable baseline in [Route 4](#route-4-ci): commit
578
+ `crapkit-baseline.tsv` on the default branch and run `crapkit verify --baseline-tsv
579
+ crapkit-baseline.tsv` in a step of your own beside this one.
580
+
581
+ `--reuse-artifacts` is what keeps the job to one test run. `coverage` ran the lanes
582
+ moments earlier on this same tree, and verify parses those artifacts rather than running
583
+ your whole suite a second time for the same numbers.
584
+
585
+ The comment is posted with `gh api` and the job's own `GITHUB_TOKEN`, which needs
586
+ `pull-requests: write`. Two things it cannot do: a pull request from a fork gets a
587
+ read-only token, so the POST is a 403 there, and a self-hosted runner without the `gh` CLI
588
+ on PATH fails that step. Both leave the rendered text in the job log.
589
+
472
590
  ## Subcommands
473
591
 
474
592
  Every subcommand takes `--repo PATH` (default `.`), and the flag goes **after** the