gwc-pybundle 1.1.1__tar.gz → 1.4.1__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.
Potentially problematic release.
This version of gwc-pybundle might be problematic. Click here for more details.
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/PKG-INFO +142 -9
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/README.md +140 -7
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/gwc_pybundle.egg-info/PKG-INFO +142 -9
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/gwc_pybundle.egg-info/SOURCES.txt +16 -1
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/cli.py +84 -11
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/context.py +86 -25
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/doctor.py +47 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/filters.py +10 -4
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/manifest.py +2 -3
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/packaging.py +9 -5
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/policy.py +25 -7
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/profiles.py +67 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/bandit.py +3 -5
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/compileall.py +2 -2
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/copy_pack.py +16 -4
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/coverage.py +19 -13
- gwc_pybundle-1.4.1/pybundle/steps/cprofile_step.py +155 -0
- gwc_pybundle-1.4.1/pybundle/steps/dependency_sizes.py +120 -0
- gwc_pybundle-1.4.1/pybundle/steps/duplication.py +94 -0
- gwc_pybundle-1.4.1/pybundle/steps/import_time.py +165 -0
- gwc_pybundle-1.4.1/pybundle/steps/interrogate.py +84 -0
- gwc_pybundle-1.4.1/pybundle/steps/license_scan.py +96 -0
- gwc_pybundle-1.4.1/pybundle/steps/line_profiler.py +108 -0
- gwc_pybundle-1.4.1/pybundle/steps/memory_profile.py +173 -0
- gwc_pybundle-1.4.1/pybundle/steps/mutation_testing.py +136 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/mypy.py +2 -2
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/pip_audit.py +3 -5
- gwc_pybundle-1.4.1/pybundle/steps/pipdeptree.py +61 -0
- gwc_pybundle-1.4.1/pybundle/steps/pylance.py +562 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/pytest.py +2 -2
- gwc_pybundle-1.4.1/pybundle/steps/radon.py +121 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/rg_scans.py +2 -2
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/ruff.py +3 -3
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/shell.py +11 -4
- gwc_pybundle-1.4.1/pybundle/steps/slow_tests.py +170 -0
- gwc_pybundle-1.4.1/pybundle/steps/test_flakiness.py +172 -0
- gwc_pybundle-1.4.1/pybundle/steps/unused_deps.py +112 -0
- gwc_pybundle-1.4.1/pybundle/steps/vulture.py +82 -0
- gwc_pybundle-1.4.1/pybundle/tools.py +63 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pyproject.toml +2 -2
- gwc_pybundle-1.1.1/pybundle/steps/pylance.py +0 -337
- gwc_pybundle-1.1.1/pybundle/tools.py +0 -7
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/LICENSE.md +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/gwc_pybundle.egg-info/dependency_links.txt +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/gwc_pybundle.egg-info/entry_points.txt +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/gwc_pybundle.egg-info/top_level.txt +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/__init__.py +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/__main__.py +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/roadmap_model.py +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/roadmap_scan.py +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/root_detect.py +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/runner.py +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/__init__.py +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/base.py +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/context_expand.py +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/error_refs.py +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/handoff_md.py +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/repro_md.py +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/roadmap.py +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/pybundle/steps/tree.py +0 -0
- {gwc_pybundle-1.1.1 → gwc_pybundle-1.4.1}/setup.cfg +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gwc-pybundle
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.1
|
|
4
4
|
Summary: Deterministic Python project context bundling for humans, automation, and AI
|
|
5
|
-
Author: Jessica Brown
|
|
5
|
+
Author-email: Jessica Brown <jessica@codenamejessica.com>
|
|
6
6
|
License: The MIT License (MIT)
|
|
7
7
|
=====================
|
|
8
8
|
|
|
@@ -47,7 +47,8 @@ Description-Content-Type: text/markdown
|
|
|
47
47
|
License-File: LICENSE.md
|
|
48
48
|
Dynamic: license-file
|
|
49
49
|
|
|
50
|
-
# 🧳 pybundle
|
|
50
|
+
# 🧳 pybundle 
|
|
51
|
+
|
|
51
52
|

