Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions tags_add/.gitmastery-exercise.json
Original file line number Diff line number Diff line change
@@ -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
}
}
23 changes: 23 additions & 0 deletions tags_add/README.md
Original file line number Diff line number Diff line change
@@ -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 <FIRST_COMMIT_SHA>

# 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" <MARCH_COMMIT_SHA>
Empty file added tags_add/__init__.py
Empty file.
4 changes: 4 additions & 0 deletions tags_add/download.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
__resources__ = []

def setup(verbose: bool = False):
pass
Empty file added tags_add/tests/__init__.py
Empty file.
6 changes: 6 additions & 0 deletions tags_add/tests/specs/base.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
initialization:
steps:
- type: commit
empty: true
message: Empty commit
id: start
12 changes: 12 additions & 0 deletions tags_add/tests/test_verify.py
Original file line number Diff line number Diff line change
@@ -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
54 changes: 54 additions & 0 deletions tags_add/verify.py
Original file line number Diff line number Diff line change
@@ -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)