diff --git a/CHANGELOG.md b/CHANGELOG.md index e435a59b..2dbe14e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] ### Added * Add support for mounting devices which identify as block device. +* Add `check-for-update` command to `wkz` CLI. ### Fixed * Test for mounting devices fails sometimes, because it was not ready for block device mounting. diff --git a/setup.py b/setup.py index f5a6f396..56bbe357 100644 --- a/setup.py +++ b/setup.py @@ -2,8 +2,6 @@ import setuptools -from workoutizer import __version__ - with open("Readme.md", "r") as fh: long_description = fh.read() @@ -18,8 +16,8 @@ def requirements_from_txt(path_to_txt): setuptools.setup( name="workoutizer", author="Fabian Gebhart", - version=__version__, - setup_requires=["setuptools_scm"], + version_config=True, + setup_requires=["setuptools_scm", "setuptools-git-versioning"], install_requires=requirements_from_txt("requirements.txt"), include_package_data=True, description="🏋️ Browser based Sport and Workout Organizer 🏃‍♀️", @@ -35,8 +33,8 @@ def requirements_from_txt(path_to_txt): "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Framework :: Django", - "Framework :: Django :: 2.2", "Framework :: Django :: 3.0", + "Framework :: Django :: 3.2", ], python_requires=">=3.7", extras_require={ diff --git a/tests/db_tests/browser_tests/test_help_page.py b/tests/db_tests/browser_tests/test_help_page.py index 2b1cbe9f..7929b81f 100644 --- a/tests/db_tests/browser_tests/test_help_page.py +++ b/tests/db_tests/browser_tests/test_help_page.py @@ -3,7 +3,7 @@ from django.urls import reverse from selenium.webdriver.common.by import By -from workoutizer.__init__ import __version__ +from workoutizer import __version__ def test_help_page(live_server, webdriver): @@ -14,7 +14,7 @@ def test_help_page(live_server, webdriver): # check version card assert "Version" in card_title - assert webdriver.find_element(By.CLASS_NAME, "badge").text == __version__ + assert webdriver.find_element(By.CLASS_NAME, "badge").text.lower() == __version__.lower() # check source code card hrefs = [a.get_attribute("href") for a in webdriver.find_elements_by_tag_name("a")] diff --git a/tests/db_tests/test_cli.py b/tests/db_tests/test_cli.py index 0394c32e..3ea29af9 100644 --- a/tests/db_tests/test_cli.py +++ b/tests/db_tests/test_cli.py @@ -65,3 +65,35 @@ def test_cli__reimport(import_one_activity): activity = models.Activity.objects.get() assert activity.distance == orig_distance + + +def test__check_for_update(monkeypatch): + # mock pypi version to be lower than the current version + pypi_version = "0.0.1" + + def mocked_get_version_pypi(pkg): + return pypi_version + + monkeypatch.setattr(cli.luddite, "get_version_pypi", mocked_get_version_pypi) + + assert cli._check_for_update() is False + + # mock pypi version to equal the current version + pypi_version = __version__ + + def mocked_get_version_pypi(pkg): + return pypi_version + + monkeypatch.setattr(cli.luddite, "get_version_pypi", mocked_get_version_pypi) + + assert cli._check_for_update() is False + + # mock pypi version to be larger than the current version + pypi_version = "9999.9999.9999" + + def mocked_get_version_pypi(pkg): + return pypi_version + + monkeypatch.setattr(cli.luddite, "get_version_pypi", mocked_get_version_pypi) + + assert cli._check_for_update() is True diff --git a/workoutizer/__init__.py b/workoutizer/__init__.py index ac824046..69b8143c 100644 --- a/workoutizer/__init__.py +++ b/workoutizer/__init__.py @@ -1 +1,21 @@ -__version__ = "0.20.1" +import os +import subprocess +from pathlib import Path + + +def _get_version() -> str: + cwd = Path.cwd() + os.chdir(Path(__file__).parent.parent) + try: + cmd = ["python", "-W", "ignore", "setup.py", "-V"] + out = subprocess.check_output(cmd, stderr=subprocess.DEVNULL) + if not isinstance(out, str): + out = out.decode("utf-8") + version = out.strip() + except Exception: + version = "unknown" + os.chdir(cwd) + return version + + +__version__ = _get_version() diff --git a/workoutizer/cli.py b/workoutizer/cli.py index 4c7c4bd0..42183c0f 100644 --- a/workoutizer/cli.py +++ b/workoutizer/cli.py @@ -36,7 +36,7 @@ def wkz(): help="Mandatory command to initialize workoutizer. This fetches the static files, creates the database, " "applies the required migrations and inserts the demo activities." ) -def init(demo): +def init(demo: bool): _init(import_demo_activities=demo) @@ -70,11 +70,16 @@ def manage(cmd): execute_from_command_line(["manage.py"] + cmd.split(" ")) -@click.command(help="Check for a newer version and install if there is any.") +@click.command(help="Upgrade workoutizer to newer version, if there is any.") def upgrade(): _upgrade() +@click.command(help="Check if a new version is available.") +def check_for_update(): + _check_for_update() + + @click.command(help="Stop a running workoutizer instance.") def stop(): _stop() @@ -96,6 +101,7 @@ def reimport(): wkz.add_command(run) wkz.add_command(manage) wkz.add_command(check) +wkz.add_command(check_for_update) wkz.add_command(reimport) @@ -115,6 +121,24 @@ def _upgrade(): click.echo(f"Successfully upgraded from {current_version} to {latest_version}") +def _check_for_update() -> bool: + pypi_version = luddite.get_version_pypi("workoutizer") + from workoutizer import __version__ as current_version + + if pypi_version > current_version: + click.echo(f"Newer version available: {pypi_version}. You are running: {current_version}") + return True + elif pypi_version == current_version: + click.echo(f"No update available. You are running the latest version: {pypi_version}") + return False + else: # current_version > pypi_version + click.echo( + f"Your installed version ({current_version}) seems to be greater" + f"than the latest version on pypi ({pypi_version})." + ) + return False + + def _build_home() -> None: if Path(WORKOUTIZER_DIR).is_dir(): if Path(TRACKS_DIR).is_dir(): @@ -127,7 +151,7 @@ def _build_home() -> None: Path(TRACKS_DIR).mkdir(exist_ok=True) -def _init(import_demo_activities=False): +def _init(import_demo_activities: bool = False): _build_home() if Path(WORKOUTIZER_DB_PATH).is_file(): execute_from_command_line(["manage.py", "check"]) @@ -164,7 +188,7 @@ def _init(import_demo_activities=False): click.echo(f"Database and track files are stored in: {WORKOUTIZER_DIR}") -def _pip_install(package, upgrade: bool = False): +def _pip_install(package: str, upgrade: bool = False) -> None: if upgrade: subprocess.check_call([sys.executable, "-m", "pip", "install", package, "--upgrade"]) else: diff --git a/workoutizer/settings.py b/workoutizer/settings.py index b6961fb0..291e3c81 100644 --- a/workoutizer/settings.py +++ b/workoutizer/settings.py @@ -130,4 +130,4 @@ path_to_log_dir=WORKOUTIZER_DIR, ) -HUEY = SqliteHuey(filename="/tmp/demo.db") +HUEY = SqliteHuey(filename="/tmp/huey.db")