Initial version of update_version.py script to bump CVAT version (#4889)
parent
6410b86a4e
commit
4167a4e40c
@ -0,0 +1,211 @@
|
|||||||
|
import argparse
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
CVAT_VERSION_PATTERN = r'VERSION\s*=\s*\((\d+),\s*(\d*),\s*(\d+),\s*[\',\"](\w+)[\',\"],\s*(\d+)\)'
|
||||||
|
COMPOSE_VERSION_PATTERN = r'(\$\{CVAT_VERSION:-)([\w.]+)(\})'
|
||||||
|
|
||||||
|
@dataclass()
|
||||||
|
class Version:
|
||||||
|
major: int = 0
|
||||||
|
minor: int = 0
|
||||||
|
patch: int = 0
|
||||||
|
prerelease: str = ''
|
||||||
|
prerelease_number: int = 0
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return f'{self.major}.{self.minor}.{self.patch}-{self.prerelease}.{self.prerelease_number}'
|
||||||
|
|
||||||
|
def cvat_repr(self):
|
||||||
|
return f"({self.major}, {self.minor}, {self.patch}, '{self.prerelease}', {self.prerelease_number})"
|
||||||
|
|
||||||
|
def compose_repr(self):
|
||||||
|
return f'v{self.major}.{self.minor}.{self.patch}'
|
||||||
|
|
||||||
|
def increment_prerelease_number(self) -> None:
|
||||||
|
self.prerelease_number += 1
|
||||||
|
|
||||||
|
def increment_prerelease(self) -> None:
|
||||||
|
flow = ('alpha', 'beta', 'rc', 'final')
|
||||||
|
idx = flow.index(self.prerelease)
|
||||||
|
if idx == len(flow) - 1:
|
||||||
|
raise ValueError(f"Cannot increment current '{self.prerelease}' prerelease version")
|
||||||
|
|
||||||
|
self.prerelease = flow[idx + 1]
|
||||||
|
self._set_default_prerelease_number()
|
||||||
|
|
||||||
|
def set_prerelease(self, value: str) -> None:
|
||||||
|
values = ('alpha', 'beta', 'rc', 'final')
|
||||||
|
if value not in values:
|
||||||
|
raise ValueError(f'{value} is a wrong, must be one of {values}')
|
||||||
|
|
||||||
|
self.prerelease = value
|
||||||
|
self._set_default_prerelease_number()
|
||||||
|
|
||||||
|
def increment_patch(self) -> None:
|
||||||
|
self.patch += 1
|
||||||
|
self._set_default_prerelease()
|
||||||
|
|
||||||
|
def increment_minor(self) -> None:
|
||||||
|
self.minor += 1
|
||||||
|
self._set_default_patch()
|
||||||
|
|
||||||
|
def increment_major(self) -> None:
|
||||||
|
self.major += 1
|
||||||
|
self._set_default_minor()
|
||||||
|
|
||||||
|
def _set_default_prerelease_number(self) -> None:
|
||||||
|
self.prerelease_number = 0
|
||||||
|
|
||||||
|
def _set_default_prerelease(self) -> None:
|
||||||
|
self.prerelease = 'alpha'
|
||||||
|
self._set_default_prerelease_number()
|
||||||
|
|
||||||
|
def _set_default_patch(self) -> None:
|
||||||
|
self.patch = 0
|
||||||
|
self._set_default_prerelease()
|
||||||
|
|
||||||
|
def _set_default_minor(self) -> None:
|
||||||
|
self.minor = 0
|
||||||
|
self._set_default_patch()
|
||||||
|
|
||||||
|
def update_compose_config(new_version: Version) -> None:
|
||||||
|
compose_file = get_compose_filename()
|
||||||
|
with open(compose_file, 'r') as fp:
|
||||||
|
compose_text = fp.read()
|
||||||
|
|
||||||
|
if new_version.prerelease == 'final':
|
||||||
|
new_version_repr = new_version.compose_repr()
|
||||||
|
else:
|
||||||
|
new_version_repr = 'dev'
|
||||||
|
|
||||||
|
match = re.search(COMPOSE_VERSION_PATTERN, compose_text)
|
||||||
|
if not match:
|
||||||
|
raise RuntimeError('Cannot match version pattern')
|
||||||
|
|
||||||
|
if match[2] != new_version_repr:
|
||||||
|
compose_text = re.sub(COMPOSE_VERSION_PATTERN, f'\\g<1>{new_version_repr}\\g<3>', compose_text)
|
||||||
|
with open(compose_file, 'w') as fp:
|
||||||
|
fp.write(compose_text)
|
||||||
|
|
||||||
|
print(f'\u2714 {compose_file} was updated. {match[2]} -> {new_version_repr}\n')
|
||||||
|
|
||||||
|
else:
|
||||||
|
print(f'\u2714 {compose_file} no need to update.')
|
||||||
|
|
||||||
|
def update_cvat_version(old_version: str, new_version: Version) -> None:
|
||||||
|
version_file = get_cvat_version_filename()
|
||||||
|
with open(version_file, 'r') as fp:
|
||||||
|
version_text = fp.read()
|
||||||
|
|
||||||
|
new_version_str = f'VERSION = {new_version.cvat_repr()}'
|
||||||
|
version_text = version_text.replace(old_version, new_version_str)
|
||||||
|
|
||||||
|
with open(version_file, 'w') as fp:
|
||||||
|
fp.write(version_text)
|
||||||
|
|
||||||
|
print(f'\u2714 {version_file} was updated. {old_version} -> {new_version_str}\n')
|
||||||
|
|
||||||
|
def verify_input(version_types: dict, args: dict) -> None:
|
||||||
|
versions_to_bump = [args[v_type] for v_type in version_types]
|
||||||
|
i = iter(versions_to_bump)
|
||||||
|
if not any(i):
|
||||||
|
raise ValueError(f'One of {list(version_types)} options must be specified')
|
||||||
|
if any(i):
|
||||||
|
raise ValueError(f'Only one of {list(version_types)} options accepted')
|
||||||
|
|
||||||
|
def get_cvat_version_filename() -> Path:
|
||||||
|
return Path(__file__).resolve().parents[2] / 'cvat' / '__init__.py'
|
||||||
|
|
||||||
|
def get_compose_filename() -> Path:
|
||||||
|
return Path(__file__).resolve().parents[2] / 'docker-compose.yml'
|
||||||
|
|
||||||
|
def get_current_version() -> tuple[str, Version]:
|
||||||
|
version_file = get_cvat_version_filename()
|
||||||
|
|
||||||
|
with open(version_file, 'r') as fp:
|
||||||
|
version_text = fp.read()
|
||||||
|
|
||||||
|
match = re.search(CVAT_VERSION_PATTERN, version_text)
|
||||||
|
if not match:
|
||||||
|
raise RuntimeError(f'Failed to find version in {version_file}')
|
||||||
|
|
||||||
|
version = Version(int(match[1]), int(match[2]), int(match[3]), match[4], int(match[5]))
|
||||||
|
return match[0], version
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
version_types = {
|
||||||
|
'major': {
|
||||||
|
'action': 'store_true',
|
||||||
|
'help': 'Increment the existing major version by 1',
|
||||||
|
},
|
||||||
|
'minor': {
|
||||||
|
'action': 'store_true',
|
||||||
|
'help': 'Increment the existing minor version by 1',
|
||||||
|
},
|
||||||
|
'patch': {
|
||||||
|
'action': 'store_true',
|
||||||
|
'help': 'Increment the existing patch version by 1',
|
||||||
|
},
|
||||||
|
'prerelease': {
|
||||||
|
'nargs': '?',
|
||||||
|
'const': 'increment',
|
||||||
|
'help': '''Increment prerelease version alpha->beta->rc->final,
|
||||||
|
Also it's possible to pass value explicitly''',
|
||||||
|
},
|
||||||
|
'prerelease_number': {
|
||||||
|
'action': 'store_true',
|
||||||
|
'help': 'Increment prerelease number by 1',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='Bump CVAT version')
|
||||||
|
|
||||||
|
for v, v_config in version_types.items():
|
||||||
|
parser.add_argument(f'--{v}', **v_config)
|
||||||
|
|
||||||
|
parser.add_argument('--current', '--show-current',
|
||||||
|
action='store_true', help='Display current version')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
version_str, version = get_current_version()
|
||||||
|
|
||||||
|
if args.current:
|
||||||
|
print(version)
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
verify_input(version_types, vars(args))
|
||||||
|
except ValueError as e:
|
||||||
|
print(f'\u2716 ERROR: {e}\n')
|
||||||
|
parser.print_help()
|
||||||
|
return
|
||||||
|
|
||||||
|
if args.prerelease_number:
|
||||||
|
version.increment_prerelease_number()
|
||||||
|
|
||||||
|
elif args.prerelease:
|
||||||
|
if args.prerelease == 'increment':
|
||||||
|
version.increment_prerelease()
|
||||||
|
else:
|
||||||
|
version.set_prerelease(args.prerelease)
|
||||||
|
|
||||||
|
elif args.patch:
|
||||||
|
version.increment_patch()
|
||||||
|
|
||||||
|
elif args.minor:
|
||||||
|
version.increment_minor()
|
||||||
|
|
||||||
|
elif args.major:
|
||||||
|
version.increment_major()
|
||||||
|
|
||||||
|
print(f'\u2714 Bump version to {version}\n')
|
||||||
|
|
||||||
|
update_cvat_version(version_str, version)
|
||||||
|
update_compose_config(version)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
Loading…
Reference in New Issue