gitvck

Purpose:

This project-generic Git version-check (gitvck) module is used to test your project’s version against the latest version available in source configuration.

The version can be checked against PyPI, GitHub or even a local (offline) Git repository.

If the project’s version number is behind the version number obtained from the source, the user is notified on import, as a notification-only service. This check is not designed to prevent the user from carrying on.

Important

A note for using a Git(Hub) repository:

When comparing version against a Git repository, this tool uses tags to determine the project’s version. Therefore, the tag on the release must be the version number and follow the convention defined in the Version scheme section of PEP-440.

For example:

[N!]N(.N)*[{a|b|rc}N][.postN][.devN]

Public version identifiers are separated into up to five segments:

  • Epoch segment: N!

  • Release segment: N(.N)*

  • Pre-release segment: {a|b|rc}N

  • Post-release segment: .postN

  • Development release segment: .devN

Platform:

Linux/Windows | Python 3.8+

Developer:

J Berendt

Email:

support@s3dev.uk

Deployment:

On deployment, simply copy/paste one of the following code examples into the project’s primary __init__.py module. When the project is imported, the __init__.py module is run, thus executing the version check.

Examples:

Check the version against a local Git repository:

from gitvck import gitvck
from <project>._version import __version__

gitvck.VersionCheck(name='project-spam',
                    source='git',
                    path='/path/to/git/project-spam',
                    version=__version__).test()

Check the version against GitHub:

from gitvck import gitvck
from <project>._version import __version__

gitvck.VersionCheck(name='project-spam',
                    source='git',
                    path='https://github.com/s3dev/project-spam',
                    version=__version__).test()

Check the version against PyPI:

from gitvck import gitvck
from <project>._version import __version__

gitvck.VersionCheck(name='project-spam',
                    source='pypi',
                    version=__version__).test()

Check the version against PyPI, using the version from the installed library.

Notice the template below passes None into the version argument. This instructs gitvck to collect the internal version from the installed library using importlib, rather than from the local project’s _version.py file.

This variation can be used with any of the templates above:

from gitvck import gitvck

gitvck.VersionCheck(name='project-spam',
                    source='pypi',
                    version=None).test()
class gitvck.VersionCheck(name: str, source: str, path: str = None, version: str = None, suppress_path_not_found_errors: bool = False)[source]

Compare a project’s version against the version in source configuration.

Parameters:
  • name (str) – Name of the project.

  • source (str) – Source against which the version is checked. Options: ‘git’ or ‘pypi’. If ‘git’, the path argument must be populated. If ‘pypi’, the name argument is used to query the PyPI register.

  • path (str, optional) – Explicit path to the project’s local Git repository, or the GitHub URL to the project. If referencing PyPI, this can be left as None. Defaults to None.

  • version (str, optional) – Version of the project. If the version of the installed library is to be tested, this argument should be left as None. Otherwise, the __version__ variable from the project’s _version.py file can be used. Defaults to None.

  • suppress_path_not_found_errors (bool, optional) – Suppress the error messages indicating a repo or path cannot be found. Defaults to False.

Note

This class is simply a warning mechanism. Processes are not stopped nor prevented, once preliminary internal checks pass. If the version test fails, the user is simply warned and allowed to carry on.

_SOURCES = ('git', 'pypi')
__init__(name: str, source: str, path: str = None, version: str = None, suppress_path_not_found_errors: bool = False)[source]

VersionCheck class initialiser.

_compare() bool[source]

Compare the internal and external version numbers.

Returns:

False if the internal version is behind (less than) the external version. Otherwise, True.

Return type:

bool

_get_version_external()[source]

Get the version from the specified external source.

Key:
  • git: Use the path argument to obtain and parse the latest tag from Git(Hub).

  • pypi: Use the name argument to query PyPI for the latest version held.

The collected version is stored into the _extvers attribute by the appropriate collection method:

Returns:

True if the _extvers attribute is now populated. Otherwise, False.

Return type:

bool

_get_version_from_git()[source]

Collect and parse the latest tag from Git(Hub).

To obtain the tag(s), the git ls-remote command is used.

Important

This method relies on the version number being the commit’s tag, and follows the versioning scheme found in PEP-440.

_get_version_from_pypi()[source]

Collect and parse the latest tag from PyPI.

Important

This method queries the PyPI register and returns the version of the latest project.

_get_version_internal() bool[source]

Collect the project’s version to be compared.

If the version argument is None, the version for the installed project is obtained using importlib.metadata. Otherwise, the string provided to the version argument is used.

The internal version is stored into the _vers attribute.

Returns:

True if the _vers attribute is now populated. Otherwise, False.

Return type:

bool

_new_version_available()[source]

Alert the user that a new version is available.

_parse_git_output(data: bytes)[source]

Parse the output from the git ls-remote command.

To keep the project OS-agnostic, the parsing of the tag collection command is parsed here, rather than during the subprocess session.

Specifically, this method extracts the last field from the last line of output. This will be the latest tag from the Git repository.

The tag (hopefully a version!) is stored into the _extvers attribute. Before the versions are compared, the version is verified by the _verify_version_numbers() method, in the event the tag is not a version number.

Parameters:

data (bytes) – Bytestring returned from the sub-process call’s stdout stream.

_verify_args() bool[source]

Verify the class arguments are valid.

Raises:

RuntimeError – Raised if the provided source is invalid, or a source of ‘git’ is provided and the path argument is None.

Returns:

True if the arguments are valid, otherwise a RuntimeError is raised.

Return type:

bool

_verify_path_is_valid() bool[source]

Verify the path argument is valid.

Returns:

True if the path is a valid URL, or if the filepath exists. Otherwise, False.

Return type:

bool

static _verify_version_is_valid(version: str) bool[source]

Verify a version string is valid.

Implementation:

This test calls the packaging.version.parse() function, wrapped in a try/except block, to verify the version string.

Parameters:

version (str) – Version string to be tested.

Returns:

True if the version string is valid, otherwise False.

Return type:

bool

_verify_version_numbers() bool[source]

Verify the version numbers are valid according to PEP-440.

Both the internal and external version numbers are tested.

Returns:

True if both version numbers are valid, otherwise False.

Return type:

bool

test() bool[source]

Test the version numbers between the library and its source.

If the version of the library is behind the source, the user is alerted. Otherwise, no further action is taken.

The following processing steps are carried out by this test:

  • Verify the arguments are valid.

  • Get the version number for the internal project.

  • Get the version number from the project’s configured source.

  • Verify the two version numbers are valid per PEP-440.

  • Compare the internal and external version numbers.

  • Notify the user if the version of the library is behind the source.

Returns:

True if the versions compared successfully and the source is not ahead of the tested library, otherwise False. The return value is used by the testing suite.

Return type:

bool