diff --git a/tags_add/.gitmastery-exercise.json b/tags_add/.gitmastery-exercise.json new file mode 100644 index 0000000..c28e3e2 --- /dev/null +++ b/tags_add/.gitmastery-exercise.json @@ -0,0 +1,14 @@ +{ + "exercise_name": "tags_add", + "tags": ["git-tag"], + "requires_git": true, + "requires_github": true, + "base_files": {}, + "exercise_repo": { + "repo_type": "remote", + "repo_name": "duty-roster", + "create_fork": false, + "repo_title": "gm-duty-roster", + "init": false + } +} diff --git a/tags_add/README.md b/tags_add/README.md new file mode 100644 index 0000000..d50129a --- /dev/null +++ b/tags_add/README.md @@ -0,0 +1,23 @@ +# tags-add + +1. Add a **lightweight** tag `first-pilot` to the **first commit**. +2. Add an **annotated** tag `v1.0` to the commit that updates March duty roster, with message `first full duty roster`. + +## Task + +This exercise clones `git-mastery/gm-duty-roster` into the `duty-roster/` folder. + +## Hints + +```bash +# first commit +git rev-list --max-parents=0 HEAD + +# add lightweight tag +git tag first-pilot + +# find the commit for "Update roster for March" +git log --oneline | grep -i "Update roster for March" + +# add annotated tag with message +git tag -a v1.0 -m "first full duty roster" \ No newline at end of file diff --git a/tags_add/__init__.py b/tags_add/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tags_add/download.py b/tags_add/download.py new file mode 100644 index 0000000..604c9e6 --- /dev/null +++ b/tags_add/download.py @@ -0,0 +1,4 @@ +__resources__ = [] + +def setup(verbose: bool = False): + pass \ No newline at end of file diff --git a/tags_add/tests/__init__.py b/tags_add/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tags_add/tests/specs/base.yml b/tags_add/tests/specs/base.yml new file mode 100644 index 0000000..00c3a53 --- /dev/null +++ b/tags_add/tests/specs/base.yml @@ -0,0 +1,6 @@ +initialization: + steps: + - type: commit + empty: true + message: Empty commit + id: start diff --git a/tags_add/tests/test_verify.py b/tags_add/tests/test_verify.py new file mode 100644 index 0000000..1e0a9b8 --- /dev/null +++ b/tags_add/tests/test_verify.py @@ -0,0 +1,12 @@ +from git_autograder import GitAutograderTestLoader + +from ..verify import verify + +REPOSITORY_NAME = "tags-add" + +loader = GitAutograderTestLoader(__file__, REPOSITORY_NAME, verify) + + +def test_base(): + with loader.load("specs/base.yml", "start"): + pass diff --git a/tags_add/verify.py b/tags_add/verify.py new file mode 100644 index 0000000..b4e90d2 --- /dev/null +++ b/tags_add/verify.py @@ -0,0 +1,54 @@ +from git import TagObject +from git_autograder.core import GitAutograderExercise, GitAutograderStatus + +FIRST_TAG = "first-pilot" +SECOND_TAG = "v1.0" +SECOND_TAG_MSG = "first full duty roster" +MARCH_MSG_FRAGMENT = "Update roster for March" + +def verify(exercise: GitAutograderExercise): + repo = exercise.repo.repo + + root_sha = next(repo.iter_commits(rev="HEAD", reverse=True)).hexsha + + march_commit = None + for c in repo.iter_commits("HEAD"): + if MARCH_MSG_FRAGMENT in c.message: + march_commit = c + break + + comments = [] + + t_first = next((t for t in repo.tags if t.name == FIRST_TAG), None) + if not t_first: + comments.append(f"Missing lightweight tag `{FIRST_TAG}`.") + else: + if t_first.commit.hexsha != root_sha: + comments.append( + f"`{FIRST_TAG}` should point to first commit {root_sha[:7]}, " + f"but points to {t_first.commit.hexsha[:7]} instead." + ) + if isinstance(getattr(t_first, "tag", None), TagObject): + comments.append(f"`{FIRST_TAG}` must be a lightweight tag (not annotated).") + + t_v1 = next((t for t in repo.tags if t.name == SECOND_TAG), None) + if not t_v1: + comments.append(f"Missing annotated tag `{SECOND_TAG}`.") + else: + if not isinstance(getattr(t_v1, "tag", None), TagObject): + comments.append(f"`{SECOND_TAG}` must be an annotated tag.") + else: + msg = (t_v1.tag.message or "").strip() + if msg != SECOND_TAG_MSG: + comments.append(f"`{SECOND_TAG}` message must be exactly `{SECOND_TAG_MSG}`.") + if not march_commit: + comments.append(f"Could not find the commit containing '{MARCH_MSG_FRAGMENT}'.") + else: + if t_v1.commit.hexsha != march_commit.hexsha: + comments.append( + f"`{SECOND_TAG}` should point to March commit {march_commit.hexsha[:7]}, " + f"but points to {t_v1.commit.hexsha[:7]} instead." + ) + + status = GitAutograderStatus.SUCCESSFUL if not comments else GitAutograderStatus.FAILED + return exercise.to_output(comments, status)