aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/obs/lib/git.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/obs/lib/git.py')
-rw-r--r--scripts/obs/lib/git.py109
1 files changed, 109 insertions, 0 deletions
diff --git a/scripts/obs/lib/git.py b/scripts/obs/lib/git.py
new file mode 100644
index 0000000..67f1d5e
--- /dev/null
+++ b/scripts/obs/lib/git.py
@@ -0,0 +1,109 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright 2022 sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+import os
+import re
+import lib.config
+
+
+def get_repo_path(project):
+ return f"{lib.config.path_cache}/{os.path.basename(project)}"
+
+
+def get_repo_url(project):
+ if project in lib.config.git_url_other:
+ return lib.config.git_url_other[project]
+ return f"{lib.config.git_url_default}/{project}"
+
+
+def get_latest_tag_pattern(project):
+ if project in lib.config.git_latest_tag_pattern_other:
+ return lib.config.git_latest_tag_pattern_other[project]
+ return lib.config.git_latest_tag_pattern_default
+
+
+def clone(project, fetch=False):
+ repo_path = get_repo_path(project)
+ url = get_repo_url(project)
+
+ if os.path.exists(repo_path):
+ if fetch:
+ print(f"{project}: cloning {url} (cached, fetching)")
+ lib.run_cmd(["git", "fetch"], cwd=repo_path)
+ else:
+ print(f"{project}: cloning {url} (cached, not fetching)")
+ return
+
+ print(f"{project}: cloning {url}")
+ os.makedirs(lib.config.path_cache, exist_ok=True)
+ lib.run_cmd(["git", "clone", url, repo_path])
+
+ lib.run_cmd(["git", "config", "user.name", "Osmocom OBS scripts"],
+ cwd=repo_path)
+ lib.run_cmd(["git", "config", "user.email", "info@osmocom.org"],
+ cwd=repo_path)
+
+
+def clean(project):
+ repo_path = get_repo_path(project)
+ lib.run_cmd(["git", "clean", "-ffxd"], cwd=repo_path)
+
+
+def checkout(project, branch):
+ repo_path = get_repo_path(project)
+ print(f"{project}: checking out {branch}")
+ lib.run_cmd(["git", "checkout", "-f", branch], cwd=repo_path)
+ lib.run_cmd(["git", "reset", "--hard", branch], cwd=repo_path)
+
+
+def checkout_default_branch(project):
+ branch = lib.config.git_branch_default
+ if project in lib.config.git_branch_other:
+ branch = lib.config.git_branch_other[project]
+
+ checkout(project, f"origin/{branch}")
+
+
+def get_latest_tag(project):
+ pattern_str = get_latest_tag_pattern(project)
+ pattern = re.compile(pattern_str)
+ repo_path = get_repo_path(project)
+
+ git_tag_ret = lib.run_cmd(["git", "tag", "-l", "--sort=-v:refname"],
+ cwd=repo_path)
+
+ for line in git_tag_ret.output.split('\n'):
+ line = line.strip('\r')
+ if pattern.match(line):
+ return line
+
+ lib.exit_error_cmd(git_tag_ret, f"couldn't find latest tag for {project},"
+ f" regex used on output: {pattern_str}")
+
+
+def get_latest_tag_remote(project):
+ pattern_str = get_latest_tag_pattern(project)
+ pattern = re.compile(pattern_str)
+
+ print(f"{project}: getting latest tag from git remote")
+ ls_remote = lib.run_cmd(["git", "ls-remote", "--tags", "--sort=-v:refname",
+ get_repo_url(project)])
+ for line in ls_remote.output.split('\n'):
+ # Tags are listed twice, skip the ones with ^{} at the end
+ if "^{}" in line:
+ continue
+
+ if "refs/tags/" not in line:
+ continue
+
+ line = line.rstrip().split("refs/tags/")[1]
+ if pattern.match(line):
+ return line
+
+ # No tag found probably means the repository was just created and doesn't
+ # have a release tag yet
+ return None
+
+
+def checkout_latest_tag(project):
+ checkout(project, get_latest_tag(project))