Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
16 changes: 16 additions & 0 deletions tags_update/.gitmastery-exercise.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"exercise_name": "tags-update",
"tags": [
"git-tag"
],
"requires_git": true,
"requires_github": true,
"base_files": {},
"exercise_repo": {
"repo_type": "remote",
"repo_name": "duty-roster",
"repo_title": "gm-duty-roster",
"create_fork": false,
"init": null
}
}
8 changes: 8 additions & 0 deletions tags_update/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# tags-update

The `duty-roster` repo contains text files that track which people are assigned for duties on which days of the week. Some of tags added earlier needs found to be incorrect.

## Task

1. To make tag names consistent, change `first-update` tag to `january-update`.
2. The `april-update` tag is currently pointing to the commit that updates the duty roster for May. Move it to the correct commit.
Empty file added tags_update/__init__.py
Empty file.
9 changes: 9 additions & 0 deletions tags_update/download.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from exercise_utils.cli import run_command

__resources__ = {}


def setup(verbose: bool = False):
run_command(["git", "tag", "first-update", "HEAD~4"], verbose)
run_command(["git", "tag", "april-update"], verbose)
run_command(["git", "tag", "may-update"], verbose)
Copy link
Member

Choose a reason for hiding this comment

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

Given that this is repeated multiple times, could we get it as a utility function for future use?

Empty file added tags_update/tests/__init__.py
Empty file.
28 changes: 28 additions & 0 deletions tags_update/tests/specs/base.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
initialization:
steps:
- type: commit
empty: true
message: Add January duty roster
id: start
- type: tag
tag-name: january-update
- type: commit
empty: true
message: Update duty roster for February
id: february-commit
- type: commit
empty: true
message: Update roster for March
id: march-commit
- type: commit
empty: true
message: Update duty roster for April
id: april-commit
- type: tag
tag-name: april-update
- type: commit
empty: true
message: Update roster for May
id: may-commit
- type: tag
tag-name: may-update
24 changes: 24 additions & 0 deletions tags_update/tests/specs/missing_january_commit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
initialization:
steps:
- type: commit
empty: true
message: Update duty roster for February
id: start
- type: tag
tag-name: january-update
- type: commit
empty: true
message: Update roster for March
id: march-commit
- type: commit
empty: true
message: Update duty roster for April
id: april-commit
- type: tag
tag-name: april-update
- type: commit
empty: true
message: Update roster for May
id: may-commit
- type: tag
tag-name: may-update
22 changes: 22 additions & 0 deletions tags_update/tests/specs/missing_tags.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
initialization:
steps:
- type: commit
empty: true
message: Add January duty roster
id: start
- type: commit
empty: true
message: Update duty roster for February
id: february-commit
- type: commit
empty: true
message: Update roster for March
id: march-commit
- type: commit
empty: true
message: Update duty roster for April
id: april-commit
- type: commit
empty: true
message: Update roster for May
id: may-commit
28 changes: 28 additions & 0 deletions tags_update/tests/specs/old_tag_still_exists.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
initialization:
steps:
- type: commit
empty: true
message: Add January duty roster
id: start
- type: tag
tag-name: first-update
- type: commit
empty: true
message: Update duty roster for February
id: february-commit
- type: commit
empty: true
message: Update roster for March
id: march-commit
- type: commit
empty: true
message: Update duty roster for April
id: april-commit
- type: commit
empty: true
message: Update roster for May
id: may-commit
- type: tag
tag-name: april-update
- type: tag
tag-name: may-update
28 changes: 28 additions & 0 deletions tags_update/tests/specs/wrong_april_tag.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
initialization:
steps:
- type: commit
empty: true
message: Add January duty roster
id: start
- type: tag
tag-name: january-update
- type: commit
empty: true
message: Update duty roster for February
id: february-commit
- type: commit
empty: true
message: Update roster for March
id: march-commit
- type: commit
empty: true
message: Update duty roster for April
id: april-commit
- type: commit
empty: true
message: Update roster for May
id: may-commit
- type: tag
tag-name: april-update
- type: tag
tag-name: may-update
41 changes: 41 additions & 0 deletions tags_update/tests/test_verify.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from git_autograder import GitAutograderTestLoader, assert_output
from git_autograder.status import GitAutograderStatus

from ..verify import (
verify,
MISSING_JANUARY_TAG,
WRONG_APRIL_TAG_COMMIT,
OLD_FIRST_UPDATE_TAG,
SUCCESS_MESSAGE,
MISSING_COMMIT_MESSAGE,
)

REPOSITORY_NAME = "tags-update"

