bump-dependencies 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.
- bump_dependencies-0.1.0/LICENSE +21 -0
- bump_dependencies-0.1.0/PKG-INFO +165 -0
- bump_dependencies-0.1.0/README.md +135 -0
- bump_dependencies-0.1.0/pyproject.toml +64 -0
- bump_dependencies-0.1.0/setup.cfg +4 -0
- bump_dependencies-0.1.0/src/bump_dependencies.egg-info/PKG-INFO +165 -0
- bump_dependencies-0.1.0/src/bump_dependencies.egg-info/SOURCES.txt +11 -0
- bump_dependencies-0.1.0/src/bump_dependencies.egg-info/dependency_links.txt +1 -0
- bump_dependencies-0.1.0/src/bump_dependencies.egg-info/entry_points.txt +2 -0
- bump_dependencies-0.1.0/src/bump_dependencies.egg-info/requires.txt +5 -0
- bump_dependencies-0.1.0/src/bump_dependencies.egg-info/top_level.txt +2 -0
- bump_dependencies-0.1.0/src/bump_dependencies.py +186 -0
- bump_dependencies-0.1.0/src/test_bump_dependencies.py +171 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Corey Goldberg
|
|
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,165 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bump-dependencies
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Bump Python package dependencies in pyproject.toml
|
|
5
|
+
Author: Corey Goldberg
|
|
6
|
+
Maintainer: Corey Goldberg
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: homepage, https://github.com/cgoldberg/bump-dependencies
|
|
9
|
+
Project-URL: source, https://github.com/cgoldberg/bump-dependencies
|
|
10
|
+
Project-URL: download, https://pypi.org/project/bump-dependencies
|
|
11
|
+
Keywords: package,dependencies,requirements,bump,upgrade
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: packaging==25.0
|
|
25
|
+
Requires-Dist: requests==2.32.4
|
|
26
|
+
Requires-Dist: rich==14.0.0
|
|
27
|
+
Requires-Dist: tomlkit==0.13.3
|
|
28
|
+
Requires-Dist: validate-pyproject==0.24.1
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# bump-dependencies
|
|
32
|
+
|
|
33
|
+
## Python - bump your package dependencies
|
|
34
|
+
|
|
35
|
+
*Update dependency specifiers in `pyproject.toml` to latest versions*
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
- Copyright (c) 2025 [Corey Goldberg][github-home]
|
|
40
|
+
- Development: [GitHub][github-repo]
|
|
41
|
+
- Download/Install: [PyPI][pypi-bump-dependencies]
|
|
42
|
+
- License: [MIT][mit-license]
|
|
43
|
+
|
|
44
|
+
----
|
|
45
|
+
|
|
46
|
+
## Installation:
|
|
47
|
+
|
|
48
|
+
Install from [PyPI][pypi-bump-dependencies]:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
pip install bump-dependencies
|
|
52
|
+
```
|
|
53
|
+
----
|
|
54
|
+
|
|
55
|
+
## Usage:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
usage: bump_dependencies [-h] [--dry-run] [--path PATH]
|
|
59
|
+
|
|
60
|
+
options:
|
|
61
|
+
-h, --help show this help message and exit
|
|
62
|
+
--dry-run don't write changes to pyproject.toml
|
|
63
|
+
--path PATH path to pyproject.toml (defaults to current directory)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## About:
|
|
67
|
+
|
|
68
|
+
`bump_dependencies` is a Python CLI program that generates a new packaging
|
|
69
|
+
configuration file (`pyproject.toml`) file with updated package dependencies.
|
|
70
|
+
|
|
71
|
+
- for more information on declaring dependencies in a configuration file, see the [PyPA pyproject.toml Spec][pypa-pyproject-dependencies]
|
|
72
|
+
- for more information on version specifiers, see [PEP 440][pep-440] and the [PyPA Version Specifiers Spec][pypa-version-specifiers]
|
|
73
|
+
- for more information on dependency specifiers, see [PEP 508][pep-508] and the [PyPA Dependency Specifiers Spec][pypa-dependency-specifiers]
|
|
74
|
+
- for more information on dependency groups, see [PEP 735][pep-735] and the [PyPA Dependency Groups Spec][pypa-dependency-groups]
|
|
75
|
+
|
|
76
|
+
#### Example:
|
|
77
|
+
|
|
78
|
+
If your `pyproject.toml` contains this:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
[project]
|
|
82
|
+
... some metadata ...
|
|
83
|
+
dependencies = ["matplotlib~=3.9", "requests==2.29.0"]
|
|
84
|
+
|
|
85
|
+
[project.optional-dependencies]
|
|
86
|
+
socks = ["PySocks>=1.5.6"]
|
|
87
|
+
|
|
88
|
+
[dependency-groups]
|
|
89
|
+
dev = ["black==23.9.1", "ruff==0.9.5"]
|
|
90
|
+
test = ["pytest>8", "pytest-mock>=3.11"]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
It will update dependency specifiers to the latest versions available on [PyPI][pypi-home]:
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
[project]
|
|
97
|
+
... some metadata ...
|
|
98
|
+
dependencies = ["matplotlib~=3.10.3", "requests==2.32.4"]
|
|
99
|
+
|
|
100
|
+
[project.optional-dependencies]
|
|
101
|
+
socks = ["PySocks>=1.7.1"]
|
|
102
|
+
|
|
103
|
+
[dependency-groups]
|
|
104
|
+
dev = ["black==25.1.0", "ruff==0.12.1"]
|
|
105
|
+
test = ["pytest>8.4.1", "pytest-mock>=3.14.1"]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
#### Which sections of `pyproject.toml` will be updated?
|
|
109
|
+
|
|
110
|
+
It will update dependency specifiers listed in various sections of `pyproject.toml`:
|
|
111
|
+
|
|
112
|
+
- `dependencies` list from `[project]` section
|
|
113
|
+
- dependency lists from `[project.optional-dependencies]` section
|
|
114
|
+
- dependency lists from `[dependency-groups]` section
|
|
115
|
+
|
|
116
|
+
#### Which dependency specifiers will be updated?
|
|
117
|
+
|
|
118
|
+
- will only update dependency specifiers with version identifier
|
|
119
|
+
containing comparison operator: `==`, `===`, `~=`, `>`, `>=`
|
|
120
|
+
- example:
|
|
121
|
+
- `foo==1.0.0`
|
|
122
|
+
- `foo~=1.0`
|
|
123
|
+
- `foo>=1`
|
|
124
|
+
- will not update dependency specifiers with version identifier
|
|
125
|
+
containing comparison operator: `<`, `<=`, `!=`
|
|
126
|
+
- example:
|
|
127
|
+
- `foo<2.0`
|
|
128
|
+
- `foo>=1,<2`
|
|
129
|
+
- `foo > 1.0, != 1.0.1`
|
|
130
|
+
- will not update unversioned dependency specifiers
|
|
131
|
+
- example:
|
|
132
|
+
- `foo`
|
|
133
|
+
- `foo[bar]`
|
|
134
|
+
- will not update direct reference dependency specifiers
|
|
135
|
+
- example:
|
|
136
|
+
- `foo @ https://github.com/foo/foo/archive/1.0.0.zip`
|
|
137
|
+
- `foo @ file:///builds/foo-1.0.0-py3-none-any.whl`
|
|
138
|
+
|
|
139
|
+
#### Supported comparison operators in version identifiers:
|
|
140
|
+
|
|
141
|
+
- `==` : version matching
|
|
142
|
+
- `===` : arbitrary equality
|
|
143
|
+
- `~=` : compatible release
|
|
144
|
+
- `>` : exclusive ordered comparison
|
|
145
|
+
- `>=` : inclusive ordered comparison
|
|
146
|
+
|
|
147
|
+
#### Unsupported comparison operators in version identifiers:
|
|
148
|
+
|
|
149
|
+
- `<` : exclusive ordered comparison
|
|
150
|
+
- `<=` : inclusive ordered comparison
|
|
151
|
+
- `!=` : version exclusion
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
[github-home]: https://github.com/cgoldberg
|
|
155
|
+
[github-repo]: https://github.com/cgoldberg/bump-dependencies
|
|
156
|
+
[pypi-home]: https://pypi.org
|
|
157
|
+
[pypi-bump-dependencies]: https://pypi.org/project/bump-dependencies
|
|
158
|
+
[mit-license]: https://raw.githubusercontent.com/cgoldberg/bump-dependencies/refs/heads/master/LICENSE
|
|
159
|
+
[pep-440]: https://peps.python.org/pep-0440
|
|
160
|
+
[pep-508]: https://peps.python.org/pep-0508
|
|
161
|
+
[pep-735]: https://peps.python.org/pep-0735
|
|
162
|
+
[pypa-version-specifiers]: https://packaging.python.org/en/latest/specifications/version-specifiers
|
|
163
|
+
[pypa-dependency-specifiers]: https://packaging.python.org/en/latest/specifications/dependency-specifiers
|
|
164
|
+
[pypa-dependency-groups]: https://packaging.python.org/en/latest/specifications/dependency-groups
|
|
165
|
+
[pypa-pyproject-dependencies]: https://packaging.python.org/en/latest/specifications/pyproject-toml/#dependencies-optional-dependencies
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# bump-dependencies
|
|
2
|
+
|
|
3
|
+
## Python - bump your package dependencies
|
|
4
|
+
|
|
5
|
+
*Update dependency specifiers in `pyproject.toml` to latest versions*
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
- Copyright (c) 2025 [Corey Goldberg][github-home]
|
|
10
|
+
- Development: [GitHub][github-repo]
|
|
11
|
+
- Download/Install: [PyPI][pypi-bump-dependencies]
|
|
12
|
+
- License: [MIT][mit-license]
|
|
13
|
+
|
|
14
|
+
----
|
|
15
|
+
|
|
16
|
+
## Installation:
|
|
17
|
+
|
|
18
|
+
Install from [PyPI][pypi-bump-dependencies]:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
pip install bump-dependencies
|
|
22
|
+
```
|
|
23
|
+
----
|
|
24
|
+
|
|
25
|
+
## Usage:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
usage: bump_dependencies [-h] [--dry-run] [--path PATH]
|
|
29
|
+
|
|
30
|
+
options:
|
|
31
|
+
-h, --help show this help message and exit
|
|
32
|
+
--dry-run don't write changes to pyproject.toml
|
|
33
|
+
--path PATH path to pyproject.toml (defaults to current directory)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## About:
|
|
37
|
+
|
|
38
|
+
`bump_dependencies` is a Python CLI program that generates a new packaging
|
|
39
|
+
configuration file (`pyproject.toml`) file with updated package dependencies.
|
|
40
|
+
|
|
41
|
+
- for more information on declaring dependencies in a configuration file, see the [PyPA pyproject.toml Spec][pypa-pyproject-dependencies]
|
|
42
|
+
- for more information on version specifiers, see [PEP 440][pep-440] and the [PyPA Version Specifiers Spec][pypa-version-specifiers]
|
|
43
|
+
- for more information on dependency specifiers, see [PEP 508][pep-508] and the [PyPA Dependency Specifiers Spec][pypa-dependency-specifiers]
|
|
44
|
+
- for more information on dependency groups, see [PEP 735][pep-735] and the [PyPA Dependency Groups Spec][pypa-dependency-groups]
|
|
45
|
+
|
|
46
|
+
#### Example:
|
|
47
|
+
|
|
48
|
+
If your `pyproject.toml` contains this:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
[project]
|
|
52
|
+
... some metadata ...
|
|
53
|
+
dependencies = ["matplotlib~=3.9", "requests==2.29.0"]
|
|
54
|
+
|
|
55
|
+
[project.optional-dependencies]
|
|
56
|
+
socks = ["PySocks>=1.5.6"]
|
|
57
|
+
|
|
58
|
+
[dependency-groups]
|
|
59
|
+
dev = ["black==23.9.1", "ruff==0.9.5"]
|
|
60
|
+
test = ["pytest>8", "pytest-mock>=3.11"]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
It will update dependency specifiers to the latest versions available on [PyPI][pypi-home]:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
[project]
|
|
67
|
+
... some metadata ...
|
|
68
|
+
dependencies = ["matplotlib~=3.10.3", "requests==2.32.4"]
|
|
69
|
+
|
|
70
|
+
[project.optional-dependencies]
|
|
71
|
+
socks = ["PySocks>=1.7.1"]
|
|
72
|
+
|
|
73
|
+
[dependency-groups]
|
|
74
|
+
dev = ["black==25.1.0", "ruff==0.12.1"]
|
|
75
|
+
test = ["pytest>8.4.1", "pytest-mock>=3.14.1"]
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
#### Which sections of `pyproject.toml` will be updated?
|
|
79
|
+
|
|
80
|
+
It will update dependency specifiers listed in various sections of `pyproject.toml`:
|
|
81
|
+
|
|
82
|
+
- `dependencies` list from `[project]` section
|
|
83
|
+
- dependency lists from `[project.optional-dependencies]` section
|
|
84
|
+
- dependency lists from `[dependency-groups]` section
|
|
85
|
+
|
|
86
|
+
#### Which dependency specifiers will be updated?
|
|
87
|
+
|
|
88
|
+
- will only update dependency specifiers with version identifier
|
|
89
|
+
containing comparison operator: `==`, `===`, `~=`, `>`, `>=`
|
|
90
|
+
- example:
|
|
91
|
+
- `foo==1.0.0`
|
|
92
|
+
- `foo~=1.0`
|
|
93
|
+
- `foo>=1`
|
|
94
|
+
- will not update dependency specifiers with version identifier
|
|
95
|
+
containing comparison operator: `<`, `<=`, `!=`
|
|
96
|
+
- example:
|
|
97
|
+
- `foo<2.0`
|
|
98
|
+
- `foo>=1,<2`
|
|
99
|
+
- `foo > 1.0, != 1.0.1`
|
|
100
|
+
- will not update unversioned dependency specifiers
|
|
101
|
+
- example:
|
|
102
|
+
- `foo`
|
|
103
|
+
- `foo[bar]`
|
|
104
|
+
- will not update direct reference dependency specifiers
|
|
105
|
+
- example:
|
|
106
|
+
- `foo @ https://github.com/foo/foo/archive/1.0.0.zip`
|
|
107
|
+
- `foo @ file:///builds/foo-1.0.0-py3-none-any.whl`
|
|
108
|
+
|
|
109
|
+
#### Supported comparison operators in version identifiers:
|
|
110
|
+
|
|
111
|
+
- `==` : version matching
|
|
112
|
+
- `===` : arbitrary equality
|
|
113
|
+
- `~=` : compatible release
|
|
114
|
+
- `>` : exclusive ordered comparison
|
|
115
|
+
- `>=` : inclusive ordered comparison
|
|
116
|
+
|
|
117
|
+
#### Unsupported comparison operators in version identifiers:
|
|
118
|
+
|
|
119
|
+
- `<` : exclusive ordered comparison
|
|
120
|
+
- `<=` : inclusive ordered comparison
|
|
121
|
+
- `!=` : version exclusion
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
[github-home]: https://github.com/cgoldberg
|
|
125
|
+
[github-repo]: https://github.com/cgoldberg/bump-dependencies
|
|
126
|
+
[pypi-home]: https://pypi.org
|
|
127
|
+
[pypi-bump-dependencies]: https://pypi.org/project/bump-dependencies
|
|
128
|
+
[mit-license]: https://raw.githubusercontent.com/cgoldberg/bump-dependencies/refs/heads/master/LICENSE
|
|
129
|
+
[pep-440]: https://peps.python.org/pep-0440
|
|
130
|
+
[pep-508]: https://peps.python.org/pep-0508
|
|
131
|
+
[pep-735]: https://peps.python.org/pep-0735
|
|
132
|
+
[pypa-version-specifiers]: https://packaging.python.org/en/latest/specifications/version-specifiers
|
|
133
|
+
[pypa-dependency-specifiers]: https://packaging.python.org/en/latest/specifications/dependency-specifiers
|
|
134
|
+
[pypa-dependency-groups]: https://packaging.python.org/en/latest/specifications/dependency-groups
|
|
135
|
+
[pypa-pyproject-dependencies]: https://packaging.python.org/en/latest/specifications/pyproject-toml/#dependencies-optional-dependencies
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "bump-dependencies"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Bump Python package dependencies in pyproject.toml"
|
|
9
|
+
license = "MIT"
|
|
10
|
+
license-files = ["LICENSE"]
|
|
11
|
+
authors = [{name = "Corey Goldberg"}]
|
|
12
|
+
maintainers = [{name = "Corey Goldberg"}]
|
|
13
|
+
readme = "README.md"
|
|
14
|
+
requires-python = ">=3.9"
|
|
15
|
+
keywords = ["package", "dependencies", "requirements", "bump", "upgrade"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Environment :: Console",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Programming Language :: Python",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.9",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
]
|
|
27
|
+
dependencies = ["packaging==25.0", "requests==2.32.4", "rich==14.0.0", "tomlkit==0.13.3", "validate-pyproject==0.24.1"]
|
|
28
|
+
|
|
29
|
+
[project.scripts]
|
|
30
|
+
bump_dependencies = "bump_dependencies:main"
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
homepage = "https://github.com/cgoldberg/bump-dependencies"
|
|
34
|
+
source = "https://github.com/cgoldberg/bump-dependencies"
|
|
35
|
+
download = "https://pypi.org/project/bump-dependencies"
|
|
36
|
+
|
|
37
|
+
[dependency-groups]
|
|
38
|
+
dev = ["tox"]
|
|
39
|
+
lint = ["black", "ruff"]
|
|
40
|
+
test = ["pytest==8.4.1", "pytest-sugar==1.0.0"]
|
|
41
|
+
validate = ["packaging==25.0", "validate-pyproject==0.24.1"]
|
|
42
|
+
|
|
43
|
+
[tool.setuptools]
|
|
44
|
+
package-dir = {"" = "src"}
|
|
45
|
+
|
|
46
|
+
[tool.pytest.ini_options]
|
|
47
|
+
addopts = "-vv" # extra verbose
|
|
48
|
+
|
|
49
|
+
[tool.black]
|
|
50
|
+
line-length = 120
|
|
51
|
+
target-version = ["py39"]
|
|
52
|
+
|
|
53
|
+
[tool.ruff]
|
|
54
|
+
line-length = 120
|
|
55
|
+
respect-gitignore = true
|
|
56
|
+
target-version = "py39"
|
|
57
|
+
|
|
58
|
+
[tool.ruff.lint]
|
|
59
|
+
extend-select = ["E4", "E7", "E9", "F", "I", "E501", "RUF022"]
|
|
60
|
+
fixable = ["ALL"]
|
|
61
|
+
|
|
62
|
+
[tool.ruff.format]
|
|
63
|
+
docstring-code-format = true
|
|
64
|
+
docstring-code-line-length = 120
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bump-dependencies
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Bump Python package dependencies in pyproject.toml
|
|
5
|
+
Author: Corey Goldberg
|
|
6
|
+
Maintainer: Corey Goldberg
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: homepage, https://github.com/cgoldberg/bump-dependencies
|
|
9
|
+
Project-URL: source, https://github.com/cgoldberg/bump-dependencies
|
|
10
|
+
Project-URL: download, https://pypi.org/project/bump-dependencies
|
|
11
|
+
Keywords: package,dependencies,requirements,bump,upgrade
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: packaging==25.0
|
|
25
|
+
Requires-Dist: requests==2.32.4
|
|
26
|
+
Requires-Dist: rich==14.0.0
|
|
27
|
+
Requires-Dist: tomlkit==0.13.3
|
|
28
|
+
Requires-Dist: validate-pyproject==0.24.1
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# bump-dependencies
|
|
32
|
+
|
|
33
|
+
## Python - bump your package dependencies
|
|
34
|
+
|
|
35
|
+
*Update dependency specifiers in `pyproject.toml` to latest versions*
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
- Copyright (c) 2025 [Corey Goldberg][github-home]
|
|
40
|
+
- Development: [GitHub][github-repo]
|
|
41
|
+
- Download/Install: [PyPI][pypi-bump-dependencies]
|
|
42
|
+
- License: [MIT][mit-license]
|
|
43
|
+
|
|
44
|
+
----
|
|
45
|
+
|
|
46
|
+
## Installation:
|
|
47
|
+
|
|
48
|
+
Install from [PyPI][pypi-bump-dependencies]:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
pip install bump-dependencies
|
|
52
|
+
```
|
|
53
|
+
----
|
|
54
|
+
|
|
55
|
+
## Usage:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
usage: bump_dependencies [-h] [--dry-run] [--path PATH]
|
|
59
|
+
|
|
60
|
+
options:
|
|
61
|
+
-h, --help show this help message and exit
|
|
62
|
+
--dry-run don't write changes to pyproject.toml
|
|
63
|
+
--path PATH path to pyproject.toml (defaults to current directory)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## About:
|
|
67
|
+
|
|
68
|
+
`bump_dependencies` is a Python CLI program that generates a new packaging
|
|
69
|
+
configuration file (`pyproject.toml`) file with updated package dependencies.
|
|
70
|
+
|
|
71
|
+
- for more information on declaring dependencies in a configuration file, see the [PyPA pyproject.toml Spec][pypa-pyproject-dependencies]
|
|
72
|
+
- for more information on version specifiers, see [PEP 440][pep-440] and the [PyPA Version Specifiers Spec][pypa-version-specifiers]
|
|
73
|
+
- for more information on dependency specifiers, see [PEP 508][pep-508] and the [PyPA Dependency Specifiers Spec][pypa-dependency-specifiers]
|
|
74
|
+
- for more information on dependency groups, see [PEP 735][pep-735] and the [PyPA Dependency Groups Spec][pypa-dependency-groups]
|
|
75
|
+
|
|
76
|
+
#### Example:
|
|
77
|
+
|
|
78
|
+
If your `pyproject.toml` contains this:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
[project]
|
|
82
|
+
... some metadata ...
|
|
83
|
+
dependencies = ["matplotlib~=3.9", "requests==2.29.0"]
|
|
84
|
+
|
|
85
|
+
[project.optional-dependencies]
|
|
86
|
+
socks = ["PySocks>=1.5.6"]
|
|
87
|
+
|
|
88
|
+
[dependency-groups]
|
|
89
|
+
dev = ["black==23.9.1", "ruff==0.9.5"]
|
|
90
|
+
test = ["pytest>8", "pytest-mock>=3.11"]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
It will update dependency specifiers to the latest versions available on [PyPI][pypi-home]:
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
[project]
|
|
97
|
+
... some metadata ...
|
|
98
|
+
dependencies = ["matplotlib~=3.10.3", "requests==2.32.4"]
|
|
99
|
+
|
|
100
|
+
[project.optional-dependencies]
|
|
101
|
+
socks = ["PySocks>=1.7.1"]
|
|
102
|
+
|
|
103
|
+
[dependency-groups]
|
|
104
|
+
dev = ["black==25.1.0", "ruff==0.12.1"]
|
|
105
|
+
test = ["pytest>8.4.1", "pytest-mock>=3.14.1"]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
#### Which sections of `pyproject.toml` will be updated?
|
|
109
|
+
|
|
110
|
+
It will update dependency specifiers listed in various sections of `pyproject.toml`:
|
|
111
|
+
|
|
112
|
+
- `dependencies` list from `[project]` section
|
|
113
|
+
- dependency lists from `[project.optional-dependencies]` section
|
|
114
|
+
- dependency lists from `[dependency-groups]` section
|
|
115
|
+
|
|
116
|
+
#### Which dependency specifiers will be updated?
|
|
117
|
+
|
|
118
|
+
- will only update dependency specifiers with version identifier
|
|
119
|
+
containing comparison operator: `==`, `===`, `~=`, `>`, `>=`
|
|
120
|
+
- example:
|
|
121
|
+
- `foo==1.0.0`
|
|
122
|
+
- `foo~=1.0`
|
|
123
|
+
- `foo>=1`
|
|
124
|
+
- will not update dependency specifiers with version identifier
|
|
125
|
+
containing comparison operator: `<`, `<=`, `!=`
|
|
126
|
+
- example:
|
|
127
|
+
- `foo<2.0`
|
|
128
|
+
- `foo>=1,<2`
|
|
129
|
+
- `foo > 1.0, != 1.0.1`
|
|
130
|
+
- will not update unversioned dependency specifiers
|
|
131
|
+
- example:
|
|
132
|
+
- `foo`
|
|
133
|
+
- `foo[bar]`
|
|
134
|
+
- will not update direct reference dependency specifiers
|
|
135
|
+
- example:
|
|
136
|
+
- `foo @ https://github.com/foo/foo/archive/1.0.0.zip`
|
|
137
|
+
- `foo @ file:///builds/foo-1.0.0-py3-none-any.whl`
|
|
138
|
+
|
|
139
|
+
#### Supported comparison operators in version identifiers:
|
|
140
|
+
|
|
141
|
+
- `==` : version matching
|
|
142
|
+
- `===` : arbitrary equality
|
|
143
|
+
- `~=` : compatible release
|
|
144
|
+
- `>` : exclusive ordered comparison
|
|
145
|
+
- `>=` : inclusive ordered comparison
|
|
146
|
+
|
|
147
|
+
#### Unsupported comparison operators in version identifiers:
|
|
148
|
+
|
|
149
|
+
- `<` : exclusive ordered comparison
|
|
150
|
+
- `<=` : inclusive ordered comparison
|
|
151
|
+
- `!=` : version exclusion
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
[github-home]: https://github.com/cgoldberg
|
|
155
|
+
[github-repo]: https://github.com/cgoldberg/bump-dependencies
|
|
156
|
+
[pypi-home]: https://pypi.org
|
|
157
|
+
[pypi-bump-dependencies]: https://pypi.org/project/bump-dependencies
|
|
158
|
+
[mit-license]: https://raw.githubusercontent.com/cgoldberg/bump-dependencies/refs/heads/master/LICENSE
|
|
159
|
+
[pep-440]: https://peps.python.org/pep-0440
|
|
160
|
+
[pep-508]: https://peps.python.org/pep-0508
|
|
161
|
+
[pep-735]: https://peps.python.org/pep-0735
|
|
162
|
+
[pypa-version-specifiers]: https://packaging.python.org/en/latest/specifications/version-specifiers
|
|
163
|
+
[pypa-dependency-specifiers]: https://packaging.python.org/en/latest/specifications/dependency-specifiers
|
|
164
|
+
[pypa-dependency-groups]: https://packaging.python.org/en/latest/specifications/dependency-groups
|
|
165
|
+
[pypa-pyproject-dependencies]: https://packaging.python.org/en/latest/specifications/pyproject-toml/#dependencies-optional-dependencies
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/bump_dependencies.py
|
|
5
|
+
src/test_bump_dependencies.py
|
|
6
|
+
src/bump_dependencies.egg-info/PKG-INFO
|
|
7
|
+
src/bump_dependencies.egg-info/SOURCES.txt
|
|
8
|
+
src/bump_dependencies.egg-info/dependency_links.txt
|
|
9
|
+
src/bump_dependencies.egg-info/entry_points.txt
|
|
10
|
+
src/bump_dependencies.egg-info/requires.txt
|
|
11
|
+
src/bump_dependencies.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# Corey Goldberg, 2025
|
|
3
|
+
# License: MIT
|
|
4
|
+
|
|
5
|
+
"""Bump Python package dependencies in pyproject.toml"""
|
|
6
|
+
|
|
7
|
+
import argparse
|
|
8
|
+
import os
|
|
9
|
+
import re
|
|
10
|
+
|
|
11
|
+
import requests
|
|
12
|
+
import tomlkit
|
|
13
|
+
from rich.console import Console
|
|
14
|
+
from validate_pyproject import api as validate_pyproject_api
|
|
15
|
+
from validate_pyproject.errors import ValidationError
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def get_dependency_name_and_operator(dependency_specifier):
|
|
19
|
+
illegal_chars = ("/", ":", "@")
|
|
20
|
+
if any(char in dependency_specifier for char in illegal_chars):
|
|
21
|
+
raise ValueError("can't handle direct reference dependency specifiers")
|
|
22
|
+
if ";" in dependency_specifier:
|
|
23
|
+
dependency_specifier = dependency_specifier.split(";")[0]
|
|
24
|
+
invalid_operators = ("!=", "<=", "<")
|
|
25
|
+
for op in invalid_operators:
|
|
26
|
+
if op in dependency_specifier:
|
|
27
|
+
raise ValueError(f"skipping unsupported '{op}' version identifier")
|
|
28
|
+
valid_operators = ("===", "==", "~=", ">=", ">")
|
|
29
|
+
operators = re.findall("|".join(valid_operators), dependency_specifier)
|
|
30
|
+
if not operators:
|
|
31
|
+
raise ValueError("no version specified")
|
|
32
|
+
elif len(operators) != 1:
|
|
33
|
+
raise ValueError("can't handle complex dependency specifiers")
|
|
34
|
+
operator = operators[0]
|
|
35
|
+
dependency_name = dependency_specifier.replace(" ", "").split(operator)[0].strip()
|
|
36
|
+
return dependency_name, operator
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_dependencies_groups(pyproject_data):
|
|
40
|
+
"""Map each dependency group name to a list of dependency specifiers
|
|
41
|
+
|
|
42
|
+
This includes:
|
|
43
|
+
- `dependencies` list from `[project]` section
|
|
44
|
+
- dependency lists from `[project.optional-dependencies]` section
|
|
45
|
+
- dependency lists from `[dependency-groups]` section
|
|
46
|
+
"""
|
|
47
|
+
groups = {}
|
|
48
|
+
project_dependencies = list(pyproject_data["project"].get("dependencies", []))
|
|
49
|
+
if project_dependencies:
|
|
50
|
+
groups.update({"project": project_dependencies})
|
|
51
|
+
optional_dependencies = dict(pyproject_data["project"].get("optional-dependencies", {}))
|
|
52
|
+
if optional_dependencies:
|
|
53
|
+
groups.update({"optional_dependencies": optional_dependencies})
|
|
54
|
+
dependency_groups = dict(pyproject_data.get("dependency-groups", {}))
|
|
55
|
+
if dependency_groups:
|
|
56
|
+
groups.update({"dependency_groups": dependency_groups})
|
|
57
|
+
if not groups:
|
|
58
|
+
raise ValueError("no dependencies found")
|
|
59
|
+
return groups
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def update_dependency(dependency_specifier):
|
|
63
|
+
dependency_name, operator = get_dependency_name_and_operator(dependency_specifier)
|
|
64
|
+
new_dependency_version = fetch_latest_package_version(get_package_base_name(dependency_name))
|
|
65
|
+
updated_dependency_specifier = None
|
|
66
|
+
if new_dependency_version is not None:
|
|
67
|
+
if ";" in dependency_specifier:
|
|
68
|
+
after_semi = "".join(dependency_specifier.split(";")[1:])
|
|
69
|
+
updated_dependency_specifier = f"{dependency_name}{operator}{new_dependency_version};{after_semi}"
|
|
70
|
+
else:
|
|
71
|
+
updated_dependency_specifier = f"{dependency_name}{operator}{new_dependency_version}"
|
|
72
|
+
return updated_dependency_specifier
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def update_dependencies(dependency_specifiers):
|
|
76
|
+
updated_dependency_specifiers = []
|
|
77
|
+
for dependency_specifier in dependency_specifiers:
|
|
78
|
+
if isinstance(dependency_specifier, tomlkit.items.InlineTable):
|
|
79
|
+
print(f"- skipping inline table: '{dependency_specifier}'")
|
|
80
|
+
updated_dependency_specifiers.append(dependency_specifier)
|
|
81
|
+
continue
|
|
82
|
+
try:
|
|
83
|
+
get_dependency_name_and_operator(dependency_specifier)
|
|
84
|
+
except ValueError as e:
|
|
85
|
+
print(f"- not updating: '{dependency_specifier}' ({e})")
|
|
86
|
+
updated_dependency_specifiers.append(dependency_specifier)
|
|
87
|
+
continue
|
|
88
|
+
updated_dependency_specifier = update_dependency(dependency_specifier)
|
|
89
|
+
if updated_dependency_specifier is not None:
|
|
90
|
+
if dependency_specifier != updated_dependency_specifier:
|
|
91
|
+
print(f"- updating: '{dependency_specifier}' to '{updated_dependency_specifier}'")
|
|
92
|
+
updated_dependency_specifiers.append(updated_dependency_specifier)
|
|
93
|
+
else:
|
|
94
|
+
print(f"- not updating: '{dependency_specifier}' (no new version available)")
|
|
95
|
+
updated_dependency_specifiers.append(dependency_specifier)
|
|
96
|
+
else:
|
|
97
|
+
print(f"- not updating: '{dependency_specifier}' (error retrieving version from pypi.org)")
|
|
98
|
+
updated_dependency_specifiers.append(dependency_specifier)
|
|
99
|
+
return updated_dependency_specifiers
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def get_package_base_name(package_name):
|
|
103
|
+
match = re.match(r"^(.*?)\[", package_name)
|
|
104
|
+
if match:
|
|
105
|
+
return match.group(1).strip()
|
|
106
|
+
return package_name.strip()
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def fetch_latest_package_version(package_name):
|
|
110
|
+
url = f"https://pypi.org/pypi/{package_name}/json"
|
|
111
|
+
try:
|
|
112
|
+
response = requests.get(url)
|
|
113
|
+
except requests.exceptions.ConnectionError:
|
|
114
|
+
print("error connecting to pypi.org")
|
|
115
|
+
return None
|
|
116
|
+
try:
|
|
117
|
+
response.raise_for_status() # raise an exception for bad status codes
|
|
118
|
+
except requests.exceptions.HTTPError:
|
|
119
|
+
return None
|
|
120
|
+
return response.json()["info"]["version"]
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def run(pyproject_toml_path, dry_run):
|
|
124
|
+
console = Console()
|
|
125
|
+
with console.status(""):
|
|
126
|
+
print(f"loading: {pyproject_toml_path}")
|
|
127
|
+
try:
|
|
128
|
+
with open(pyproject_toml_path) as f:
|
|
129
|
+
pyproject_data = tomlkit.load(f)
|
|
130
|
+
except FileNotFoundError:
|
|
131
|
+
exit("\nno pyproject.toml found")
|
|
132
|
+
except Exception as e:
|
|
133
|
+
exit(f"\ninvalid pyproject.toml: {e}")
|
|
134
|
+
print(f"validating: {os.path.basename(pyproject_toml_path)}\n")
|
|
135
|
+
validator = validate_pyproject_api.Validator()
|
|
136
|
+
try:
|
|
137
|
+
validator(pyproject_data)
|
|
138
|
+
except ValidationError as e:
|
|
139
|
+
exit(f"invalid pyproject.toml: {e.message}")
|
|
140
|
+
try:
|
|
141
|
+
dependencies_groups_map = get_dependencies_groups(pyproject_data)
|
|
142
|
+
except ValueError as e:
|
|
143
|
+
exit(e)
|
|
144
|
+
|
|
145
|
+
for key, value in dependencies_groups_map.items():
|
|
146
|
+
if key == "project":
|
|
147
|
+
pyproject_data["project"]["dependencies"] = update_dependencies(value)
|
|
148
|
+
if key == "optional_dependencies":
|
|
149
|
+
pyproject_data["project"]["optional-dependencies"] = {
|
|
150
|
+
dependency_group: update_dependencies(dependency_specifiers)
|
|
151
|
+
for dependency_group, dependency_specifiers in value.items()
|
|
152
|
+
}
|
|
153
|
+
if key == "dependency_groups":
|
|
154
|
+
pyproject_data["dependency-groups"] = {
|
|
155
|
+
dependency_group: update_dependencies(dependency_specifiers)
|
|
156
|
+
for dependency_group, dependency_specifiers in value.items()
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if dry_run:
|
|
160
|
+
print("\nnot writing new pyproject.toml with updated dependencies")
|
|
161
|
+
else:
|
|
162
|
+
with open(pyproject_toml_path, "w") as f:
|
|
163
|
+
tomlkit.dump(pyproject_data, f)
|
|
164
|
+
print("\ngenerated new pyproject.toml with updated dependencies")
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def main():
|
|
168
|
+
parser = argparse.ArgumentParser()
|
|
169
|
+
parser.add_argument(
|
|
170
|
+
"--dry-run",
|
|
171
|
+
action="store_true",
|
|
172
|
+
default=False,
|
|
173
|
+
dest="dry_run",
|
|
174
|
+
help="don't write changes to pyproject.toml",
|
|
175
|
+
)
|
|
176
|
+
parser.add_argument(
|
|
177
|
+
"--path",
|
|
178
|
+
default=os.path.join(os.getcwd(), "pyproject.toml"),
|
|
179
|
+
help="path to pyproject.toml (defaults to current directory)",
|
|
180
|
+
)
|
|
181
|
+
args = parser.parse_args()
|
|
182
|
+
run(args.path, args.dry_run)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
if __name__ == "__main__":
|
|
186
|
+
main()
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Corey Goldberg, 2025
|
|
2
|
+
# License: MIT
|
|
3
|
+
|
|
4
|
+
"""Tests for bump_dependencies"""
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
import bump_dependencies as bd
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@pytest.fixture(
|
|
12
|
+
params=[
|
|
13
|
+
("foo==1.0.0", "foo"),
|
|
14
|
+
("foo~=1.0", "foo"),
|
|
15
|
+
("foo===1.0.0", "foo"),
|
|
16
|
+
("foo==1.0.*", "foo"),
|
|
17
|
+
("foo==1.0.1dev0", "foo"),
|
|
18
|
+
("foo~=1.1a1", "foo"),
|
|
19
|
+
("foo==1.1.*", "foo"),
|
|
20
|
+
("foo>1", "foo"),
|
|
21
|
+
("foo>=1.0", "foo"),
|
|
22
|
+
("foo[bar] == 2012.4", "foo[bar]"),
|
|
23
|
+
("foo==1.0.post2.dev3", "foo"),
|
|
24
|
+
("foo[bar] >= 1.0dev1", "foo[bar]"),
|
|
25
|
+
("foo>1.0; python_version < '4.0'", "foo"),
|
|
26
|
+
("foo[bar]>=1.0", "foo[bar]"),
|
|
27
|
+
("foo[bar,baz]==1.0.0", "foo[bar,baz]"),
|
|
28
|
+
("foo[ bar, baz ] ~= 1.0.0", "foo[bar,baz]"),
|
|
29
|
+
("foo > 1.0", "foo"),
|
|
30
|
+
("foo[bar] == 1.0", "foo[bar]"),
|
|
31
|
+
("foo== 1.0", "foo"),
|
|
32
|
+
("foo ==1.0", "foo"),
|
|
33
|
+
("foo == 1.0", "foo"),
|
|
34
|
+
(" foo==1.0 ", "foo"),
|
|
35
|
+
(" foo > 1.0 ", "foo"),
|
|
36
|
+
("foo==1.0 ; python_version < '4.0'", "foo"),
|
|
37
|
+
("foo~=1.0.0;python_version>'2.7'", "foo"),
|
|
38
|
+
("foo[bar, baz, qux]==1.0.0;python_version>'2.7'", "foo[bar,baz,qux]"),
|
|
39
|
+
("foo == 1.0; os_name=='a' or os_name=='b'", "foo"),
|
|
40
|
+
]
|
|
41
|
+
)
|
|
42
|
+
def valid_specifier_name(request):
|
|
43
|
+
return request.param
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@pytest.fixture(
|
|
47
|
+
params=[
|
|
48
|
+
"foo<1.0",
|
|
49
|
+
"foo<=1.0",
|
|
50
|
+
" foo <= 1.0.0 ",
|
|
51
|
+
"foo!=1.0",
|
|
52
|
+
"foo==1!1.0foo>=1,<2foo >= 1.0.1, <= 2.0.*",
|
|
53
|
+
"foo>1.0.0,<2.0.0",
|
|
54
|
+
"foo <=2.0, != 1.0.1",
|
|
55
|
+
"foo~=1.0.0,!=1.0.1foo ~=1.0.0, != 1.0.1foo>=1.0,<2.0,!=1.5.7",
|
|
56
|
+
]
|
|
57
|
+
)
|
|
58
|
+
def unsupported_specifier(request):
|
|
59
|
+
return request.param
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@pytest.fixture(
|
|
63
|
+
params=[
|
|
64
|
+
"foo",
|
|
65
|
+
"foo-bar2",
|
|
66
|
+
" foo ",
|
|
67
|
+
"foo[bar]",
|
|
68
|
+
"foo [bar,baz]",
|
|
69
|
+
"foo[bar, baz, qux] ;platform_version=='2'",
|
|
70
|
+
"foo; os_name=='a' or os_name=='b'",
|
|
71
|
+
]
|
|
72
|
+
)
|
|
73
|
+
def unversioned_specifier(request):
|
|
74
|
+
return request.param
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@pytest.fixture(
|
|
78
|
+
params=[
|
|
79
|
+
"foo >= 1.0.1, == 1.0.*",
|
|
80
|
+
"foo [bar,baz] >= 2.8.1, == 2.8.* ; python_version < '4.0'",
|
|
81
|
+
]
|
|
82
|
+
)
|
|
83
|
+
def complex_specifier(request):
|
|
84
|
+
return request.param
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@pytest.fixture(
|
|
88
|
+
params=[
|
|
89
|
+
"foo@http://foo.com",
|
|
90
|
+
"foo @ http://foo.com ; python_version=='2.7'",
|
|
91
|
+
"foo @ https://github.com/foo/foo/archive/1.0.0.zip",
|
|
92
|
+
"foo @ file:///builds/foo-1.0.0-py3-none-any.whl`",
|
|
93
|
+
]
|
|
94
|
+
)
|
|
95
|
+
def direct_reference_specifier(request):
|
|
96
|
+
return request.param
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@pytest.fixture(
|
|
100
|
+
params=[
|
|
101
|
+
"foo",
|
|
102
|
+
" foo ",
|
|
103
|
+
" foo",
|
|
104
|
+
"foo[",
|
|
105
|
+
"foo [",
|
|
106
|
+
"foo[bar]",
|
|
107
|
+
"foo[ bar ]",
|
|
108
|
+
"foo [bar]",
|
|
109
|
+
"foo[bar,baz]",
|
|
110
|
+
"foo[bar, baz]",
|
|
111
|
+
"foo [ bar , baz ]",
|
|
112
|
+
]
|
|
113
|
+
)
|
|
114
|
+
def package_name(request):
|
|
115
|
+
return request.param
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def test_name_and_operator(valid_specifier_name):
|
|
119
|
+
dependency_specifier, name = valid_specifier_name
|
|
120
|
+
valid_operators = ("===", "==", "~=", ">=", ">")
|
|
121
|
+
dependency_name, operator = bd.get_dependency_name_and_operator(dependency_specifier)
|
|
122
|
+
assert isinstance(operator, str)
|
|
123
|
+
assert operator in valid_operators
|
|
124
|
+
assert isinstance(dependency_name, str)
|
|
125
|
+
assert dependency_name == name
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def test_name_and_operator_with_unsupported_operator(unsupported_specifier):
|
|
129
|
+
with pytest.raises(ValueError, match="skipping unsupported '.*' version identifier"):
|
|
130
|
+
bd.get_dependency_name_and_operator(unsupported_specifier)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def test_name_and_operator_with_unversioned_specifier(unversioned_specifier):
|
|
134
|
+
with pytest.raises(ValueError, match="no version specified"):
|
|
135
|
+
bd.get_dependency_name_and_operator(unversioned_specifier)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def test_name_and_operator_with_complex_specifier(complex_specifier):
|
|
139
|
+
with pytest.raises(ValueError, match="can't handle complex dependency specifiers"):
|
|
140
|
+
bd.get_dependency_name_and_operator(complex_specifier)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def test_name_and_operator_with_direct_reference_specifier(direct_reference_specifier):
|
|
144
|
+
with pytest.raises(ValueError, match="can't handle direct reference dependency specifiers"):
|
|
145
|
+
bd.get_dependency_name_and_operator(direct_reference_specifier)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def test_update_dependency(valid_specifier_name):
|
|
149
|
+
dependency_specifier, name = valid_specifier_name
|
|
150
|
+
dependency_name, operator = bd.get_dependency_name_and_operator(dependency_specifier)
|
|
151
|
+
updated_dependency_specifier = bd.update_dependency(dependency_specifier)
|
|
152
|
+
assert isinstance(updated_dependency_specifier, str)
|
|
153
|
+
assert operator in updated_dependency_specifier
|
|
154
|
+
assert dependency_specifier not in updated_dependency_specifier
|
|
155
|
+
assert name in updated_dependency_specifier
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def test_fetch_latest_package_version():
|
|
159
|
+
version = bd.fetch_latest_package_version("requests")
|
|
160
|
+
assert isinstance(version, str)
|
|
161
|
+
assert version[0].isdigit()
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def test_fetch_unavailable_package_version():
|
|
165
|
+
version = bd.fetch_latest_package_version("definitely-not-a-package-found-on-pypi-1234")
|
|
166
|
+
assert version is None
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def test_package_base_name(package_name):
|
|
170
|
+
base_name = bd.get_package_base_name(package_name)
|
|
171
|
+
assert base_name == "foo"
|