Skip to content
Snippets Groups Projects
Commit 527236a1 authored by Newbyte's avatar Newbyte :snowflake: Committed by Luca Weiss
Browse files

pmb.helpers: Automatically migrate fetch and push URL (MR 2429)


This could be re-purposed in the future in case we migrate URLs again.

Co-authored-by: default avatarCaleb Connolly <caleb@postmarketos.org>
Tweaked-by: default avatarOliver Smith <ollieparanoid@postmarketos.org>
(cherry picked from commit 344d6f22)
[luca: backport to 2.3.x, add "2.x" suffix to workdir]
parent 3be59b66
No related branches found
No related tags found
No related merge requests found
......@@ -45,7 +45,7 @@ pmaports_min_version = "7"
# Version of the work folder (as asked during 'pmbootstrap init'). Increase
# this number, whenever migration is required and provide the migration code,
# see migrate_work_folder()).
work_version = 6
work_version = 7
# Minimum required version of postmarketos-ondev (pmbootstrap install --ondev).
# Try to support the current versions of all channels (edge, v21.03). When
......
......@@ -84,9 +84,10 @@ def ask_for_work_path(args):
# created the work directory or the user has deleted it for
# whatever reason then we need to write initialize it.
work_version_file = f"{work}/version"
suffix = "-2.x"
if not os.path.isfile(work_version_file):
with open(work_version_file, "w") as handle:
handle.write(f"{pmb.config.work_version}\n")
handle.write(f"{pmb.config.work_version}{suffix}\n")
# Create cache_git dir, so it is owned by the host system's user
# (otherwise pmb.helpers.mount.bind would create it as root)
......
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import configparser
from enum import Enum
import logging
import os
......@@ -85,6 +86,12 @@ def clean_worktree(args, path):
return pmb.helpers.run.user(args, command, path, output_return=True) == ""
def list_remotes(args, aports) -> list[str]:
command = ["git", "remote", "-v"]
output = pmb.helpers.run.user(args, command, aports, output_return=True)
return output.splitlines()
def get_upstream_remote(args, name_repo):
"""Find the remote, which matches the git URL from the config.
......@@ -92,15 +99,74 @@ def get_upstream_remote(args, name_repo):
"""
url = pmb.config.git_repos[name_repo]
path = get_path(args, name_repo)
command = ["git", "remote", "-v"]
output = pmb.helpers.run.user(args, command, path, output_return=True)
for line in output.split("\n"):
lines = list_remotes(args, args.aports)
for line in lines:
if url in line:
return line.split("\t", 1)[0]
raise RuntimeError("{}: could not find remote name for URL '{}' in git"
" repository: {}".format(name_repo, url, path))
class RemoteType(Enum):
FETCH = "fetch"
PUSH = "push"
@staticmethod
def from_git_output(git_remote_type: str) -> "RemoteType":
match git_remote_type:
case "(fetch)":
return RemoteType.FETCH
case "(push)":
return RemoteType.PUSH
case _:
raise ValueError(f'Unknown remote type "{git_remote_type}"')
def set_remote_url(args, repo: str, remote_name: str, remote_url: str, remote_type: RemoteType) -> None:
command: list[str] = [
"git",
"-C",
repo,
"remote",
"set-url",
remote_name,
remote_url,
"--push" if remote_type == RemoteType.PUSH else "--no-push",
]
pmb.helpers.run.user(args, command, output="stdout")
# Intentionally lower case for case-insensitive comparison
OUTDATED_GIT_REMOTES_HTTP: list[str] = ["https://gitlab.com/postmarketos/pmaports.git"]
def migrate_upstream_remote(args) -> None:
"""Migrate pmaports git remote URL from gitlab.com to gitlab.postmarketos.org."""
lines = list_remotes(args, args.aports)
current_git_remote_http: str = pmb.config.git_repos["pmaports"]
for line in lines:
if not line:
continue # Skip empty line at the end.
remote_name, remote_url, remote_type_raw = line.split()
remote_type = RemoteType.from_git_output(remote_type_raw)
if remote_url.lower() in OUTDATED_GIT_REMOTES_HTTP:
new_remote = current_git_remote_http
else:
new_remote = None
if new_remote:
logging.info(
f"Migrating to new {remote_type.value} URL (from {remote_url} to {new_remote})"
)
set_remote_url(args, args.aports, remote_name, current_git_remote_http, remote_type)
def parse_channels_cfg(args):
"""Parse channels.cfg from pmaports.git, origin/master branch.
......
......@@ -67,10 +67,10 @@ def check_binfmt_misc(args):
raise RuntimeError(f"Failed to set up binfmt_misc, see: {link}")
def migrate_success(args, version):
def migrate_success(args, version, suffix=""):
logging.info("Migration to version " + str(version) + " done")
with open(args.work + "/version", "w") as handle:
handle.write(str(version) + "\n")
handle.write(str(version) + suffix + "\n")
def migrate_work_folder(args):
......@@ -79,7 +79,8 @@ def migrate_work_folder(args):
path = args.work + "/version"
if os.path.exists(path):
with open(path, "r") as f:
current = int(f.read().rstrip())
# In 2.3.x branch we have some special versions, here we can just ignore this suffix.
current = int(f.read().rstrip().replace("-2.x", ""))
# Compare version, print warning or do nothing
required = pmb.config.work_version
......@@ -231,6 +232,30 @@ def migrate_work_folder(args):
migrate_success(args, 6)
current = 6
if current == 6:
# Ask for confirmation
logging.info("Changelog:")
logging.info("* Moved from gitlab.com to gitlab.postmarketOS.org")
logging.info("Migration will do the following:")
logging.info("* Update your pmaports remote URL")
if not pmb.helpers.cli.confirm(args):
raise RuntimeError("Aborted.")
pmb.helpers.git.migrate_upstream_remote(args)
try:
pmb.helpers.git.get_upstream_remote(args, "pmaports")
except RuntimeError:
logging.error(
"Couldn't find new upstream remote, migration failed."
" Please try updating the remote manually with:\n"
f" $ git -C '{args.aports}' remote set-url origin 'https://gitlab.postmarketos.org/postmarketOS/pmaports.git'"
)
raise RuntimeError("Migration failed.")
# Update version file
migrate_success(args, 7, "-2.x")
current = 7
# Can't migrate, user must delete it
if current != required:
raise RuntimeError("Sorry, we can't migrate that automatically. Please"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment