pysentry-rs 0.1.5__tar.gz → 0.2.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.

Potentially problematic release.


This version of pysentry-rs might be problematic. Click here for more details.

Files changed (45) hide show
  1. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/Cargo.lock +1 -1
  2. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/Cargo.toml +1 -1
  3. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/PKG-INFO +30 -14
  4. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/README.md +29 -13
  5. pysentry_rs-0.2.0/python/pysentry/__init__.py +187 -0
  6. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/main.rs +169 -107
  7. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/parsers/lock.rs +155 -182
  8. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/parsers/mod.rs +4 -3
  9. pysentry_rs-0.2.0/src/parsers/poetry_lock.rs +300 -0
  10. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/parsers/pyproject.rs +87 -36
  11. pysentry_rs-0.1.5/python/pysentry/__init__.py +0 -167
  12. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/.github/dependabot.yml +0 -0
  13. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/.github/workflows/ci.yml +0 -0
  14. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/.github/workflows/release.yml +0 -0
  15. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/.gitignore +0 -0
  16. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/.pre-commit-config.yaml +0 -0
  17. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/LICENSE +0 -0
  18. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/fixtures/requirements-tests/requirements-dev.txt +0 -0
  19. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/fixtures/requirements-tests/requirements.txt +0 -0
  20. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/fixtures/requirements-tests-vulnerable/requirements.txt +0 -0
  21. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/pyproject.toml +0 -0
  22. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/python/pysentry/__main__.py +0 -0
  23. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/cache/audit.rs +0 -0
  24. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/cache/mod.rs +0 -0
  25. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/cache/storage.rs +0 -0
  26. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/dependency/mod.rs +0 -0
  27. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/dependency/resolvers/mod.rs +0 -0
  28. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/dependency/resolvers/pip_tools.rs +0 -0
  29. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/dependency/resolvers/uv.rs +0 -0
  30. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/dependency/scanner.rs +0 -0
  31. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/error.rs +0 -0
  32. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/lib.rs +0 -0
  33. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/output/mod.rs +0 -0
  34. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/output/report.rs +0 -0
  35. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/output/sarif.rs +0 -0
  36. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/parsers/requirements.rs +0 -0
  37. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/providers/mod.rs +0 -0
  38. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/providers/osv.rs +0 -0
  39. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/providers/pypa.rs +0 -0
  40. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/providers/pypi.rs +0 -0
  41. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/python.rs +0 -0
  42. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/types.rs +0 -0
  43. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/vulnerability/database.rs +0 -0
  44. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/vulnerability/matcher.rs +0 -0
  45. {pysentry_rs-0.1.5 → pysentry_rs-0.2.0}/src/vulnerability/mod.rs +0 -0
