Skip to content

Commit

Permalink
merge the development updates (#4)
Browse files Browse the repository at this point in the history
* Updated README.md

* Add pytest tests and GitHub Actions workflow

* Add pytest tests and GitHub Actions workflow

* Add pytest tests and GitHub Actions workflow

* Added the Check version Capability
  • Loading branch information
muhammad-fiaz authored Dec 7, 2023
1 parent 50493bf commit 83c89c0
Show file tree
Hide file tree
Showing 7 changed files with 206 additions and 6 deletions.
38 changes: 38 additions & 0 deletions checkversions/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""
CheckVersions Package
This package provides functionality for comparing version numbers and determining the latest version
based on a specified hierarchy.
Usage:
from checkversions import *
current_version = "v1.0.0"
latest_version = "v1.0.0-beta"
result = compare_versions(current_version, latest_version)
print(result)
Functions:
- compare_versions(current_version, latest_version, custom_hierarchy=None):
Compares two versions and returns the latest version based on the provided hierarchy.
- get_default_hierarchy_from_json():
Loads the default hierarchy from a JSON file and returns it as a dictionary.
Modules:
- checkversions.py
Contains the implementation of version comparison functions.
- default_hierarchy.json
Default hierarchy configuration file in JSON format.
Exceptions:
- DotSetupException
- FileNotFoundError
- VariableNotFoundError
- JSONDecodeError
Note: Ensure that 'dotsetup' and 'packaging' packages are installed for proper functionality.
"""

from .checkversions import compare_versions
110 changes: 110 additions & 0 deletions checkversions/checkversions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import os
from packaging import version
from packaging.version import InvalidVersion
from dotsetup import DotSetup, FileNotFoundError, VariableNotFoundError, JSONDecodeError

def get_default_hierarchy_from_json():
"""
Load the default hierarchy from a JSON file.
This function initializes a DotSetup instance, gets the absolute path to
the 'default_hierarchy.json' file, and loads the hierarchy from the JSON file.
Returns:
dict: The default version hierarchy loaded from the JSON file.
Raises:
FileNotFoundError: If the 'default_hierarchy.json' file is not found.
VariableNotFoundError: If a variable is not found during JSON loading.
JSONDecodeError: If there is an error decoding JSON.
"""
try:
# Initialize DotSetup
ds = DotSetup()

# Get absolute path to JSON file
script_dir = os.path.dirname(os.path.abspath(__file__))
json_file_path = os.path.join(script_dir, '../default_hierarchy.json')

# Load from JSON file
value_json = ds.load('default_hierarchy', file_type='json', file_path=json_file_path)
return value_json
except (FileNotFoundError, VariableNotFoundError, JSONDecodeError) as e:
print(f"Error loading default hierarchy from JSON: {e}")
return {"beta": 0, "prerelease": 1, "alpha": 2, "unstable": 3, "stable": 4, "release": 5}

def compare_versions(current_version, latest_version, custom_hierarchy=None):
"""
Compare two versions and determine the latest version.
This function compares two versions, taking into account version numbers,
hyphen-separated parts, and additional words (e.g., beta, release, alpha).
Args:
current_version (str): The current version.
latest_version (str): The version to compare against.
custom_hierarchy (dict, optional): Custom version hierarchy. Defaults to None.
Returns:
str: The latest version, considering version numbers and hierarchy.
Raises:
InvalidVersion: If there is an issue with the version comparison.
"""
try:
# Check if 'v' prefix is present and retain it in the output
current_version_output = current_version if current_version.startswith('v') else 'v' + current_version
latest_version_output = latest_version if latest_version.startswith('v') else 'v' + latest_version

# Extract version codes before hyphen
current_version_before_hyphen = current_version.split('-')[0]
latest_version_before_hyphen = latest_version.split('-')[0]

# Extract additional words (e.g., beta, release, alpha, stable, unstable)
current_version_words = ''.join(filter(str.isalpha, current_version))
latest_version_words = ''.join(filter(str.isalpha, latest_version))

# Extract parts after hyphen for additional comparison
current_version_after_hyphen_parts = current_version.split('-')[1:] if '-' in current_version else []
latest_version_after_hyphen_parts = latest_version.split('-')[1:] if '-' in latest_version else []

# Check if after hyphen contains a word not available in default or custom hierarchy
current_version_after_hyphen_word = ''.join(filter(str.isalpha, current_version_after_hyphen_parts[0])) if current_version_after_hyphen_parts else ''
latest_version_after_hyphen_word = ''.join(filter(str.isalpha, latest_version_after_hyphen_parts[0])) if latest_version_after_hyphen_parts else ''

# Default version hierarchy
default_hierarchy = get_default_hierarchy_from_json()

# Use custom hierarchy if provided, otherwise use default
version_hierarchy = custom_hierarchy or default_hierarchy

# Check if the word after hyphen is in the hierarchy, else raise an error
if current_version_after_hyphen_word and current_version_after_hyphen_word not in version_hierarchy:
raise InvalidVersion(f"Version hierarchy not found for '{current_version_after_hyphen_word}'. Use custom hierarchy.")
if latest_version_after_hyphen_word and latest_version_after_hyphen_word not in version_hierarchy:
raise InvalidVersion(f"Version hierarchy not found for '{latest_version_after_hyphen_word}'. Use custom hierarchy.")

# Use packaging.version for version comparison
current_version_obj = version.parse(current_version_before_hyphen)
latest_version_obj = version.parse(latest_version_before_hyphen)

# Compare version numbers first
if current_version_obj < latest_version_obj:
return latest_version_output
elif current_version_obj > latest_version_obj:
return current_version_output

# Compare hierarchy only if version numbers are equal
if version_hierarchy.get(current_version_after_hyphen_word, 5) < version_hierarchy.get(latest_version_after_hyphen_word, 5):
return latest_version_output
elif version_hierarchy.get(current_version_after_hyphen_word, 5) > version_hierarchy.get(latest_version_after_hyphen_word, 5):
return current_version_output
elif version_hierarchy.get(current_version_words, 5) < version_hierarchy.get(latest_version_words, 5):
return latest_version_output
elif version_hierarchy.get(current_version_words, 5) > version_hierarchy.get(latest_version_words, 5):
return current_version_output

return current_version_output

except InvalidVersion as e:
return f"Error: {e}"
10 changes: 10 additions & 0 deletions default_hierarchy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"default_hierarchy": {
"beta": 0,
"prerelease": 1,
"alpha": 2,
"unstable": 3,
"stable": 4,
"release": 5
}
}
4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pip==23.3.1
setuptools==69.0.2
pytest==7.4.3
pytest==7.4.3
dotsetup~=0.0.2

4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
],
python_requires='>=3.8',
install_requires=INSTALL_REQUIRES,
setup_requires=['pytest-runner'], # Added setup_requires for pytest-runner
tests_require=['pytest'], # Added tests_require for pytest
setup_requires=['pytest-runner'],
tests_require=['pytest'],
license='MIT License',
project_urls={
'Source Code': 'https://github.com/muhammad-fiaz/checkversions.git',
Expand Down
Empty file added tests/__init__.py
Empty file.
46 changes: 43 additions & 3 deletions tests/test_sample.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,43 @@
#sample tests case for pytest
def test_example():
assert 1 + 1 == 2
import pytest
from checkversions.checkversions import compare_versions

@pytest.fixture(params=[
("2.0.0-release", "v2.0.1", "v2.0.1"), # Current version is older
("v1.0.0", "1.0.0-beta", "v1.0.0"), # Current version is newer
("v3.1.2", "v3.1.2", "v3.1.2"), # Versions are the same
("v2.0.0-beta", "2.0.1", "v2.0.1"), # Current version is older with hyphen
("v1.0.0", "v1.0.0-beta", "v1.0.0"), # Current version is newer with hyphen
("v3.1.2", "v3.1.2", "v3.1.2"), # Versions are the same with hyphen
("v2.0.0-beta", "v2.0.1-alpha", "v2.0.1-alpha"), # Current version is older with hyphen and words
("v1.0.0-beta", "1.0.0-alpha", "v1.0.0-alpha"), # Current version is newer with hyphen and words
("v3.1.2-beta", "v3.1.2-alpha", "v3.1.2-alpha"), # Versions are the same with hyphen and words
("v2.0.0-beta", "v2.0.1", "v2.0.1"), # Current version is older with words
("v1.0.0-beta", "1.0.0", "v1.0.0"), # Current version is newer with words
])
def version_data(request):
"""
Fixture providing version data for testing.
Each parameter is a tuple containing three elements:
1. Current version
2. Latest version
3. Expected result of the version comparison
Returns:
tuple: A set of version data for testing.
"""
return request.param

def test_compare_versions(version_data):
"""
Test the compare_versions function with different version scenarios.
Args:
version_data (tuple): A tuple containing current_version, latest_version, and expected_result.
The test compares two versions using the compare_versions function and asserts that the result
matches the expected outcome.
"""
current_version, latest_version, expected_result = version_data
result = compare_versions(current_version, latest_version)
assert result == expected_result

0 comments on commit 83c89c0

Please sign in to comment.