depkeeper 0.1.0.dev0__tar.gz → 0.1.0.dev2__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.
- {depkeeper-0.1.0.dev0 → depkeeper-0.1.0.dev2}/PKG-INFO +92 -50
- depkeeper-0.1.0.dev2/README.md +167 -0
- depkeeper-0.1.0.dev2/depkeeper/__init__.py +32 -0
- depkeeper-0.1.0.dev2/depkeeper/__main__.py +45 -0
- depkeeper-0.1.0.dev2/depkeeper/__version__.py +12 -0
- depkeeper-0.1.0.dev2/depkeeper/cli.py +157 -0
- depkeeper-0.1.0.dev2/depkeeper/constants.py +94 -0
- depkeeper-0.1.0.dev2/depkeeper/context.py +37 -0
- depkeeper-0.1.0.dev2/depkeeper/exceptions.py +189 -0
- {depkeeper-0.1.0.dev0 → depkeeper-0.1.0.dev2}/depkeeper.egg-info/PKG-INFO +92 -50
- {depkeeper-0.1.0.dev0 → depkeeper-0.1.0.dev2}/depkeeper.egg-info/SOURCES.txt +4 -0
- depkeeper-0.1.0.dev2/depkeeper.egg-info/requires.txt +26 -0
- {depkeeper-0.1.0.dev0 → depkeeper-0.1.0.dev2}/pyproject.toml +17 -51
- depkeeper-0.1.0.dev0/README.md +0 -123
- depkeeper-0.1.0.dev0/depkeeper/__init__.py +0 -43
- depkeeper-0.1.0.dev0/depkeeper/__main__.py +0 -50
- depkeeper-0.1.0.dev0/depkeeper/__version__.py +0 -72
- depkeeper-0.1.0.dev0/depkeeper.egg-info/requires.txt +0 -28
- {depkeeper-0.1.0.dev0 → depkeeper-0.1.0.dev2}/LICENSE +0 -0
- {depkeeper-0.1.0.dev0 → depkeeper-0.1.0.dev2}/depkeeper.egg-info/dependency_links.txt +0 -0
- {depkeeper-0.1.0.dev0 → depkeeper-0.1.0.dev2}/depkeeper.egg-info/entry_points.txt +0 -0
- {depkeeper-0.1.0.dev0 → depkeeper-0.1.0.dev2}/depkeeper.egg-info/top_level.txt +0 -0
- {depkeeper-0.1.0.dev0 → depkeeper-0.1.0.dev2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: depkeeper
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev2
|
|
4
4
|
Summary: Modern Python dependency management for requirements.txt files
|
|
5
5
|
Author: depkeeper Contributors
|
|
6
6
|
License: Apache-2.0
|
|
@@ -25,33 +25,31 @@ Classifier: Topic :: System :: Software Distribution
|
|
|
25
25
|
Requires-Python: >=3.8
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
License-File: LICENSE
|
|
28
|
-
Requires-Dist: click>=8.1.
|
|
29
|
-
Requires-Dist: packaging>=23.
|
|
30
|
-
Requires-Dist: httpx>=0.24.
|
|
31
|
-
Requires-Dist: rich>=13.
|
|
32
|
-
Requires-Dist: pydantic>=2.0.0
|
|
28
|
+
Requires-Dist: click>=8.1.8
|
|
29
|
+
Requires-Dist: packaging>=23.2
|
|
30
|
+
Requires-Dist: httpx[http2]>=0.24.1
|
|
31
|
+
Requires-Dist: rich>=13.9.4
|
|
33
32
|
Provides-Extra: dev
|
|
34
|
-
Requires-Dist: pytest>=7.4.
|
|
33
|
+
Requires-Dist: pytest>=7.4.4; extra == "dev"
|
|
35
34
|
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
36
|
-
Requires-Dist: pytest-asyncio>=0.
|
|
37
|
-
Requires-Dist: pytest-mock>=3.
|
|
35
|
+
Requires-Dist: pytest-asyncio>=0.23.8; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest-mock>=3.14.1; extra == "dev"
|
|
38
37
|
Requires-Dist: pytest-httpx>=0.22.0; extra == "dev"
|
|
39
|
-
Requires-Dist:
|
|
40
|
-
Requires-Dist: mypy>=1.5.0; extra == "dev"
|
|
38
|
+
Requires-Dist: mypy>=1.14.1; extra == "dev"
|
|
41
39
|
Requires-Dist: types-setuptools; extra == "dev"
|
|
42
|
-
Requires-Dist: pre-commit>=3.
|
|
40
|
+
Requires-Dist: pre-commit>=3.5.0; extra == "dev"
|
|
43
41
|
Provides-Extra: test
|
|
44
|
-
Requires-Dist: pytest>=7.4.
|
|
42
|
+
Requires-Dist: pytest>=7.4.4; extra == "test"
|
|
45
43
|
Requires-Dist: pytest-cov>=4.1.0; extra == "test"
|
|
46
|
-
Requires-Dist: pytest-asyncio>=0.
|
|
47
|
-
Requires-Dist: pytest-mock>=3.
|
|
44
|
+
Requires-Dist: pytest-asyncio>=0.23.8; extra == "test"
|
|
45
|
+
Requires-Dist: pytest-mock>=3.14.1; extra == "test"
|
|
48
46
|
Requires-Dist: pytest-httpx>=0.22.0; extra == "test"
|
|
49
47
|
Provides-Extra: docs
|
|
50
|
-
Requires-Dist: mkdocs>=1.
|
|
51
|
-
Requires-Dist: mkdocs-material>=9.
|
|
52
|
-
Requires-Dist: mkdocstrings[python]>=0.
|
|
48
|
+
Requires-Dist: mkdocs>=1.6.1; extra == "docs"
|
|
49
|
+
Requires-Dist: mkdocs-material>=9.7.1; extra == "docs"
|
|
50
|
+
Requires-Dist: mkdocstrings[python]>=0.26.1; extra == "docs"
|
|
53
51
|
|
|
54
|
-
# depkeeper
|
|
52
|
+
# depkeeper
|
|
55
53
|
|
|
56
54
|
[](https://github.com/rahulkaushal04/depkeeper/actions)
|
|
57
55
|
[](https://codecov.io/gh/rahulkaushal04/depkeeper)
|
|
@@ -60,26 +58,31 @@ Requires-Dist: mkdocstrings[python]>=0.23.0; extra == "docs"
|
|
|
60
58
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
61
59
|
|
|
62
60
|
Modern, intelligent Python dependency management for `requirements.txt` files.
|
|
63
|
-
Keep your dependencies up-to-date
|
|
61
|
+
Keep your dependencies up-to-date and conflict-free — without switching from pip.
|
|
64
62
|
|
|
65
63
|
---
|
|
66
64
|
|
|
67
|
-
##
|
|
65
|
+
## Features
|
|
68
66
|
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
-
|
|
75
|
-
-
|
|
76
|
-
-
|
|
77
|
-
|
|
78
|
-
|
|
67
|
+
- **Smart Version Checking** — discover available package updates with intelligent recommendations
|
|
68
|
+
- **Dependency Conflict Resolution** — detect and resolve version conflicts automatically
|
|
69
|
+
- **Safe Updates** — never cross major version boundaries to prevent breaking changes
|
|
70
|
+
- **Fast & Concurrent** — async PyPI queries for maximum performance
|
|
71
|
+
- **Beautiful CLI** — rich terminal UI with colors & status indicators
|
|
72
|
+
- **Multiple Output Formats** — table, simple text, or JSON for CI/CD integration
|
|
73
|
+
- **Full Requirements Parsing** — PEP 440/508 compliant with support for `-r`, `-c`, VCS URLs, and more
|
|
74
|
+
- **Flexible** — works alongside pip, not instead of it
|
|
75
|
+
|
|
76
|
+
### Coming Soon
|
|
77
|
+
|
|
78
|
+
- **Security Scanning** — detect known vulnerabilities
|
|
79
|
+
- **Lock File Generation** — create reproducible environments
|
|
80
|
+
- **Health Scoring** — measure package quality & maintainability
|
|
81
|
+
- **Format Conversion** — import/export between `requirements.txt`, `pyproject.toml`, Pipfile, and more
|
|
79
82
|
|
|
80
83
|
---
|
|
81
84
|
|
|
82
|
-
##
|
|
85
|
+
## Quick Start
|
|
83
86
|
|
|
84
87
|
### Installation
|
|
85
88
|
|
|
@@ -93,28 +96,69 @@ pip install depkeeper
|
|
|
93
96
|
# Check for available updates
|
|
94
97
|
depkeeper check
|
|
95
98
|
|
|
96
|
-
#
|
|
99
|
+
# Check and show only outdated packages
|
|
100
|
+
depkeeper check --outdated-only
|
|
101
|
+
|
|
102
|
+
# Output as JSON (for CI/CD pipelines)
|
|
103
|
+
depkeeper check --format json
|
|
104
|
+
|
|
105
|
+
# Update all packages to safe versions (within major version)
|
|
97
106
|
depkeeper update
|
|
98
107
|
|
|
99
|
-
#
|
|
100
|
-
depkeeper
|
|
108
|
+
# Preview updates without applying
|
|
109
|
+
depkeeper update --dry-run
|
|
110
|
+
|
|
111
|
+
# Update specific packages only
|
|
112
|
+
depkeeper update -p flask -p requests
|
|
113
|
+
|
|
114
|
+
# Create backup before updating and skip confirmation
|
|
115
|
+
depkeeper update --backup -y
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Commands
|
|
121
|
+
|
|
122
|
+
### `depkeeper check`
|
|
101
123
|
|
|
102
|
-
|
|
103
|
-
depkeeper lock
|
|
124
|
+
Analyze your `requirements.txt` file to identify packages with available updates.
|
|
104
125
|
|
|
105
|
-
|
|
106
|
-
depkeeper
|
|
126
|
+
```bash
|
|
127
|
+
depkeeper check [FILE] [OPTIONS]
|
|
128
|
+
|
|
129
|
+
Options:
|
|
130
|
+
--outdated-only Show only packages with available updates
|
|
131
|
+
-f, --format [table|simple|json]
|
|
132
|
+
Output format (default: table)
|
|
133
|
+
--strict-version-matching Only use exact version pins
|
|
134
|
+
--check-conflicts Check for dependency conflicts (default: enabled)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### `depkeeper update`
|
|
138
|
+
|
|
139
|
+
Update packages to their safe recommended versions (within major version boundaries).
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
depkeeper update [FILE] [OPTIONS]
|
|
143
|
+
|
|
144
|
+
Options:
|
|
145
|
+
--dry-run Preview changes without applying
|
|
146
|
+
-y, --yes Skip confirmation prompt
|
|
147
|
+
--backup Create backup file before updating
|
|
148
|
+
-p, --packages TEXT Update only specific packages (repeatable)
|
|
149
|
+
--strict-version-matching Only use exact version pins
|
|
150
|
+
--check-conflicts Check for conflicts (default: enabled)
|
|
107
151
|
```
|
|
108
152
|
|
|
109
153
|
---
|
|
110
154
|
|
|
111
|
-
##
|
|
155
|
+
## Documentation
|
|
112
156
|
|
|
113
157
|
Full documentation will be available soon at **[https://docs.depkeeper.dev](https://docs.depkeeper.dev)**
|
|
114
158
|
|
|
115
159
|
---
|
|
116
160
|
|
|
117
|
-
##
|
|
161
|
+
## Why depkeeper?
|
|
118
162
|
|
|
119
163
|
Depkeeper bridges the gap between pip’s simplicity and Poetry’s sophistication:
|
|
120
164
|
|
|
@@ -123,12 +167,13 @@ Depkeeper bridges the gap between pip’s simplicity and Poetry’s sophisticati
|
|
|
123
167
|
| simple | powerful | simple + powerful |
|
|
124
168
|
| minimal tooling | strict workflow | flexible workflow |
|
|
125
169
|
| limited dependency checking | strong resolver | strong resolver + update automation |
|
|
170
|
+
| no conflict detection | automatic | automatic with safe boundaries |
|
|
126
171
|
|
|
127
172
|
**Focus on code — let depkeeper handle dependency hygiene.**
|
|
128
173
|
|
|
129
174
|
---
|
|
130
175
|
|
|
131
|
-
##
|
|
176
|
+
## Contributing
|
|
132
177
|
|
|
133
178
|
We welcome contributions of all kinds!
|
|
134
179
|
Please see our **[Contributing Guide](CONTRIBUTING.md)** for details.
|
|
@@ -152,25 +197,22 @@ pre-commit install
|
|
|
152
197
|
|
|
153
198
|
---
|
|
154
199
|
|
|
155
|
-
##
|
|
200
|
+
## License
|
|
156
201
|
|
|
157
202
|
This project is licensed under the **Apache-2.0 License** — see the [LICENSE](LICENSE) file for details.
|
|
158
203
|
|
|
159
204
|
---
|
|
160
205
|
|
|
161
|
-
##
|
|
206
|
+
## Acknowledgments
|
|
162
207
|
|
|
163
208
|
- Built with amazing libraries like **Click**, **Rich**, and **httpx**
|
|
164
209
|
- Inspired by tools such as **pip-tools**, **Poetry**, and **Dependabot**
|
|
165
210
|
|
|
166
211
|
---
|
|
167
212
|
|
|
168
|
-
##
|
|
213
|
+
## Support
|
|
169
214
|
|
|
170
|
-
-
|
|
171
|
-
-
|
|
172
|
-
- 🐞 Issues: [https://github.com/rahulkaushal04/depkeeper/issues](https://github.com/rahulkaushal04/depkeeper/issues)
|
|
215
|
+
- GitHub Discussions: [https://github.com/rahulkaushal04/depkeeper/discussions](https://github.com/rahulkaushal04/depkeeper/discussions)
|
|
216
|
+
- Issues: [https://github.com/rahulkaushal04/depkeeper/issues](https://github.com/rahulkaushal04/depkeeper/issues)
|
|
173
217
|
|
|
174
218
|
---
|
|
175
|
-
|
|
176
|
-
**Made with ❤️ by the depkeeper team**
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# depkeeper
|
|
2
|
+
|
|
3
|
+
[](https://github.com/rahulkaushal04/depkeeper/actions)
|
|
4
|
+
[](https://codecov.io/gh/rahulkaushal04/depkeeper)
|
|
5
|
+
[](https://badge.fury.io/py/depkeeper)
|
|
6
|
+
[](https://pypi.org/project/depkeeper/)
|
|
7
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
8
|
+
|
|
9
|
+
Modern, intelligent Python dependency management for `requirements.txt` files.
|
|
10
|
+
Keep your dependencies up-to-date and conflict-free — without switching from pip.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- **Smart Version Checking** — discover available package updates with intelligent recommendations
|
|
17
|
+
- **Dependency Conflict Resolution** — detect and resolve version conflicts automatically
|
|
18
|
+
- **Safe Updates** — never cross major version boundaries to prevent breaking changes
|
|
19
|
+
- **Fast & Concurrent** — async PyPI queries for maximum performance
|
|
20
|
+
- **Beautiful CLI** — rich terminal UI with colors & status indicators
|
|
21
|
+
- **Multiple Output Formats** — table, simple text, or JSON for CI/CD integration
|
|
22
|
+
- **Full Requirements Parsing** — PEP 440/508 compliant with support for `-r`, `-c`, VCS URLs, and more
|
|
23
|
+
- **Flexible** — works alongside pip, not instead of it
|
|
24
|
+
|
|
25
|
+
### Coming Soon
|
|
26
|
+
|
|
27
|
+
- **Security Scanning** — detect known vulnerabilities
|
|
28
|
+
- **Lock File Generation** — create reproducible environments
|
|
29
|
+
- **Health Scoring** — measure package quality & maintainability
|
|
30
|
+
- **Format Conversion** — import/export between `requirements.txt`, `pyproject.toml`, Pipfile, and more
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
### Installation
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install depkeeper
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Basic Usage
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Check for available updates
|
|
46
|
+
depkeeper check
|
|
47
|
+
|
|
48
|
+
# Check and show only outdated packages
|
|
49
|
+
depkeeper check --outdated-only
|
|
50
|
+
|
|
51
|
+
# Output as JSON (for CI/CD pipelines)
|
|
52
|
+
depkeeper check --format json
|
|
53
|
+
|
|
54
|
+
# Update all packages to safe versions (within major version)
|
|
55
|
+
depkeeper update
|
|
56
|
+
|
|
57
|
+
# Preview updates without applying
|
|
58
|
+
depkeeper update --dry-run
|
|
59
|
+
|
|
60
|
+
# Update specific packages only
|
|
61
|
+
depkeeper update -p flask -p requests
|
|
62
|
+
|
|
63
|
+
# Create backup before updating and skip confirmation
|
|
64
|
+
depkeeper update --backup -y
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Commands
|
|
70
|
+
|
|
71
|
+
### `depkeeper check`
|
|
72
|
+
|
|
73
|
+
Analyze your `requirements.txt` file to identify packages with available updates.
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
depkeeper check [FILE] [OPTIONS]
|
|
77
|
+
|
|
78
|
+
Options:
|
|
79
|
+
--outdated-only Show only packages with available updates
|
|
80
|
+
-f, --format [table|simple|json]
|
|
81
|
+
Output format (default: table)
|
|
82
|
+
--strict-version-matching Only use exact version pins
|
|
83
|
+
--check-conflicts Check for dependency conflicts (default: enabled)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### `depkeeper update`
|
|
87
|
+
|
|
88
|
+
Update packages to their safe recommended versions (within major version boundaries).
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
depkeeper update [FILE] [OPTIONS]
|
|
92
|
+
|
|
93
|
+
Options:
|
|
94
|
+
--dry-run Preview changes without applying
|
|
95
|
+
-y, --yes Skip confirmation prompt
|
|
96
|
+
--backup Create backup file before updating
|
|
97
|
+
-p, --packages TEXT Update only specific packages (repeatable)
|
|
98
|
+
--strict-version-matching Only use exact version pins
|
|
99
|
+
--check-conflicts Check for conflicts (default: enabled)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Documentation
|
|
105
|
+
|
|
106
|
+
Full documentation will be available soon at **[https://docs.depkeeper.dev](https://docs.depkeeper.dev)**
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Why depkeeper?
|
|
111
|
+
|
|
112
|
+
Depkeeper bridges the gap between pip’s simplicity and Poetry’s sophistication:
|
|
113
|
+
|
|
114
|
+
| pip | poetry | depkeeper |
|
|
115
|
+
| --------------------------- | --------------- | ----------------------------------- |
|
|
116
|
+
| simple | powerful | simple + powerful |
|
|
117
|
+
| minimal tooling | strict workflow | flexible workflow |
|
|
118
|
+
| limited dependency checking | strong resolver | strong resolver + update automation |
|
|
119
|
+
| no conflict detection | automatic | automatic with safe boundaries |
|
|
120
|
+
|
|
121
|
+
**Focus on code — let depkeeper handle dependency hygiene.**
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Contributing
|
|
126
|
+
|
|
127
|
+
We welcome contributions of all kinds!
|
|
128
|
+
Please see our **[Contributing Guide](CONTRIBUTING.md)** for details.
|
|
129
|
+
|
|
130
|
+
### Development Setup
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# Clone the repository
|
|
134
|
+
git clone https://github.com/rahulkaushal04/depkeeper.git
|
|
135
|
+
cd depkeeper
|
|
136
|
+
|
|
137
|
+
# Run setup script
|
|
138
|
+
bash scripts/setup_dev.sh
|
|
139
|
+
|
|
140
|
+
# Or manually:
|
|
141
|
+
python -m venv venv
|
|
142
|
+
source venv/bin/activate # Windows: venv\Scripts\activate
|
|
143
|
+
pip install -e ".[dev]"
|
|
144
|
+
pre-commit install
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## License
|
|
150
|
+
|
|
151
|
+
This project is licensed under the **Apache-2.0 License** — see the [LICENSE](LICENSE) file for details.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Acknowledgments
|
|
156
|
+
|
|
157
|
+
- Built with amazing libraries like **Click**, **Rich**, and **httpx**
|
|
158
|
+
- Inspired by tools such as **pip-tools**, **Poetry**, and **Dependabot**
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Support
|
|
163
|
+
|
|
164
|
+
- GitHub Discussions: [https://github.com/rahulkaushal04/depkeeper/discussions](https://github.com/rahulkaushal04/depkeeper/discussions)
|
|
165
|
+
- Issues: [https://github.com/rahulkaushal04/depkeeper/issues](https://github.com/rahulkaushal04/depkeeper/issues)
|
|
166
|
+
|
|
167
|
+
---
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
depkeeper — modern Python dependency management for requirements.txt.
|
|
3
|
+
|
|
4
|
+
depkeeper is an intelligent dependency management tool that helps developers
|
|
5
|
+
keep their ``requirements.txt`` files up to date, secure, and conflict-free.
|
|
6
|
+
|
|
7
|
+
Quick start
|
|
8
|
+
-----------
|
|
9
|
+
Check for available updates::
|
|
10
|
+
|
|
11
|
+
$ depkeeper check
|
|
12
|
+
|
|
13
|
+
Update packages to newer versions::
|
|
14
|
+
|
|
15
|
+
$ depkeeper update
|
|
16
|
+
|
|
17
|
+
Programmatic usage::
|
|
18
|
+
|
|
19
|
+
>>> from depkeeper.core.parser import RequirementsParser
|
|
20
|
+
>>> from depkeeper.core.checker import VersionChecker
|
|
21
|
+
>>> parser = RequirementsParser()
|
|
22
|
+
>>> requirements = parser.parse_file("requirements.txt")
|
|
23
|
+
|
|
24
|
+
For more information, see:
|
|
25
|
+
https://docs.depkeeper.dev
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from __future__ import annotations
|
|
29
|
+
|
|
30
|
+
from depkeeper.__version__ import __version__
|
|
31
|
+
|
|
32
|
+
__all__ = ["__version__"]
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module entry point for depkeeper.
|
|
3
|
+
|
|
4
|
+
This file enables execution via ``python -m depkeeper`` and delegates
|
|
5
|
+
control to the main CLI implementation.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import sys
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def main() -> int:
|
|
14
|
+
"""Entry point for ``python -m depkeeper``.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
Exit code:
|
|
18
|
+
0 Success
|
|
19
|
+
1 Import or runtime error
|
|
20
|
+
130 Interrupted by user
|
|
21
|
+
"""
|
|
22
|
+
try:
|
|
23
|
+
from depkeeper.cli import main as cli_main
|
|
24
|
+
except ImportError as exc:
|
|
25
|
+
_print_startup_error(exc)
|
|
26
|
+
return 1
|
|
27
|
+
|
|
28
|
+
return cli_main()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _print_startup_error(exc: ImportError) -> None:
|
|
32
|
+
"""Print a helpful error message if the CLI cannot be imported."""
|
|
33
|
+
try:
|
|
34
|
+
from depkeeper.__version__ import __version__
|
|
35
|
+
|
|
36
|
+
sys.stderr.write(f"depkeeper version: {__version__}\n")
|
|
37
|
+
except Exception:
|
|
38
|
+
sys.stderr.write("depkeeper version: <unknown>\n")
|
|
39
|
+
|
|
40
|
+
sys.stderr.write("\n")
|
|
41
|
+
sys.stderr.write(f"ImportError: {exc}\n")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
if __name__ == "__main__":
|
|
45
|
+
sys.exit(main())
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Version information for depkeeper.
|
|
3
|
+
|
|
4
|
+
This module exposes the canonical version string for the depkeeper
|
|
5
|
+
package. It is intentionally isolated to avoid import cycles and to
|
|
6
|
+
allow tools (CLI, packaging, docs) to query the version reliably.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
#: Current depkeeper version (PEP 440 compliant).
|
|
12
|
+
__version__: str = "0.1.0.dev2"
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Command-line interface for depkeeper.
|
|
3
|
+
|
|
4
|
+
This module defines the main Click entry point, global options, command
|
|
5
|
+
registration, and top-level error handling for the depkeeper CLI.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
import sys
|
|
12
|
+
import logging
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Optional
|
|
15
|
+
|
|
16
|
+
import click
|
|
17
|
+
|
|
18
|
+
from depkeeper.__version__ import __version__
|
|
19
|
+
from depkeeper.context import DepKeeperContext
|
|
20
|
+
from depkeeper.exceptions import DepKeeperError
|
|
21
|
+
from depkeeper.utils.console import print_error, print_warning
|
|
22
|
+
from depkeeper.utils.logger import get_logger, setup_logging
|
|
23
|
+
|
|
24
|
+
logger = get_logger("cli")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@click.group(context_settings={"help_option_names": ["-h", "--help"]})
|
|
28
|
+
@click.option(
|
|
29
|
+
"--config",
|
|
30
|
+
"-c",
|
|
31
|
+
type=click.Path(exists=True, dir_okay=False, path_type=Path),
|
|
32
|
+
help="Path to configuration file.",
|
|
33
|
+
envvar="DEPKEEPER_CONFIG",
|
|
34
|
+
)
|
|
35
|
+
@click.option(
|
|
36
|
+
"--verbose",
|
|
37
|
+
"-v",
|
|
38
|
+
count=True,
|
|
39
|
+
help="Increase verbosity (can be repeated: -v, -vv).",
|
|
40
|
+
)
|
|
41
|
+
@click.option(
|
|
42
|
+
"--color/--no-color",
|
|
43
|
+
default=True,
|
|
44
|
+
help="Enable or disable colored output.",
|
|
45
|
+
envvar="DEPKEEPER_COLOR",
|
|
46
|
+
)
|
|
47
|
+
@click.version_option(
|
|
48
|
+
version=__version__,
|
|
49
|
+
prog_name="depkeeper",
|
|
50
|
+
message="%(prog)s %(version)s",
|
|
51
|
+
)
|
|
52
|
+
@click.pass_context
|
|
53
|
+
def cli(
|
|
54
|
+
ctx: click.Context,
|
|
55
|
+
config: Optional[Path],
|
|
56
|
+
verbose: int,
|
|
57
|
+
color: bool,
|
|
58
|
+
) -> None:
|
|
59
|
+
"""depkeeper — modern dependency management for requirements.txt files.
|
|
60
|
+
|
|
61
|
+
\b
|
|
62
|
+
Available commands:
|
|
63
|
+
depkeeper check Check for available updates
|
|
64
|
+
depkeeper update Update packages to newer versions
|
|
65
|
+
|
|
66
|
+
\b
|
|
67
|
+
Examples:
|
|
68
|
+
depkeeper check
|
|
69
|
+
depkeeper update
|
|
70
|
+
depkeeper -v check
|
|
71
|
+
|
|
72
|
+
Use ``depkeeper COMMAND --help`` for command-specific options.
|
|
73
|
+
"""
|
|
74
|
+
_configure_logging(verbose)
|
|
75
|
+
|
|
76
|
+
depkeeper_ctx = DepKeeperContext()
|
|
77
|
+
depkeeper_ctx.config_path = config
|
|
78
|
+
depkeeper_ctx.verbose = verbose
|
|
79
|
+
depkeeper_ctx.color = color
|
|
80
|
+
ctx.obj = depkeeper_ctx
|
|
81
|
+
|
|
82
|
+
# Respect NO_COLOR for downstream libraries
|
|
83
|
+
if color:
|
|
84
|
+
os.environ.pop("NO_COLOR", None)
|
|
85
|
+
else:
|
|
86
|
+
os.environ["NO_COLOR"] = "1"
|
|
87
|
+
|
|
88
|
+
logger.debug("depkeeper v%s", __version__)
|
|
89
|
+
logger.debug("Config path: %s", config)
|
|
90
|
+
logger.debug("Verbosity: %s | Color: %s", verbose, color)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _configure_logging(verbose: int) -> None:
|
|
94
|
+
"""Configure logging level based on verbosity flags."""
|
|
95
|
+
if verbose <= 0:
|
|
96
|
+
level = logging.WARNING
|
|
97
|
+
elif verbose == 1:
|
|
98
|
+
level = logging.INFO
|
|
99
|
+
else:
|
|
100
|
+
level = logging.DEBUG
|
|
101
|
+
|
|
102
|
+
setup_logging(level=level)
|
|
103
|
+
logger.debug("Logging initialized at %s level", logging.getLevelName(level))
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
# Register CLI subcommands
|
|
107
|
+
try:
|
|
108
|
+
from depkeeper.commands.check import check
|
|
109
|
+
from depkeeper.commands.update import update
|
|
110
|
+
|
|
111
|
+
cli.add_command(check)
|
|
112
|
+
cli.add_command(update)
|
|
113
|
+
|
|
114
|
+
except ImportError as exc:
|
|
115
|
+
sys.stderr.write(f"FATAL: Failed to import CLI commands: {exc}\n")
|
|
116
|
+
sys.exit(1)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def main() -> int:
|
|
120
|
+
"""Main entry point for the depkeeper CLI.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
Exit code:
|
|
124
|
+
0 Success
|
|
125
|
+
1 Unhandled or application error
|
|
126
|
+
2 Usage error (Click)
|
|
127
|
+
130 Interrupted by user (Ctrl+C)
|
|
128
|
+
"""
|
|
129
|
+
try:
|
|
130
|
+
cli(standalone_mode=False)
|
|
131
|
+
return 0
|
|
132
|
+
|
|
133
|
+
except click.ClickException as exc:
|
|
134
|
+
exc.show()
|
|
135
|
+
return exc.exit_code
|
|
136
|
+
|
|
137
|
+
except DepKeeperError as exc:
|
|
138
|
+
print_error(str(exc))
|
|
139
|
+
logger.debug(
|
|
140
|
+
"DepKeeperError details: %s",
|
|
141
|
+
exc.details or "<none>",
|
|
142
|
+
exc_info=True,
|
|
143
|
+
)
|
|
144
|
+
return 1
|
|
145
|
+
|
|
146
|
+
except KeyboardInterrupt:
|
|
147
|
+
print_warning("\nOperation cancelled by user")
|
|
148
|
+
return 130
|
|
149
|
+
|
|
150
|
+
except Exception as exc:
|
|
151
|
+
print_error(f"Unexpected error: {exc}")
|
|
152
|
+
logger.exception("Unhandled exception in CLI")
|
|
153
|
+
return 1
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
if __name__ == "__main__":
|
|
157
|
+
sys.exit(main())
|