95 lines
2.9 KiB
Python
95 lines
2.9 KiB
Python
"""Retrieve collection detail."""
|
|
from __future__ import (absolute_import, division, print_function)
|
|
__metaclass__ = type
|
|
|
|
import json
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
import yaml
|
|
|
|
|
|
# See semantic versioning specification (https://semver.org/)
|
|
NUMERIC_IDENTIFIER = r'(?:0|[1-9][0-9]*)'
|
|
ALPHANUMERIC_IDENTIFIER = r'(?:[0-9]*[a-zA-Z-][a-zA-Z0-9-]*)'
|
|
|
|
PRE_RELEASE_IDENTIFIER = r'(?:' + NUMERIC_IDENTIFIER + r'|' + ALPHANUMERIC_IDENTIFIER + r')'
|
|
BUILD_IDENTIFIER = r'[a-zA-Z0-9-]+' # equivalent to r'(?:[0-9]+|' + ALPHANUMERIC_IDENTIFIER + r')'
|
|
|
|
VERSION_CORE = NUMERIC_IDENTIFIER + r'\.' + NUMERIC_IDENTIFIER + r'\.' + NUMERIC_IDENTIFIER
|
|
PRE_RELEASE = r'(?:-' + PRE_RELEASE_IDENTIFIER + r'(?:\.' + PRE_RELEASE_IDENTIFIER + r')*)?'
|
|
BUILD = r'(?:\+' + BUILD_IDENTIFIER + r'(?:\.' + BUILD_IDENTIFIER + r')*)?'
|
|
|
|
SEMVER_REGULAR_EXPRESSION = r'^' + VERSION_CORE + PRE_RELEASE + BUILD + r'$'
|
|
|
|
|
|
def validate_version(version):
|
|
"""Raise exception if the provided version is not None or a valid semantic version."""
|
|
if version is None:
|
|
return
|
|
if not re.match(SEMVER_REGULAR_EXPRESSION, version):
|
|
raise Exception('Invalid version number "{0}". Collection version numbers must '
|
|
'follow semantic versioning (https://semver.org/).'.format(version))
|
|
|
|
|
|
def read_manifest_json(collection_path):
|
|
"""Return collection information from the MANIFEST.json file."""
|
|
manifest_path = os.path.join(collection_path, 'MANIFEST.json')
|
|
|
|
if not os.path.exists(manifest_path):
|
|
return None
|
|
|
|
try:
|
|
with open(manifest_path) as manifest_file:
|
|
manifest = json.load(manifest_file)
|
|
|
|
collection_info = manifest.get('collection_info') or dict()
|
|
|
|
result = dict(
|
|
version=collection_info.get('version'),
|
|
)
|
|
validate_version(result['version'])
|
|
except Exception as ex: # pylint: disable=broad-except
|
|
raise Exception('{0}: {1}'.format(os.path.basename(manifest_path), ex))
|
|
|
|
return result
|
|
|
|
|
|
def read_galaxy_yml(collection_path):
|
|
"""Return collection information from the galaxy.yml file."""
|
|
galaxy_path = os.path.join(collection_path, 'galaxy.yml')
|
|
|
|
if not os.path.exists(galaxy_path):
|
|
return None
|
|
|
|
try:
|
|
with open(galaxy_path) as galaxy_file:
|
|
galaxy = yaml.safe_load(galaxy_file)
|
|
|
|
result = dict(
|
|
version=galaxy.get('version'),
|
|
)
|
|
validate_version(result['version'])
|
|
except Exception as ex: # pylint: disable=broad-except
|
|
raise Exception('{0}: {1}'.format(os.path.basename(galaxy_path), ex))
|
|
|
|
return result
|
|
|
|
|
|
def main():
|
|
"""Retrieve collection detail."""
|
|
collection_path = sys.argv[1]
|
|
|
|
try:
|
|
result = read_manifest_json(collection_path) or read_galaxy_yml(collection_path) or dict()
|
|
except Exception as ex: # pylint: disable=broad-except
|
|
result = dict(
|
|
error='{0}'.format(ex),
|
|
)
|
|
|
|
print(json.dumps(result))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|