checkupdates: parse default branch from upstream remote
This commit is contained in:
parent
fd15ac9276
commit
e3f724681a
@ -18,6 +18,7 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import configparser
|
||||||
import git
|
import git
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
@ -688,11 +689,17 @@ def get_last_build_from_app(app: metadata.App) -> metadata.Build:
|
|||||||
return metadata.Build()
|
return metadata.Build()
|
||||||
|
|
||||||
|
|
||||||
def get_git_repo_and_main_branch():
|
def get_upstream_main_branch(git_repo):
|
||||||
git_repo = git.Repo.init('.')
|
if len(git_repo.remotes.upstream.refs) == 1:
|
||||||
with git_repo.config_reader() as reader:
|
return git_repo.remotes.upstream.refs[0].name
|
||||||
main_branch = reader.get_value('init', 'defaultBranch')
|
for name in ('main', 'master'):
|
||||||
return git_repo, main_branch
|
if name in git_repo.remotes.upstream.refs:
|
||||||
|
return f'upstream/{name}'
|
||||||
|
try:
|
||||||
|
with git_repo.config_reader() as reader:
|
||||||
|
return 'upstream/%s' % reader.get_value('init', 'defaultBranch')
|
||||||
|
except configparser.NoSectionError:
|
||||||
|
return 'upstream/main'
|
||||||
|
|
||||||
|
|
||||||
def checkout_appid_branch(appid):
|
def checkout_appid_branch(appid):
|
||||||
@ -711,7 +718,8 @@ def checkout_appid_branch(appid):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
logging.debug(f'Creating merge request branch for {appid}')
|
logging.debug(f'Creating merge request branch for {appid}')
|
||||||
git_repo, main_branch = get_git_repo_and_main_branch()
|
git_repo = git.Repo.init('.')
|
||||||
|
upstream_main = get_upstream_main_branch(git_repo)
|
||||||
for remote in git_repo.remotes:
|
for remote in git_repo.remotes:
|
||||||
remote.fetch()
|
remote.fetch()
|
||||||
try:
|
try:
|
||||||
@ -721,16 +729,14 @@ def checkout_appid_branch(appid):
|
|||||||
if appid in git_repo.remotes.origin.refs:
|
if appid in git_repo.remotes.origin.refs:
|
||||||
start_point = f"origin/{appid}"
|
start_point = f"origin/{appid}"
|
||||||
for commit in git_repo.iter_commits(
|
for commit in git_repo.iter_commits(
|
||||||
f'upstream/{main_branch}...{start_point}', right_only=True
|
f'{upstream_main}...{start_point}', right_only=True
|
||||||
):
|
):
|
||||||
if commit.committer.email != BOT_EMAIL or commit.author.email != BOT_EMAIL:
|
if commit.committer.email != BOT_EMAIL or commit.author.email != BOT_EMAIL:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
start_point = f"upstream/{main_branch}"
|
start_point = upstream_main
|
||||||
git_repo.git.checkout('-B', appid, start_point)
|
git_repo.git.checkout('-B', appid, start_point)
|
||||||
git_repo.git.rebase(
|
git_repo.git.rebase(upstream_main, strategy_option='ours', kill_after_timeout=120)
|
||||||
f'upstream/{main_branch}', strategy_option='ours', kill_after_timeout=120
|
|
||||||
)
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@ -751,11 +757,11 @@ def push_commits(remote_name='origin', branch_name='checkupdates', verbose=False
|
|||||||
* https://docs.gitlab.com/ee/user/project/push_options.html
|
* https://docs.gitlab.com/ee/user/project/push_options.html
|
||||||
|
|
||||||
"""
|
"""
|
||||||
git_repo, default = get_git_repo_and_main_branch()
|
git_repo = git.Repo.init('.')
|
||||||
|
upstream_main = get_upstream_main_branch(git_repo)
|
||||||
files = set()
|
files = set()
|
||||||
upstream_main = default if default in git_repo.remotes.upstream.refs else 'main'
|
|
||||||
for commit in git_repo.iter_commits(
|
for commit in git_repo.iter_commits(
|
||||||
f'upstream/{upstream_main}...HEAD', right_only=True
|
f'{upstream_main}...HEAD', right_only=True
|
||||||
):
|
):
|
||||||
files.update(commit.stats.files.keys())
|
files.update(commit.stats.files.keys())
|
||||||
|
|
||||||
@ -780,7 +786,7 @@ def push_commits(remote_name='origin', branch_name='checkupdates', verbose=False
|
|||||||
current_version_only = True
|
current_version_only = True
|
||||||
for m in re.findall(
|
for m in re.findall(
|
||||||
r"^[+-].*",
|
r"^[+-].*",
|
||||||
git_repo.git.diff(f"upstream/{upstream_main}...HEAD"),
|
git_repo.git.diff(f"{upstream_main}...HEAD"),
|
||||||
flags=re.MULTILINE,
|
flags=re.MULTILINE,
|
||||||
):
|
):
|
||||||
if re.match(r"^(\+\+\+|---) ", m):
|
if re.match(r"^(\+\+\+|---) ", m):
|
||||||
@ -835,8 +841,9 @@ def push_commits(remote_name='origin', branch_name='checkupdates', verbose=False
|
|||||||
def prune_empty_appid_branches(git_repo=None, main_branch='main'):
|
def prune_empty_appid_branches(git_repo=None, main_branch='main'):
|
||||||
"""Remove empty branches from checkupdates-bot git remote."""
|
"""Remove empty branches from checkupdates-bot git remote."""
|
||||||
if git_repo is None:
|
if git_repo is None:
|
||||||
git_repo, main_branch = get_git_repo_and_main_branch()
|
git_repo = git.Repo.init('.')
|
||||||
upstream_main = 'upstream/' + main_branch
|
upstream_main = get_upstream_main_branch(git_repo)
|
||||||
|
main_branch = upstream_main.split('/')[1]
|
||||||
|
|
||||||
remote = git_repo.remotes.origin
|
remote = git_repo.remotes.origin
|
||||||
remote.update(prune=True)
|
remote.update(prune=True)
|
||||||
|
@ -453,20 +453,47 @@ class CheckupdatesTest(unittest.TestCase):
|
|||||||
fdroidserver.checkupdates.main()
|
fdroidserver.checkupdates.main()
|
||||||
sys_exit.assert_not_called()
|
sys_exit.assert_not_called()
|
||||||
|
|
||||||
def test_get_git_repo_and_main_branch(self):
|
def test_get_upstream_main_branch(self):
|
||||||
os.chdir(self.testdir.name)
|
os.chdir(self.testdir.name)
|
||||||
git_repo = git.Repo.init()
|
testvalue = 'foo'
|
||||||
|
git_repo = git.Repo.init('.', initial_branch=testvalue)
|
||||||
|
|
||||||
open('foo', 'w').close()
|
open('foo', 'w').close()
|
||||||
git_repo.git.add(all=True)
|
git_repo.git.add(all=True)
|
||||||
git_repo.index.commit("all files")
|
git_repo.index.commit("all files")
|
||||||
|
git_repo.create_remote('upstream', os.getcwd()).fetch()
|
||||||
|
|
||||||
repo, branch = fdroidserver.checkupdates.get_git_repo_and_main_branch()
|
branch = fdroidserver.checkupdates.get_upstream_main_branch(git_repo)
|
||||||
self.assertTrue(branch in repo.heads)
|
self.assertEqual(
|
||||||
|
f'upstream/{testvalue}',
|
||||||
|
branch,
|
||||||
|
f'The default branch should be called {testvalue}!',
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_get_upstream_main_branch_git_config(self):
|
||||||
|
os.chdir(self.testdir.name)
|
||||||
|
testvalue = 'foo'
|
||||||
|
git_repo = git.Repo.init('.', initial_branch=testvalue)
|
||||||
|
with git_repo.config_writer() as cw:
|
||||||
|
cw.set_value('init', 'defaultBranch', testvalue)
|
||||||
|
|
||||||
|
open('foo', 'w').close()
|
||||||
|
git_repo.git.add(all=True)
|
||||||
|
git_repo.index.commit("all files")
|
||||||
|
git_repo.git.branch('somethingelse') # make another remote branch
|
||||||
|
git_repo.create_remote('upstream', os.getcwd()).fetch()
|
||||||
|
|
||||||
|
branch = fdroidserver.checkupdates.get_upstream_main_branch(git_repo)
|
||||||
|
self.assertEqual(
|
||||||
|
f'upstream/{testvalue}',
|
||||||
|
branch,
|
||||||
|
f'The default branch should be called {testvalue}!',
|
||||||
|
)
|
||||||
|
|
||||||
def test_checkout_appid_branch_does_not_exist(self):
|
def test_checkout_appid_branch_does_not_exist(self):
|
||||||
appid = 'com.example'
|
appid = 'com.example'
|
||||||
os.chdir(self.testdir.name)
|
os.chdir(self.testdir.name)
|
||||||
git_repo, main_branch = fdroidserver.checkupdates.get_git_repo_and_main_branch()
|
git_repo = git.Repo.init('.')
|
||||||
open('foo', 'w').close()
|
open('foo', 'w').close()
|
||||||
git_repo.git.add(all=True)
|
git_repo.git.add(all=True)
|
||||||
git_repo.index.commit("all files")
|
git_repo.index.commit("all files")
|
||||||
@ -491,7 +518,7 @@ class CheckupdatesTest(unittest.TestCase):
|
|||||||
local_dir = os.path.join(self.testdir.name, 'local_git')
|
local_dir = os.path.join(self.testdir.name, 'local_git')
|
||||||
git.Repo.clone_from(upstream_dir, local_dir)
|
git.Repo.clone_from(upstream_dir, local_dir)
|
||||||
os.chdir(local_dir)
|
os.chdir(local_dir)
|
||||||
git_repo, main_branch = fdroidserver.checkupdates.get_git_repo_and_main_branch()
|
git_repo = git.Repo.init('.')
|
||||||
# --merge-request assumes remotes called 'origin' and 'upstream'
|
# --merge-request assumes remotes called 'origin' and 'upstream'
|
||||||
git_repo.create_remote('upstream', upstream_dir).fetch()
|
git_repo.create_remote('upstream', upstream_dir).fetch()
|
||||||
|
|
||||||
@ -513,7 +540,7 @@ class CheckupdatesTest(unittest.TestCase):
|
|||||||
local_dir = os.path.join(self.testdir.name, 'local_git')
|
local_dir = os.path.join(self.testdir.name, 'local_git')
|
||||||
git.Repo.clone_from(upstream_dir, local_dir)
|
git.Repo.clone_from(upstream_dir, local_dir)
|
||||||
os.chdir(local_dir)
|
os.chdir(local_dir)
|
||||||
git_repo, main_branch = fdroidserver.checkupdates.get_git_repo_and_main_branch()
|
git_repo = git.Repo.init('.')
|
||||||
# --merge-request assumes remotes called 'origin' and 'upstream'
|
# --merge-request assumes remotes called 'origin' and 'upstream'
|
||||||
git_repo.create_remote('upstream', upstream_dir).fetch()
|
git_repo.create_remote('upstream', upstream_dir).fetch()
|
||||||
|
|
||||||
@ -530,7 +557,8 @@ class CheckupdatesTest(unittest.TestCase):
|
|||||||
|
|
||||||
# set up starting from remote branch
|
# set up starting from remote branch
|
||||||
git_repo.remotes.origin.push(appid)
|
git_repo.remotes.origin.push(appid)
|
||||||
git_repo.git.checkout(main_branch)
|
upstream_main = fdroidserver.checkupdates.get_upstream_main_branch(git_repo)
|
||||||
|
git_repo.git.checkout(upstream_main.split('/')[1])
|
||||||
git_repo.delete_head(appid, force=True)
|
git_repo.delete_head(appid, force=True)
|
||||||
|
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
@ -552,7 +580,7 @@ class CheckupdatesTest(unittest.TestCase):
|
|||||||
local_dir = os.path.join(self.testdir.name, 'local_git')
|
local_dir = os.path.join(self.testdir.name, 'local_git')
|
||||||
git.Repo.clone_from(upstream_dir, local_dir)
|
git.Repo.clone_from(upstream_dir, local_dir)
|
||||||
os.chdir(local_dir)
|
os.chdir(local_dir)
|
||||||
git_repo, main_branch = fdroidserver.checkupdates.get_git_repo_and_main_branch()
|
git_repo = git.Repo.init('.')
|
||||||
# --merge-request assumes remotes called 'origin' and 'upstream'
|
# --merge-request assumes remotes called 'origin' and 'upstream'
|
||||||
git_repo.create_remote('upstream', upstream_dir).fetch()
|
git_repo.create_remote('upstream', upstream_dir).fetch()
|
||||||
|
|
||||||
@ -577,7 +605,8 @@ class CheckupdatesTest(unittest.TestCase):
|
|||||||
|
|
||||||
# set up starting from remote branch
|
# set up starting from remote branch
|
||||||
git_repo.remotes.origin.push(appid)
|
git_repo.remotes.origin.push(appid)
|
||||||
git_repo.git.reset(main_branch)
|
upstream_main = fdroidserver.checkupdates.get_upstream_main_branch(git_repo)
|
||||||
|
git_repo.git.reset(upstream_main.split('/')[1])
|
||||||
|
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
fdroidserver.checkupdates.checkout_appid_branch(appid),
|
fdroidserver.checkupdates.checkout_appid_branch(appid),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user