reqsync 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,78 @@
1
+ # .gitignore
2
+
3
+ # ---------------------
4
+ # Python bytecode/caches
5
+ # ---------------------
6
+ __pycache__/
7
+ *.py[cod]
8
+ *$py.class
9
+ .pyre/
10
+ .pytype/
11
+ .mypy_cache/
12
+ .ruff_cache/
13
+ .pytest_cache/
14
+ .cache/
15
+
16
+ # ---------------------
17
+ # Virtual environments
18
+ # ---------------------
19
+ .venv/
20
+ venv/
21
+ env/
22
+ .conda/
23
+ conda-env/
24
+
25
+ # ---------------------
26
+ # Distribution / packaging
27
+ # ---------------------
28
+ build/
29
+ dist/
30
+ wheelhouse/
31
+ *.egg-info/
32
+ *.egg
33
+ pip-wheel-metadata/
34
+ .installed.cfg
35
+
36
+ # ---------------------
37
+ # Test/coverage artifacts
38
+ # ---------------------
39
+ .coverage
40
+ .coverage.*
41
+ htmlcov/
42
+ coverage.xml
43
+ pytestdebug.log
44
+ .tox/
45
+ .nox/
46
+ .hypothesis/
47
+
48
+ # ---------------------
49
+ # IDE/editor/OS files
50
+ # ---------------------
51
+ .vscode/
52
+ .idea/
53
+ *.iml
54
+ *.code-workspace
55
+ .DS_Store
56
+ Thumbs.db
57
+
58
+ # ---------------------
59
+ # Logs and local env
60
+ # ---------------------
61
+ *.log
62
+ .env
63
+ .env.*
64
+ .envrc
65
+
66
+ # ---------------------
67
+ # Reqsync artifacts/backups
68
+ # ---------------------
69
+ .artifacts/
70
+ *.bak
71
+ *.bak.*
72
+ requirements*.bak
73
+ reqsync-*.tmp
74
+
75
+ # ---------------------
76
+ # Node or misc (in case of mixed repos)
77
+ # ---------------------
78
+ node_modules/
@@ -0,0 +1,68 @@
1
+ # CHANGELOG.md
2
+
3
+ # Changelog
4
+ All notable changes to this project will be documented in this file.
5
+
6
+ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and versions follow [SemVer](https://semver.org/).
7
+ Version numbers are derived from Git tags via `hatch-vcs` (tags must be `vX.Y.Z`).
8
+
9
+ ## [Unreleased]
10
+ ### Planned
11
+ - Per-package cap strategies (next-minor, calendar-based) via config.
12
+ - Git cleanliness guard (block writes on dirty repo unless `--allow-dirty`).
13
+ - Optional pretty console output using `rich`.
14
+
15
+ ---
16
+
17
+ ## [v0.1.0] β€” 2025-08-18
18
+ ### Added
19
+ - Core command `reqsync run` to:
20
+ - Upgrade the active environment with `pip install -U -r <file>` (skippable with `--no-upgrade`).
21
+ - Rewrite requirement lines to **lower-bound** floors (`>= installed_version`) while preserving:
22
+ - extras (`pkg[extra1,extra2]`)
23
+ - markers (`; sys_platform == "win32"`)
24
+ - inline comments and spacing
25
+ - file encoding (BOM) and newline style (LF/CRLF)
26
+ - Backup existing files and perform atomic writes with rollback on failure.
27
+ - **Venv guard**: refuses to run outside a virtualenv by default; override with `--system-ok`.
28
+ - **Safety gates**:
29
+ - Abort if any line contains `--hash=` unless `--allow-hashes` is set (then hashed stanzas are skipped, never edited).
30
+ - Skip VCS/URL/local paths and editables (`-e/--editable`) and all pip directives (`-r`, `-c`, `--index-url`, etc.).
31
+ - File locking with `portalocker` to prevent concurrent edits.
32
+ - **Policy engine**:
33
+ - `lower-bound` (default), `floor-only`, and `floor-and-cap` (cap defaults to next major).
34
+ - Controls for pre/dev and local versions: `--allow-prerelease`, `--keep-local`.
35
+ - **Includes and constraints**:
36
+ - Recursive processing of `-r` includes (on by default).
37
+ - Detect but don’t modify constraint files unless `--update-constraints` is set.
38
+ - Option `--last-wins` to resolve duplicates across included files.
39
+ - **UX & CI**:
40
+ - `--dry-run` with optional `--show-diff` unified diff.
41
+ - `--check` mode exits nonzero if changes would be made (no writes).
42
+ - `--json-report` to emit a machine-readable change log for tooling.
43
+ - Allowlisted `--pip-args` passthrough for indexes/proxies (safe subset only).
44
+ - `--only`/`--exclude` globs to scope which packages are updated.
45
+ - Verbosity flags (`-v`, `-vv`) and optional file logging with secret redaction.
46
+ - **APIs & docs**:
47
+ - Clean Python API: `reqsync.core.sync(Options)` returning a structured `Result`.
48
+ - Docs: USAGE, CONFIG, INTEGRATION. Examples: config presets and minimal API usage.
49
+ - **Tooling & release**:
50
+ - `pyproject.toml` with `hatchling` + `hatch-vcs` dynamic versioning.
51
+ - CI workflow (lint, type-check, test, build, twine check, wheel smoke test).
52
+ - PyPI Trusted Publishing workflow via OIDC (no secrets).
53
+
54
+ ### Fixed
55
+ - N/A. First release.
56
+
57
+ ### Security
58
+ - Redacts common token shapes from logs (index credentials, tokens) by default.
59
+
60
+ ### Known limitations (by design)
61
+ - Does not recompute or update `--hash` lines. Use `pip-compile` if you need hashed lockfiles.
62
+ - Does not manage transitive dependency locks. Pair with a `constraints.txt` if you need determinism.
63
+ - Assumes the active interpreter’s environment is the source of truth.
64
+
65
+ ---
66
+
67
+ [Unreleased]: https://github.com/ImYourBoyRoy/reqsync/compare/v0.1.0...HEAD
68
+ [v0.1.0]: https://github.com/ImYourBoyRoy/reqsync/releases/tag/v0.1.0
reqsync-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 I'm Your Boy Roy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
reqsync-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,298 @@
1
+ Metadata-Version: 2.4
2
+ Name: reqsync
3
+ Version: 0.1.0
4
+ Summary: Synchronize requirements.txt to >= installed versions, safely and atomically.
5
+ Project-URL: Homepage, https://github.com/ImYourBoyRoy/reqsync
6
+ Project-URL: Source, https://github.com/ImYourBoyRoy/reqsync
7
+ Project-URL: Issues, https://github.com/ImYourBoyRoy/reqsync/issues
8
+ Author-email: ImYourBoyRoy <roy.dawson.iv@gmail.com.com>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: automation,dependencies,packaging,pip,requirements,venv
12
+ Classifier: Environment :: Console
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.8
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.8
25
+ Requires-Dist: packaging>=24.1
26
+ Requires-Dist: tomli>=2.0; python_version < '3.11'
27
+ Requires-Dist: typer>=0.12
28
+ Requires-Dist: typing-extensions>=4.7; python_version < '3.11'
29
+ Provides-Extra: dev
30
+ Requires-Dist: build>=1.2.1; extra == 'dev'
31
+ Requires-Dist: mypy>=1.10; extra == 'dev'
32
+ Requires-Dist: pytest>=8.2; extra == 'dev'
33
+ Requires-Dist: ruff>=0.5.0; extra == 'dev'
34
+ Requires-Dist: twine>=5.1; extra == 'dev'
35
+ Provides-Extra: pretty
36
+ Requires-Dist: rich>=13.7; extra == 'pretty'
37
+ Description-Content-Type: text/markdown
38
+
39
+ # 🧩 reqsync
40
+
41
+ [![PyPI Version](https://img.shields.io/pypi/v/reqsync.svg)](https://pypi.org/project/reqsync/)
42
+ [![Python Versions](https://img.shields.io/pypi/pyversions/reqsync.svg)](https://pypi.org/project/reqsync/)
43
+ [![CI Status](https://github.com/ImYourBoyRoy/reqsync/actions/workflows/ci.yml/badge.svg)](https://github.com/ImYourBoyRoy/reqsync/actions/workflows/ci.yml)
44
+ [![License](https://img.shields.io/pypi/l/reqsync.svg)](https://opensource.org/licenses/MIT)
45
+ [![Typing: PEP 561](https://img.shields.io/badge/Typing-PEP%20561-informational.svg)](https://peps.python.org/pep-0561/)
46
+
47
+ > Upgrade a venv and rewrite requirements to `>= installed_version`, safely and atomically. Preserves extras, markers, comments, encoding, and line endings.
48
+
49
+ ---
50
+
51
+ ## ✨ Design goals
52
+
53
+ * **Safety first**
54
+ Refuse outside a venv by default. Abort on `--hash` unless you opt in to skipping those stanzas. Atomic writes with rollback.
55
+
56
+ * **Do one job well**
57
+ Upgrade env, then floor top-level requirements to what’s actually installed. No lockfile management.
58
+
59
+ * **Zero ceremony**
60
+ Works from the CLI without any config. Optional TOML/pyproject config if you want it.
61
+
62
+ * **Agent friendly**
63
+ Clean Python API that returns a structured `Result` for tool-calling, MCP, CrewAI, AG2, etc.
64
+
65
+ ---
66
+
67
+ ## ⭐ Features
68
+
69
+ * Venv guard on by default; `--system-ok` to override.
70
+ * Preserves extras `[a,b]`, markers `; sys_platform != "win32"`, inline comments, encoding (BOM), and newline style (LF/CRLF).
71
+ * Includes recursion: follows `-r other.txt` by default.
72
+ * Constraints awareness: detects `-c constraints.txt` and skips modifying unless `--update-constraints`.
73
+ * Policy modes: `lower-bound` (default), `floor-only`, `floor-and-cap` (`< next major`).
74
+ * Pre/dev handling: `--allow-prerelease` to adopt, `--keep-local` to keep `+local` suffixes.
75
+ * Hash-aware: refuses by default if `--hash` is present; `--allow-hashes` skips those stanzas without editing.
76
+ * File locking with `portalocker`. Backup + atomic replace. Rollback on failure.
77
+ * UX for humans and CI: `--dry-run`, `--show-diff`, `--check`, `--json-report`, `--only/--exclude`.
78
+ * Minimal runtime deps.
79
+
80
+ ---
81
+
82
+ ## πŸš€ Installation
83
+
84
+ ```bash
85
+ pip install reqsync
86
+ ```
87
+
88
+ > Requires Python 3.8+.
89
+
90
+ ---
91
+
92
+ ## πŸ§ͺ Quick start
93
+
94
+ ```bash
95
+ # Activate your venv (required by default)
96
+ source .venv/bin/activate
97
+
98
+ # Preview
99
+ reqsync run --path requirements.txt --dry-run --show-diff
100
+
101
+ # Apply with backup
102
+ reqsync run --path requirements.txt --show-diff
103
+ ```
104
+
105
+ Common variations:
106
+
107
+ ```bash
108
+ # Read-only sync to current env (don’t run pip)
109
+ reqsync run --no-upgrade --show-diff
110
+
111
+ # CI gate: fail if changes would be made
112
+ reqsync run --check --no-upgrade --path requirements.txt
113
+ ```
114
+
115
+ ---
116
+
117
+ ## πŸ› οΈ CLI
118
+
119
+ ```bash
120
+ reqsync run [OPTIONS]
121
+ ```
122
+
123
+ Key options:
124
+
125
+ * `--path PATH` target requirements (default `requirements.txt`)
126
+ * `--follow-includes / --no-follow-includes` follow `-r` recursively (default true)
127
+ * `--update-constraints` allow modifying constraint files (default false)
128
+ * `--policy [lower-bound|floor-only|floor-and-cap]` default `lower-bound`
129
+ * `--allow-prerelease` adopt pre/dev; `--keep-local` keep `+local`
130
+ * `--no-upgrade` skip `pip install -U -r`
131
+ * `--pip-args "..."` allowlisted pip flags (indexes, proxies, `-r`, `-c`)
132
+ * `--only PATTERNS` and `--exclude PATTERNS` scope by canonical names
133
+ * `--check` no writes; exit 11 if changes would be made
134
+ * `--dry-run` no writes; pair with `--show-diff` for unified diff
135
+ * `--json-report FILE` machine-readable changes
136
+ * `--backup-suffix S` `.bak` by default; `--timestamped-backups/--no-timestamped-backups`
137
+ * `--system-ok` allow outside a venv (not recommended)
138
+ * `--allow-hashes` skip hashed stanzas instead of refusing
139
+
140
+ Full option details: see [docs/USAGE.md](docs/USAGE.md).
141
+
142
+ ---
143
+
144
+ ## βš™οΈ Configuration
145
+
146
+ Config is optional. CLI flags always win.
147
+
148
+ Resolution order:
149
+
150
+ 1. CLI flags
151
+ 2. `reqsync.toml` at project root
152
+ 3. `[tool.reqsync]` in `pyproject.toml`
153
+ 4. `reqsync.json`
154
+ 5. Built-in defaults
155
+
156
+ Examples: see [docs/CONFIG.md](docs/CONFIG.md) and `examples/`.
157
+
158
+ ---
159
+
160
+ ## 🧬 Policy modes
161
+
162
+ * **lower-bound**
163
+ Always set `>= installed_version`.
164
+
165
+ * **floor-only**
166
+ Only raise existing lower bounds. If none exists, leave it unchanged.
167
+
168
+ * **floor-and-cap**
169
+ Set `>= installed_version,<next_major`. Useful guardrail in larger teams.
170
+
171
+ ---
172
+
173
+ ## πŸ“ Includes and constraints
174
+
175
+ * `-r` includes are followed (on by default) and processed with the same rules.
176
+ * `-c` constraints are detected but not modified unless you pass `--update-constraints`.
177
+
178
+ ---
179
+
180
+ ## 🧡 Preservation rules
181
+
182
+ * Lines that are comments, directives (`-r`, `-c`, `--index-url`, etc.), `-e/--editable`, VCS/URL/local paths are preserved and not edited.
183
+ * Inline comments are preserved. URLs containing `#` are handled safely.
184
+ * Encoding and newline style are preserved exactly.
185
+
186
+ ---
187
+
188
+ ## πŸ”’ Safety gates
189
+
190
+ * Refuses to run outside a venv unless `--system-ok`.
191
+ * Refuses to edit hashed files (`--hash=`) by default. Use `--allow-hashes` to skip those stanzas instead.
192
+ * File lock prevents concurrent edits. Atomic replace with backup and rollback.
193
+
194
+ ---
195
+
196
+ ## πŸ€– Python API (for agents/tools)
197
+
198
+ ```python
199
+ from pathlib import Path
200
+ from reqsync._types import Options
201
+ from reqsync.core import sync
202
+
203
+ opts = Options(
204
+ path=Path("requirements.txt"),
205
+ follow_includes=True,
206
+ policy="lower-bound",
207
+ dry_run=True,
208
+ show_diff=True,
209
+ no_upgrade=True,
210
+ )
211
+ result = sync(opts)
212
+ print("Changed:", result.changed)
213
+ print(result.diff or "")
214
+ ```
215
+
216
+ More integration patterns: [docs/INTEGRATION.md](docs/INTEGRATION.md).
217
+
218
+ ---
219
+
220
+ ## πŸ“Š Exit codes
221
+
222
+ | Code | Meaning |
223
+ | ---: | ------------------------------------------------- |
224
+ | 0 | Success |
225
+ | 1 | Generic error |
226
+ | 2 | Requirements file not found |
227
+ | 3 | Hashes present without `--allow-hashes` |
228
+ | 4 | Pip upgrade failed |
229
+ | 5 | Parse error |
230
+ | 6 | Constraint conflict detected |
231
+ | 7 | Refused to run outside venv without `--system-ok` |
232
+ | 8 | Repo dirty and guard blocked (if enabled) |
233
+ | 9 | Lock acquisition timeout |
234
+ | 10 | Write failed; backup restored |
235
+ | 11 | `--check` and changes would be made |
236
+
237
+ ---
238
+
239
+ ## πŸ”„ How this compares
240
+
241
+ | Tool | Primary goal | Edits your file | Hash-aware | Lockfile |
242
+ | ---------------- | ----------------------- | ------------------------- | ---------------- | -------- |
243
+ | **reqsync** | Floor to installed (>=) | Yes, preserves formatting | Refuses or skips | No |
244
+ | pip-tools | Deterministic pins | Generates pinned file | Yes | Yes |
245
+ | pip-upgrader/pur | Bump versions | Rewrites pins (==) | No | No |
246
+ | uv/poetry/pdm | Env + lock mgmt | Manage lockfiles | Yes | Yes |
247
+
248
+ Use reqsync when you want your `requirements.txt` to reflect the versions you’re actually running, while keeping future installs flexible.
249
+
250
+ ---
251
+
252
+ ## πŸ“¦ Versioning & release
253
+
254
+ * Version is derived from Git tags via `hatch-vcs`. Tag format: `vX.Y.Z`.
255
+ * Repo: [https://github.com/ImYourBoyRoy/reqsync](https://github.com/ImYourBoyRoy/reqsync)
256
+ * CI: tests, lint, type-check, build, twine metadata check, wheel smoke test.
257
+ * Publishing: PyPI Trusted Publishing via OIDC on tags.
258
+
259
+ ---
260
+
261
+ ## 🧰 Development
262
+
263
+ ```bash
264
+ python -m venv .venv
265
+ source .venv/bin/activate
266
+ pip install -U pip
267
+ pip install -e .[dev]
268
+ pre-commit install
269
+
270
+ pre-commit run -a
271
+ pytest -q
272
+ ruff check .
273
+ ruff format --check .
274
+ mypy src/reqsync
275
+ ```
276
+
277
+ Contributing guidelines: [CONTRIBUTING.md](CONTRIBUTING.md)
278
+ Changelog: [CHANGELOG.md](CHANGELOG.md)
279
+
280
+ ---
281
+
282
+ ## πŸ“š Docs
283
+
284
+ * Usage: [docs/USAGE.md](docs/USAGE.md)
285
+ * Config: [docs/CONFIG.md](docs/CONFIG.md)
286
+ * Integration: [docs/INTEGRATION.md](docs/INTEGRATION.md)
287
+
288
+ ---
289
+
290
+ ## πŸ“œ License
291
+
292
+ MIT. See [LICENSE](LICENSE).
293
+
294
+ ---
295
+
296
+ ## ⭐ Support
297
+
298
+ If this tool helps you, star the repo and share it. Issues and PRs welcome.