renovate-apply 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,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Julio Batista Silva
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.
@@ -0,0 +1,219 @@
1
+ Metadata-Version: 2.4
2
+ Name: renovate-apply
3
+ Version: 0.1.0
4
+ Summary: Apply the dependency updates Renovate finds, locally, without a pull request
5
+ Keywords: renovate,dependencies,updates,cli,docker,pre-commit,github-actions
6
+ Author: Julio Batista Silva
7
+ Author-email: Julio Batista Silva <python@juliobs.com>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Natural Language :: English
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.15
16
+ Classifier: Topic :: Software Development :: Build Tools
17
+ Classifier: Topic :: Software Development :: Version Control :: Git
18
+ Classifier: Topic :: System :: Software Distribution
19
+ Requires-Dist: cyclopts>=5.2.0
20
+ Requires-Dist: rich>=15.0.0
21
+ Requires-Python: >=3.15, <4
22
+ Project-URL: Documentation, https://jbsilva.github.io/renovate-apply/
23
+ Project-URL: Repository, https://github.com/jbsilva/renovate-apply
24
+ Project-URL: Issues, https://github.com/jbsilva/renovate-apply/issues
25
+ Description-Content-Type: text/markdown
26
+
27
+ # renovate-apply
28
+
29
+ [![MIT License](https://img.shields.io/badge/license-MIT-007EC7.svg?style=flat-square)](https://github.com/jbsilva/renovate-apply/blob/main/LICENSE)
30
+ [![Python 3.15+](https://img.shields.io/badge/python-3.15+-blue.svg?style=flat-square)](https://www.python.org/downloads/)
31
+ [![PyPI version](https://img.shields.io/pypi/v/renovate-apply.svg?style=flat-square)](https://pypi.org/project/renovate-apply)
32
+ [![Documentation](https://img.shields.io/badge/docs-jbsilva.github.io-blue.svg?style=flat-square)](https://jbsilva.github.io/renovate-apply/)
33
+ [![tests](https://github.com/jbsilva/renovate-apply/actions/workflows/tests.yml/badge.svg)](https://github.com/jbsilva/renovate-apply/actions/workflows/tests.yml)
34
+ [![CodeQL](https://github.com/jbsilva/renovate-apply/actions/workflows/codeql.yml/badge.svg)](https://github.com/jbsilva/renovate-apply/actions/workflows/codeql.yml)
35
+ [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=jbsilva_renovate-apply&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=jbsilva_renovate-apply)
36
+ [![codecov](https://codecov.io/github/jbsilva/renovate-apply/graph/badge.svg)](https://codecov.io/github/jbsilva/renovate-apply)
37
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
38
+ [![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
39
+ [![prek](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/j178/prek/master/docs/assets/badge-v0.json)](https://github.com/j178/prek)
40
+
41
+ Apply the dependency updates [Renovate](https://docs.renovatebot.com) finds, in your working copy,
42
+ without a pull request. One commit per group, the same grouping your Renovate configuration gives a
43
+ pull request. Nothing is pushed.
44
+
45
+ **Full documentation:** <https://jbsilva.github.io/renovate-apply/>
46
+
47
+ ```console
48
+ $ rnv
49
+ renovate-apply: scanning /home/you/infra ...
50
+ applied deps: update the atuin images
51
+ ghcr.io/atuinsh/atuin v18.13.3 -> 18.22.0
52
+ postgres 18-alpine, new digest
53
+ applied deps: update the hook revs
54
+ astral-sh/ruff-pre-commit v0.16.5 -> v0.16.8
55
+ crate-ci/typos v1.50.1 -> v1.50.2
56
+
57
+ Committed. Nothing is pushed.
58
+ ```
59
+
60
+ ## Why this exists
61
+
62
+ Renovate can read a local working copy. `renovate --platform=local` finds every pending update and
63
+ reports it. It cannot write one: the local platform turns the run into a lookup-only dry run as it
64
+ starts, so the run ends after the lookup, before the step that edits a file. No flag turns that off,
65
+ because the clamp is inside the platform, not in the configuration.
66
+
67
+ So the updates Renovate finds on your laptop can only be applied by hand, or by merging the pull
68
+ requests it opens on the server. This tool is the missing half: it runs that same scan, reads the
69
+ JSON report, and makes the replacement the report describes for each update.
70
+
71
+ The edit is not guesswork. For every dependency, the report carries `replaceString`, the exact text
72
+ the manager found in the file, and `autoReplaceStringTemplate`, how to write that text again with
73
+ the new version or digest in it. That pair is Renovate's own auto-replace, handed over as data.
74
+
75
+ ## Highlights
76
+
77
+ - Works with everything Renovate's own managers report: image tags and digests in compose files and
78
+ Dockerfiles, GitHub Actions SHA pins with their version comment, pre-commit and prek hook revs,
79
+ versions matched by a custom regex manager, and the rest
80
+ - One commit per Renovate branch, so a grouped pull request and a local run produce the same commits
81
+ - Refreshes `uv.lock` when it raises a floor in `pyproject.toml`, and commits the two together, the
82
+ way Renovate's own pull request carries them
83
+ - Reads your repository's Renovate configuration by running Renovate itself, so grouping, holds,
84
+ package rules and versioning schemes all apply without being restated here
85
+ - Holds every major back until you ask for it
86
+ - Never skips your git hooks, and never commits anything it did not write
87
+ - Never leaves a `pyproject.toml` that does not lock: such a group is undone and held back
88
+ - `--dry-run` to read first, `--no-commit` or `--stage` to review everything at once
89
+
90
+ ## Requirements
91
+
92
+ - Python 3.15+
93
+ - `git`
94
+ - Either `renovate` on `PATH` (`npm i -g renovate`) or Node.js, for `npx` to fetch it
95
+ - Optional: [`gh`](https://cli.github.com), logged in, or `GITHUB_TOKEN` in the environment. Without
96
+ a token, everything Renovate looks up on GitHub is rate limited, and updates can silently go
97
+ missing. Prefer either to `--token`, which puts the token in argv and in your shell history.
98
+
99
+ ## Installation
100
+
101
+ ```sh
102
+ uv tool install renovate-apply
103
+ ```
104
+
105
+ Or run it without installing:
106
+
107
+ ```sh
108
+ uvx renovate-apply --dry-run
109
+ ```
110
+
111
+ ## Usage
112
+
113
+ ```console
114
+ $ renovate-apply --help
115
+ ```
116
+
117
+ | Command | What it does |
118
+ | ----------------------------- | --------------------------------------------------------- |
119
+ | `rnv` | Scan, apply, one commit per group |
120
+ | `rnv --dry-run` | Say what would change and write nothing |
121
+ | `rnv --no-commit` | Write the files and stop, for one review of everything |
122
+ | `rnv --stage` | Write and stage the files, and commit nothing |
123
+ | `rnv --major` | Include the major updates, which are held back by default |
124
+ | `rnv --skip python` | Hold a dependency back by name, as a glob, repeatable |
125
+ | `rnv --prefix "build(deps):"` | Set the first word of every commit subject |
126
+ | `rnv --no-lock` | Do not refresh `uv.lock` after editing a `pyproject.toml` |
127
+ | `rnv ~/code/other-repo` | Work on another repository |
128
+
129
+ `renovate-apply` and `rnv` are the same command.
130
+
131
+ The working copy must be clean before a run that commits: a commit takes the whole index, not only
132
+ the files this staged, so anything else in flight would be swept into a dependency commit.
133
+
134
+ ### Commit messages
135
+
136
+ The subject says what a person needs in `git log --oneline`; the body lists the group, aligned:
137
+
138
+ ```text
139
+ deps: update the action pins
140
+
141
+ astral-sh/setup-uv v10.1.0 -> v10.2.0
142
+ github/codeql-action v4.38.0 -> v4.38.2
143
+ docker/setup-buildx-action v4.3.0 -> v4.4.1
144
+ actions/upload-artifact v7.0.1 -> v7.0.2
145
+ ```
146
+
147
+ Match `--prefix` to what your `renovate.json5` writes, so local commits and merged pull requests
148
+ read alike: `deps:` for `commitMessagePrefix`, `build(deps):` for semantic commits.
149
+
150
+ ### Per-repository defaults
151
+
152
+ Any option can be set once, in the `pyproject.toml` of the repository being updated:
153
+
154
+ ```toml
155
+ [tool.renovate-apply]
156
+ prefix = "build(deps):"
157
+ skip = ["python"]
158
+ ```
159
+
160
+ The file is read from the directory being updated, so `rnv ~/code/other-repo` takes that
161
+ repository's settings and not those of wherever you happen to be standing. Only that directory is
162
+ read, never a parent of it, and a flag typed for one run wins over the file.
163
+
164
+ A repository without a `pyproject.toml` (an infrastructure repository, say) passes the flags
165
+ instead.
166
+
167
+ ## What is held back
168
+
169
+ Nothing is applied silently past a hold. Whatever is held is listed at the end of the run, with the
170
+ reason:
171
+
172
+ - **Majors**, unless `--major`. Renovate can be configured to send some majors to the dependency
173
+ dashboard to be approved by hand. The report does not say which ones carry that flag, so holding
174
+ every major is the only reading that cannot contradict your configuration.
175
+ - **Updates Renovate would not open yet**, the ones still waiting out `minimumReleaseAge`. A
176
+ security fix bypasses that hold in Renovate, and bypasses it here too.
177
+ - **Renames**, where Renovate wants to replace a dependency with a different one. That edit is not a
178
+ version bump, and this tool does not write it.
179
+ - **Lock file updates**, where the range in the manifest already allows the new version, so only the
180
+ lock file beside it moves. There is no edit to make in the package file, and moving the lock file
181
+ takes that package manager. Only `uv.lock` is refreshed here, after an edit to its manifest.
182
+ - **Updates that do not lock**, where `uv lock` finds no solution for the new floor in
183
+ `pyproject.toml`. The group is undone, `uv.lock` included, and uv's explanation is printed.
184
+ - **A line two managers found**, when a regex manager in your Renovate configuration matches a line
185
+ a built-in manager also reads. Renovate reports the line twice. The first update makes the edit,
186
+ and the second is listed with it.
187
+ - **Anything named in `--skip`**, as a glob. That is the answer to the blind spot above on an update
188
+ that is not a major: a repository that keeps `requires-python` on the dependency dashboard writes
189
+ `skip = ["python"]` once and stops being asked.
190
+
191
+ ## Limits
192
+
193
+ - **`dependencyDashboardApproval` is invisible.** Renovate resolves it per package and the report
194
+ does not carry it, so this tool cannot see which updates your configuration wants approved by
195
+ hand. Holding every major covers the usual case; `--skip` covers the rest.
196
+ - **Lock files: uv only.** A `pyproject.toml` with a `uv.lock` beside it is relocked and committed
197
+ together. Any other package manager's lock file is left untouched, so run its update yourself.
198
+ - **Renovate's lock file maintenance is not applied.** Those branches carry no dependency updates,
199
+ so they are not in the report at all.
200
+ - **A group that cannot be applied is reported and passed over.** The groups after it are still
201
+ applied and committed, and the run ends non-zero. Only a failure before the first group, such as a
202
+ scan that did not run or a working copy that is not clean, ends the run with nothing done.
203
+ - The scan is a full Renovate run, so it takes as long as Renovate takes, usually under a minute.
204
+ - A dependency Renovate cannot look up is one this cannot apply. Everything upstream of the report
205
+ is Renovate's own behavior, configuration included.
206
+ - This writes files and commits. It never pushes, never merges and never deploys.
207
+
208
+ ## Development
209
+
210
+ ```sh
211
+ uv sync --group dev --group test
212
+ uv run pytest
213
+ uv run poe check
214
+ uv run poe docs # preview the documentation site
215
+ ```
216
+
217
+ ## License
218
+
219
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,193 @@
1
+ # renovate-apply
2
+
3
+ [![MIT License](https://img.shields.io/badge/license-MIT-007EC7.svg?style=flat-square)](https://github.com/jbsilva/renovate-apply/blob/main/LICENSE)
4
+ [![Python 3.15+](https://img.shields.io/badge/python-3.15+-blue.svg?style=flat-square)](https://www.python.org/downloads/)
5
+ [![PyPI version](https://img.shields.io/pypi/v/renovate-apply.svg?style=flat-square)](https://pypi.org/project/renovate-apply)
6
+ [![Documentation](https://img.shields.io/badge/docs-jbsilva.github.io-blue.svg?style=flat-square)](https://jbsilva.github.io/renovate-apply/)
7
+ [![tests](https://github.com/jbsilva/renovate-apply/actions/workflows/tests.yml/badge.svg)](https://github.com/jbsilva/renovate-apply/actions/workflows/tests.yml)
8
+ [![CodeQL](https://github.com/jbsilva/renovate-apply/actions/workflows/codeql.yml/badge.svg)](https://github.com/jbsilva/renovate-apply/actions/workflows/codeql.yml)
9
+ [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=jbsilva_renovate-apply&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=jbsilva_renovate-apply)
10
+ [![codecov](https://codecov.io/github/jbsilva/renovate-apply/graph/badge.svg)](https://codecov.io/github/jbsilva/renovate-apply)
11
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
12
+ [![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
13
+ [![prek](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/j178/prek/master/docs/assets/badge-v0.json)](https://github.com/j178/prek)
14
+
15
+ Apply the dependency updates [Renovate](https://docs.renovatebot.com) finds, in your working copy,
16
+ without a pull request. One commit per group, the same grouping your Renovate configuration gives a
17
+ pull request. Nothing is pushed.
18
+
19
+ **Full documentation:** <https://jbsilva.github.io/renovate-apply/>
20
+
21
+ ```console
22
+ $ rnv
23
+ renovate-apply: scanning /home/you/infra ...
24
+ applied deps: update the atuin images
25
+ ghcr.io/atuinsh/atuin v18.13.3 -> 18.22.0
26
+ postgres 18-alpine, new digest
27
+ applied deps: update the hook revs
28
+ astral-sh/ruff-pre-commit v0.16.5 -> v0.16.8
29
+ crate-ci/typos v1.50.1 -> v1.50.2
30
+
31
+ Committed. Nothing is pushed.
32
+ ```
33
+
34
+ ## Why this exists
35
+
36
+ Renovate can read a local working copy. `renovate --platform=local` finds every pending update and
37
+ reports it. It cannot write one: the local platform turns the run into a lookup-only dry run as it
38
+ starts, so the run ends after the lookup, before the step that edits a file. No flag turns that off,
39
+ because the clamp is inside the platform, not in the configuration.
40
+
41
+ So the updates Renovate finds on your laptop can only be applied by hand, or by merging the pull
42
+ requests it opens on the server. This tool is the missing half: it runs that same scan, reads the
43
+ JSON report, and makes the replacement the report describes for each update.
44
+
45
+ The edit is not guesswork. For every dependency, the report carries `replaceString`, the exact text
46
+ the manager found in the file, and `autoReplaceStringTemplate`, how to write that text again with
47
+ the new version or digest in it. That pair is Renovate's own auto-replace, handed over as data.
48
+
49
+ ## Highlights
50
+
51
+ - Works with everything Renovate's own managers report: image tags and digests in compose files and
52
+ Dockerfiles, GitHub Actions SHA pins with their version comment, pre-commit and prek hook revs,
53
+ versions matched by a custom regex manager, and the rest
54
+ - One commit per Renovate branch, so a grouped pull request and a local run produce the same commits
55
+ - Refreshes `uv.lock` when it raises a floor in `pyproject.toml`, and commits the two together, the
56
+ way Renovate's own pull request carries them
57
+ - Reads your repository's Renovate configuration by running Renovate itself, so grouping, holds,
58
+ package rules and versioning schemes all apply without being restated here
59
+ - Holds every major back until you ask for it
60
+ - Never skips your git hooks, and never commits anything it did not write
61
+ - Never leaves a `pyproject.toml` that does not lock: such a group is undone and held back
62
+ - `--dry-run` to read first, `--no-commit` or `--stage` to review everything at once
63
+
64
+ ## Requirements
65
+
66
+ - Python 3.15+
67
+ - `git`
68
+ - Either `renovate` on `PATH` (`npm i -g renovate`) or Node.js, for `npx` to fetch it
69
+ - Optional: [`gh`](https://cli.github.com), logged in, or `GITHUB_TOKEN` in the environment. Without
70
+ a token, everything Renovate looks up on GitHub is rate limited, and updates can silently go
71
+ missing. Prefer either to `--token`, which puts the token in argv and in your shell history.
72
+
73
+ ## Installation
74
+
75
+ ```sh
76
+ uv tool install renovate-apply
77
+ ```
78
+
79
+ Or run it without installing:
80
+
81
+ ```sh
82
+ uvx renovate-apply --dry-run
83
+ ```
84
+
85
+ ## Usage
86
+
87
+ ```console
88
+ $ renovate-apply --help
89
+ ```
90
+
91
+ | Command | What it does |
92
+ | ----------------------------- | --------------------------------------------------------- |
93
+ | `rnv` | Scan, apply, one commit per group |
94
+ | `rnv --dry-run` | Say what would change and write nothing |
95
+ | `rnv --no-commit` | Write the files and stop, for one review of everything |
96
+ | `rnv --stage` | Write and stage the files, and commit nothing |
97
+ | `rnv --major` | Include the major updates, which are held back by default |
98
+ | `rnv --skip python` | Hold a dependency back by name, as a glob, repeatable |
99
+ | `rnv --prefix "build(deps):"` | Set the first word of every commit subject |
100
+ | `rnv --no-lock` | Do not refresh `uv.lock` after editing a `pyproject.toml` |
101
+ | `rnv ~/code/other-repo` | Work on another repository |
102
+
103
+ `renovate-apply` and `rnv` are the same command.
104
+
105
+ The working copy must be clean before a run that commits: a commit takes the whole index, not only
106
+ the files this staged, so anything else in flight would be swept into a dependency commit.
107
+
108
+ ### Commit messages
109
+
110
+ The subject says what a person needs in `git log --oneline`; the body lists the group, aligned:
111
+
112
+ ```text
113
+ deps: update the action pins
114
+
115
+ astral-sh/setup-uv v10.1.0 -> v10.2.0
116
+ github/codeql-action v4.38.0 -> v4.38.2
117
+ docker/setup-buildx-action v4.3.0 -> v4.4.1
118
+ actions/upload-artifact v7.0.1 -> v7.0.2
119
+ ```
120
+
121
+ Match `--prefix` to what your `renovate.json5` writes, so local commits and merged pull requests
122
+ read alike: `deps:` for `commitMessagePrefix`, `build(deps):` for semantic commits.
123
+
124
+ ### Per-repository defaults
125
+
126
+ Any option can be set once, in the `pyproject.toml` of the repository being updated:
127
+
128
+ ```toml
129
+ [tool.renovate-apply]
130
+ prefix = "build(deps):"
131
+ skip = ["python"]
132
+ ```
133
+
134
+ The file is read from the directory being updated, so `rnv ~/code/other-repo` takes that
135
+ repository's settings and not those of wherever you happen to be standing. Only that directory is
136
+ read, never a parent of it, and a flag typed for one run wins over the file.
137
+
138
+ A repository without a `pyproject.toml` (an infrastructure repository, say) passes the flags
139
+ instead.
140
+
141
+ ## What is held back
142
+
143
+ Nothing is applied silently past a hold. Whatever is held is listed at the end of the run, with the
144
+ reason:
145
+
146
+ - **Majors**, unless `--major`. Renovate can be configured to send some majors to the dependency
147
+ dashboard to be approved by hand. The report does not say which ones carry that flag, so holding
148
+ every major is the only reading that cannot contradict your configuration.
149
+ - **Updates Renovate would not open yet**, the ones still waiting out `minimumReleaseAge`. A
150
+ security fix bypasses that hold in Renovate, and bypasses it here too.
151
+ - **Renames**, where Renovate wants to replace a dependency with a different one. That edit is not a
152
+ version bump, and this tool does not write it.
153
+ - **Lock file updates**, where the range in the manifest already allows the new version, so only the
154
+ lock file beside it moves. There is no edit to make in the package file, and moving the lock file
155
+ takes that package manager. Only `uv.lock` is refreshed here, after an edit to its manifest.
156
+ - **Updates that do not lock**, where `uv lock` finds no solution for the new floor in
157
+ `pyproject.toml`. The group is undone, `uv.lock` included, and uv's explanation is printed.
158
+ - **A line two managers found**, when a regex manager in your Renovate configuration matches a line
159
+ a built-in manager also reads. Renovate reports the line twice. The first update makes the edit,
160
+ and the second is listed with it.
161
+ - **Anything named in `--skip`**, as a glob. That is the answer to the blind spot above on an update
162
+ that is not a major: a repository that keeps `requires-python` on the dependency dashboard writes
163
+ `skip = ["python"]` once and stops being asked.
164
+
165
+ ## Limits
166
+
167
+ - **`dependencyDashboardApproval` is invisible.** Renovate resolves it per package and the report
168
+ does not carry it, so this tool cannot see which updates your configuration wants approved by
169
+ hand. Holding every major covers the usual case; `--skip` covers the rest.
170
+ - **Lock files: uv only.** A `pyproject.toml` with a `uv.lock` beside it is relocked and committed
171
+ together. Any other package manager's lock file is left untouched, so run its update yourself.
172
+ - **Renovate's lock file maintenance is not applied.** Those branches carry no dependency updates,
173
+ so they are not in the report at all.
174
+ - **A group that cannot be applied is reported and passed over.** The groups after it are still
175
+ applied and committed, and the run ends non-zero. Only a failure before the first group, such as a
176
+ scan that did not run or a working copy that is not clean, ends the run with nothing done.
177
+ - The scan is a full Renovate run, so it takes as long as Renovate takes, usually under a minute.
178
+ - A dependency Renovate cannot look up is one this cannot apply. Everything upstream of the report
179
+ is Renovate's own behavior, configuration included.
180
+ - This writes files and commits. It never pushes, never merges and never deploys.
181
+
182
+ ## Development
183
+
184
+ ```sh
185
+ uv sync --group dev --group test
186
+ uv run pytest
187
+ uv run poe check
188
+ uv run poe docs # preview the documentation site
189
+ ```
190
+
191
+ ## License
192
+
193
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,244 @@
1
+ [project]
2
+ name = "renovate-apply"
3
+ version = "0.1.0"
4
+ description = "Apply the dependency updates Renovate finds, locally, without a pull request"
5
+ readme = "README.md"
6
+ requires-python = ">=3.15,<4"
7
+ license = "MIT"
8
+ license-files = ["LICENSE"]
9
+ keywords = [
10
+ "renovate",
11
+ "dependencies",
12
+ "updates",
13
+ "cli",
14
+ "docker",
15
+ "pre-commit",
16
+ "github-actions",
17
+ ]
18
+ classifiers = [
19
+ "Development Status :: 4 - Beta",
20
+ "Environment :: Console",
21
+ "Intended Audience :: Developers",
22
+ "Natural Language :: English",
23
+ "Programming Language :: Python :: 3",
24
+ "Programming Language :: Python :: 3.15",
25
+ "Topic :: Software Development :: Build Tools",
26
+ "Topic :: Software Development :: Version Control :: Git",
27
+ "Topic :: System :: Software Distribution",
28
+ ]
29
+ dependencies = [
30
+ "cyclopts>=5.2.0",
31
+ "rich>=15.0.0",
32
+ ]
33
+
34
+ [[project.authors]]
35
+ name = "Julio Batista Silva"
36
+ email = "python@juliobs.com"
37
+
38
+ [project.urls]
39
+ Documentation = "https://jbsilva.github.io/renovate-apply/"
40
+ Repository = "https://github.com/jbsilva/renovate-apply"
41
+ Issues = "https://github.com/jbsilva/renovate-apply/issues"
42
+
43
+ [project.scripts]
44
+ renovate-apply = "renovate_apply.main:main"
45
+ rnv = "renovate_apply.main:main"
46
+
47
+ [dependency-groups]
48
+ dev = [
49
+ "bandit>=1.9.4",
50
+ "poethepoet>=0.48.0",
51
+ "pycroscope>=0.5.0",
52
+ "ruff>=0.17.0",
53
+ "ty>=0.0.85",
54
+ "zizmor>=1.30.1",
55
+ "zuban>=0.10.0",
56
+ ]
57
+ docs = ["zensical>=0.0.69"]
58
+ test = [
59
+ "pytest-cov>=7.1.0",
60
+ "pytest-random-order>=1.2.0",
61
+ "pytest-xdist[psutil]>=3.8.0",
62
+ "pytest>=9.1.1",
63
+ ]
64
+
65
+ [tool.uv]
66
+ default-groups = [
67
+ "dev",
68
+ "test",
69
+ ]
70
+ exclude-newer = "1 day"
71
+
72
+ [tool.uv.exclude-newer-package]
73
+ cyclopts = "6 hours"
74
+ ruff = "6 hours"
75
+ zensical = "6 hours"
76
+ zuban = "6 hours"
77
+
78
+ [tool.poe.executor]
79
+ type = "uv"
80
+
81
+ [tool.poe.tasks.lint]
82
+ help = "Lint with ruff and apply its fixes"
83
+ cmd = "ruff check --fix ."
84
+
85
+ [tool.poe.tasks.format]
86
+ help = "Format the code with ruff"
87
+ cmd = "ruff format ."
88
+
89
+ [tool.poe.tasks.typecheck]
90
+ help = "Type check with ty"
91
+ cmd = "ty check"
92
+
93
+ [tool.poe.tasks.zuban]
94
+ help = "Strict type check with zuban, which no hook or CI job runs"
95
+ cmd = "zuban check"
96
+
97
+ [tool.poe.tasks.pycroscope]
98
+ help = "Semi-static analysis with pycroscope, which no hook or CI job runs"
99
+ cmd = "pycroscope --config-file pyproject.toml"
100
+
101
+ [tool.poe.tasks.hooks]
102
+ help = "Run every prek hook on all files"
103
+ cmd = "prek run -a"
104
+
105
+ [tool.poe.tasks.hooks.executor]
106
+ with = ["prek"]
107
+
108
+ [tool.poe.tasks.check]
109
+ help = "Run all the checks to do before a commit"
110
+ sequence = [
111
+ "lint",
112
+ "format",
113
+ "typecheck",
114
+ "hooks",
115
+ ]
116
+
117
+ [tool.poe.tasks.test]
118
+ help = "Run the test suite (extra arguments go to pytest)"
119
+ cmd = "pytest"
120
+
121
+ [tool.poe.tasks.docs]
122
+ help = "Serve the docs site locally with live reload"
123
+ cmd = "zensical serve"
124
+
125
+ [tool.poe.tasks.docs.executor]
126
+ group = "docs"
127
+
128
+ [tool.poe.tasks.docs-build]
129
+ help = "Build the static docs site into site/"
130
+ cmd = "zensical build --clean"
131
+
132
+ [tool.poe.tasks.docs-build.executor]
133
+ group = "docs"
134
+
135
+ [tool.ruff]
136
+ line-length = 100
137
+ indent-width = 4
138
+ target-version = "py315"
139
+ fix = true
140
+ unsafe-fixes = false
141
+
142
+ [tool.ruff.lint]
143
+ select = ["ALL"]
144
+ ignore = [
145
+ "COM812",
146
+ "CPY001",
147
+ "D203",
148
+ "D212",
149
+ "D413",
150
+ ]
151
+
152
+ [tool.ruff.lint.per-file-ignores]
153
+ "**/tests/{test_*.py,conftest.py,helpers.py}" = [
154
+ "S101",
155
+ "S603",
156
+ "S607",
157
+ "ARG001",
158
+ "INP001",
159
+ "TC001",
160
+ "TC002",
161
+ "TC003",
162
+ "PLR2004",
163
+ ]
164
+ "**/__init__.py" = ["D104"]
165
+
166
+ [tool.ruff.lint.isort]
167
+ combine-as-imports = true
168
+ force-wrap-aliases = true
169
+ lines-after-imports = 2
170
+
171
+ [tool.ruff.format]
172
+ quote-style = "double"
173
+ indent-style = "space"
174
+ line-ending = "lf"
175
+
176
+ [tool.docformatter]
177
+ recursive = true
178
+ wrap-summaries = 100
179
+ wrap-descriptions = 100
180
+ pre-summary-newline = true
181
+
182
+ [tool.ty.terminal]
183
+ error-on-warning = true
184
+
185
+ [tool.zuban]
186
+ strict = true
187
+ disallow_untyped_defs = true
188
+ warn_unreachable = true
189
+ python_executable = ".venv/bin/python"
190
+
191
+ [tool.pycroscope]
192
+ paths = ["src/renovate_apply"]
193
+ import_paths = ["src"]
194
+ output_format = "concise"
195
+ possibly_undefined_name = true
196
+ unused_variable = true
197
+ value_always_true = true
198
+ use_fstrings = true
199
+ missing_return_annotation = true
200
+ missing_parameter_annotation = true
201
+ suggested_parameter_type = true
202
+ suggested_return_type = true
203
+ incompatible_override = true
204
+ missing_generic_parameters = true
205
+
206
+ [[tool.pycroscope.overrides]]
207
+ module = "tests"
208
+ missing_return_annotation = false
209
+ missing_parameter_annotation = false
210
+ suggested_parameter_type = false
211
+ suggested_return_type = false
212
+
213
+ [tool.bandit]
214
+ exclude_dirs = [
215
+ ".git",
216
+ ".venv",
217
+ "__pycache__",
218
+ "tests",
219
+ ]
220
+
221
+ [tool.bandit.assert_used]
222
+ skips = ["tests/test_*.py"]
223
+
224
+ [tool.pytest.ini_options]
225
+ pythonpath = ["tests"]
226
+ addopts = [
227
+ "-ra",
228
+ "--durations=10",
229
+ "--import-mode=importlib",
230
+ "--random-order",
231
+ "--numprocesses=logical",
232
+ "--dist=load",
233
+ "--tb=short",
234
+ "--verbose",
235
+ "--cov=src/renovate_apply",
236
+ "--cov-branch",
237
+ "--cov-report=term-missing",
238
+ "--cov-report=xml:reports/coverage.xml",
239
+ ]
240
+ filterwarnings = ["error"]
241
+
242
+ [build-system]
243
+ requires = ["uv_build>=0.12.23,<1.0.0"]
244
+ build-backend = "uv_build"