mirror of
https://github.com/MousaZeidBaker/poetry-plugin-up.git
synced 2025-10-05 21:32:40 +02:00
feat: initial commit
This commit is contained in:
77
.github/workflows/release.yaml
vendored
Normal file
77
.github/workflows/release.yaml
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
# Workflow to release our package
|
||||
|
||||
name: Release
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
release_created: ${{ steps.release.outputs.release_created }}
|
||||
steps:
|
||||
- name: Release
|
||||
id: release
|
||||
uses: google-github-actions/release-please-action@v3
|
||||
with:
|
||||
# https://github.com/google-github-actions/release-please-action#configuration
|
||||
release-type: python
|
||||
changelog-types: >
|
||||
[
|
||||
{"type": "build", "section": "🏗️ Build System", "hidden": true},
|
||||
{"type": "chore", "section": "🧹 Miscellaneous Chores", "hidden": true},
|
||||
{"type": "ci", "section": "👷 Continuous Integration", "hidden": true},
|
||||
{"type": "docs", "section": "📝 Documentation"},
|
||||
{"type": "feat", "section": "🚀 Features"},
|
||||
{"type": "fix", "section": "🐛 Bug Fixes"},
|
||||
{"type": "perf", "section": "⚡ Performance Improvements"},
|
||||
{"type": "refactor", "section": "♻️ Code Refactoring", "hidden": true},
|
||||
{"type": "revert", "section": "⏪️ Reverts"},
|
||||
{"type": "style", "section": "💄 Styles", "hidden": true},
|
||||
{"type": "test", "section": "✅ Tests", "hidden": true}
|
||||
]
|
||||
include-v-in-tag: false
|
||||
publish:
|
||||
name: Publish
|
||||
runs-on: ubuntu-latest
|
||||
needs: release
|
||||
# only run when a new release is created
|
||||
if: ${{ needs.release.outputs.release_created }}
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
environment: [ testpypi, pypi ]
|
||||
environment: ${{ matrix.environment }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
|
||||
- name: Install poetry
|
||||
uses: snok/install-poetry@v1
|
||||
with:
|
||||
version: 1.2.1
|
||||
|
||||
- name: Build
|
||||
run: poetry build
|
||||
|
||||
- name: Publish testpypi
|
||||
if: ${{ matrix.environment=='testpypi' }}
|
||||
env:
|
||||
POETRY_REPOSITORIES_TESTPYPI_URL: https://test.pypi.org/legacy/
|
||||
POETRY_HTTP_BASIC_TESTPYPI_USERNAME: __token__
|
||||
POETRY_HTTP_BASIC_TESTPYPI_PASSWORD: ${{secrets.TESTPYPI_API_TOKEN}}
|
||||
run: poetry publish --repository testpypi
|
||||
|
||||
- name: Publish pypi
|
||||
if: ${{ matrix.environment=='pypi' }}
|
||||
env:
|
||||
POETRY_HTTP_BASIC_PYPI_USERNAME: __token__
|
||||
POETRY_HTTP_BASIC_PYPI_PASSWORD: ${{secrets.PYPI_API_TOKEN}}
|
||||
run: poetry publish
|
50
.github/workflows/test.yaml
vendored
Normal file
50
.github/workflows/test.yaml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
# Workflow to test our package
|
||||
|
||||
name: Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: [ '3.7', '3.8', '3.9', '3.10' ]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Install poetry
|
||||
uses: snok/install-poetry@v1
|
||||
with:
|
||||
version: 1.3.0
|
||||
|
||||
- name: Install dependencies
|
||||
run: poetry install
|
||||
|
||||
- name: Lint
|
||||
run: |
|
||||
source $(poetry env info --path)/bin/activate
|
||||
pre-commit install --install-hooks
|
||||
pre-commit run --all-files
|
||||
pre-commit run commitizen-branch --hook-stage push
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
source $(poetry env info --path)/bin/activate
|
||||
pytest tests -vv
|
||||
poetry up --help
|
||||
|
||||
- name: Build
|
||||
run: poetry build
|
132
.gitignore
vendored
Normal file
132
.gitignore
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# IntelliJ’s project specific settings files
|
||||
.idea
|
46
.pre-commit-config.yaml
Normal file
46
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,46 @@
|
||||
# https://pre-commit.com/#pre-commit-configyaml---top-level
|
||||
default_stages:
|
||||
- commit
|
||||
default_install_hook_types:
|
||||
- pre-commit
|
||||
- commit-msg
|
||||
- pre-push
|
||||
exclude: pypoetry
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.4.0
|
||||
hooks:
|
||||
- id: trailing-whitespace # https://github.com/pre-commit/pre-commit-hooks/tree/v4.3.0#trailing-whitespace
|
||||
- id: end-of-file-fixer # https://github.com/pre-commit/pre-commit-hooks/tree/v4.3.0#end-of-file-fixer
|
||||
- id: check-json # https://github.com/pre-commit/pre-commit-hooks/tree/v4.3.0#check-json
|
||||
- id: check-yaml # https://github.com/pre-commit/pre-commit-hooks/tree/v4.3.0#check-yaml
|
||||
- id: check-toml # https://github.com/pre-commit/pre-commit-hooks/tree/v4.3.0#check-toml
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 22.10.0
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.10.1
|
||||
hooks:
|
||||
- id: isort
|
||||
- repo: https://github.com/pycqa/flake8
|
||||
rev: 5.0.4
|
||||
hooks:
|
||||
- id: flake8
|
||||
additional_dependencies:
|
||||
- flake8-black
|
||||
- flake8-isort
|
||||
- repo: https://github.com/commitizen-tools/commitizen
|
||||
rev: v2.37.1
|
||||
hooks:
|
||||
- id: commitizen
|
||||
stages:
|
||||
- commit-msg
|
||||
- id: commitizen-branch
|
||||
stages:
|
||||
- push
|
||||
args:
|
||||
- --rev-range
|
||||
- origin/master..HEAD
|
||||
always_run: true
|
||||
pass_filenames: false
|
111
CONTRIBUTING.md
Normal file
111
CONTRIBUTING.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# Contributing
|
||||
|
||||
Contributions are welcome via pull requests. Please make sure to install git
|
||||
hooks which enforces certain rules and linting.
|
||||
|
||||
|
||||
## Getting started
|
||||
|
||||
Install dependencies & activate virtual env
|
||||
|
||||
```shell
|
||||
poetry install --sync && poetry shell
|
||||
```
|
||||
|
||||
Install git hooks
|
||||
|
||||
```shell
|
||||
pre-commit install --install-hooks --overwrite
|
||||
```
|
||||
|
||||
Run pre-commit hooks against all files
|
||||
|
||||
```shell
|
||||
pre-commit run --all-files
|
||||
```
|
||||
|
||||
Run tests
|
||||
|
||||
```shell
|
||||
pytest tests
|
||||
```
|
||||
|
||||
Install current project from branch
|
||||
|
||||
```shell
|
||||
poetry add git+https://github.com/MousaZeidBaker/poetry-plugin-up.git#branch-name
|
||||
```
|
||||
|
||||
|
||||
## Commit message
|
||||
|
||||
Commit messages **MUST** follow [Conventional
|
||||
Commits](https://www.conventionalcommits.org/) specification.
|
||||
|
||||
```
|
||||
<type>(<scope>): <description>
|
||||
│ │ │
|
||||
│ │ └─ Description: Short summary in present tense. Not capitalized. No period at the end.
|
||||
│ │
|
||||
│ └─ Scope: Optional contextual information
|
||||
│
|
||||
└─ Type: build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test
|
||||
|
||||
[optional body]
|
||||
|
||||
[optional footer(s)]
|
||||
```
|
||||
**Commit type** must be one of following:
|
||||
- **build**: Changes that affect the build system or external dependencies
|
||||
- **chore**: Other changes that don't modify src or test files
|
||||
- **ci**: Changes to our CI configuration files and scripts
|
||||
- **docs**: Documentation only changes
|
||||
- **feat**: A new feature
|
||||
- **fix**: A bug fix
|
||||
- **perf**: A code change that improves performance
|
||||
- **refactor**: A code change that neither fixes a bug nor adds a feature
|
||||
- **revert**: Reverts a previous commit
|
||||
- **style**: Changes that do not affect the meaning of the code (white-space,
|
||||
formatting, missing semi-colons, etc)
|
||||
- **test**: Adding missing tests or correcting existing tests
|
||||
|
||||
|
||||
### Automated releases
|
||||
|
||||
A fully automated release process is implemented using [Release
|
||||
Please](https://github.com/googleapis/release-please). The **commit type**
|
||||
determines the next [semantic version](https://semver.org/), see following
|
||||
examples:
|
||||
|
||||
- `fix:` represents a bug fix which correlates with a PATCH bump
|
||||
- `feat:` represents a new feature which correlates with a MINOR bump
|
||||
- `feat!:`, or `fix!:`, `refactor!:`, etc., represents a breaking change
|
||||
(indicated by the `!`) which correlates with a MAJOR bump
|
||||
|
||||
One can manually set the version number by adding `Release-As: x.y.z` to the
|
||||
**commit body**, but this should not be needed.
|
||||
|
||||
|
||||
### How to change a commit message?
|
||||
|
||||
Amend the most recent commit
|
||||
|
||||
```shell
|
||||
git commit --amend -m "fix: new message"
|
||||
```
|
||||
|
||||
Force push the changes if already pushed to remote
|
||||
|
||||
```shell
|
||||
git push --force-with-lease origin EXAMPLE-BRANCH
|
||||
```
|
||||
|
||||
Amend older or multiple commits with interactive rebase
|
||||
- use the `git rebase -i HEAD~N` command to display a list of the last `N`
|
||||
commits in your default text editor
|
||||
- replace `pick` with `reword` for each commit message that needs to be changed
|
||||
- save the changes and close the editor
|
||||
- for each chosen commit, a new editor will open, change the commit message,
|
||||
save the file, and close the editor
|
||||
- force push the changes, if already pushed to remote, with `git push
|
||||
--force-with-lease origin EXAMPLE-BRANCH`
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Mousa Zeid Baker
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
89
README.md
Normal file
89
README.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# Poetry Plugin: up
|
||||
|
||||

|
||||
[](LICENSE)
|
||||

|
||||

|
||||
|
||||
This package is a plugin that updates dependencies and bumps their versions in
|
||||
`pyproject.toml` file. The version constraints are respected, unless the
|
||||
`--latest` flag is passed, in which case dependencies are updated to latest
|
||||
available compatible versions.
|
||||
|
||||
This plugin provides similar features as the existing `update` command with
|
||||
additional features.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
The easiest way to install the `up` plugin is via the `self add` command of
|
||||
Poetry.
|
||||
|
||||
```shell
|
||||
poetry self add poetry-plugin-up
|
||||
```
|
||||
|
||||
If you used `pipx` to install Poetry you can add the plugin via the `pipx
|
||||
inject` command.
|
||||
|
||||
```shell
|
||||
pipx inject poetry poetry-plugin-up
|
||||
```
|
||||
|
||||
Otherwise, if you used `pip` to install Poetry you can add the plugin packages
|
||||
via the `pip install` command.
|
||||
|
||||
```shell
|
||||
pip install poetry-plugin-up
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
The plugin provides an `up` command to update dependencies
|
||||
|
||||
```shell
|
||||
poetry up --help
|
||||
```
|
||||
|
||||
Update dependencies
|
||||
|
||||
```shell
|
||||
poetry up
|
||||
```
|
||||
|
||||
Update dependencies to latest available compatible versions
|
||||
|
||||
```shell
|
||||
poetry up --latest
|
||||
```
|
||||
|
||||
Update the `foo` and `bar` packages
|
||||
|
||||
```shell
|
||||
poetry up foo bar
|
||||
```
|
||||
|
||||
Update packages only in the `main` group
|
||||
|
||||
```shell
|
||||
poetry up --only main
|
||||
```
|
||||
|
||||
Update packages but ignore the `dev` group
|
||||
|
||||
```shell
|
||||
poetry up --without dev
|
||||
```
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! See the [Contributing Guide](https://github.com/MousaZeidBaker/poetry-plugin-up/blob/master/CONTRIBUTING.md).
|
||||
|
||||
|
||||
## Issues
|
||||
|
||||
If you encounter any problems, please file an
|
||||
[issue](https://github.com/MousaZeidBaker/poetry-plugin-up/issues) along with a
|
||||
detailed description.
|
1444
poetry.lock
generated
Normal file
1444
poetry.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
48
pyproject.toml
Normal file
48
pyproject.toml
Normal file
@@ -0,0 +1,48 @@
|
||||
[tool.poetry]
|
||||
name = "poetry-plugin-up"
|
||||
version = "0.0.0"
|
||||
description = "Poetry plugin that updates dependencies and bumps their versions in pyproject.toml file"
|
||||
authors = ["Mousa Zeid Baker"]
|
||||
packages = [
|
||||
{ include = "poetry_plugin_up", from = "src" },
|
||||
]
|
||||
license = "MIT"
|
||||
readme = "README.md"
|
||||
homepage = "https://github.com/MousaZeidBaker/poetry-plugin-up"
|
||||
repository = "https://github.com/MousaZeidBaker/poetry-plugin-up"
|
||||
keywords=[
|
||||
"packaging",
|
||||
"dependency",
|
||||
"poetry",
|
||||
"update",
|
||||
"upgrade",
|
||||
]
|
||||
classifiers=[
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Programming Language :: Python :: 3",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Operating System :: OS Independent",
|
||||
]
|
||||
include = ["LICENSE"]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.7"
|
||||
poetry = "^1.2.0"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pre-commit = "^2.20.0"
|
||||
pytest = "^7.2.0"
|
||||
pytest-mock = "^3.10.0"
|
||||
|
||||
[tool.poetry.plugins."poetry.application.plugin"]
|
||||
up = "poetry_plugin_up.plugin:UpApplicationPlugin"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
[tool.black]
|
||||
line-length = 80
|
||||
|
||||
[tool.isort]
|
||||
profile = "black"
|
0
src/poetry_plugin_up/__init__.py
Normal file
0
src/poetry_plugin_up/__init__.py
Normal file
199
src/poetry_plugin_up/command.py
Normal file
199
src/poetry_plugin_up/command.py
Normal file
@@ -0,0 +1,199 @@
|
||||
from typing import Any, Dict, Iterable, List
|
||||
|
||||
from cleo.helpers import argument, option
|
||||
from poetry.console.commands.installer_command import InstallerCommand
|
||||
from poetry.core.packages.dependency import Dependency
|
||||
from poetry.core.packages.dependency_group import DependencyGroup
|
||||
from poetry.core.packages.package import Package
|
||||
from poetry.version.version_selector import VersionSelector
|
||||
from tomlkit import dumps
|
||||
from tomlkit.toml_document import TOMLDocument
|
||||
|
||||
|
||||
class UpCommand(InstallerCommand):
|
||||
name = "up"
|
||||
description = (
|
||||
"Update dependencies and bump versions in <comment>pyproject.toml</>"
|
||||
)
|
||||
|
||||
arguments = [
|
||||
argument(
|
||||
name="packages",
|
||||
description="The packages to update.",
|
||||
optional=True,
|
||||
multiple=True,
|
||||
)
|
||||
]
|
||||
|
||||
options = [
|
||||
*InstallerCommand._group_dependency_options(),
|
||||
option(
|
||||
long_name="latest",
|
||||
short_name=None,
|
||||
description="Update to latest available compatible versions.",
|
||||
),
|
||||
option(
|
||||
long_name="no-install",
|
||||
short_name=None,
|
||||
description="Do not install dependencies, only refresh "
|
||||
"<comment>pyproject.toml</> and <comment>poetry.lock</>.",
|
||||
),
|
||||
option(
|
||||
long_name="dry-run",
|
||||
short_name=None,
|
||||
description="Output bumped <comment>pyproject.toml</> but do not "
|
||||
"execute anything.",
|
||||
),
|
||||
]
|
||||
|
||||
def handle(self) -> int:
|
||||
only_packages = self.argument("packages")
|
||||
latest = self.option("latest")
|
||||
no_install = self.option("no-install")
|
||||
dry_run = self.option("dry-run")
|
||||
|
||||
selector = VersionSelector(self.poetry.pool)
|
||||
pyproject_content = self.poetry.file.read()
|
||||
|
||||
for group in self.get_groups():
|
||||
for dependency in group.dependencies:
|
||||
self.handle_dependency(
|
||||
dependency=dependency,
|
||||
latest=latest,
|
||||
only_packages=only_packages,
|
||||
pyproject_content=pyproject_content,
|
||||
selector=selector,
|
||||
)
|
||||
|
||||
if dry_run:
|
||||
self.line(dumps(pyproject_content))
|
||||
return 0
|
||||
|
||||
# write new content to pyproject.toml
|
||||
self.poetry.file.write(pyproject_content)
|
||||
|
||||
if no_install:
|
||||
# update lock file
|
||||
self.call(name="lock", args="--no-update")
|
||||
return 0
|
||||
|
||||
# update dependencies
|
||||
self.call(name="update")
|
||||
return 0
|
||||
|
||||
def get_groups(self) -> Iterable[DependencyGroup]:
|
||||
"""Returns activated dependency groups"""
|
||||
|
||||
for group in self.activated_groups:
|
||||
yield self.poetry.package.dependency_group(group)
|
||||
|
||||
def handle_dependency(
|
||||
self,
|
||||
dependency: Dependency,
|
||||
latest: bool,
|
||||
only_packages: List[str],
|
||||
pyproject_content: TOMLDocument,
|
||||
selector: VersionSelector,
|
||||
) -> None:
|
||||
"""Handles a dependency"""
|
||||
|
||||
if not self.is_bumpable(dependency, only_packages, latest):
|
||||
return
|
||||
|
||||
target_package_version = dependency.pretty_constraint
|
||||
if latest:
|
||||
target_package_version = "*"
|
||||
|
||||
candidate: Package = selector.find_best_candidate(
|
||||
package_name=dependency.name,
|
||||
target_package_version=target_package_version,
|
||||
allow_prereleases=dependency.allows_prereleases(),
|
||||
source=dependency.source_name,
|
||||
)
|
||||
if candidate is None:
|
||||
self.line(f"No new version for '{dependency.name}'")
|
||||
return
|
||||
|
||||
new_version = "^" + candidate.pretty_version
|
||||
if not latest:
|
||||
if dependency.pretty_constraint[0] == "~":
|
||||
new_version = "~" + candidate.pretty_version
|
||||
elif dependency.pretty_constraint[:2] == ">=":
|
||||
new_version = ">=" + candidate.pretty_version
|
||||
|
||||
self.bump_version_in_pyproject_content(
|
||||
dependency=dependency,
|
||||
new_version=new_version,
|
||||
pyproject_content=pyproject_content,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def is_bumpable(
|
||||
dependency: Dependency,
|
||||
only_packages: List[str],
|
||||
latest: bool,
|
||||
) -> bool:
|
||||
"""Determines if a dependency can be bumped in pyproject.toml"""
|
||||
|
||||
if dependency.source_type in ["git", "file", "directory"]:
|
||||
return False
|
||||
if dependency.name in ["python"]:
|
||||
return False
|
||||
if only_packages and dependency.name not in only_packages:
|
||||
return False
|
||||
if not latest:
|
||||
constraint = dependency.pretty_constraint
|
||||
if constraint[0].isdigit():
|
||||
# pinned
|
||||
return False
|
||||
if constraint[0] == "*":
|
||||
# wildcard
|
||||
return False
|
||||
if constraint[0] == "<" and constraint[1].isdigit():
|
||||
# less than
|
||||
return False
|
||||
if constraint[0] == ">" and constraint[1].isdigit():
|
||||
# greater than
|
||||
return False
|
||||
if constraint[:2] == "<=":
|
||||
# less than or equal to
|
||||
return False
|
||||
if constraint[:2] == "!=":
|
||||
# inequality
|
||||
return False
|
||||
if len(constraint.split(",")) > 1:
|
||||
# multiple requirements e.g. '>=1.0.0, <2.0.0'
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def bump_version_in_pyproject_content(
|
||||
dependency: Dependency,
|
||||
new_version: str,
|
||||
pyproject_content: TOMLDocument,
|
||||
) -> None:
|
||||
"""Bumps versions in pyproject content (pyproject.toml)"""
|
||||
|
||||
poetry_content: Dict[str, Any] = pyproject_content["tool"]["poetry"]
|
||||
|
||||
for group in dependency.groups:
|
||||
# find section to modify
|
||||
section = {}
|
||||
if group == "main":
|
||||
section = poetry_content.get("dependencies", {})
|
||||
elif group == "dev" and "dev-dependencies" in poetry_content:
|
||||
# take account for the old `dev-dependencies` section
|
||||
section = poetry_content.get("dev-dependencies", {})
|
||||
else:
|
||||
section = (
|
||||
poetry_content.get("group", {})
|
||||
.get(group, {})
|
||||
.get("dependencies", {})
|
||||
)
|
||||
|
||||
# modify section
|
||||
if isinstance(section.get(dependency.pretty_name), str):
|
||||
section[dependency.pretty_name] = new_version
|
||||
elif "version" in section.get(dependency.pretty_name, {}):
|
||||
section[dependency.pretty_name]["version"] = new_version
|
12
src/poetry_plugin_up/plugin.py
Normal file
12
src/poetry_plugin_up/plugin.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from poetry.plugins.application_plugin import ApplicationPlugin
|
||||
|
||||
from poetry_plugin_up.command import UpCommand
|
||||
|
||||
|
||||
def factory():
|
||||
return UpCommand()
|
||||
|
||||
|
||||
class UpApplicationPlugin(ApplicationPlugin):
|
||||
def activate(self, application):
|
||||
application.command_loader.register_factory("up", factory)
|
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
88
tests/conftest.py
Normal file
88
tests/conftest.py
Normal file
@@ -0,0 +1,88 @@
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
import pytest
|
||||
from cleo.testers.application_tester import ApplicationTester
|
||||
from poetry.core.packages.dependency_group import DependencyGroup
|
||||
from poetry.core.packages.package import Package
|
||||
from poetry.core.pyproject.toml import PyProjectTOML
|
||||
from poetry.factory import Factory
|
||||
from poetry.poetry import Poetry
|
||||
from pytest import TempPathFactory
|
||||
from tomlkit.toml_document import TOMLDocument
|
||||
|
||||
from tests.helpers import TestApplication, TestUpCommand
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def project_path() -> Path:
|
||||
return Path(__file__).parent / "fixtures" / "simple_project"
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def pyproject_content(project_path: Path) -> TOMLDocument:
|
||||
path = project_path / "pyproject.toml"
|
||||
return PyProjectTOML(path).file.read()
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def expected_pyproject_content(project_path: Path) -> TOMLDocument:
|
||||
path = project_path / "expected_pyproject.toml"
|
||||
return PyProjectTOML(path).file.read()
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def tmp_pyproject_path(
|
||||
tmp_path_factory: TempPathFactory,
|
||||
pyproject_content: TOMLDocument,
|
||||
) -> Path:
|
||||
tmp_pyproject_path = (
|
||||
tmp_path_factory.mktemp("simple_project") / "pyproject.toml"
|
||||
)
|
||||
tmp_pyproject_path.write_text(pyproject_content.as_string())
|
||||
return tmp_pyproject_path
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def app_tester(tmp_pyproject_path: Path) -> ApplicationTester:
|
||||
poetry = Factory().create_poetry(tmp_pyproject_path)
|
||||
app = TestApplication(poetry)
|
||||
return ApplicationTester(app)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def poetry(project_path: Path) -> Poetry:
|
||||
return Factory().create_poetry(project_path)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def up_cmd_tester(poetry: Poetry) -> TestUpCommand:
|
||||
return TestUpCommand(poetry)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def groups(poetry: Poetry) -> List[DependencyGroup]:
|
||||
return poetry.package._dependency_groups.values()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def packages() -> List[Package]:
|
||||
return [
|
||||
Package(name="foo", version="2.2.2"),
|
||||
Package(name="bar", version="2.2.2"),
|
||||
Package(name="baz", version="2.2.2"),
|
||||
Package(name="corge", version="2.2.2"),
|
||||
Package(name="grault", version="2.2.2"),
|
||||
Package(name="garply", version="2.2.2"),
|
||||
Package(name="waldo", version="2.2.2"),
|
||||
Package(name="fred", version="2.2.2"),
|
||||
Package(name="plugh", version="2.2.2"),
|
||||
Package(name="xyzzy", version="2.2.2"),
|
||||
Package(name="nacho", version="2.2.2"),
|
||||
Package(name="thud", version="2.2.2"),
|
||||
Package(name="foobar", version="2.2.2"),
|
||||
Package(name="foobaz", version="2.2.2"),
|
||||
Package(name="fooqux", version="2.2.2"),
|
||||
Package(name="fooquux", version="2.2.2"),
|
||||
Package(name="foo-corge", version="2.2.2"),
|
||||
]
|
102
tests/e2e/test_e2e.py
Normal file
102
tests/e2e/test_e2e.py
Normal file
@@ -0,0 +1,102 @@
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
from cleo.testers.application_tester import ApplicationTester
|
||||
from poetry.core.packages.package import Package
|
||||
from poetry.core.pyproject.toml import PyProjectTOML
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
|
||||
def test_command(
|
||||
app_tester: ApplicationTester,
|
||||
packages: List[Package],
|
||||
mocker: MockerFixture,
|
||||
project_path: Path,
|
||||
tmp_pyproject_path: Path,
|
||||
) -> None:
|
||||
command_call = mocker.patch(
|
||||
"poetry.console.commands.command.Command.call",
|
||||
return_value=0,
|
||||
)
|
||||
mocker.patch(
|
||||
"poetry.version.version_selector.VersionSelector.find_best_candidate",
|
||||
side_effect=packages,
|
||||
)
|
||||
|
||||
path = project_path / "expected_pyproject.toml"
|
||||
expected = PyProjectTOML(path).file.read()
|
||||
|
||||
assert app_tester.execute("up") == 0
|
||||
assert PyProjectTOML(tmp_pyproject_path).file.read() == expected
|
||||
command_call.assert_called_once_with(name="update")
|
||||
|
||||
|
||||
def test_command_with_latest(
|
||||
app_tester: ApplicationTester,
|
||||
packages: List[Package],
|
||||
mocker: MockerFixture,
|
||||
project_path: Path,
|
||||
tmp_pyproject_path: Path,
|
||||
) -> None:
|
||||
command_call = mocker.patch(
|
||||
"poetry.console.commands.command.Command.call",
|
||||
return_value=0,
|
||||
)
|
||||
mocker.patch(
|
||||
"poetry.version.version_selector.VersionSelector.find_best_candidate",
|
||||
side_effect=packages,
|
||||
)
|
||||
|
||||
path = project_path / "expected_pyproject_with_latest.toml"
|
||||
expected = PyProjectTOML(path).file.read()
|
||||
|
||||
assert app_tester.execute("up --latest") == 0
|
||||
assert PyProjectTOML(tmp_pyproject_path).file.read() == expected
|
||||
command_call.assert_called_once_with(name="update")
|
||||
|
||||
|
||||
def test_command_with_dry_run(
|
||||
app_tester: ApplicationTester,
|
||||
packages: List[Package],
|
||||
mocker: MockerFixture,
|
||||
tmp_pyproject_path: Path,
|
||||
) -> None:
|
||||
command_call = mocker.patch(
|
||||
"poetry.console.commands.command.Command.call",
|
||||
return_value=0,
|
||||
)
|
||||
mocker.patch(
|
||||
"poetry.version.version_selector.VersionSelector.find_best_candidate",
|
||||
side_effect=packages,
|
||||
)
|
||||
|
||||
expected = PyProjectTOML(tmp_pyproject_path).file.read()
|
||||
|
||||
assert app_tester.execute("up --dry-run") == 0
|
||||
# assert pyproject.toml file not modified
|
||||
assert PyProjectTOML(tmp_pyproject_path).file.read() == expected
|
||||
command_call.assert_not_called()
|
||||
|
||||
|
||||
def test_command_with_no_install(
|
||||
app_tester: ApplicationTester,
|
||||
packages: List[Package],
|
||||
mocker: MockerFixture,
|
||||
project_path: Path,
|
||||
tmp_pyproject_path: Path,
|
||||
) -> None:
|
||||
command_call = mocker.patch(
|
||||
"poetry.console.commands.command.Command.call",
|
||||
return_value=0,
|
||||
)
|
||||
mocker.patch(
|
||||
"poetry.version.version_selector.VersionSelector.find_best_candidate",
|
||||
side_effect=packages,
|
||||
)
|
||||
|
||||
path = project_path / "expected_pyproject.toml"
|
||||
expected = PyProjectTOML(path).file.read()
|
||||
|
||||
assert app_tester.execute("up --no-install") == 0
|
||||
assert PyProjectTOML(tmp_pyproject_path).file.read() == expected
|
||||
command_call.assert_called_once_with(name="lock", args="--no-update")
|
30
tests/fixtures/simple_project/expected_pyproject.toml
vendored
Normal file
30
tests/fixtures/simple_project/expected_pyproject.toml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
[tool.poetry]
|
||||
name = "simple-project"
|
||||
version = "1.2.3"
|
||||
description = "Some description."
|
||||
authors = ["Mousa Zeid Baker"]
|
||||
license = "MIT"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.7"
|
||||
foo = "^2.2.2"
|
||||
bar = "^2.2.2"
|
||||
baz = {version = "^2.2.2", extras = ["qux", "quux"]}
|
||||
corge = {version = "^2.2.2", optional = true}
|
||||
grault = {version = "^2.2.2", allow-prereleases = true}
|
||||
garply = {path = "./"}
|
||||
waldo = {git = "https://example.com/test/project.git"}
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
fred = "1.1.1"
|
||||
plugh = "^2.2.2"
|
||||
xyzzy = "~2.2.2"
|
||||
nacho = "<1.1.1"
|
||||
thud = ">1.1.1"
|
||||
|
||||
[tool.poetry.group.docs.dependencies]
|
||||
foobar = "<=1.1.1"
|
||||
foobaz = ">=2.2.2"
|
||||
fooqux = "!=1.1.1"
|
||||
fooquux = "*"
|
||||
Foo_Corge = "^2.2.2"
|
30
tests/fixtures/simple_project/expected_pyproject_with_latest.toml
vendored
Normal file
30
tests/fixtures/simple_project/expected_pyproject_with_latest.toml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
[tool.poetry]
|
||||
name = "simple-project"
|
||||
version = "1.2.3"
|
||||
description = "Some description."
|
||||
authors = ["Mousa Zeid Baker"]
|
||||
license = "MIT"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.7"
|
||||
foo = "^2.2.2"
|
||||
bar = "^2.2.2"
|
||||
baz = {version = "^2.2.2", extras = ["qux", "quux"]}
|
||||
corge = {version = "^2.2.2", optional = true}
|
||||
grault = {version = "^2.2.2", allow-prereleases = true}
|
||||
garply = {path = "./"}
|
||||
waldo = {git = "https://example.com/test/project.git"}
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
fred = "^2.2.2"
|
||||
plugh = "^2.2.2"
|
||||
xyzzy = "^2.2.2"
|
||||
nacho = "^2.2.2"
|
||||
thud = "^2.2.2"
|
||||
|
||||
[tool.poetry.group.docs.dependencies]
|
||||
foobar = "^2.2.2"
|
||||
foobaz = "^2.2.2"
|
||||
fooqux = "^2.2.2"
|
||||
fooquux = "^2.2.2"
|
||||
Foo_Corge = "^2.2.2"
|
30
tests/fixtures/simple_project/pyproject.toml
vendored
Normal file
30
tests/fixtures/simple_project/pyproject.toml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
[tool.poetry]
|
||||
name = "simple-project"
|
||||
version = "1.2.3"
|
||||
description = "Some description."
|
||||
authors = ["Mousa Zeid Baker"]
|
||||
license = "MIT"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.7"
|
||||
foo = "^1.1.1"
|
||||
bar = "^1.1.1"
|
||||
baz = {version = "^1.1.1", extras = ["qux", "quux"]}
|
||||
corge = {version = "^1.1.1", optional = true}
|
||||
grault = {version = "^1.1.1", allow-prereleases = true}
|
||||
garply = {path = "./"}
|
||||
waldo = {git = "https://example.com/test/project.git"}
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
fred = "1.1.1"
|
||||
plugh = "^1.1.1"
|
||||
xyzzy = "~1.1.1"
|
||||
nacho = "<1.1.1"
|
||||
thud = ">1.1.1"
|
||||
|
||||
[tool.poetry.group.docs.dependencies]
|
||||
foobar = "<=1.1.1"
|
||||
foobaz = ">=1.1.1"
|
||||
fooqux = "!=1.1.1"
|
||||
fooquux = "*"
|
||||
Foo_Corge = "^1.1.1"
|
23
tests/helpers.py
Normal file
23
tests/helpers.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from typing import Any
|
||||
|
||||
from poetry.console.application import Application
|
||||
from poetry.poetry import Poetry
|
||||
|
||||
from poetry_plugin_up.command import UpCommand
|
||||
|
||||
|
||||
class TestUpCommand(UpCommand):
|
||||
def __init__(self, poetry: Poetry) -> None:
|
||||
super().__init__()
|
||||
self._poetry = poetry
|
||||
|
||||
__test__ = False
|
||||
|
||||
def line(self, data: Any):
|
||||
print(data)
|
||||
|
||||
|
||||
class TestApplication(Application):
|
||||
def __init__(self, poetry: Poetry) -> None:
|
||||
super().__init__()
|
||||
self._poetry = poetry
|
98
tests/integration/test_integration.py
Normal file
98
tests/integration/test_integration.py
Normal file
@@ -0,0 +1,98 @@
|
||||
from unittest.mock import Mock
|
||||
|
||||
from poetry.core.packages.dependency import Dependency
|
||||
from poetry.core.packages.package import Package
|
||||
from pytest_mock import MockerFixture
|
||||
from tomlkit import parse
|
||||
|
||||
from tests.helpers import TestUpCommand
|
||||
|
||||
|
||||
def test_handle_dependency(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
mocker: MockerFixture,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint="^1.0",
|
||||
groups=["main"],
|
||||
)
|
||||
new_version = "2.0.0"
|
||||
package = Package(
|
||||
name=dependency.name,
|
||||
version=new_version,
|
||||
)
|
||||
|
||||
content = parse("")
|
||||
|
||||
selector = Mock()
|
||||
selector.find_best_candidate = Mock(return_value=package)
|
||||
bump_version_in_pyproject_content = mocker.patch(
|
||||
"poetry_plugin_up.command.UpCommand.bump_version_in_pyproject_content",
|
||||
return_value=None,
|
||||
)
|
||||
|
||||
up_cmd_tester.handle_dependency(
|
||||
dependency=dependency,
|
||||
latest=False,
|
||||
only_packages=[],
|
||||
pyproject_content=content,
|
||||
selector=selector,
|
||||
)
|
||||
|
||||
selector.find_best_candidate.assert_called_once_with(
|
||||
package_name=dependency.name,
|
||||
target_package_version=dependency.pretty_constraint,
|
||||
allow_prereleases=dependency.allows_prereleases(),
|
||||
source=dependency.source_name,
|
||||
)
|
||||
bump_version_in_pyproject_content.assert_called_once_with(
|
||||
dependency=dependency,
|
||||
new_version=f"^{new_version}",
|
||||
pyproject_content=content,
|
||||
)
|
||||
|
||||
|
||||
def test_handle_dependency_with_latest(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
mocker: MockerFixture,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint="^1.0",
|
||||
groups=["main"],
|
||||
)
|
||||
new_version = "2.0.0"
|
||||
package = Package(
|
||||
name=dependency.name,
|
||||
version=new_version,
|
||||
)
|
||||
|
||||
content = parse("")
|
||||
|
||||
selector = Mock()
|
||||
selector.find_best_candidate = Mock(return_value=package)
|
||||
bump_version_in_pyproject_content = mocker.patch(
|
||||
"poetry_plugin_up.command.UpCommand.bump_version_in_pyproject_content",
|
||||
return_value=None,
|
||||
)
|
||||
|
||||
up_cmd_tester.handle_dependency(
|
||||
dependency=dependency,
|
||||
latest=True,
|
||||
only_packages=[],
|
||||
pyproject_content=content,
|
||||
selector=selector,
|
||||
)
|
||||
|
||||
selector.find_best_candidate.assert_called_once_with(
|
||||
package_name=dependency.name,
|
||||
target_package_version="*",
|
||||
allow_prereleases=dependency.allows_prereleases(),
|
||||
source=dependency.source_name,
|
||||
)
|
||||
bump_version_in_pyproject_content.assert_called_once_with(
|
||||
dependency=dependency,
|
||||
new_version=f"^{new_version}",
|
||||
pyproject_content=content,
|
||||
)
|
414
tests/unit/test_unit.py
Normal file
414
tests/unit/test_unit.py
Normal file
@@ -0,0 +1,414 @@
|
||||
from poetry.core.packages.dependency import Dependency
|
||||
from tomlkit import parse
|
||||
|
||||
from tests.helpers import TestUpCommand
|
||||
|
||||
|
||||
def test_bump_version_in_pyproject_content(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
|
||||
dependencies = [
|
||||
Dependency(
|
||||
name="foo",
|
||||
constraint="^1.0",
|
||||
groups=["main"],
|
||||
),
|
||||
Dependency(
|
||||
name="bar",
|
||||
constraint="^1.0",
|
||||
groups=["main"],
|
||||
optional=True,
|
||||
),
|
||||
Dependency(
|
||||
name="baz",
|
||||
constraint="^1.0",
|
||||
groups=["dev"],
|
||||
),
|
||||
]
|
||||
|
||||
content = parse(
|
||||
"""
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.7"
|
||||
foo = "^1.0"
|
||||
bar = { version = "^1.1", optional = true }
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
baz = "^1.2"
|
||||
"""
|
||||
)
|
||||
|
||||
for dependency in dependencies:
|
||||
new_version = "^1.9"
|
||||
up_cmd_tester.bump_version_in_pyproject_content(
|
||||
dependency=dependency,
|
||||
new_version=new_version,
|
||||
pyproject_content=content,
|
||||
)
|
||||
|
||||
poetry_content = content["tool"]["poetry"]
|
||||
assert poetry_content["dependencies"]["foo"] == new_version
|
||||
assert poetry_content["dependencies"]["bar"]["version"] == new_version
|
||||
assert poetry_content["group"]["dev"]["dependencies"]["baz"] == new_version
|
||||
|
||||
|
||||
def test_bump_version_in_pyproject_content_with_old_dev_dependencies(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
|
||||
dependencies = [
|
||||
Dependency(
|
||||
name="foo",
|
||||
constraint="^1.0",
|
||||
groups=["main"],
|
||||
),
|
||||
Dependency(
|
||||
name="bar",
|
||||
constraint="^1.0",
|
||||
groups=["main"],
|
||||
optional=True,
|
||||
),
|
||||
Dependency(
|
||||
name="baz",
|
||||
constraint="^1.0",
|
||||
groups=["dev"],
|
||||
),
|
||||
]
|
||||
|
||||
content = parse(
|
||||
"""
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.7"
|
||||
foo = "^1.0"
|
||||
bar = { version = "^1.1", optional = true }
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
baz = "^1.2"
|
||||
"""
|
||||
)
|
||||
|
||||
for dependency in dependencies:
|
||||
new_version = "^1.9"
|
||||
up_cmd_tester.bump_version_in_pyproject_content(
|
||||
dependency=dependency,
|
||||
new_version=new_version,
|
||||
pyproject_content=content,
|
||||
)
|
||||
|
||||
poetry_content = content["tool"]["poetry"]
|
||||
assert poetry_content["dependencies"]["foo"] == new_version
|
||||
assert poetry_content["dependencies"]["bar"]["version"] == new_version
|
||||
assert poetry_content["dev-dependencies"]["baz"] == new_version
|
||||
|
||||
|
||||
def test_is_bumpable_is_false_when_source_type_is_git(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint="*",
|
||||
source_type="git",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=False,
|
||||
)
|
||||
assert is_bumpable is False
|
||||
|
||||
|
||||
def test_is_bumpable_is_false_when_source_type_is_file(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint="*",
|
||||
source_type="file",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=False,
|
||||
)
|
||||
assert is_bumpable is False
|
||||
|
||||
|
||||
def test_is_bumpable_is_false_when_source_type_is_directory(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint="*",
|
||||
source_type="directory",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=False,
|
||||
)
|
||||
assert is_bumpable is False
|
||||
|
||||
|
||||
def test_is_bumpable_is_false_when_name_is_python(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(name="python", constraint="^1.2.3")
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=False,
|
||||
)
|
||||
assert is_bumpable is False
|
||||
|
||||
|
||||
def test_is_bumpable_is_false_when_dependency_not_in_only_packages(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(name="foo", constraint="^1.2.3")
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=["bar"],
|
||||
latest=False,
|
||||
)
|
||||
assert is_bumpable is False
|
||||
|
||||
|
||||
def test_is_bumpable_is_false_when_version_pinned(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint="1.2.3",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=False,
|
||||
)
|
||||
assert is_bumpable is False
|
||||
|
||||
|
||||
def test_is_bumpable_is_false_when_version_wildcard(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint="*",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=False,
|
||||
)
|
||||
assert is_bumpable is False
|
||||
|
||||
|
||||
def test_is_bumpable_is_false_when_version_less_than(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint="<1.2.3",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=False,
|
||||
)
|
||||
assert is_bumpable is False
|
||||
|
||||
|
||||
def test_is_bumpable_is_false_when_version_greater_than(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint=">1.2.3",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=False,
|
||||
)
|
||||
assert is_bumpable is False
|
||||
|
||||
|
||||
def test_is_bumpable_is_false_when_version_less_than_or_equal(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint="<=1.2.3",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=False,
|
||||
)
|
||||
assert is_bumpable is False
|
||||
|
||||
|
||||
def test_is_bumpable_is_false_when_version_inequality(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint="!=1.2.3",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=False,
|
||||
)
|
||||
assert is_bumpable is False
|
||||
|
||||
|
||||
def test_is_bumpable_is_false_when_version_multiple_requirements(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint=">=1.2.3, <2.0.0",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=False,
|
||||
)
|
||||
assert is_bumpable is False
|
||||
|
||||
|
||||
def test_is_bumpable_is_true_when_version_caret(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint="^1.2.3",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=False,
|
||||
)
|
||||
assert is_bumpable is True
|
||||
|
||||
|
||||
def test_is_bumpable_is_true_when_version_tilde(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint="~1.2.3",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=False,
|
||||
)
|
||||
assert is_bumpable is True
|
||||
|
||||
|
||||
def test_is_bumpable_is_true_when_version_greater_than_or_equal(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint=">=1.2.3",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=False,
|
||||
)
|
||||
assert is_bumpable is True
|
||||
|
||||
|
||||
def test_is_bumpable_is_true_when_version_tilde_pep440(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint="~=1.2.3",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=False,
|
||||
)
|
||||
assert is_bumpable is True
|
||||
|
||||
|
||||
def test_is_bumpable_is_true_when_version_pinned_and_latest(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint="1.2.3",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=True,
|
||||
)
|
||||
assert is_bumpable is True
|
||||
|
||||
|
||||
def test_is_bumpable_is_true_when_version_wildcard_and_latest(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint="*",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=True,
|
||||
)
|
||||
assert is_bumpable is True
|
||||
|
||||
|
||||
def test_is_bumpable_is_true_when_version_less_than_and_latest(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint="<1.2.3",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=True,
|
||||
)
|
||||
assert is_bumpable is True
|
||||
|
||||
|
||||
def test_is_bumpable_is_true_when_version_greater_than_and_latest(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint=">1.2.3",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=True,
|
||||
)
|
||||
assert is_bumpable is True
|
||||
|
||||
|
||||
def test_is_bumpable_is_true_when_version_less_than_or_equal_and_latest(
|
||||
up_cmd_tester: TestUpCommand,
|
||||
) -> None:
|
||||
dependency = Dependency(
|
||||
name="foo",
|
||||
constraint="<=1.2.3",
|
||||
)
|
||||
is_bumpable = up_cmd_tester.is_bumpable(
|
||||
dependency=dependency,
|
||||
only_packages=[],
|
||||
latest=True,
|
||||
)
|
||||
assert is_bumpable is True
|
Reference in New Issue
Block a user