Feat: add a script to script/bump_mri_versions 15/103615/23
authorMario Doman <mario.doman@pantheon.tech>
Tue, 6 Dec 2022 17:13:47 +0000 (18:13 +0100)
committerMario Doman <mario.doman@pantheon.tech>
Mon, 30 Jan 2023 09:52:16 +0000 (10:52 +0100)
This script loops through pom.xml files in given dir and update patch
versions on parent/dependencies artifacts.

Also updating versions in feature.xml files.

Change-Id: Ib709260b71a2f62179397e17df5a71251e0f4042
Signed-off-by: Mario Doman <mario.doman@pantheon.tech>
.gitignore
scripts/bump_mri_versions/main.py [new file with mode: 0644]
scripts/bump_mri_versions/python_lib.py [new file with mode: 0644]
scripts/bump_mri_versions/readme.md [new file with mode: 0644]

index 53704da62ae6d03e1cdb58cbad6643e2cf1d2bf9..851fcaa4f5731f0d47b06db181fe95af8da9aff6 100644 (file)
@@ -24,3 +24,7 @@ target/
 .tox/
 __pycache__/
 *.pyc
+
+# Bump_MRI_versions
+scripts/bump_mri_versions/venv/
+scripts/bump_mri_versions/repos/*
\ No newline at end of file
diff --git a/scripts/bump_mri_versions/main.py b/scripts/bump_mri_versions/main.py
new file mode 100644 (file)
index 0000000..b6ee7ee
--- /dev/null
@@ -0,0 +1,95 @@
+# Copyright (c) 2023 PANTHEON.tech s.r.o. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v1.0 which accompanies this distribution,
+# and is available at http://www.eclipse.org/legal/epl-v10.html
+
+import re
+import requests
+import python_lib
+# pylint: disable=wrong-import-order
+from pathlib import Path
+from bs4 import BeautifulSoup
+from lxml import etree
+
+
+def get_version_for_artifact(group_id_elem, artifact_id_elem):
+    versions_list = []
+    url = f'https://repo1.maven.org/maven2/org/opendaylight/{group_id_elem}/{artifact_id_elem}/'
+    response = requests.get(url).content
+    soup = BeautifulSoup(response, 'html.parser')
+    try:
+        html_lines = str(soup.find_all('pre')[0]).splitlines()
+    except IndexError:
+        return "NOT FOUND"
+    for line in html_lines:
+        # Use a regular expression to find version
+        pattern = re.compile(r'\d+\.\d+\.\d+')
+        title = pattern.search(line)
+        try:
+            versions_list.append(title.group())
+        except AttributeError:
+            pass
+    return python_lib.find_highest_revision(versions_list)
+
+
+# get all xml files
+for path in Path(python_lib.bumping_dir).rglob('*.xml'):
+    if ("pom.xml" or "feature.xml" in str(path)):
+        if "test/resources" not in str(path):
+            tree = etree.parse(path)
+            root = tree.getroot()
+            # update major and minor artifacts versions
+            if "pom.xml" in str(path):
+                prefix = "{" + root.nsmap[None] + "}"
+                all_elements = tree.findall(
+                    f'.//{prefix}parent') + tree.findall(f'.//{prefix}dependency')
+                for element in all_elements:
+                    group_id_elem = (element.find(f'{prefix}groupId'))
+                    artifact_id_elem = (element.find(f'{prefix}artifactId'))
+                    version = (element.find(f'{prefix}version'))
+                    try:
+                        if "org.opendaylight" in group_id_elem.text and version is not None:
+                            # skip artifacts containing items in skipped list
+                            skipped = ["${project.version}",
+                                    "SNAPSHOT", "@project.version@"]
+                            if not any(x in version.text for x in skipped):
+                                new_version = get_version_for_artifact(
+                                    group_id_elem.text.split(".")[2], artifact_id_elem.text)
+                                if python_lib.check_minor_version(version, new_version):
+                                    print(python_lib.log_artifact(
+                                        path, group_id_elem, artifact_id_elem, version.text, new_version))
+                                    version.text = new_version
+                                    tree.write(path, encoding="UTF-8", pretty_print=True,
+                                            doctype='<?xml version="1.0" encoding="UTF-8"?>')
+                    except AttributeError:
+                        pass
+
+        # update feature versions
+        if "feature.xml" in str(path):
+            prefix = "{" + root.nsmap[None] + "}"
+            all_featuress = tree.findall(f'.//{prefix}feature')
+
+            # feature versions add +1
+            for feature in all_featuress:
+                try:
+                    if feature.attrib["version"] and feature.attrib["version"] != "${project.version}":
+                        current_version = feature.attrib["version"]
+                        # workaround for float feature versions
+                        nums = current_version[1:-1].split(',')
+                        if "." in nums[0]:
+                            nums[0] = str(round((float(nums[0]) + 0.01), 2))
+                        else:
+                            nums[0], nums[1] = str(
+                                int(nums[0]) + 1), str(int(nums[1])+1)
+                        result = '[' + ','.join(nums) + ')'
+                        feature.attrib["version"] = result
+                        print(python_lib.log_artifact(
+                            path=path, version=current_version, new_version=result))
+                        standalone = ''
+                        if tree.docinfo.standalone:
+                            standalone = ' standalone="yes"'
+                        tree.write(path, encoding="UTF-8", pretty_print=True,
+                                   doctype=f'<?xml version="1.0" encoding="UTF-8"{standalone}?>')
+                except KeyError:
+                    pass
diff --git a/scripts/bump_mri_versions/python_lib.py b/scripts/bump_mri_versions/python_lib.py
new file mode 100644 (file)
index 0000000..c724154
--- /dev/null
@@ -0,0 +1,39 @@
+# Copyright (c) 2023 PANTHEON.tech s.r.o. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v1.0 which accompanies this distribution,
+# and is available at http://www.eclipse.org/legal/epl-v10.html
+
+# modify this dir for pick up project from there
+bumping_dir = "repos"
+
+
+def find_highest_revision(revisions):
+    # convert list of strings to list of tuples
+    converted_items = [tuple(map(int, item.split('.'))) for item in revisions]
+    biggest_item = max(converted_items, key=lambda x: x)
+    biggest_version = '.'.join(str(x) for x in biggest_item)
+    return biggest_version
+
+
+def log_artifact(path, group_id=None, artifact_id=None, version=None, new_version=None):
+    log = ""
+    log += "XML FILE: " + str(path) + "\n"
+    # if none, printing feature update
+    if group_id is None:
+        log_line = ("path:", path, "VERSION:", version,
+                    "NEW VERSION:", new_version)
+    # else printing artifact update
+    else:
+        log_line = ("groupId:", group_id.text, "ARTIFACT ID:",
+                    artifact_id.text, "VERSION:", version, "NEW VERSION:", new_version)
+    log += str(log_line) + "\n"
+    log += str(100 * "*" + "\n")
+    return log
+
+
+def check_minor_version(version, new_version):
+    # compares the corresponding elements of the two version strings
+    if any(int(elem_a) != int(elem_b) for elem_a, elem_b in zip(version.text.split("."), new_version.split("."))):
+        return True
+    return False
diff --git a/scripts/bump_mri_versions/readme.md b/scripts/bump_mri_versions/readme.md
new file mode 100644 (file)
index 0000000..4659a3f
--- /dev/null
@@ -0,0 +1,66 @@
+# Copyright (c) 2023 PANTHEON.tech s.r.o. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v1.0 which accompanies this distribution,
+# and is available at http://www.eclipse.org/legal/epl-v10.html
+
+
+# Bumping MRI versions tool
+This program is making versions changes in pom.xml files. For example 10.0.1 to 10.0.2
+The change will aply only if groupId.text contain "org.opendaylight".
+
+This program is also making changes in feature.xml files. For example [0.16,1) to [0.17,1)
+
+
+## Installing
+
+*Prerequisite:*  The followings are required for building test:
+
+- Python 3.8+
+
+GET THE CODE:
+
+USING HTTPS:
+    git clone "https://git.opendaylight.org/gerrit/releng/builder"
+
+USING SSH:
+    git clone "ssh://{USERNAME}@git.opendaylight.org:29418/releng/builder"
+
+NAVIGATE TO:
+    cd ~/builder/scripts/bump_mri_versions
+
+INSTALL VIRTUAL ENVIROMENT PACKAGE:
+    sudo apt install python3-virtualenv
+
+CREATE NEW VIRTUAL ENVIROMENT:
+    virtualenv venv
+
+ACTIVATE VIRTUAL ENVIROMENT:
+    . venv/bin/activate
+
+INSTALL LIBRARIES:
+    pip install requests bs4 lxml
+
+SET FOLDER FOR TESTING:
+    clone repo for version updating in ~/builder/scripts/bump_mri_versions/repos or
+        update "bumping_dir" variable in python_lib.py file
+
+
+## Running
+
+RUN: python main.py
+
+## Logs
+
+PRINT:
+    Every change will be printed out to the console.
+
+    examples here:
+
+    XML FILE: repos/aaa/features/odl-aaa-api/pom.xml
+    ('groupId:', 'org.opendaylight.mdsal', 'ARTIFACT ID:', 'odl-mdsal-binding-base', 'VERSION:', '11.0.1', 'NEW VERSION:', '11.0.2')
+    ****************************************************************************************************
+
+    XML FILE: repos/ovsdb/southbound/southbound-features/odl-ovsdb-southbound-impl/src/main/feature/feature.xml
+    ('path:', PosixPath('repos/ovsdb/southbound/southbound-features/odl-ovsdb-southbound-impl/src/main/feature/feature.xml'), 'VERSION:', '[4,5)', 'NEW VERSION:', '[5,6)')
+    ****************************************************************************************************
\ No newline at end of file