Skip to content
This repository has been archived by the owner on Dec 18, 2022. It is now read-only.

Commit

Permalink
Merge pull request #22 from MousaZeidBaker/poetryup-latest
Browse files Browse the repository at this point in the history
add --latset flag in order to update dependencies to their latest available version
  • Loading branch information
MousaZeidBaker authored Jan 23, 2022
2 parents 7fd78c8 + 5346978 commit 549fba9
Show file tree
Hide file tree
Showing 8 changed files with 417 additions and 291 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ is that the latter also modifies the `pyproject.toml` file.

## Usage
```shell
poetryup
poetryup --help
```

## Automate Dependency Updates with GitHub Actions
Expand Down
207 changes: 114 additions & 93 deletions poetry.lock

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "poetryup"
version = "0.4.3"
version = "0.5.0"
description = "Update dependencies and bump their version in the pyproject.toml file"
authors = ["Mousa Zeid Baker"]
packages = [
Expand All @@ -26,7 +26,9 @@ include = ["LICENSE"]

[tool.poetry.dependencies]
python = "^3.6"
tomlkit = "^0.7.2"
tomlkit = "^0.8.0"
typer = "^0.4.0"
packaging = "^21.3"

[tool.poetry.dev-dependencies]
pytest = "^6.2.5"
Expand All @@ -39,10 +41,10 @@ flake8 = "^4.0.1"
flake8-black = "^0.2.3"
flake8-isort = "^4.1.1"
isort = { version = "^5.10.1", python = "^3.6.1" }
pre-commit = { version = "^2.16.0", python = "^3.6.1" }
pre-commit = { version = "^2.17.0", python = "^3.6.1" }

[tool.poetry.scripts]
poetryup = "poetryup.main:main"
poetryup = "poetryup.main:app"

[build-system]
requires = ["poetry-core>=1.0.0"]
Expand Down
140 changes: 17 additions & 123 deletions src/poetryup/main.py
Original file line number Diff line number Diff line change
@@ -1,144 +1,38 @@
#!/usr/bin/env python

import logging
import re
import subprocess
from dataclasses import dataclass
import os
from pathlib import Path
from typing import List

import tomlkit
from tomlkit import items
from tomlkit.toml_document import TOMLDocument
import typer

from poetryup import utils
from poetryup.pyproject import Pyproject

logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO").upper())

@dataclass
class Dependency:
name: str
version: str
app = typer.Typer(add_completion=False)


def _setup_logging() -> None:
"""Setup and configure logging"""
@app.command()
def poetryup(
latest: bool = typer.Option(
default=False,
help="Whether to update dependencies to their latest version.",
),
):
"""Update dependencies and bump their version in pyproject.toml file"""

logging.basicConfig(level=logging.INFO)


def _run_poetry_update() -> None:
"""Run poetry update command"""

subprocess.run(["poetry", "update"])


def _run_poetry_show() -> str:
"""Run poetry show command
Returns:
str: The output from the poetry show command
"""

return subprocess.run(
["poetry", "show", "--tree"], capture_output=True
).stdout.decode()


def _list_dependencies() -> List[Dependency]:
"""List all top-level dependencies
Returns:
List[Dependency]: A list of dependencies
"""

output = _run_poetry_show()

pattern = re.compile("^[a-zA-Z-]+")
dependencies: List[Dependency] = []
for line in output.split("\n"):
if pattern.match(line) is not None:
name, version, *_ = line.split()
dependency = Dependency(name=name, version=version)
dependencies.append(dependency)

return dependencies


def _bump_versions_in_pyproject(
dependencies: List[Dependency], pyproject: TOMLDocument
) -> TOMLDocument:
"""Bump versions in pyproject
Args:
dependencies (List[Dependency]): A list of dependencies
pyproject (TOMLDocument): The pyproject file parsed as a TOMLDocument
Returns:
TOMLDocument: The updated pyproject
"""

logging.info(f"Found {len(dependencies)} dependencies in pyproject.toml")

for dependency in dependencies:
value = utils.lookup_tomlkit_table(
table=pyproject["tool"]["poetry"],
key=dependency.name,
)

if type(value) is items.String and value.startswith(("^", "~")):
new_value = value[0] + dependency.version
elif (
type(value) is items.InlineTable
and "version" in value
and value["version"].startswith(("^", "~"))
):
new_value = value
new_value["version"] = value["version"][0] + dependency.version
else:
# skip if exact version or not found or complex dependency
logging.info(f"Bumping skipped for dependency: {dependency.name}")
continue

utils.update_tomlkit_table(
table=pyproject["tool"]["poetry"],
key=dependency.name,
new_value=new_value,
)

return pyproject


def poetryup(pyproject_str: str) -> str:
"""Update dependencies and bump their version
Args:
pyproject_str (str): The pyproject file parsed as a string
Returns:
str: The updated pyproject string
"""

_run_poetry_update()
dependencies = _list_dependencies()
pyproject = tomlkit.loads(pyproject_str)
updated_pyproject = _bump_versions_in_pyproject(dependencies, pyproject)

return tomlkit.dumps(updated_pyproject)


def main():
_setup_logging()

# read pyproject.toml file
try:
pyproject_str = Path("pyproject.toml").read_text()
except FileNotFoundError:
raise Exception(
"poetryup couldn't find a pyproject.toml file in current directory"
)

updated_pyproject_str = poetryup(pyproject_str)
Path("pyproject.toml").write_text(updated_pyproject_str)
pyproject = Pyproject(pyproject_str)
pyproject.update_dependencies(latest)
Path("pyproject.toml").write_text(pyproject.dumps())


if __name__ == "__main__":
main()
app()
Loading

0 comments on commit 549fba9

Please sign in to comment.