Skip to content
Open
10 changes: 10 additions & 0 deletions exercise_utils/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Comment on lines +13 to +20
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is technically not necessary to have both of these functions, as the -a flag is unnecessary to make an annotated tag if the -m flag is passed with its message. However, since it increases code readability, I am not opposed to keeping both of these in.



def add(files: List[str], verbose: bool) -> None:
"""Adds a given list of file paths."""
run_command(["git", "add", *files], verbose)
Expand Down
35 changes: 35 additions & 0 deletions exercise_utils/github_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 ""
32 changes: 32 additions & 0 deletions hands_on/push_tags.py
Original file line number Diff line number Diff line change
@@ -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)