From 4de8f259b9b858444a6b96259fbe50652547cb6c Mon Sep 17 00:00:00 2001 From: Julen Landa Alustiza Date: Sep 25 2019 12:55:54 +0000 Subject: [PATCH 1/3] Move set_ref_head to lib --- diff --git a/pagure/lib/git.py b/pagure/lib/git.py index 5702b79..0199dcf 100644 --- a/pagure/lib/git.py +++ b/pagure/lib/git.py @@ -2512,6 +2512,18 @@ def new_git_branch( tempclone.push(username, branch, branch) +def git_set_ref_head(project, branch): + """ Set the HEAD reference of the project + :arg project: The project instance to set the HEAD reference + :arg branch: The branch to be set as HEAD reference + """ + repo_path = pagure.utils.get_repo_path(project) + repo_obj = PagureRepo(repo_path) + + reference = repo_obj.lookup_reference("refs/heads/%s" % branch).resolve() + repo_obj.set_head(reference.name) + + def delete_project_repos(project): """ Deletes the actual git repositories on disk or repoSpanner diff --git a/pagure/ui/repo.py b/pagure/ui/repo.py index 88ca471..5630ad3 100644 --- a/pagure/ui/repo.py +++ b/pagure/ui/repo.py @@ -1631,10 +1631,7 @@ def change_ref_head(repo, username=None, namespace=None): if form.validate_on_submit(): branchname = form.branches.data try: - reference = repo_obj.lookup_reference( - "refs/heads/%s" % branchname - ).resolve() - repo_obj.set_head(reference.name) + pagure.lib.git.git_set_ref_head(project=repo, branch=branchname) flask.flash("Default branch updated to %s" % branchname) except Exception as err: # pragma: no cover _log.exception(err) From 803bbd093997e7dfe82c9e8d91f663514875cded Mon Sep 17 00:00:00 2001 From: Julen Landa Alustiza Date: Sep 25 2019 12:55:54 +0000 Subject: [PATCH 2/3] Add a set-default-branch action to pagure-admin --- diff --git a/pagure/cli/admin.py b/pagure/cli/admin.py index c327291..a00cc1b 100644 --- a/pagure/cli/admin.py +++ b/pagure/cli/admin.py @@ -17,6 +17,7 @@ import os import requests from string import Template import sys +import pygit2 import arrow from six.moves import input @@ -34,6 +35,7 @@ import pagure.lib.model_base # noqa: E402 import pagure.lib.query # noqa: E402 import pagure.lib.tasks_utils # noqa: E402 from pagure.flask_app import generate_user_key_files # noqa: E402 +from pagure.utils import get_repo_path # noqa: E402 _config = pagure.config.reload_config() @@ -462,6 +464,30 @@ def _parser_create_branch(subparser): local_parser.set_defaults(func=do_create_branch) +def _parser_set_default_branch(subparser): + """ Set up the CLI argument parser for the set-default-branch action. + + :arg subparser: an argparse subparser allowing to have action's specific + arguments + + """ + local_parser = subparser.add_parser( + "set-default-branch", help="Set the specified branch as default" + ) + local_parser.add_argument( + "project", + help="Project to update (as namespace/project if there " + "is a namespace)", + ) + local_parser.add_argument( + "--user", help="User of the project (to use only on forks)" + ) + local_parser.add_argument( + "branch", help="Name of the branch to be set as default" + ) + local_parser.set_defaults(func=do_set_default_branch) + + def parse_arguments(args=None): """ Set-up the argument parsing. """ parser = argparse.ArgumentParser( @@ -523,6 +549,9 @@ def parse_arguments(args=None): # create-branch _parser_create_branch(subparser) + # set-default-branch + _parser_set_default_branch(subparser) + return parser.parse_args(args) @@ -1219,6 +1248,37 @@ def do_create_branch(args): print("Branch created") +def do_set_default_branch(args): + """ Sets the specified git branch as default + + Args: + args (argparse.Namespace): Parsed arguments + """ + _log.debug("project: %s", args.project) + _log.debug("user: %s", args.user) + _log.debug("branch: %s", args.branch) + + # Get the project + project = _get_project(args.project, user=args.user) + + if project is None: + raise pagure.exceptions.PagureException( + "No project found with: %s, user: %s" % (args.project, args.user) + ) + + repo_path = get_repo_path(project) + repo_obj = pygit2.Repository(repo_path) + + if args.branch not in repo_obj.listall_branches(): + raise pagure.exceptions.PagureException( + "No %s branch found on project: %s" % (args.branch, args.project) + ) + + pagure.lib.git.git_set_ref_head(project, args.branch) + + print("Branch %s set as default" % (args.branch)) + + def main(): """ Start of the application. """ diff --git a/tests/test_config b/tests/test_config index 04970a4..1b0734d 100644 --- a/tests/test_config +++ b/tests/test_config @@ -1,2 +1,2 @@ -PAGURE_CI_SERVICES = ['jenkins'] +PAGURE_CI_SERVICES = ["jenkins"] ALLOW_PROJECT_DOWAIT = True diff --git a/tests/test_pagure_admin.py b/tests/test_pagure_admin.py index bbc8999..8ddeed2 100644 --- a/tests/test_pagure_admin.py +++ b/tests/test_pagure_admin.py @@ -1974,5 +1974,98 @@ class PagureCreateBranchTests(tests.Modeltests): ) +class PagureSetDefaultBranchTests(tests.Modeltests): + """ Tests for pagure-admin set-default-branch """ + + populate_db = True + + def setUp(self): + """ Set up the environment, run before every tests. """ + super(PagureSetDefaultBranchTests, self).setUp() + + # Create a couple of projects + tests.create_projects(self.session) + # Create their git repo + tests.create_projects_git(os.path.join(self.path, "repos"), bare=True) + + # Make the imported pagure use the correct db session + pagure.cli.admin.session = self.session + + def test_set_default_branch_unknown_project(self): + """ Test the set-default-branch function of pagure-admin on an unknown + project. + """ + + args = munch.Munch( + {"project": "foob", "user": None, "branch": "master"} + ) + with self.assertRaises(pagure.exceptions.PagureException) as cm: + pagure.cli.admin.do_set_default_branch(args) + self.assertEqual( + cm.exception.args[0], "No project found with: foob, user: None" + ) + + def test_set_default_branch_invalid_project(self): + """ Test the set-default-branch function of pagure-admin on an invalid + project. + """ + + args = munch.Munch( + {"project": "f/o/o/b", "user": None, "branch": "master"} + ) + with self.assertRaises(pagure.exceptions.PagureException) as cm: + pagure.cli.admin.do_set_default_branch(args) + self.assertEqual( + cm.exception.args[0], + 'Invalid project name, has more than one "/": f/o/o/b', + ) + + def test_set_default_branch_unknown_branch(self): + """ Test the set-default-branch function of pagure-admin on an unknown + branch. + """ + + args = munch.Munch({"project": "test", "user": None, "branch": "foob"}) + with self.assertRaises(pagure.exceptions.PagureException) as cm: + pagure.cli.admin.do_set_default_branch(args) + self.assertEqual( + cm.exception.args[0], "No foob branch found on project: test" + ) + + def test_set_default_branch_invalid_branch(self): + """ Test the set-default-branch function of pagure-admin on an invalid branch. + """ + + args = munch.Munch( + {"project": "test", "user": None, "branch": "~invalid~"} + ) + with self.assertRaises(pagure.exceptions.PagureException) as cm: + pagure.cli.admin.do_set_default_branch(args) + self.assertEqual( + cm.exception.args[0], "No ~invalid~ branch found on project: test" + ) + + def test_set_default_branch(self): + """ Test the set-default-branch funcion of pagure-admin. """ + + gitrepo_path = os.path.join(self.path, "repos", "test.git") + tests.add_content_git_repo(gitrepo_path) + tests.add_commit_git_repo(gitrepo_path, branch="dev") + + # Check default branch before: + gitrepo = pygit2.Repository(gitrepo_path) + self.assertEqual(gitrepo.head.shorthand, "master") + + args = munch.Munch({"project": "test", "user": None, "branch": "dev"}) + + with tests.capture_output() as output: + pagure.cli.admin.do_set_default_branch(args) + output = output.getvalue() + self.assertEqual("Branch dev set as default\n", output) + + # Check default branch after: + self.assertEqual(gitrepo.head.shorthand, "dev") + + if __name__ == "__main__": unittest.main(verbosity=2) From 76327a810d485c67df6c5732c135d768da575806 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sep 25 2019 12:55:54 +0000 Subject: [PATCH 3/3] pagure-admin: reusable project checking --- diff --git a/pagure/cli/admin.py b/pagure/cli/admin.py index a00cc1b..3808f3c 100644 --- a/pagure/cli/admin.py +++ b/pagure/cli/admin.py @@ -585,6 +585,16 @@ def _get_project(arg_project, user=None): ) +def _check_project(_project, **kwargs): + """ Check that the project extracted with args is a valid project """ + if _project is None: + raise pagure.exceptions.PagureException( + "No project found with: {}".format( + ", ".join(["{}={}".format(k, v) for k, v in kwargs.items()]) + ) + ) + + def do_generate_acl(args): """ Regenerate the gitolite ACL file. @@ -835,10 +845,7 @@ def do_delete_project(args): # Get the project project = _get_project(args.project, user=args.user) - if project is None: - raise pagure.exceptions.PagureException( - "No project found with: %s" % args.project - ) + _check_project(project, project=args.project, user=args.user) print( "Are you sure you want to delete: %s?\n This cannot be undone!" @@ -871,10 +878,7 @@ def do_get_watch_status(args): # Get the project project = _get_project(args.project) - if project is None: - raise pagure.exceptions.PagureException( - "No project found with: %s" % args.project - ) + _check_project(project, project=args.project) level = ( pagure.lib.query.get_watch_level_on_repo( @@ -928,10 +932,7 @@ def do_update_watch_status(args): # Get the project project = _get_project(args.project) - if project is None: - raise pagure.exceptions.PagureException( - "No project found with: %s" % args.project - ) + _check_project(project, project=args.project) print( "Updating watch status of %s to %s (%s) on %s" @@ -961,10 +962,7 @@ def do_read_only(args): # Get the project project = _get_project(args.project, user=args.user) - if project is None: - raise pagure.exceptions.PagureException( - "No project found with: %s" % args.project - ) + _check_project(project, project=args.project) # Validate ro flag if args.ro and args.ro.lower() not in ["true", "false"]: @@ -1224,10 +1222,7 @@ def do_create_branch(args): # Get the project project = _get_project(args.project, user=args.user) - if project is None: - raise pagure.exceptions.PagureException( - "No project found with: %s, user: %s" % (args.project, args.user) - ) + _check_project(project, project=args.project, user=args.user) try: pagure.lib.git.new_git_branch( @@ -1261,10 +1256,7 @@ def do_set_default_branch(args): # Get the project project = _get_project(args.project, user=args.user) - if project is None: - raise pagure.exceptions.PagureException( - "No project found with: %s, user: %s" % (args.project, args.user) - ) + _check_project(project, project=args.project, user=args.user) repo_path = get_repo_path(project) repo_obj = pygit2.Repository(repo_path) diff --git a/tests/test_pagure_admin.py b/tests/test_pagure_admin.py index 8ddeed2..b647679 100644 --- a/tests/test_pagure_admin.py +++ b/tests/test_pagure_admin.py @@ -771,7 +771,9 @@ class PagureAdminGetWatchTests(tests.Modeltests): args = munch.Munch({"project": "foobar", "user": "pingou"}) with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_get_watch_status(args) - self.assertEqual(cm.exception.args[0], "No project found with: foobar") + self.assertEqual( + cm.exception.args[0], "No project found with: project=foobar" + ) def test_get_watch_get_project_invalid_project(self): """ Test the get-watch function of pagure-admin with an invalid @@ -912,7 +914,9 @@ class PagureAdminUpdateWatchTests(tests.Modeltests): ) with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_update_watch_status(args) - self.assertEqual(cm.exception.args[0], "No project found with: foob") + self.assertEqual( + cm.exception.args[0], "No project found with: project=foob" + ) def test_get_watch_update_project_invalid_project(self): """ Test the update-watch function of pagure-admin on an invalid @@ -1041,7 +1045,9 @@ class PagureAdminReadOnlyTests(tests.Modeltests): args = munch.Munch({"project": "foob", "user": None, "ro": None}) with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_read_only(args) - self.assertEqual(cm.exception.args[0], "No project found with: foob") + self.assertEqual( + cm.exception.args[0], "No project found with: project=foob" + ) def test_read_only_invalid_project(self): """ Test the read-only function of pagure-admin on an invalid @@ -1725,7 +1731,10 @@ class PagureAdminDeleteProjectTests(tests.Modeltests): ) with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_delete_project(args) - self.assertEqual(cm.exception.args[0], "No project found with: foob") + self.assertEqual( + cm.exception.args[0], + "No project found with: project=foob, user=None", + ) def test_delete_project_invalid_project(self): """ Test the read-only function of pagure-admin on an invalid @@ -1851,7 +1860,8 @@ class PagureCreateBranchTests(tests.Modeltests): with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_create_branch(args) self.assertEqual( - cm.exception.args[0], "No project found with: foob, user: None" + cm.exception.args[0], + "No project found with: project=foob, user=None", ) def test_create_branch_invalid_project(self): @@ -2002,7 +2012,8 @@ class PagureSetDefaultBranchTests(tests.Modeltests): with self.assertRaises(pagure.exceptions.PagureException) as cm: pagure.cli.admin.do_set_default_branch(args) self.assertEqual( - cm.exception.args[0], "No project found with: foob, user: None" + cm.exception.args[0], + "No project found with: project=foob, user=None", ) def test_set_default_branch_invalid_project(self):