Skip to content

Commit

Permalink
Merge branch 'mainline' into tjachetta/fix_git_flavor_successive_auto…
Browse files Browse the repository at this point in the history
…_bumps
  • Loading branch information
tyler-jachetta committed Jan 20, 2021
2 parents 2aa9c54 + 58c7a63 commit a5c17dc
Show file tree
Hide file tree
Showing 5 changed files with 259 additions and 56 deletions.
132 changes: 121 additions & 11 deletions avakas/avakas.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
Avakas classes and plugin handlers
"""

import copy
import datetime

from semantic_version import Version

from .errors import AvakasError
Expand Down Expand Up @@ -49,6 +52,7 @@ def __init__(self, **kwargs):
@property
def version(self):
"""Get version"""

tag_prefix = self.options.get('tag_prefix', '')
return "%s%s" % (tag_prefix, self._version)

Expand All @@ -67,6 +71,18 @@ def version(self, version):
raise AvakasError("Invalid version string %s" %
version) from err

@property
def version_obj(self):
"""
Get a copy (not the original) of the `semantic_version.Version object
which this instance uses to internally manage its version
Returns:
* `semantic_version.Version` : A copy of `self._version`
"""

return copy.deepcopy(self._version)

@classmethod
def read(cls):
"""Read version data from a project"""
Expand All @@ -76,8 +92,15 @@ def read(cls):
def write(cls):
"""Write version data to a project"""

def bump(self, bump=None):
def bump(self,
bump=None,
prerelease=False,
prerelease_prefix=None,
build_date=None):
"""Bump version"""

original = self._version

if not bump:
return False

Expand All @@ -90,19 +113,105 @@ def bump(self, bump=None):
else:
raise AvakasError("Invalid version component")

if prerelease:
prerelease_version = self.get_next_prerelease_version(
original, prefix=prerelease_prefix
)

self.make_prerelease(
prerelease_version,
prefix=prerelease_prefix,
build_date=build_date)

if self._version == original:
msg = "Attempted to set the version to its previous value!"
raise AvakasError(msg)

return True

def make_prerelease(self, prefix=None, build_date=None):
"""Make current version a prerelease"""
release_pos = 1 if prefix else 0
if self._version.prerelease:
release = self._version.prerelease[release_pos]
def get_next_prerelease_version(
self, starting_version=None, prefix=None,
new_version=None):
"""
Return an integer representing the version of a given prerelase label
(i.e. alpha, beta, rc) which comes next.
if `starting_version` is not passed in, this will use `self`'s
version object as the starting version.
"""

if starting_version is None:
starting_version = self._version

if new_version is None:
new_version = self._version

# This \/ checks whether last version was a pre-release, and then
# whether the beginning (at minimum) of the current pre-release
# prefix (PRP) matches the intended PRP. This could resolve to
# being `True` in the case that we're doing some sort of pre-pre
# release, e.g. rc.1.dev.1 would match an attempted 'rc' bump), but
# that's actually desirable (because bumping to the next 'rc'
# should treat `dev.1` as if it doesn't exist.
prerelease_len = 0
if not prefix:
prefix = tuple()
if isinstance(prefix, str):
prefix = (prefix, )

prerelease_len = len(prefix)

current_prefix_match = starting_version.prerelease[:prerelease_len]

if (new_version == starting_version.truncate() and
prefix == current_prefix_match):

# prerelease bumping for the same release.
# this will catch a case where there's e.g. rc.dev.1
# and we're trying to bump the 'rc' prefix, in that
# case per semver, there is an implicit zero (i.e. .alpha comes
# before .alpha.1).
try:
prerelease_version = int(
starting_version.prerelease[prerelease_len])

except (IndexError, TypeError):
# either there is no explicit prerelease version in the
# current version, or there are additional prerelease
# prefixes which are not intended for this bump
prerelease_version = 0
else:
release = 1
# different release or different prefix
prerelease_version = 0

prerelease_version += 1

return prerelease_version

def make_prerelease(self, version, prefix=None, build_date=None):
"""
Make current version a prerelease
Args:
* version (`int` or `str`(digits only)): The numeric prerelease
version. i.e., for -dev.3, this is `3` or `"3"`.
* prefix (`str`, optional): the alphabetic (not enforced) prebuild
prefix, such as `a`, `beta`, `dev`, and such.
* build_date
"""

self.apply_prerelease((str(release)),
prerelease_date = None
time_fmt = "%Y%m%d%H%M%S"

if build_date is True:
prerelease_date = datetime.datetime.utcnow().strftime(time_fmt)

elif build_date:
prerelease_date = build_date.strftime(time_fmt)

self.apply_prerelease((str(version)),
prefix=prefix,
build_date=build_date)
build_date=prerelease_date)

def apply_metadata(self, *metadata):
"""Apply build metadata to project version"""
Expand All @@ -113,9 +222,10 @@ def apply_prerelease(self, *prebuild, prefix=None, build_date=None):
if prefix:
self._version.prerelease = (prefix,)

self._version.prerelease += prebuild
self._version.prerelease += tuple(str(element) for element in prebuild)

if build_date is not None and build_date:

if build_date:
self._version.prerelease += (build_date,)


Expand Down
40 changes: 24 additions & 16 deletions avakas/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

import os
import sys
from datetime import datetime
import argparse

from git import Repo
Expand All @@ -29,26 +28,18 @@ def git_rev(directory):
return str(get_repo(directory).head.commit)[0:8]


def add_metadata(project, **kwargs):
def add_metadata(project, buildmeta=False, **kwargs):
"""
Add metadata for set/bump actions
"""
directory = kwargs['directory'][0]

git_str = str(git_rev(directory))
if kwargs['buildmeta']:
if buildmeta:
metadata = (git_str,)
metadata += ci_build_meta()
project.apply_metadata(*metadata)

now = None
if kwargs['prerelease_date']:
time_fmt = "%Y%m%d%H%M%S"
now = datetime.utcnow().strftime(time_fmt)

if kwargs['prerelease']:
project.make_prerelease(prefix=kwargs['prerelease_prefix'],
build_date=now)
return project


Expand Down Expand Up @@ -76,16 +67,21 @@ def cli_show_version(**kwargs):
print("%s" % str(project.version))


def cli_bump_version(**kwargs):
def cli_bump_version(
level=None,
prerelease=False,
prerelease_date=False, **kwargs):
"""Bump the flavour specific version for a project."""
project = detect_project_flavor(**kwargs)
if not project.read():
raise AvakasError('Unable to extract current version')
old_version = project.version

bump = kwargs['level'][0]

if not project.bump(bump=bump):
if not project.bump(
bump=level[0],
prerelease=prerelease,
prerelease_prefix=kwargs['prerelease_prefix'],
build_date=prerelease_date):
sys.exit(0)
project = add_metadata(project, **kwargs)
project.write()
Expand All @@ -94,12 +90,24 @@ def cli_bump_version(**kwargs):
(old_version, str(project.version)))


def cli_set_version(**kwargs):
def cli_set_version(prerelease=False,
prerelease_date=False,
prerelease_prefix=None,
**kwargs):
"""Manually set the flavour specific version for a project."""

version = kwargs['version'][0]
project = detect_project_flavor(**kwargs)
original_version = project.version_obj

project.version = version
if prerelease:
prerelease_version = project.get_next_prerelease_version(
starting_version=original_version,
prefix=prerelease_prefix,
new_version=project.version_obj
)
project.make_prerelease(prerelease_version, build_date=prerelease_date)
project = add_metadata(project, **kwargs)
project.write()

Expand Down
12 changes: 10 additions & 2 deletions avakas/flavors/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ def check_if_dirty(self):

def write_versionfile(self):
"""Write the version file"""

path = os.path.join(self.directory, self.version_filename)
version_file = open(path, 'w')
version_file.write("%s\n" % self.version)
Expand All @@ -142,7 +143,10 @@ def write_git(self):
tag = self.__create_git_tag()
self.__git_push(tag=tag)

def bump(self, bump=None):
def bump(self,
bump=None,
prerelease=False,
prerelease_prefix=None, build_date=None):
"""
When using 'auto', flavor will attempt to determine whether or not
the project needs to be bumped from git log history. If keywords are
Expand All @@ -155,7 +159,11 @@ def bump(self, bump=None):
if bump is None and self.options['default_bump']:
bump = self.options['default_bump']

return super().bump(bump=bump)
return super().bump(
bump=bump,
prerelease=prerelease,
prerelease_prefix=prerelease_prefix,
build_date=build_date)

def read(self):
"""
Expand Down
11 changes: 9 additions & 2 deletions avakas/flavors/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,10 @@ def write_git(self):
tag = self.__create_git_tag()
self.__git_push(tag=tag)

def bump(self, bump=None):
def bump(self,
bump=None,
prerelease=False,
prerelease_prefix=None, build_date=None):
"""
When using 'auto', flavor will attempt to determine whether or not
the project needs to be bumped from git log history. If keywords are
Expand All @@ -116,7 +119,11 @@ def bump(self, bump=None):
if bump is None and self.options['default_bump']:
bump = self.options['default_bump']

return super().bump(bump=bump)
return super().bump(
bump=bump,
prerelease=prerelease,
prerelease_prefix=prerelease_prefix,
build_date=build_date)

def read(self):
git = Git(self.directory)
Expand Down
Loading

0 comments on commit a5c17dc

Please sign in to comment.