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
openSUSE Build Service is sponsored by