diff --git a/glossary_branch_push/.gitmastery-exercise.json b/glossary_branch_push/.gitmastery-exercise.json new file mode 100644 index 00000000..5204d783 --- /dev/null +++ b/glossary_branch_push/.gitmastery-exercise.json @@ -0,0 +1,14 @@ +{ + "exercise_name": "glossary-branch-push", + "tags": ["git-push"], + "requires_git": true, + "requires_github": true, + "base_files": {}, + "exercise_repo": { + "repo_type": "local", + "repo_name": "funny-glossary", + "repo_title": null, + "create_fork": null, + "init": false + } +} diff --git a/glossary_branch_push/README.md b/glossary_branch_push/README.md new file mode 100644 index 00000000..b95d6c74 --- /dev/null +++ b/glossary_branch_push/README.md @@ -0,0 +1 @@ +See https://git-mastery.github.io/lessons/{LESSON_ID}/exercise-glossary-branch-push.html diff --git a/glossary_branch_push/__init__.py b/glossary_branch_push/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/glossary_branch_push/download.py b/glossary_branch_push/download.py new file mode 100644 index 00000000..ade59a7d --- /dev/null +++ b/glossary_branch_push/download.py @@ -0,0 +1,43 @@ +import os + +from exercise_utils.cli import run_command +from exercise_utils.file import create_or_update_file +from exercise_utils.git import add, checkout, clone_repo_with_git, commit +from exercise_utils.github_cli import ( + delete_repo, + get_github_username, + has_repo, +) + +__requires_git__ = True +__requires_github__ = True + +REPO_OWNER = "git-mastery" +REPO_NAME = "samplerepo-funny-glossary" + + +def setup(verbose: bool = False): + username = get_github_username(verbose) + FORK_NAME = f"{username}-gitmastery-samplerepo-funny-glossary" + + if has_repo(FORK_NAME, True, verbose): + delete_repo(FORK_NAME, verbose) + + run_command( + ["gh", "repo", "fork", f"{REPO_OWNER}/{REPO_NAME}", "--fork-name", FORK_NAME], + verbose, + ) + + clone_repo_with_git( + f"https://github.com/{username}/{FORK_NAME}", verbose, "." + ) + + checkout("PQR", True, verbose) + + create_or_update_file( + "r.txt", + "refactoring: Improving the code without changing what it does... in theory.\n", + ) + + add(["r.txt"], verbose) + commit("Add 'refactoring'", verbose) diff --git a/glossary_branch_push/test_verify.py b/glossary_branch_push/test_verify.py new file mode 100644 index 00000000..750bbfb6 --- /dev/null +++ b/glossary_branch_push/test_verify.py @@ -0,0 +1,59 @@ +from contextlib import contextmanager +from typing import Iterator, Tuple +import tempfile +import os + +from exercise_utils.test import ( + GitAutograderTest, + GitAutograderTestLoader, + assert_output, +) +from git_autograder import GitAutograderStatus +from repo_smith.repo_smith import RepoSmith +from repo_smith.steps.bash_step import BashStep + +from .verify import PQR_BRANCH_NOT_PUSHED, verify + +REPOSITORY_NAME = "glossary-branch-push" + +loader = GitAutograderTestLoader(REPOSITORY_NAME, verify) + + +@contextmanager +def base_setup() -> Iterator[Tuple[GitAutograderTest, RepoSmith]]: + with loader.start() as (test, rs): + rs.git.commit(message="Initial commit", allow_empty=True) + + # Create a bare repo to use as remote + remote_dir = tempfile.mkdtemp() + remote_path = os.path.join(remote_dir, "remote.git") + os.makedirs(remote_path) + BashStep(name=None, description=None, id=None, body=f"git init --bare {remote_path}").execute(rs.repo) + + rs.git.remote_add("origin", remote_path) + + rs.git.checkout("PQR", branch=True) + rs.files.create_or_update("r.txt", "refactoring: Improving the code without changing what it does... in theory.\n") + rs.git.add(all=True) + rs.git.commit(message="Add 'refactoring'") + rs.git.checkout("main") + + yield test, rs + + +def test_base(): + with base_setup() as (test, rs): + BashStep(name=None, description=None, id=None, body="git push origin PQR").execute(rs.repo) + + output = test.run() + assert_output(output, GitAutograderStatus.SUCCESSFUL) + + +def test_pqr_not_pushed(): + with base_setup() as (test, rs): + output = test.run() + assert_output( + output, + GitAutograderStatus.UNSUCCESSFUL, + [PQR_BRANCH_NOT_PUSHED], + ) diff --git a/glossary_branch_push/verify.py b/glossary_branch_push/verify.py new file mode 100644 index 00000000..ed6614eb --- /dev/null +++ b/glossary_branch_push/verify.py @@ -0,0 +1,22 @@ +from git_autograder import ( + GitAutograderExercise, + GitAutograderOutput, + GitAutograderStatus, +) + +PQR_BRANCH_NOT_PUSHED = "Branch 'PQR' has not been pushed to the remote." + + +def verify(exercise: GitAutograderExercise) -> GitAutograderOutput: + origin_remote = exercise.repo.remotes.remote("origin") + origin_remote.remote.fetch() + + try: + remote_pqr = exercise.repo.repo.refs["origin/PQR"] + except (IndexError, KeyError): + raise exercise.wrong_answer([PQR_BRANCH_NOT_PUSHED]) + + return exercise.to_output( + ["Great work pushing the PQR branch to your fork!"], + GitAutograderStatus.SUCCESSFUL, + )