blob: c0841e95f91ed9c8891f846f4c3ebf6b1c3eb11c [file] [log] [blame] [edit]
"""Utilities related to the Cast branching scheme."""
from __future__ import absolute_import
import re
RELEASE_BRANCH_PATTERN = r'(?P<major>\d+)\.(?P<minor>\d+)(?P<version>.+)?'
# See go/nest-tv-branch-strategy.
ANDROID_TV_RELEASE_BRANCH_PATTERN = (r'^android(\d+)-(\d+\.\d+)-(.+)'
r'-(factory|ota)(|\d+)$')
def parse_release_branch(branch_name):
"""Converts string branch_name to tuple (int major, int minor, version)."""
match = re.match(RELEASE_BRANCH_PATTERN, branch_name)
if not match:
raise ValueError('Invalid branch name: {}'.format(branch_name))
major = int(match.group('major'))
minor = int(match.group('minor'))
version = match.group('version')
try:
version = int(version)
except (TypeError, ValueError):
pass
return major, minor, version
def is_release_branch(branch):
"""Returns True if |branch| matching release branch patterns."""
return (branch and
(re.match(RELEASE_BRANCH_PATTERN, branch) or
re.match(ANDROID_TV_RELEASE_BRANCH_PATTERN, branch)))
def is_master_branch(branch):
"""Returns True if |branch| is a master branch."""
return branch == 'master'
def is_branch_equal_to_or_later_than(branch, threshold):
"""Returns True if |branch| is at least as new as |threshold|.
Returns False if |branch| is older than |threshold|. Returns True if
|branch| is newer than |threshold|, matches |threshold|, or is 'master'.
Args:
branch: A Cast branch, of the form X.YY{a-d} or 'master'.
threshold: A Cast branch, of the form X.YY{a-d} or 'master'.
Returns:
True if |branch| is at least as new as |threshold|.
Raises:
ValueError: if either |branch| or |threshold| is poorly-formed.
"""
if is_master_branch(branch):
return True
# This means it is a named branch. Usually a bringup branch so we should run
# everything.
if not is_release_branch(branch):
return True
# Exclude Android TV release branch from version comparison.
if re.match(ANDROID_TV_RELEASE_BRANCH_PATTERN, branch):
return True
if threshold == 'master':
return False
if threshold is None:
return True
t_major, t_minor, t_ver = parse_release_branch(threshold)
major, minor, ver = parse_release_branch(branch)
t_ver = t_ver if t_ver is not None else -1
ver = ver if ver is not None else -1
# If the version is a string for one of them we need to compare both as
# strings.
if any(isinstance(v, str) for v in (t_ver, ver)):
t_ver = str(t_ver)
ver = str(ver)
return (major > t_major or
(major == t_major and minor > t_minor) or
(major == t_major and minor == t_minor and ver >= t_ver))