diff --git a/exercise_utils/git.py b/exercise_utils/git.py index 28d8441..2f12ed2 100644 --- a/exercise_utils/git.py +++ b/exercise_utils/git.py @@ -10,6 +10,16 @@ def tag(tag_name: str, verbose: bool) -> None: run_command(["git", "tag", tag_name], verbose) +def tag_with_options(tag_name: str, options: List[str], verbose: bool) -> None: + """Tags with the given tag_name with specified options.""" + run_command(["git", "tag", tag_name, *options], verbose) + + +def annotated_tag_with_options(tag_name: str, options: List[str], verbose: bool) -> None: + """Adds an annotated tag with the given tag_name with specified options.""" + run_command(["git", "tag", "-a", tag_name, *options], verbose) + + def add(files: List[str], verbose: bool) -> None: """Adds a given list of file paths.""" run_command(["git", "add", *files], verbose) diff --git a/exercise_utils/github_cli.py b/exercise_utils/github_cli.py index 235602d..8c354a3 100644 --- a/exercise_utils/github_cli.py +++ b/exercise_utils/github_cli.py @@ -64,3 +64,38 @@ def has_repo(repo_name: str, is_fork: bool, verbose: bool) -> bool: ) return result.is_success() and (not is_fork or result.stdout == "true") + +def has_fork(repository_name: str, owner_name: str, username: str, verbose: bool) -> bool: + """Returns if the current user has a fork of the given repository by owner""" + result = run( + [ + "gh", + "api", + "--paginate", + f"repos/{owner_name}/{repository_name}/forks", + "-q", + f'''.[] | .owner.login | select(. =="{username}")''', + ], + verbose + ) + + return result.is_success() and result.stdout.strip() == username + +def get_fork_name(repository_name: str, owner_name: str, username: str, verbose: bool) -> str: + """Returns the name of the current user's fork repo""" + result = run( + [ + "gh", + "api", + "--paginate", + f"repos/{owner_name}/{repository_name}/forks", + "-q", + f'''.[] | select(.owner.login =="{username}") | .name''', + ], + verbose + ) + + if result.is_success(): + forkname = result.stdout.splitlines()[0] + return forkname + return "" diff --git a/hands_on/push_tags.py b/hands_on/push_tags.py new file mode 100644 index 0000000..cf69ed8 --- /dev/null +++ b/hands_on/push_tags.py @@ -0,0 +1,32 @@ +import os +from exercise_utils.git import tag_with_options, annotated_tag_with_options +from exercise_utils.github_cli import clone_repo_with_gh, fork_repo, get_fork_name, get_github_username, has_fork, has_repo + +__requires_git__ = True +__requires_github__ = True + +def check_same_repo_name(username: str, repo_name: str, verbose: bool) -> str: + if has_repo(repo_name, False, verbose): + print(f"Warning: {username}/{repo_name} already exists, the fork repo will be " + f"named as {username}/{repo_name}-1") + return repo_name + "-1" + return repo_name + +def download(verbose: bool): + REPO_NAME = "samplerepo-preferences" + FORK_NAME = "gitmastery-samplerepo-preferences" + username = get_github_username(verbose) + + if has_fork(REPO_NAME, "git-mastery", username, verbose): + existing_name = get_fork_name(REPO_NAME, "git-mastery", username, verbose) + clone_repo_with_gh(existing_name, verbose, FORK_NAME) + else: + NEW_FORK_NAME = check_same_repo_name(username, FORK_NAME, verbose) + fork_repo(f"git-mastery/{REPO_NAME}", NEW_FORK_NAME, verbose) + clone_repo_with_gh(NEW_FORK_NAME, verbose, FORK_NAME) + + os.chdir(FORK_NAME) + + tag_with_options("v1.0", ["HEAD~1"], verbose) + annotated_tag_with_options("v0.9", ["HEAD~2", "-m", "First beta release"], verbose) +