Skip to content

Commit ab9a8b2

Browse files
committed
Correct exercise configuration and verify logic
1 parent 71a164a commit ab9a8b2

File tree

4 files changed

+70
-51
lines changed

4 files changed

+70
-51
lines changed

tags_add/.gitmastery-exercise.json

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
{
2-
"exercise_name": "tags-add",
3-
"tags": [
4-
"tags"
5-
],
2+
"exercise_name": "tags_add",
3+
"tags": ["git-tag"],
64
"requires_git": true,
7-
"requires_github": false,
5+
"requires_github": true,
86
"base_files": {},
97
"exercise_repo": {
10-
"repo_type": "local",
11-
"repo_name": "project",
12-
"repo_title": null,
8+
"repo_type": "remote",
9+
"repo_name": "duty-roster",
1310
"create_fork": false,
14-
"init": true
11+
"repo_title": "gm-duty-roster",
12+
"init": false
1513
}
16-
}
14+
}

tags_add/README.md

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
# tags-add
22

3-
<!--- Insert exercise description -->
3+
1. Add a **lightweight** tag `first-pilot` to the **first commit**.
4+
2. Add an **annotated** tag `v1.0` to the commit that updates March duty roster, with message `first full duty roster`.
45

56
## Task
67

7-
<!--- Insert exercise task, simplify what needs to be done -->
8+
This exercise clones `git-mastery/gm-duty-roster` into the `duty-roster/` folder.
89

910
## Hints
1011

11-
<!--- Insert hints here -->
12-
<!---
13-
Use Github Markdown's collapsible content:
14-
<details>
15-
<summary>...</summary>
16-
...
17-
</details>
18-
-->
12+
```bash
13+
# first commit
14+
git rev-list --max-parents=0 HEAD
15+
16+
# add lightweight tag
17+
git tag first-pilot <FIRST_COMMIT_SHA>
18+
19+
# find the commit for "Update roster for March"
20+
git log --oneline | grep -i "Update roster for March"
21+
22+
# add annotated tag with message
23+
git tag -a v1.0 -m "first full duty roster" <MARCH_COMMIT_SHA>

tags_add/download.py

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,4 @@
1-
from exercise_utils.file import create_or_update_file
2-
from exercise_utils.git import add, commit
3-
from exercise_utils.gitmastery import create_start_tag
4-
51
__resources__ = []
62

73
def setup(verbose: bool = False):
8-
create_or_update_file("README.md", "# T4L2: Add a tag\n")
9-
add(["README.md"], verbose)
10-
commit("chore: init README", verbose)
11-
12-
create_or_update_file("main.txt", "v1 content\n")
13-
add(["main.txt"], verbose)
14-
commit("feat: initial content", verbose)
15-
16-
create_start_tag(verbose)
4+
pass

tags_add/verify.py

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,54 @@
1-
from typing import List
1+
from git import TagObject
22
from git_autograder.core import GitAutograderExercise, GitAutograderStatus
33

4-
MSG_NO_TAG = "Tag 'v1.0.0' was not found."
5-
MSG_NOT_AT_HEAD = "Tag 'v1.0.0' does not point to HEAD."
4+
FIRST_TAG = "first-pilot"
5+
SECOND_TAG = "v1.0"
6+
SECOND_TAG_MSG = "first full duty roster"
7+
MARCH_MSG_FRAGMENT = "Update roster for March"
68

79
def verify(exercise: GitAutograderExercise):
8-
"""
9-
Pass condition:
10-
1) exist 1.0.0 tag
11-
2) the tag is pointing to current head
12-
"""
1310
repo = exercise.repo.repo
14-
target = next((t for t in repo.tags if t.name == "v1.0.0"), None)
1511

16-
messages: List[str] = []
17-
status = GitAutograderStatus.SUCCESSFUL
12+
root_sha = next(repo.iter_commits(rev="HEAD", reverse=True)).hexsha
1813

19-
if target is None:
20-
messages.append(MSG_NO_TAG)
21-
status = GitAutograderStatus.FAILED
22-
elif target.commit.hexsha != repo.head.commit.hexsha:
23-
messages.append(MSG_NOT_AT_HEAD)
24-
status = GitAutograderStatus.FAILED
14+
march_commit = None
15+
for c in repo.iter_commits("HEAD"):
16+
if MARCH_MSG_FRAGMENT in c.message:
17+
march_commit = c
18+
break
2519

26-
return exercise.to_output(messages, status)
20+
comments = []
21+
22+
t_first = next((t for t in repo.tags if t.name == FIRST_TAG), None)
23+
if not t_first:
24+
comments.append(f"Missing lightweight tag `{FIRST_TAG}`.")
25+
else:
26+
if t_first.commit.hexsha != root_sha:
27+
comments.append(
28+
f"`{FIRST_TAG}` should point to first commit {root_sha[:7]}, "
29+
f"but points to {t_first.commit.hexsha[:7]} instead."
30+
)
31+
if isinstance(getattr(t_first, "tag", None), TagObject):
32+
comments.append(f"`{FIRST_TAG}` must be a lightweight tag (not annotated).")
33+
34+
t_v1 = next((t for t in repo.tags if t.name == SECOND_TAG), None)
35+
if not t_v1:
36+
comments.append(f"Missing annotated tag `{SECOND_TAG}`.")
37+
else:
38+
if not isinstance(getattr(t_v1, "tag", None), TagObject):
39+
comments.append(f"`{SECOND_TAG}` must be an annotated tag.")
40+
else:
41+
msg = (t_v1.tag.message or "").strip()
42+
if msg != SECOND_TAG_MSG:
43+
comments.append(f"`{SECOND_TAG}` message must be exactly `{SECOND_TAG_MSG}`.")
44+
if not march_commit:
45+
comments.append(f"Could not find the commit containing '{MARCH_MSG_FRAGMENT}'.")
46+
else:
47+
if t_v1.commit.hexsha != march_commit.hexsha:
48+
comments.append(
49+
f"`{SECOND_TAG}` should point to March commit {march_commit.hexsha[:7]}, "
50+
f"but points to {t_v1.commit.hexsha[:7]} instead."
51+
)
52+
53+
status = GitAutograderStatus.SUCCESSFUL if not comments else GitAutograderStatus.FAILED
54+
return exercise.to_output(comments, status)

0 commit comments

Comments
 (0)