File 0013-add-suse-container-tagger.patch of Package tito
Index: tito-tito-0.6.11-1/src/tito/common.py
===================================================================
--- tito-tito-0.6.11-1.orig/src/tito/common.py
+++ tito-tito-0.6.11-1/src/tito/common.py
@@ -348,7 +348,7 @@ def find_gemspec_file(in_dir=None):
def find_spec_like_file(in_dir=None):
if in_dir is None:
in_dir = os.getcwd()
- extension_list = ['.spec', '.spec.tmpl']
+ extension_list = ['.spec', '.spec.tmpl', 'Dockerfile', 'Chart.yaml', '.kiwi']
for ext in extension_list:
result = find_file_with_extension(in_dir, ext)
if result:
@@ -638,6 +638,19 @@ def debug(text, cmd=None):
def get_spec_version_and_release(sourcedir, spec_file_name):
+
+ if os.path.split(spec_file_name)[-1] == "Chart.yaml":
+ line_to_match_version = "version: (.+)"
+ return get_semver_from_file(line_to_match_version, spec_file_name)
+
+ if os.path.split(spec_file_name)[-1] == "Dockerfile":
+ line_to_match_version = "LABEL org.opencontainers.image.version=(.+)"
+ return get_semver_from_file(line_to_match_version, spec_file_name)
+
+ if os.path.split(spec_file_name)[-1].endswith(".kiwi"):
+ line_to_match_version = '<label name="org.opencontainers.image.version" value="([^"]+)"/>'
+ return get_semver_from_file(line_to_match_version, spec_file_name)
+
if os.path.splitext(spec_file_name)[1] == ".tmpl":
return scrape_version_and_release(spec_file_name)
@@ -767,6 +780,26 @@ def scrape_version_and_release(template_
return "%s-%s" % (version, release)
+def get_semver_from_file(line_to_match, file_name):
+
+ # Official Semver regex
+ # see https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
+ semver_regex = re.compile(r"^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$")
+ semver = ""
+ line_regex = re.compile(line_to_match)
+ with open(file_name) as file:
+ for line in file:
+ line_match = re.match(line_regex, line)
+ if line_match:
+ semver = line_match.group(1)
+ break
+ if semver == "":
+ error_out("Could not find match to %s in %s" % (line_to_match, file_name))
+ if not semver_regex.match(semver):
+ error_out("Invalid version format at %s in %s" % (line_to_match, file_name))
+ return semver
+
+
def scl_to_rpm_option(scl, silent=None):
""" Returns rpm option which disable or enable SC and print warning if needed """
rpm_options = ""
@@ -803,6 +836,34 @@ def get_project_name(tag=None, scl=None)
return m.group(1)
else:
file_path = find_spec_like_file()
+
+ if os.path.split(file_path)[-1] == "Dockerfile":
+ name_regex = re.compile("^(LABEL org.opencontainers.image.name=\s*)(.+)$", re.IGNORECASE)
+ in_f = open(file_path, 'r')
+ for line in in_f.readlines():
+ name_match = re.match(name_regex, line)
+ if name_match:
+ return name_match.group(2)
+ error_out("Dockerfile: %s does not contain the name label" % file_path)
+
+ if os.path.split(file_path)[-1] == "Chart.yaml":
+ name_regex = re.compile("^(name:\s*)(.+)$", re.IGNORECASE)
+ in_f = open(file_path, 'r')
+ for line in in_f.readlines():
+ name_match = re.match(name_regex, line)
+ if name_match:
+ return name_match.group(2)
+ error_out("Chart.yaml: %s does not contain the name label" % file_path)
+
+ if os.path.split(file_path)[-1].endswith('.kiwi'):
+ name_regex = re.compile('^\s*<label name="org\.opencontainers\.image\.name" value="(.+)"/>\s*$')
+ in_f = open(file_path, 'r')
+ for line in in_f.readlines():
+ name_match = re.match(name_regex, line)
+ if name_match:
+ return name_match.group(1)
+ error_out("kiwi file: %s does not contain the name label" % file_path)
+
if not os.path.exists(file_path):
error_out("spec file: %s does not exist" % file_path)
Index: tito-tito-0.6.11-1/src/tito/tagger/__init__.py
===================================================================
--- tito-tito-0.6.11-1.orig/src/tito/tagger/__init__.py
+++ tito-tito-0.6.11-1/src/tito/tagger/__init__.py
@@ -9,3 +9,4 @@ from tito.tagger.rheltagger import RHELT
from tito.tagger.zstreamtagger import zStreamTagger
from tito.tagger.cargobump import CargoBump
from tito.tagger.susetagger import SUSETagger
+from tito.tagger.susecontainertagger import SUSEContainerTagger
Index: tito-tito-0.6.11-1/src/tito/tagger/main.py
===================================================================
--- tito-tito-0.6.11-1.orig/src/tito/tagger/main.py
+++ tito-tito-0.6.11-1/src/tito/tagger/main.py
@@ -653,10 +653,12 @@ class VersionTagger(ConfigObject):
return self._get_tag_for_version(suffixed_version, release)
def _get_release(self, version_and_release):
- return version_and_release.split('-')[-1]
+ vr_split = version_and_release.split('-')
+ return vr_split[-1] if len(vr_split) >= 2 else ''
def _get_version(self, version_and_release):
- return version_and_release.split('-')[-2]
+ vr_split = version_and_release.split('-')
+ return vr_split[-2] if len(vr_split) >= 2 else vr_split[-1]
def _get_suffixed_version(self, version):
""" If global config specifies a tag suffix, use it """
Index: tito-tito-0.6.11-1/src/tito/tagger/susecontainertagger.py
===================================================================
--- /dev/null
+++ tito-tito-0.6.11-1/src/tito/tagger/susecontainertagger.py
@@ -0,0 +1,97 @@
+# Copyright (c) 2022 SUSE Linux Products GmbH
+#
+# This software is licensed to you under the GNU General Public License,
+# version 2 (GPLv2). There is NO WARRANTY for this software, express or
+# implied, including the implied warranties of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+# along with this software; if not, see
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+"""
+Code for tagging containers in SUSE Style.
+"""
+import os
+import re
+import shutil
+
+try:
+ from StringIO import StringIO
+except ImportError:
+ from io import StringIO
+from tito.tagger import SUSETagger
+
+from tito.common import (error_out, get_latest_tagged_version,
+ increase_version, reset_release, increase_zstream, info_out, get_spec_version_and_release)
+
+
+class SUSEContainerTagger(SUSETagger):
+ def __init__(self, config=None, keep_version=False, offline=False, user_config=None):
+ SUSETagger.__init__(self, config=config, keep_version=keep_version, offline=offline, user_config=user_config)
+ self.changes_file_name = f"{self.project_name}.changes"
+ self.changes_file = os.path.join(self.full_project_dir, self.changes_file_name)
+
+ def _bump_version(self, release=False, zstream=False):
+ """
+ Bump up the package version in the spec file.
+
+ Set release to True to bump the package release instead.
+
+ Checks for the keep version option and if found, won't actually
+ bump the version or release.
+ """
+ old_version = get_latest_tagged_version(self.project_name)
+ if old_version is None:
+ old_version = "untagged"
+ if not self.keep_version:
+
+ version_prefix = ""
+ if os.path.split(self.spec_file_name)[-1] == "Chart.yaml":
+ version_prefix = "version:"
+ version_release_regex = re.compile(rf"^({version_prefix}\s*)(.+)$", re.IGNORECASE)
+ elif os.path.split(self.spec_file_name)[-1] == "Dockerfile":
+ version_prefix = "LABEL org.opencontainers.image.version="
+ version_release_regex = re.compile(rf"^({version_prefix}\s*)(.+)$", re.IGNORECASE)
+ elif os.path.split(self.spec_file_name)[-1].endswith(".kiwi"):
+ version_release_regex = re.compile(r'^\s*<label name="org\.opencontainers\.image\.version" value="(.+)"/>\s*$')
+
+
+ in_f = open(self.spec_file, 'r')
+ out_f = open(self.spec_file + ".new", 'w')
+ new_version = None
+ old_version = None
+ lines = []
+
+ for line in in_f.readlines():
+ version_match = re.match(version_release_regex, line)
+
+ if version_match and not zstream and not release:
+ current_version = version_match.group(2)
+ old_version = current_version
+ release = None
+ if len(current_version.split("-")) >= 2:
+ (current_version, release) = current_version.split("-")
+
+ if hasattr(self, '_use_version'):
+ new_version = self._use_version
+ else:
+ new_version = increase_version(current_version)
+
+ if release:
+ new_version = f"{new_version}-{release}"
+ line = "".join([version_match.group(1), new_version, "\n"])
+
+ lines.append(line)
+
+ new_file_content = "".join(lines)
+
+ out_f.write(new_file_content)
+
+ in_f.close()
+ out_f.close()
+ shutil.move(self.spec_file + ".new", self.spec_file)
+
+ new_version = get_spec_version_and_release(self.full_project_dir, self.spec_file_name)
+ if new_version.strip() == "":
+ msg = "Error getting bumped package version"
+ error_out(msg)
+ info_out("Tagging new version of %s: %s -> %s" % (self.project_name, old_version, new_version))
+ return new_version