|
|
52
53
|
|
|
53
54
|
[](https://pypi.org/project/gwc-pybundle/)
|
|
@@ -173,7 +174,7 @@ pytest
|
|
|
173
174
|
pytest-cov
|
|
174
175
|
bandit
|
|
175
176
|
pip-audit
|
|
176
|
-
gwc-pybundle==1.
|
|
177
|
+
gwc-pybundle==1.3.1
|
|
177
178
|
```
|
|
178
179
|
|
|
179
180
|
Then install:
|
|
@@ -210,7 +211,7 @@ See **Usage** for more details.
|
|
|
210
211
|
#### From GitHub
|
|
211
212
|
|
|
212
213
|
```bash
|
|
213
|
-
pip install "gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.
|
|
214
|
+
pip install "gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.3.1"
|
|
214
215
|
```
|
|
215
216
|
|
|
216
217
|
Pinning to a tag ensures reproducible behavior.
|
|
@@ -359,6 +360,10 @@ The `analysis` and `debug` profiles run comprehensive quality and security check
|
|
|
359
360
|
* **ruff** - Fast Python linter and formatter checks
|
|
360
361
|
* **mypy** - Static type checking for type hints
|
|
361
362
|
* **pylance** - Syntax error detection and import analysis
|
|
363
|
+
* **vulture** - Dead code detection (v1.3.0+)
|
|
364
|
+
* **radon** - Cyclomatic complexity and maintainability metrics (v1.3.0+)
|
|
365
|
+
* **interrogate** - Docstring coverage analysis (v1.3.0+)
|
|
366
|
+
* **pylint duplication** - Code duplication detection (v1.3.0+)
|
|
362
367
|
|
|
363
368
|
#### Testing & Coverage
|
|
364
369
|
* **pytest** - Test execution and results
|
|
@@ -368,13 +373,31 @@ The `analysis` and `debug` profiles run comprehensive quality and security check
|
|
|
368
373
|
* **bandit** - Security vulnerability scanning for Python code
|
|
369
374
|
* **pip-audit** - Dependency vulnerability checking against known CVEs
|
|
370
375
|
|
|
376
|
+
#### Dependency Analysis (v1.3.1+)
|
|
377
|
+
* **pipdeptree** - Full dependency tree with conflict detection
|
|
378
|
+
* **unused dependencies** - Identify installed but unused packages
|
|
379
|
+
* **pip-licenses** - License scanning and compatibility warnings
|
|
380
|
+
* **dependency sizes** - Disk usage analysis per package
|
|
381
|
+
|
|
382
|
+
#### Performance Profiling (v1.4.0+)
|
|
383
|
+
* **cProfile** - CPU profiling to identify bottlenecks
|
|
384
|
+
* **import time analysis** - Detect slow module imports
|
|
385
|
+
* **tracemalloc** - Memory profiling (optional, via `--profile-memory`)
|
|
386
|
+
* **line_profiler** - Line-by-line profiling (optional, requires `@profile` decorators and `--enable-line-profiler`)
|
|
387
|
+
|
|
388
|
+
#### Test Quality & Coverage Enhancement (v1.4.1+)
|
|
389
|
+
* **Test flakiness detection** - Run tests multiple times to identify non-deterministic failures
|
|
390
|
+
* **Branch coverage** - Enhanced coverage.py integration showing missing branches, not just lines
|
|
391
|
+
* **Slow test identification** - Automatically identify and rank tests exceeding time threshold
|
|
392
|
+
* **Mutation testing** - Optional mutmut integration to measure test suite effectiveness (VERY SLOW - disabled by default)
|
|
393
|
+
|
|
371
394
|
#### Pattern Scanning
|
|
372
395
|
* **ripgrep scans** - TODO detection, print statements, bare excepts
|
|
373
396
|
|
|
374
397
|
All tools gracefully skip if not installed. Install recommended tools:
|
|
375
398
|
|
|
376
399
|
```bash
|
|
377
|
-
pip install ruff mypy pytest pytest-cov bandit pip-audit
|
|
400
|
+
pip install ruff mypy pytest pytest-cov bandit pip-audit vulture radon interrogate pylint pipdeptree pip-licenses
|
|
378
401
|
```
|
|
379
402
|
|
|
380
403
|
For ripgrep (system dependency):
|
|
@@ -445,7 +468,6 @@ Commonly used options:
|
|
|
445
468
|
* `--outdir PATH` - output directory (default: `<project>/artifacts`)
|
|
446
469
|
* `--name NAME` - override archive name prefix
|
|
447
470
|
* `--strict` - fail with non-zero exit code if any step fails
|
|
448
|
-
* `--no-spinner` - disable spinner output (CI-friendly)
|
|
449
471
|
* `--redact / --no-redact` - control secret redaction
|
|
450
472
|
|
|
451
473
|
Tool execution can be selectively disabled:
|
|
@@ -533,7 +555,7 @@ When enabled, `pybundle` emits **exactly one JSON object to stdout**, with a **s
|
|
|
533
555
|
* AI orchestration
|
|
534
556
|
* reproducible analysis
|
|
535
557
|
|
|
536
|
-
No human text
|
|
558
|
+
No human text or formatting are mixed into the output.
|
|
537
559
|
|
|
538
560
|
### Example
|
|
539
561
|
|
|
@@ -653,7 +675,118 @@ By default, pybundle:
|
|
|
653
675
|
Use `--redact / --no-redact` to control behavior.
|
|
654
676
|
|
|
655
677
|
---
|
|
678
|
+
## 🔒 Security Considerations
|
|
679
|
+
|
|
680
|
+
**pybundle** is a development tool designed for trusted environments.
|
|
681
|
+
|
|
682
|
+
### Threat Model
|
|
683
|
+
|
|
684
|
+
* **Environment:** Development machines and CI/CD pipelines
|
|
685
|
+
* **Trust Boundary:** Assumes trusted development environment
|
|
686
|
+
* **Execution Context:** Runs external tools (git, ruff, mypy, pytest, etc.)
|
|
687
|
+
* **Input Sources:** Project files, git repository, installed packages
|
|
688
|
+
|
|
689
|
+
### Security Posture
|
|
690
|
+
|
|
691
|
+
**Tool Path Resolution:**
|
|
692
|
+
- All external tools use full resolved paths (via `shutil.which()`)
|
|
693
|
+
- Tools are resolved at detection time and stored in `Tooling` dataclass
|
|
694
|
+
- No dynamic PATH manipulation or shell interpretation
|
|
695
|
+
- Eliminates partial path execution vulnerabilities (B607)
|
|
696
|
+
- **Optional strict-paths mode** for enhanced security (v1.2.0+)
|
|
697
|
+
- **Code quality tools** for dead code, complexity, docstrings, and duplication (v1.3.0+)
|
|
698
|
+
- **Dependency intelligence** for conflict detection, license scanning, and size analysis (v1.3.1+)
|
|
699
|
+
|
|
700
|
+
**Subprocess Execution:**
|
|
701
|
+
- All subprocess calls use `shell=False` (default, secure)
|
|
702
|
+
- Arguments passed as lists, never as strings
|
|
703
|
+
- No user-controlled command construction
|
|
704
|
+
- Commands are hardcoded in source code
|
|
705
|
+
|
|
706
|
+
**Data Handling:**
|
|
707
|
+
- Optional secret redaction for sensitive strings in logs
|
|
708
|
+
- Environment variables and paths logged for reproducibility
|
|
709
|
+
- All file operations respect `.gitignore` rules
|
|
710
|
+
|
|
711
|
+
### Strict-Paths Mode (v1.2.0+)
|
|
712
|
+
|
|
713
|
+
For high-security environments, enable `--strict-paths` to enforce that all tools must be in trusted system directories:
|
|
714
|
+
|
|
715
|
+
```bash
|
|
716
|
+
pybundle run analysis --strict-paths
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
**Trusted directories** (configurable via `PYBUNDLE_TRUSTED_PATHS`):
|
|
720
|
+
- `/usr/bin/`, `/usr/local/bin/`, `/bin/`
|
|
721
|
+
- `/opt/homebrew/bin/` (macOS Homebrew)
|
|
722
|
+
- `/snap/bin/` (Ubuntu snaps)
|
|
723
|
+
- Virtual environment paths (`.venv`, `venv`, `.pybundle-venv`)
|
|
724
|
+
|
|
725
|
+
Tools outside trusted directories are excluded in strict mode. This prevents:
|
|
726
|
+
- Accidental execution of tools from user-writable directories
|
|
727
|
+
- PATH manipulation attacks
|
|
728
|
+
- Use of potentially compromised tool installations
|
|
729
|
+
|
|
730
|
+
**Example:** Verify tool paths before running:
|
|
731
|
+
```bash
|
|
732
|
+
pybundle doctor --strict-paths
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
Output shows trust status:
|
|
736
|
+
```
|
|
737
|
+
🔧 Tool Detection:
|
|
738
|
+
git ✅ /usr/bin/git
|
|
739
|
+
python ✅ /path/to/venv/bin/python
|
|
740
|
+
npm ⚠️ /home/user/.nvm/.../npm (untrusted in strict mode)
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
**Configure custom trusted paths:**
|
|
744
|
+
```bash
|
|
745
|
+
export PYBUNDLE_TRUSTED_PATHS="/opt/custom/bin:/company/tools/bin"
|
|
746
|
+
pybundle run debug --strict-paths
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
### Known Limitations
|
|
750
|
+
|
|
751
|
+
1. **Requires Trusted Environment**
|
|
752
|
+
- Assumes developer controls their machine and installed tools
|
|
753
|
+
- Not designed for untrusted code execution or sandboxing
|
|
754
|
+
- Tool integrity depends on system package management
|
|
755
|
+
|
|
756
|
+
2. **Tool Availability**
|
|
757
|
+
- External tools (git, ruff, mypy) are optional
|
|
758
|
+
- Missing tools result in SKIP status, not failure
|
|
759
|
+
- Use `pybundle doctor` to verify available tools
|
|
656
760
|
|
|
761
|
+
3. **File System Access**
|
|
762
|
+
- Reads entire project tree (respecting ignore rules)
|
|
763
|
+
- Writes to `artifacts/` directory by default
|
|
764
|
+
- No privilege escalation or system modification
|
|
765
|
+
|
|
766
|
+
### For Security Auditors
|
|
767
|
+
|
|
768
|
+
**Bandit Security Scan Results:**
|
|
769
|
+
- 33 low-severity findings (all expected for CLI tool)
|
|
770
|
+
- **B404** (subprocess import): Required for tool functionality
|
|
771
|
+
- **B603** (subprocess calls): Using secure pattern (shell=False, full paths)
|
|
772
|
+
- **B112** (try/except/continue): Acceptable error handling pattern
|
|
773
|
+
|
|
774
|
+
**Risk Classification:** LOW
|
|
775
|
+
- No user-controlled command injection
|
|
776
|
+
- No untrusted input in command execution
|
|
777
|
+
- Full path resolution prevents PATH manipulation attacks
|
|
778
|
+
- Standard development tool security posture
|
|
779
|
+
|
|
780
|
+
**Recommended Usage:**
|
|
781
|
+
```bash
|
|
782
|
+
# Verify tool paths before execution
|
|
783
|
+
pybundle doctor
|
|
784
|
+
|
|
785
|
+
# Review what tools will be used
|
|
786
|
+
pybundle doctor analysis --json
|
|
787
|
+
```
|
|
788
|
+
|
|
789
|
+
---
|
|
657
790
|
## 🧩 Why pybundle?
|
|
658
791
|
|
|
659
792
|
pybundle is designed for:
|
|
@@ -694,7 +827,7 @@ pybundle follows **Semantic Versioning**.
|
|
|
694
827
|
Pinned Git tags are recommended when used as a dependency:
|
|
695
828
|
|
|
696
829
|
```txt
|
|
697
|
-
gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.
|
|
830
|
+
gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.3.1
|
|
698
831
|
```
|
|
699
832
|
|
|
700
833
|
---
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
# 🧳 pybundle
|
|
1
|
+
# 🧳 pybundle 
|
|
2
|
+
|
|
2
3
|

|
|
3
4
|
|
|
4
5
|
[](https://pypi.org/project/gwc-pybundle/)
|
|
@@ -124,7 +125,7 @@ pytest
|
|
|
124
125
|
pytest-cov
|
|
125
126
|
bandit
|
|
126
127
|
pip-audit
|
|
127
|
-
gwc-pybundle==1.
|
|
128
|
+
gwc-pybundle==1.3.1
|
|
128
129
|
```
|
|
129
130
|
|
|
130
131
|
Then install:
|
|
@@ -161,7 +162,7 @@ See **Usage** for more details.
|
|
|
161
162
|
#### From GitHub
|
|
162
163
|
|
|
163
164
|
```bash
|
|
164
|
-
pip install "gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.
|
|
165
|
+
pip install "gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.3.1"
|
|
165
166
|
```
|
|
166
167
|
|
|
167
168
|
Pinning to a tag ensures reproducible behavior.
|
|
@@ -310,6 +311,10 @@ The `analysis` and `debug` profiles run comprehensive quality and security check
|
|
|
310
311
|
* **ruff** - Fast Python linter and formatter checks
|
|
311
312
|
* **mypy** - Static type checking for type hints
|
|
312
313
|
* **pylance** - Syntax error detection and import analysis
|
|
314
|
+
* **vulture** - Dead code detection (v1.3.0+)
|
|
315
|
+
* **radon** - Cyclomatic complexity and maintainability metrics (v1.3.0+)
|
|
316
|
+
* **interrogate** - Docstring coverage analysis (v1.3.0+)
|
|
317
|
+
* **pylint duplication** - Code duplication detection (v1.3.0+)
|
|
313
318
|
|
|
314
319
|
#### Testing & Coverage
|
|
315
320
|
* **pytest** - Test execution and results
|
|
@@ -319,13 +324,31 @@ The `analysis` and `debug` profiles run comprehensive quality and security check
|
|
|
319
324
|
* **bandit** - Security vulnerability scanning for Python code
|
|
320
325
|
* **pip-audit** - Dependency vulnerability checking against known CVEs
|
|
321
326
|
|
|
327
|
+
#### Dependency Analysis (v1.3.1+)
|
|
328
|
+
* **pipdeptree** - Full dependency tree with conflict detection
|
|
329
|
+
* **unused dependencies** - Identify installed but unused packages
|
|
330
|
+
* **pip-licenses** - License scanning and compatibility warnings
|
|
331
|
+
* **dependency sizes** - Disk usage analysis per package
|
|
332
|
+
|
|
333
|
+
#### Performance Profiling (v1.4.0+)
|
|
334
|
+
* **cProfile** - CPU profiling to identify bottlenecks
|
|
335
|
+
* **import time analysis** - Detect slow module imports
|
|
336
|
+
* **tracemalloc** - Memory profiling (optional, via `--profile-memory`)
|
|
337
|
+
* **line_profiler** - Line-by-line profiling (optional, requires `@profile` decorators and `--enable-line-profiler`)
|
|
338
|
+
|
|
339
|
+
#### Test Quality & Coverage Enhancement (v1.4.1+)
|
|
340
|
+
* **Test flakiness detection** - Run tests multiple times to identify non-deterministic failures
|
|
341
|
+
* **Branch coverage** - Enhanced coverage.py integration showing missing branches, not just lines
|
|
342
|
+
* **Slow test identification** - Automatically identify and rank tests exceeding time threshold
|
|
343
|
+
* **Mutation testing** - Optional mutmut integration to measure test suite effectiveness (VERY SLOW - disabled by default)
|
|
344
|
+
|
|
322
345
|
#### Pattern Scanning
|
|
323
346
|
* **ripgrep scans** - TODO detection, print statements, bare excepts
|
|
324
347
|
|
|
325
348
|
All tools gracefully skip if not installed. Install recommended tools:
|
|
326
349
|
|
|
327
350
|
```bash
|
|
328
|
-
pip install ruff mypy pytest pytest-cov bandit pip-audit
|
|
351
|
+
pip install ruff mypy pytest pytest-cov bandit pip-audit vulture radon interrogate pylint pipdeptree pip-licenses
|
|
329
352
|
```
|
|
330
353
|
|
|
331
354
|
For ripgrep (system dependency):
|
|
@@ -396,7 +419,6 @@ Commonly used options:
|
|
|
396
419
|
* `--outdir PATH` - output directory (default: `<project>/artifacts`)
|
|
397
420
|
* `--name NAME` - override archive name prefix
|
|
398
421
|
* `--strict` - fail with non-zero exit code if any step fails
|
|
399
|
-
* `--no-spinner` - disable spinner output (CI-friendly)
|
|
400
422
|
* `--redact / --no-redact` - control secret redaction
|
|
401
423
|
|
|
402
424
|
Tool execution can be selectively disabled:
|
|
@@ -484,7 +506,7 @@ When enabled, `pybundle` emits **exactly one JSON object to stdout**, with a **s
|
|
|
484
506
|
* AI orchestration
|
|
485
507
|
* reproducible analysis
|
|
486
508
|
|
|
487
|
-
No human text
|
|
509
|
+
No human text or formatting are mixed into the output.
|
|
488
510
|
|
|
489
511
|
### Example
|
|
490
512
|
|
|
@@ -604,7 +626,118 @@ By default, pybundle:
|
|
|
604
626
|
Use `--redact / --no-redact` to control behavior.
|
|
605
627
|
|
|
606
628
|
---
|
|
629
|
+
## 🔒 Security Considerations
|
|
630
|
+
|
|
631
|
+
**pybundle** is a development tool designed for trusted environments.
|
|
632
|
+
|
|
633
|
+
### Threat Model
|
|
634
|
+
|
|
635
|
+
* **Environment:** Development machines and CI/CD pipelines
|
|
636
|
+
* **Trust Boundary:** Assumes trusted development environment
|
|
637
|
+
* **Execution Context:** Runs external tools (git, ruff, mypy, pytest, etc.)
|
|
638
|
+
* **Input Sources:** Project files, git repository, installed packages
|
|
639
|
+
|
|
640
|
+
### Security Posture
|
|
641
|
+
|
|
642
|
+
**Tool Path Resolution:**
|
|
643
|
+
- All external tools use full resolved paths (via `shutil.which()`)
|
|
644
|
+
- Tools are resolved at detection time and stored in `Tooling` dataclass
|
|
645
|
+
- No dynamic PATH manipulation or shell interpretation
|
|
646
|
+
- Eliminates partial path execution vulnerabilities (B607)
|
|
647
|
+
- **Optional strict-paths mode** for enhanced security (v1.2.0+)
|
|
648
|
+
- **Code quality tools** for dead code, complexity, docstrings, and duplication (v1.3.0+)
|
|
649
|
+
- **Dependency intelligence** for conflict detection, license scanning, and size analysis (v1.3.1+)
|
|
650
|
+
|
|
651
|
+
**Subprocess Execution:**
|
|
652
|
+
- All subprocess calls use `shell=False` (default, secure)
|
|
653
|
+
- Arguments passed as lists, never as strings
|
|
654
|
+
- No user-controlled command construction
|
|
655
|
+
- Commands are hardcoded in source code
|
|
656
|
+
|
|
657
|
+
**Data Handling:**
|
|
658
|
+
- Optional secret redaction for sensitive strings in logs
|
|
659
|
+
- Environment variables and paths logged for reproducibility
|
|
660
|
+
- All file operations respect `.gitignore` rules
|
|
661
|
+
|
|
662
|
+
### Strict-Paths Mode (v1.2.0+)
|
|
663
|
+
|
|
664
|
+
For high-security environments, enable `--strict-paths` to enforce that all tools must be in trusted system directories:
|
|
665
|
+
|
|
666
|
+
```bash
|
|
667
|
+
pybundle run analysis --strict-paths
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
**Trusted directories** (configurable via `PYBUNDLE_TRUSTED_PATHS`):
|
|
671
|
+
- `/usr/bin/`, `/usr/local/bin/`, `/bin/`
|
|
672
|
+
- `/opt/homebrew/bin/` (macOS Homebrew)
|
|
673
|
+
- `/snap/bin/` (Ubuntu snaps)
|
|
674
|
+
- Virtual environment paths (`.venv`, `venv`, `.pybundle-venv`)
|
|
675
|
+
|
|
676
|
+
Tools outside trusted directories are excluded in strict mode. This prevents:
|
|
677
|
+
- Accidental execution of tools from user-writable directories
|
|
678
|
+
- PATH manipulation attacks
|
|
679
|
+
- Use of potentially compromised tool installations
|
|
680
|
+
|
|
681
|
+
**Example:** Verify tool paths before running:
|
|
682
|
+
```bash
|
|
683
|
+
pybundle doctor --strict-paths
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
Output shows trust status:
|
|
687
|
+
```
|
|
688
|
+
🔧 Tool Detection:
|
|
689
|
+
git ✅ /usr/bin/git
|
|
690
|
+
python ✅ /path/to/venv/bin/python
|
|
691
|
+
npm ⚠️ /home/user/.nvm/.../npm (untrusted in strict mode)
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
**Configure custom trusted paths:**
|
|
695
|
+
```bash
|
|
696
|
+
export PYBUNDLE_TRUSTED_PATHS="/opt/custom/bin:/company/tools/bin"
|
|
697
|
+
pybundle run debug --strict-paths
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
### Known Limitations
|
|
701
|
+
|
|
702
|
+
1. **Requires Trusted Environment**
|
|
703
|
+
- Assumes developer controls their machine and installed tools
|
|
704
|
+
- Not designed for untrusted code execution or sandboxing
|
|
705
|
+
- Tool integrity depends on system package management
|
|
706
|
+
|
|
707
|
+
2. **Tool Availability**
|
|
708
|
+
- External tools (git, ruff, mypy) are optional
|
|
709
|
+
- Missing tools result in SKIP status, not failure
|
|
710
|
+
- Use `pybundle doctor` to verify available tools
|
|
607
711
|
|
|
712
|
+
3. **File System Access**
|
|
713
|
+
- Reads entire project tree (respecting ignore rules)
|
|
714
|
+
- Writes to `artifacts/` directory by default
|
|
715
|
+
- No privilege escalation or system modification
|
|
716
|
+
|
|
717
|
+
### For Security Auditors
|
|
718
|
+
|
|
719
|
+
**Bandit Security Scan Results:**
|
|
720
|
+
- 33 low-severity findings (all expected for CLI tool)
|
|
721
|
+
- **B404** (subprocess import): Required for tool functionality
|
|
722
|
+
- **B603** (subprocess calls): Using secure pattern (shell=False, full paths)
|
|
723
|
+
- **B112** (try/except/continue): Acceptable error handling pattern
|
|
724
|
+
|
|
725
|
+
**Risk Classification:** LOW
|
|
726
|
+
- No user-controlled command injection
|
|
727
|
+
- No untrusted input in command execution
|
|
728
|
+
- Full path resolution prevents PATH manipulation attacks
|
|
729
|
+
- Standard development tool security posture
|
|
730
|
+
|
|
731
|
+
**Recommended Usage:**
|
|
732
|
+
```bash
|
|
733
|
+
# Verify tool paths before execution
|
|
734
|
+
pybundle doctor
|
|
735
|
+
|
|
736
|
+
# Review what tools will be used
|
|
737
|
+
pybundle doctor analysis --json
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
---
|
|
608
741
|
## 🧩 Why pybundle?
|
|
609
742
|
|
|
610
743
|
pybundle is designed for:
|
|
@@ -645,7 +778,7 @@ pybundle follows **Semantic Versioning**.
|
|
|
645
778
|
Pinned Git tags are recommended when used as a dependency:
|
|
646
779
|
|
|
647
780
|
```txt
|
|
648
|
-
gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.
|
|
781
|
+
gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.3.1
|
|
649
782
|
```
|
|
650
783
|
|
|
651
784
|
---
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gwc-pybundle
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.1
|
|
4
4
|
Summary: Deterministic Python project context bundling for humans, automation, and AI
|
|
5
|
-
Author: Jessica Brown
|
|
5
|
+
Author-email: Jessica Brown <jessica@codenamejessica.com>
|
|
6
6
|
License: The MIT License (MIT)
|
|
7
7
|
=====================
|
|
8
8
|
|
|
@@ -47,7 +47,8 @@ Description-Content-Type: text/markdown
|
|
|
47
47
|
License-File: LICENSE.md
|
|
48
48
|
Dynamic: license-file
|
|
49
49
|
|
|
50
|
-
# 🧳 pybundle
|
|
50
|
+
# 🧳 pybundle 
|
|
51
|
+
|
|
51
52
|

|
|
52
53
|
|
|
53
54
|
[](https://pypi.org/project/gwc-pybundle/)
|
|
@@ -173,7 +174,7 @@ pytest
|
|
|
173
174
|
pytest-cov
|
|
174
175
|
bandit
|
|
175
176
|
pip-audit
|
|
176
|
-
gwc-pybundle==1.
|
|
177
|
+
gwc-pybundle==1.3.1
|
|
177
178
|
```
|
|
178
179
|
|
|
179
180
|
Then install:
|
|
@@ -210,7 +211,7 @@ See **Usage** for more details.
|
|
|
210
211
|
#### From GitHub
|
|
211
212
|
|
|
212
213
|
```bash
|
|
213
|
-
pip install "gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.
|
|
214
|
+
pip install "gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.3.1"
|
|
214
215
|
```
|
|
215
216
|
|
|
216
217
|
Pinning to a tag ensures reproducible behavior.
|
|
@@ -359,6 +360,10 @@ The `analysis` and `debug` profiles run comprehensive quality and security check
|
|
|
359
360
|
* **ruff** - Fast Python linter and formatter checks
|
|
360
361
|
* **mypy** - Static type checking for type hints
|
|
361
362
|
* **pylance** - Syntax error detection and import analysis
|
|
363
|
+
* **vulture** - Dead code detection (v1.3.0+)
|
|
364
|
+
* **radon** - Cyclomatic complexity and maintainability metrics (v1.3.0+)
|
|
365
|
+
* **interrogate** - Docstring coverage analysis (v1.3.0+)
|
|
366
|
+
* **pylint duplication** - Code duplication detection (v1.3.0+)
|
|
362
367
|
|
|
363
368
|
#### Testing & Coverage
|
|
364
369
|
* **pytest** - Test execution and results
|
|
@@ -368,13 +373,31 @@ The `analysis` and `debug` profiles run comprehensive quality and security check
|
|
|
368
373
|
* **bandit** - Security vulnerability scanning for Python code
|
|
369
374
|
* **pip-audit** - Dependency vulnerability checking against known CVEs
|
|
370
375
|
|
|
376
|
+
#### Dependency Analysis (v1.3.1+)
|
|
377
|
+
* **pipdeptree** - Full dependency tree with conflict detection
|
|
378
|
+
* **unused dependencies** - Identify installed but unused packages
|
|
379
|
+
* **pip-licenses** - License scanning and compatibility warnings
|
|
380
|
+
* **dependency sizes** - Disk usage analysis per package
|
|
381
|
+
|
|
382
|
+
#### Performance Profiling (v1.4.0+)
|
|
383
|
+
* **cProfile** - CPU profiling to identify bottlenecks
|
|
384
|
+
* **import time analysis** - Detect slow module imports
|
|
385
|
+
* **tracemalloc** - Memory profiling (optional, via `--profile-memory`)
|
|
386
|
+
* **line_profiler** - Line-by-line profiling (optional, requires `@profile` decorators and `--enable-line-profiler`)
|
|
387
|
+
|
|
388
|
+
#### Test Quality & Coverage Enhancement (v1.4.1+)
|
|
389
|
+
* **Test flakiness detection** - Run tests multiple times to identify non-deterministic failures
|
|
390
|
+
* **Branch coverage** - Enhanced coverage.py integration showing missing branches, not just lines
|
|
391
|
+
* **Slow test identification** - Automatically identify and rank tests exceeding time threshold
|
|
392
|
+
* **Mutation testing** - Optional mutmut integration to measure test suite effectiveness (VERY SLOW - disabled by default)
|
|
393
|
+
|
|
371
394
|
#### Pattern Scanning
|
|
372
395
|
* **ripgrep scans** - TODO detection, print statements, bare excepts
|
|
373
396
|
|
|
374
397
|
All tools gracefully skip if not installed. Install recommended tools:
|
|
375
398
|
|
|
376
399
|
```bash
|
|
377
|
-
pip install ruff mypy pytest pytest-cov bandit pip-audit
|
|
400
|
+
pip install ruff mypy pytest pytest-cov bandit pip-audit vulture radon interrogate pylint pipdeptree pip-licenses
|
|
378
401
|
```
|
|
379
402
|
|
|
380
403
|
For ripgrep (system dependency):
|
|
@@ -445,7 +468,6 @@ Commonly used options:
|
|
|
445
468
|
* `--outdir PATH` - output directory (default: `<project>/artifacts`)
|
|
446
469
|
* `--name NAME` - override archive name prefix
|
|
447
470
|
* `--strict` - fail with non-zero exit code if any step fails
|
|
448
|
-
* `--no-spinner` - disable spinner output (CI-friendly)
|
|
449
471
|
* `--redact / --no-redact` - control secret redaction
|
|
450
472
|
|
|
451
473
|
Tool execution can be selectively disabled:
|
|
@@ -533,7 +555,7 @@ When enabled, `pybundle` emits **exactly one JSON object to stdout**, with a **s
|
|
|
533
555
|
* AI orchestration
|
|
534
556
|
* reproducible analysis
|
|
535
557
|
|
|
536
|
-
No human text
|
|
558
|
+
No human text or formatting are mixed into the output.
|
|
537
559
|
|
|
538
560
|
### Example
|
|
539
561
|
|
|
@@ -653,7 +675,118 @@ By default, pybundle:
|
|
|
653
675
|
Use `--redact / --no-redact` to control behavior.
|
|
654
676
|
|
|
655
677
|
---
|
|
678
|
+
## 🔒 Security Considerations
|
|
679
|
+
|
|
680
|
+
**pybundle** is a development tool designed for trusted environments.
|
|
681
|
+
|
|
682
|
+
### Threat Model
|
|
683
|
+
|
|
684
|
+
* **Environment:** Development machines and CI/CD pipelines
|
|
685
|
+
* **Trust Boundary:** Assumes trusted development environment
|
|
686
|
+
* **Execution Context:** Runs external tools (git, ruff, mypy, pytest, etc.)
|
|
687
|
+
* **Input Sources:** Project files, git repository, installed packages
|
|
688
|
+
|
|
689
|
+
### Security Posture
|
|
690
|
+
|
|
691
|
+
**Tool Path Resolution:**
|
|
692
|
+
- All external tools use full resolved paths (via `shutil.which()`)
|
|
693
|
+
- Tools are resolved at detection time and stored in `Tooling` dataclass
|
|
694
|
+
- No dynamic PATH manipulation or shell interpretation
|
|
695
|
+
- Eliminates partial path execution vulnerabilities (B607)
|
|
696
|
+
- **Optional strict-paths mode** for enhanced security (v1.2.0+)
|
|
697
|
+
- **Code quality tools** for dead code, complexity, docstrings, and duplication (v1.3.0+)
|
|
698
|
+
- **Dependency intelligence** for conflict detection, license scanning, and size analysis (v1.3.1+)
|
|
699
|
+
|
|
700
|
+
**Subprocess Execution:**
|
|
701
|
+
- All subprocess calls use `shell=False` (default, secure)
|
|
702
|
+
- Arguments passed as lists, never as strings
|
|
703
|
+
- No user-controlled command construction
|
|
704
|
+
- Commands are hardcoded in source code
|
|
705
|
+
|
|
706
|
+
**Data Handling:**
|
|
707
|
+
- Optional secret redaction for sensitive strings in logs
|
|
708
|
+
- Environment variables and paths logged for reproducibility
|
|
709
|
+
- All file operations respect `.gitignore` rules
|
|
710
|
+
|
|
711
|
+
### Strict-Paths Mode (v1.2.0+)
|
|
712
|
+
|
|
713
|
+
For high-security environments, enable `--strict-paths` to enforce that all tools must be in trusted system directories:
|
|
714
|
+
|
|
715
|
+
```bash
|
|
716
|
+
pybundle run analysis --strict-paths
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
**Trusted directories** (configurable via `PYBUNDLE_TRUSTED_PATHS`):
|
|
720
|
+
- `/usr/bin/`, `/usr/local/bin/`, `/bin/`
|
|
721
|
+
- `/opt/homebrew/bin/` (macOS Homebrew)
|
|
722
|
+
- `/snap/bin/` (Ubuntu snaps)
|
|
723
|
+
- Virtual environment paths (`.venv`, `venv`, `.pybundle-venv`)
|
|
724
|
+
|
|
725
|
+
Tools outside trusted directories are excluded in strict mode. This prevents:
|
|
726
|
+
- Accidental execution of tools from user-writable directories
|
|
727
|
+
- PATH manipulation attacks
|
|
728
|
+
- Use of potentially compromised tool installations
|
|
729
|
+
|
|
730
|
+
**Example:** Verify tool paths before running:
|
|
731
|
+
```bash
|
|
732
|
+
pybundle doctor --strict-paths
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
Output shows trust status:
|
|
736
|
+
```
|
|
737
|
+
🔧 Tool Detection:
|
|
738
|
+
git ✅ /usr/bin/git
|
|
739
|
+
python ✅ /path/to/venv/bin/python
|
|
740
|
+
npm ⚠️ /home/user/.nvm/.../npm (untrusted in strict mode)
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
**Configure custom trusted paths:**
|
|
744
|
+
```bash
|
|
745
|
+
export PYBUNDLE_TRUSTED_PATHS="/opt/custom/bin:/company/tools/bin"
|
|
746
|
+
pybundle run debug --strict-paths
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
### Known Limitations
|
|
750
|
+
|
|
751
|
+
1. **Requires Trusted Environment**
|
|
752
|
+
- Assumes developer controls their machine and installed tools
|
|
753
|
+
- Not designed for untrusted code execution or sandboxing
|
|
754
|
+
- Tool integrity depends on system package management
|
|
755
|
+
|
|
756
|
+
2. **Tool Availability**
|
|
757
|
+
- External tools (git, ruff, mypy) are optional
|
|
758
|
+
- Missing tools result in SKIP status, not failure
|
|
759
|
+
- Use `pybundle doctor` to verify available tools
|
|
656
760
|
|
|
761
|
+
3. **File System Access**
|
|
762
|
+
- Reads entire project tree (respecting ignore rules)
|
|
763
|
+
- Writes to `artifacts/` directory by default
|
|
764
|
+
- No privilege escalation or system modification
|
|
765
|
+
|
|
766
|
+
### For Security Auditors
|
|
767
|
+
|
|
768
|
+
**Bandit Security Scan Results:**
|
|
769
|
+
- 33 low-severity findings (all expected for CLI tool)
|
|
770
|
+
- **B404** (subprocess import): Required for tool functionality
|
|
771
|
+
- **B603** (subprocess calls): Using secure pattern (shell=False, full paths)
|
|
772
|
+
- **B112** (try/except/continue): Acceptable error handling pattern
|
|
773
|
+
|
|
774
|
+
**Risk Classification:** LOW
|
|
775
|
+
- No user-controlled command injection
|
|
776
|
+
- No untrusted input in command execution
|
|
777
|
+
- Full path resolution prevents PATH manipulation attacks
|
|
778
|
+
- Standard development tool security posture
|
|
779
|
+
|
|
780
|
+
**Recommended Usage:**
|
|
781
|
+
```bash
|
|
782
|
+
# Verify tool paths before execution
|
|
783
|
+
pybundle doctor
|
|
784
|
+
|
|
785
|
+
# Review what tools will be used
|
|
786
|
+
pybundle doctor analysis --json
|
|
787
|
+
```
|
|
788
|
+
|
|
789
|
+
---
|
|
657
790
|
## 🧩 Why pybundle?
|
|
658
791
|
|
|
659
792
|
pybundle is designed for:
|
|
@@ -694,7 +827,7 @@ pybundle follows **Semantic Versioning**.
|
|
|
694
827
|
Pinned Git tags are recommended when used as a dependency:
|
|
695
828
|
|
|
696
829
|
```txt
|
|
697
|
-
gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.
|
|
830
|
+
gwc-pybundle @ git+https://github.com/girls-whocode/pybundle.git@v1.3.1
|
|
698
831
|
```
|
|
699
832
|
|
|
700
833
|
---
|
|
@@ -28,15 +28,30 @@ pybundle/steps/compileall.py
|
|
|
28
28
|
pybundle/steps/context_expand.py
|
|
29
29
|
pybundle/steps/copy_pack.py
|
|
30
30
|
pybundle/steps/coverage.py
|
|
31
|
+
pybundle/steps/cprofile_step.py
|
|
32
|
+
pybundle/steps/dependency_sizes.py
|
|
33
|
+
pybundle/steps/duplication.py
|
|
31
34
|
pybundle/steps/error_refs.py
|
|
32
35
|
pybundle/steps/handoff_md.py
|
|
36
|
+
pybundle/steps/import_time.py
|
|
37
|
+
pybundle/steps/interrogate.py
|
|
38
|
+
pybundle/steps/license_scan.py
|
|
39
|
+
pybundle/steps/line_profiler.py
|
|
40
|
+
pybundle/steps/memory_profile.py
|
|
41
|
+
pybundle/steps/mutation_testing.py
|
|
33
42
|
pybundle/steps/mypy.py
|
|
34
43
|
pybundle/steps/pip_audit.py
|
|
44
|
+
pybundle/steps/pipdeptree.py
|
|
35
45
|
pybundle/steps/pylance.py
|
|
36
46
|
pybundle/steps/pytest.py
|
|
47
|
+
pybundle/steps/radon.py
|
|
37
48
|
pybundle/steps/repro_md.py
|
|
38
49
|
pybundle/steps/rg_scans.py
|
|
39
50
|
pybundle/steps/roadmap.py
|
|
40
51
|
pybundle/steps/ruff.py
|
|
41
52
|
pybundle/steps/shell.py
|
|
42
|
-
pybundle/steps/
|
|
53
|
+
pybundle/steps/slow_tests.py
|
|
54
|
+
pybundle/steps/test_flakiness.py
|
|
55
|
+
pybundle/steps/tree.py
|
|
56
|
+
pybundle/steps/unused_deps.py
|
|
57
|
+
pybundle/steps/vulture.py
|