loader = GitAutograderTestLoader(__file__, REPOSITORY_NAME, verify)


def test_base():
with loader.load("specs/base.yml", "start") as output:
print(output)
assert_output(output, GitAutograderStatus.SUCCESSFUL, [SUCCESS_MESSAGE])


def test_missing_tags():
with loader.load("specs/missing_tags.yml", "start") as output:
assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [MISSING_JANUARY_TAG])


def test_wrong_april_tag():
with loader.load("specs/wrong_april_tag.yml", "start") as output:
assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [WRONG_APRIL_TAG_COMMIT])
Comment on lines +34 to +36
Copy link
Member

Choose a reason for hiding this comment

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

I think we would also want to ensure that the same check for the January tag commit should exist too, what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a good point, would make the tests more comprehensive!



def test_old_tag_still_exists():
with loader.load("specs/old_tag_still_exists.yml", "start") as output:
assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [OLD_FIRST_UPDATE_TAG])


def test_missing_january_commit():
with loader.load("specs/missing_january_commit.yml", "start") as output:
assert_output(output, GitAutograderStatus.UNSUCCESSFUL, [MISSING_COMMIT_MESSAGE.format(message="January")])
57 changes: 57 additions & 0 deletions tags_update/verify.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from git_autograder import (
GitAutograderExercise,
GitAutograderOutput,
GitAutograderStatus,
)

MISSING_JANUARY_TAG = "The 'january-update' tag is missing! You need to rename 'first-update' to 'january-update'."
WRONG_JANUARY_TAG_COMMIT = "The 'january-update' tag is pointing to the wrong commit! It should point to the January commit."
MISSING_APRIL_TAG = "The 'april-update' tag is missing!"
WRONG_APRIL_TAG_COMMIT = "The 'april-update' tag is pointing to the wrong commit! It should point to the April commit, not the May commit."
OLD_FIRST_UPDATE_TAG = "The old 'first-update' tag still exists! You need to delete it after renaming to 'january-update'."
SUCCESS_MESSAGE = "Great work! You have successfully updated the tags to point to the correct commits."
MISSING_COMMIT_MESSAGE = "Could not find a commit with '{message}' in the message"


def find_commit_by_message(exercise: GitAutograderExercise, message: str):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Similar in functionality with get_target_commit_sha from log_and_order/verify.py, but more flexible and simpler logic.

"""Find a commit with the given message."""
commits = list(exercise.repo.repo.iter_commits(all=True))
for commit in commits:
if message.strip() == commit.message.strip():
return commit
return None


def verify(exercise: GitAutograderExercise) -> GitAutograderOutput:
tags = exercise.repo.repo.tags

# Verify that the tags exist and that the old first-update tag is deleted
if "first-update" in tags:
raise exercise.wrong_answer([OLD_FIRST_UPDATE_TAG])
if "january-update" not in tags:
raise exercise.wrong_answer([MISSING_JANUARY_TAG])
if "april-update" not in tags:
raise exercise.wrong_answer([MISSING_APRIL_TAG])

# Get correct commits that the tags should point to
january_commit = find_commit_by_message(exercise, "Add January duty roster")
if january_commit is None:
raise exercise.wrong_answer([MISSING_COMMIT_MESSAGE.format(message="January")])

april_commit = find_commit_by_message(exercise, "Update duty roster for April")
if april_commit is None:
raise exercise.wrong_answer([MISSING_COMMIT_MESSAGE.format(message="April")])

# Verify that the tags point to the correct commits
january_tag_commit = tags["january-update"].commit
if january_tag_commit.hexsha != january_commit.hexsha:
raise exercise.wrong_answer([WRONG_JANUARY_TAG_COMMIT])

april_tag_commit = tags["april-update"].commit
if april_tag_commit.hexsha != april_commit.hexsha:
raise exercise.wrong_answer([WRONG_APRIL_TAG_COMMIT])

return exercise.to_output(
[SUCCESS_MESSAGE],
GitAutograderStatus.SUCCESSFUL,
)
Copy link
Member

Choose a reason for hiding this comment

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

I think it would make more sense that the grading following the order of the tasks provided. The rationale is that students may attempt each task and run gitmastery verify immediately after. So if the autograding provides feedback for tasks later down the line, they might not really understand the feedback.

For instance, in this exercise, the first task is to rename the first-update tag to january-update. So you would want to

  1. Ensure that first-update does not exist
  2. Ensure that january-update exists
  3. Ensure that the january-update tag points to the right commit

Copy link
Member

Choose a reason for hiding this comment

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

Other than that, I like the comprehensiveness of the checks. But I think it would greatly benefit from a little reshuffling!