@@ -1067,7 +1067,7 @@ dependencies = [
1067
1067
 
1068
1068
  [[package]]
1069
1069
  name = "pysentry"
1070
- version = "0.1.5"
1070
+ version = "0.2.0"
1071
1071
  dependencies = [
1072
1072
  "anyhow",
1073
1073
  "async-trait",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "pysentry"
3
- version = "0.1.5"
3
+ version = "0.2.0"
4
4
  edition = "2021"
5
5
  rust-version = "1.79"
6
6
  description = "Security vulnerability auditing for Python packages"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pysentry-rs
3
- Version: 0.1.5
3
+ Version: 0.2.0
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
@@ -32,11 +32,11 @@ A fast, reliable security vulnerability scanner for Python projects, written in
32
32
 
33
33
  ## Overview
34
34
 
35
- PySentry audits Python projects for known security vulnerabilities by analyzing dependency files (`uv.lock`, `pyproject.toml`, `requirements.txt`) and cross-referencing them against multiple vulnerability databases. It provides comprehensive reporting with support for various output formats and filtering options.
35
+ PySentry audits Python projects for known security vulnerabilities by analyzing dependency files (`uv.lock`, `poetry.lock`, `pyproject.toml`, `requirements.txt`) and cross-referencing them against multiple vulnerability databases. It provides comprehensive reporting with support for various output formats and filtering options.
36
36
 
37
37
  ## Key Features
38
38
 
39
- - **Multiple Project Formats**: Supports `uv.lock`, `pyproject.toml`, and `requirements.txt` files
39
+ - **Multiple Project Formats**: Supports `uv.lock`, `poetry.lock`, `pyproject.toml`, and `requirements.txt` files
40
40
  - **External Resolver Integration**: Leverages `uv` and `pip-tools` for accurate requirements.txt constraint solving
41
41
  - **Multiple Data Sources**:
42
42
  - PyPA Advisory Database (default)
@@ -49,7 +49,7 @@ PySentry audits Python projects for known security vulnerabilities by analyzing
49
49
  - Intelligent caching system
50
50
  - **Comprehensive Filtering**:
51
51
  - Severity levels (low, medium, high, critical)
52
- - Dependency types (production, development, optional)
52
+ - Dependency scopes (main only vs all [optional, dev, prod, etc] dependencies)
53
53
  - Direct vs. transitive dependencies
54
54
  - **Enterprise Ready**: SARIF output for IDE/CI integration
55
55
 
@@ -174,7 +174,7 @@ pip install pip-tools
174
174
  ```
175
175
  - Alternatively, install resolvers globally for system-wide availability
176
176
 
177
- **Auto-detection:** PySentry automatically detects and prefers: `uv` > `pip-tools`. Without a resolver, only `uv.lock` and `pyproject.toml` files can be scanned.
177
+ **Auto-detection:** PySentry automatically detects and prefers: `uv` > `pip-tools`. Without a resolver, only `uv.lock` and `poetry.lock` files can be scanned.
178
178
 
179
179
  ## Quick Start
180
180
 
@@ -189,15 +189,15 @@ uvx pysentry-rs /path/to/python/project
189
189
  pysentry
190
190
  pysentry /path/to/python/project
191
191
 
192
- # Scan requirements.txt (auto-detects resolver)
192
+ # Automatically detects project type (uv.lock, poetry.lock, pyproject.toml, requirements.txt)
193
193
  pysentry /path/to/project
194
194
 
195
195
  # Force specific resolver
196
196
  pysentry --resolver uv /path/to/project
197
197
  pysentry --resolver pip-tools /path/to/project
198
198
 
199
- # Include development dependencies
200
- pysentry --dev
199
+ # Include all dependencies (main + dev + optional)
200
+ pysentry --all
201
201
 
202
202
  # Filter by severity (only show high and critical)
203
203
  pysentry --severity high
@@ -210,13 +210,13 @@ pysentry --format json --output audit-results.json
210
210
 
211
211
  ```bash
212
212
  # Using uvx for comprehensive audit
213
- uvx pysentry-rs --dev --optional --format sarif --output security-report.sarif
213
+ uvx pysentry-rs --all --format sarif --output security-report.sarif
214
214
 
215
215
  # Check only direct dependencies using OSV database
216
216
  uvx pysentry-rs --direct-only --source osv
217
217
 
218
218
  # Or with installed binary
219
- pysentry --dev --optional --format sarif --output security-report.sarif
219
+ pysentry --all --format sarif --output security-report.sarif
220
220
  pysentry --direct-only --source osv
221
221
 
222
222
  # Ignore specific vulnerabilities
@@ -255,8 +255,7 @@ pysentry --verbose --resolver uv /path/to/project
255
255
  | `--format` | Output format: `human`, `json`, `sarif` | `human` |
256
256
  | `--severity` | Minimum severity: `low`, `medium`, `high`, `critical` | `low` |
257
257
  | `--source` | Vulnerability source: `pypa`, `pypi`, `osv` | `pypa` |
258
- | `--dev` | Include development dependencies | `false` |
259
- | `--optional` | Include optional dependencies | `false` |
258
+ | `--all` | Include all dependencies (main + dev + optional) | `false` |
260
259
  | `--direct-only` | Check only direct dependencies | `false` |
261
260
  | `--ignore` | Vulnerability IDs to ignore (repeatable) | `[]` |
262
261
  | `--output` | Output file path | `stdout` |
@@ -293,6 +292,23 @@ PySentry has support for `uv.lock` files:
293
292
  - Source tracking
294
293
  - Dependency classification (main, dev, optional) including transitive dependencies
295
294
 
295
+ ### poetry.lock Files
296
+
297
+ Full support for Poetry lock files:
298
+
299
+ - **Exact Version Resolution**: Scans exact dependency versions locked by Poetry
300
+ - **Lock-File Only Analysis**: Relies purely on the lock file structure, no pyproject.toml parsing needed
301
+ - **Complete Dependency Tree**: Analyzes all resolved dependencies including transitive ones
302
+ - **Dependency Classification**: Distinguishes between main dependencies and optional groups (dev, test, etc.)
303
+ - **Source Tracking**: Supports PyPI registry, Git repositories, local paths, and direct URLs
304
+
305
+ **Key Features:**
306
+
307
+ - No external tools required
308
+ - Fast parsing with exact version information
309
+ - Handles Poetry's dependency groups and optional dependencies
310
+ - Perfect for Poetry-managed projects with established lock files
311
+
296
312
  ### requirements.txt Files (External Resolution)
297
313
 
298
314
  Advanced support for `requirements.txt` files using external dependency resolvers:
@@ -447,7 +463,7 @@ src/
447
463
 
448
464
  ```bash
449
465
  # Ensure you're in a Python project directory
450
- ls pyproject.toml uv.lock requirements.txt
466
+ ls pyproject.toml uv.lock poetry.lock requirements.txt
451
467
 
452
468
  # Or specify the path explicitly
453
469
  pysentry /path/to/python/project
@@ -524,7 +540,7 @@ pysentry /path/to/python/project
524
540
  pysentry --requirements requirements-dev.txt --requirements requirements-test.txt
525
541
 
526
542
  # Check if higher-priority files exist (they take precedence)
527
- ls uv.lock pyproject.toml
543
+ ls uv.lock poetry.lock pyproject.toml
528
544
  ```
529
545
 
530
546
  **Performance Issues**
@@ -6,11 +6,11 @@ A fast, reliable security vulnerability scanner for Python projects, written in
6
6
 
7
7
  ## Overview
8
8
 
9
- PySentry audits Python projects for known security vulnerabilities by analyzing dependency files (`uv.lock`, `pyproject.toml`, `requirements.txt`) and cross-referencing them against multiple vulnerability databases. It provides comprehensive reporting with support for various output formats and filtering options.
9
+ PySentry audits Python projects for known security vulnerabilities by analyzing dependency files (`uv.lock`, `poetry.lock`, `pyproject.toml`, `requirements.txt`) and cross-referencing them against multiple vulnerability databases. It provides comprehensive reporting with support for various output formats and filtering options.
10
10
 
11
11
  ## Key Features
12
12
 
13
- - **Multiple Project Formats**: Supports `uv.lock`, `pyproject.toml`, and `requirements.txt` files
13
+ - **Multiple Project Formats**: Supports `uv.lock`, `poetry.lock`, `pyproject.toml`, and `requirements.txt` files
14
14
  - **External Resolver Integration**: Leverages `uv` and `pip-tools` for accurate requirements.txt constraint solving
15
15
  - **Multiple Data Sources**:
16
16
  - PyPA Advisory Database (default)
@@ -23,7 +23,7 @@ PySentry audits Python projects for known security vulnerabilities by analyzing
23
23
  - Intelligent caching system
24
24
  - **Comprehensive Filtering**:
25
25
  - Severity levels (low, medium, high, critical)
26
- - Dependency types (production, development, optional)
26
+ - Dependency scopes (main only vs all [optional, dev, prod, etc] dependencies)
27
27
  - Direct vs. transitive dependencies
28
28
  - **Enterprise Ready**: SARIF output for IDE/CI integration
29
29
 
@@ -148,7 +148,7 @@ pip install pip-tools
148
148
  ```
149
149
  - Alternatively, install resolvers globally for system-wide availability
150
150
 
151
- **Auto-detection:** PySentry automatically detects and prefers: `uv` > `pip-tools`. Without a resolver, only `uv.lock` and `pyproject.toml` files can be scanned.
151
+ **Auto-detection:** PySentry automatically detects and prefers: `uv` > `pip-tools`. Without a resolver, only `uv.lock` and `poetry.lock` files can be scanned.
152
152
 
153
153
  ## Quick Start
154
154
 
@@ -163,15 +163,15 @@ uvx pysentry-rs /path/to/python/project
163
163
  pysentry
164
164
  pysentry /path/to/python/project
165
165
 
166
- # Scan requirements.txt (auto-detects resolver)
166
+ # Automatically detects project type (uv.lock, poetry.lock, pyproject.toml, requirements.txt)
167
167
  pysentry /path/to/project
168
168
 
169
169
  # Force specific resolver
170
170
  pysentry --resolver uv /path/to/project
171
171
  pysentry --resolver pip-tools /path/to/project
172
172
 
173
- # Include development dependencies
174
- pysentry --dev
173
+ # Include all dependencies (main + dev + optional)
174
+ pysentry --all
175
175
 
176
176
  # Filter by severity (only show high and critical)
177
177
  pysentry --severity high
@@ -184,13 +184,13 @@ pysentry --format json --output audit-results.json
184
184
 
185
185
  ```bash
186
186
  # Using uvx for comprehensive audit
187
- uvx pysentry-rs --dev --optional --format sarif --output security-report.sarif
187
+ uvx pysentry-rs --all --format sarif --output security-report.sarif
188
188
 
189
189
  # Check only direct dependencies using OSV database
190
190
  uvx pysentry-rs --direct-only --source osv
191
191
 
192
192
  # Or with installed binary
193
- pysentry --dev --optional --format sarif --output security-report.sarif
193
+ pysentry --all --format sarif --output security-report.sarif
194
194
  pysentry --direct-only --source osv
195
195
 
196
196
  # Ignore specific vulnerabilities
@@ -229,8 +229,7 @@ pysentry --verbose --resolver uv /path/to/project
229
229
  | `--format` | Output format: `human`, `json`, `sarif` | `human` |
230
230
  | `--severity` | Minimum severity: `low`, `medium`, `high`, `critical` | `low` |
231
231
  | `--source` | Vulnerability source: `pypa`, `pypi`, `osv` | `pypa` |
232
- | `--dev` | Include development dependencies | `false` |
233
- | `--optional` | Include optional dependencies | `false` |
232
+ | `--all` | Include all dependencies (main + dev + optional) | `false` |
234
233
  | `--direct-only` | Check only direct dependencies | `false` |
235
234
  | `--ignore` | Vulnerability IDs to ignore (repeatable) | `[]` |
236
235
  | `--output` | Output file path | `stdout` |
@@ -267,6 +266,23 @@ PySentry has support for `uv.lock` files:
267
266
  - Source tracking
268
267
  - Dependency classification (main, dev, optional) including transitive dependencies
269
268
 
269
+ ### poetry.lock Files
270
+
271
+ Full support for Poetry lock files:
272
+
273
+ - **Exact Version Resolution**: Scans exact dependency versions locked by Poetry
274
+ - **Lock-File Only Analysis**: Relies purely on the lock file structure, no pyproject.toml parsing needed
275
+ - **Complete Dependency Tree**: Analyzes all resolved dependencies including transitive ones
276
+ - **Dependency Classification**: Distinguishes between main dependencies and optional groups (dev, test, etc.)
277
+ - **Source Tracking**: Supports PyPI registry, Git repositories, local paths, and direct URLs
278
+
279
+ **Key Features:**
280
+
281
+ - No external tools required
282
+ - Fast parsing with exact version information
283
+ - Handles Poetry's dependency groups and optional dependencies
284
+ - Perfect for Poetry-managed projects with established lock files
285
+
270
286
  ### requirements.txt Files (External Resolution)
271
287
 
272
288
  Advanced support for `requirements.txt` files using external dependency resolvers:
@@ -421,7 +437,7 @@ src/
421
437
 
422
438
  ```bash
423
439
  # Ensure you're in a Python project directory
424
- ls pyproject.toml uv.lock requirements.txt
440
+ ls pyproject.toml uv.lock poetry.lock requirements.txt
425
441
 
426
442
  # Or specify the path explicitly
427
443
  pysentry /path/to/python/project
@@ -498,7 +514,7 @@ pysentry /path/to/python/project
498
514
  pysentry --requirements requirements-dev.txt --requirements requirements-test.txt
499
515
 
500
516
  # Check if higher-priority files exist (they take precedence)
501
- ls uv.lock pyproject.toml
517
+ ls uv.lock poetry.lock pyproject.toml
502
518
  ```
503
519
 
504
520
  **Performance Issues**
@@ -0,0 +1,187 @@
1
+ """pysentry: Security vulnerability auditing tool for Python packages."""
2
+
3
+ from ._internal import audit_python, audit_with_options, check_resolvers, check_version
4
+
5
+ __version__ = "0.2.0"
6
+ __all__ = [
7
+ "audit_python",
8
+ "audit_with_options",
9
+ "check_resolvers",
10
+ "check_version",
11
+ "main",
12
+ ]
13
+
14
+
15
+ def main():
16
+ """CLI entry point."""
17
+ import sys
18
+ import argparse
19
+
20
+ # Handle subcommands manually to match Rust CLI structure exactly
21
+ if len(sys.argv) > 1:
22
+ if sys.argv[1] == "resolvers":
23
+ # Resolvers subcommand
24
+ parser = argparse.ArgumentParser(
25
+ prog="pysentry resolvers",
26
+ description="Check available dependency resolvers",
27
+ )
28
+ parser.add_argument(
29
+ "-v", "--verbose", action="store_true", help="Enable verbose output"
30
+ )
31
+
32
+ args = parser.parse_args(sys.argv[2:])
33
+ try:
34
+ result = check_resolvers(args.verbose)
35
+ print(result)
36
+ except Exception as e:
37
+ print(f"Error: {e}", file=sys.stderr)
38
+ sys.exit(1)
39
+ return
40
+
41
+ elif sys.argv[1] == "check-version":
42
+ # Check-version subcommand
43
+ parser = argparse.ArgumentParser(
44
+ prog="pysentry-rs check-version",
45
+ description="Check if a newer version is available",
46
+ )
47
+ parser.add_argument(
48
+ "-v", "--verbose", action="store_true", help="Enable verbose output"
49
+ )
50
+
51
+ args = parser.parse_args(sys.argv[2:])
52
+ try:
53
+ result = check_version(args.verbose)
54
+ print(result)
55
+ except Exception as e:
56
+ print(f"Error: {e}", file=sys.stderr)
57
+ sys.exit(1)
58
+ return
59
+ elif sys.argv[1] in ["-h", "--help"]:
60
+ # Show main help
61
+ pass
62
+ elif sys.argv[1] in ["-V", "--version"]:
63
+ print(f"pysentry-rs {__version__}")
64
+ return
65
+
66
+ # Main parser for audit command (default) and help
67
+ parser = argparse.ArgumentParser(
68
+ prog="pysentry-rs",
69
+ description="Security vulnerability auditing for Python packages",
70
+ usage="pysentry-rs [OPTIONS] [PATH] [COMMAND]",
71
+ )
72
+
73
+ # Add version argument
74
+ parser.add_argument(
75
+ "-V", "--version", action="version", version=f"pysentry-rs {__version__}"
76
+ )
77
+
78
+ # Main audit arguments
79
+ parser.add_argument(
80
+ "path",
81
+ nargs="?",
82
+ default=".",
83
+ metavar="PATH",
84
+ help="Path to the project directory to audit [default: .]",
85
+ )
86
+ parser.add_argument(
87
+ "--format",
88
+ choices=["human", "json", "sarif"],
89
+ default="human",
90
+ help="Output format [default: human] [possible values: human, json, sarif]",
91
+ )
92
+ parser.add_argument(
93
+ "--severity",
94
+ choices=["low", "medium", "high", "critical"],
95
+ default="low",
96
+ help="Minimum severity level to report [default: low] [possible values: low, medium, high, critical]",
97
+ )
98
+ parser.add_argument(
99
+ "--ignore",
100
+ action="append",
101
+ dest="ignore_ids",
102
+ metavar="ID",
103
+ help="Vulnerability IDs to ignore (can be specified multiple times)",
104
+ )
105
+ parser.add_argument(
106
+ "-o", "--output", metavar="FILE", help="Output file path (defaults to stdout)"
107
+ )
108
+ parser.add_argument(
109
+ "--all",
110
+ action="store_true",
111
+ help="Include ALL dependencies (main + dev, optional, etc)",
112
+ )
113
+ parser.add_argument(
114
+ "--direct-only",
115
+ action="store_true",
116
+ help="Only check direct dependencies (exclude transitive)",
117
+ )
118
+ parser.add_argument("--no-cache", action="store_true", help="Disable caching")
119
+ parser.add_argument("--cache-dir", metavar="DIR", help="Custom cache directory")
120
+ parser.add_argument(
121
+ "--source",
122
+ choices=["pypa", "pypi", "osv"],
123
+ default="pypa",
124
+ help="Vulnerability data source [default: pypa] [possible values: pypa, pypi, osv]",
125
+ )
126
+ parser.add_argument(
127
+ "--resolver",
128
+ choices=["uv", "pip-tools"],
129
+ default="uv",
130
+ help="Dependency resolver for requirements.txt files [default: uv] [possible values: uv, pip-tools]",
131
+ )
132
+ parser.add_argument(
133
+ "--requirements-files",
134
+ nargs="+",
135
+ metavar="FILE",
136
+ help="Specific requirements files to audit (disables auto-discovery)",
137
+ )
138
+ parser.add_argument(
139
+ "-v", "--verbose", action="store_true", help="Enable verbose output"
140
+ )
141
+ parser.add_argument(
142
+ "-q", "--quiet", action="store_true", help="Suppress non-error output"
143
+ )
144
+
145
+ # Add custom help text for commands
146
+ parser.epilog = """
147
+ Commands:
148
+ resolvers Check available dependency resolvers
149
+ check-version Check if a newer version is available
150
+ help Print this message or the help of the given subcommand(s)
151
+ """
152
+
153
+ args = parser.parse_args()
154
+
155
+ try:
156
+ # Main audit functionality - convert --all to dev/optional
157
+ dev = args.all
158
+ optional = args.all
159
+
160
+ result = audit_with_options(
161
+ path=args.path,
162
+ format=args.format,
163
+ source=args.source,
164
+ min_severity=args.severity,
165
+ ignore_ids=args.ignore_ids,
166
+ output=args.output,
167
+ dev=dev,
168
+ optional=optional,
169
+ direct_only=args.direct_only,
170
+ no_cache=args.no_cache,
171
+ cache_dir=args.cache_dir,
172
+ resolver=args.resolver,
173
+ requirements_files=args.requirements_files,
174
+ verbose=args.verbose,
175
+ quiet=args.quiet,
176
+ )
177
+
178
+ if not args.output:
179
+ print(result)
180
+
181
+ except Exception as e:
182
+ print(f"Error: {e}", file=sys.stderr)
183
+ sys.exit(1)
184
+
185
+
186
+ if __name__ == "__main__":
187
+ main()