How to add a hands-on
What is a hands-on?
Lessons accompanying Git-Mastery App contains hands-on practicals for students to get hands-on experience of the Git concepts covered by the lesson. Some of those hands-on practicals need to set up a sandbox containing the required folders, files, and repositories before the student can start. Git-Mastery app can set up that sandbox for students so that they can get to the practical part more easily.
For example, a student can run gitmastery download hp-init-repo to set up a sandbox for a specific hands-on practical.
Some examples of how Git-Mastery app helps create the sandbox for a hands-on practical can be seen in this Git Tour (see T1L3 and T1L4).
Before contributing
New contributors are recommended to start by implementing an already approved hands-on proposal.
If you are proposing a new hands-on instead, make sure that you have done the following:
- Create a hands-on discussion
- Obtain approval on the hands-on
- File a remote repository request (if needed)
Implementing a hands-on
First, run the provided new.sh script to generate the scaffolding for a new hands-on sandbox:
./new.sh
The script will first prompt if you want to create a hands-on or exercise.
Enter h to create a new hands-on.
Then, the script will prompt you for:
- The name of the hands-on, likely specified in the corresponding hands-on discussion, without the
hp-prefix. Use kebab case. - Whether the hands-on requires Git
- Whether the hands-on requires GitHub
Each hands-on is implemented as a single file at hands_on/<hands-on name>.py, containing the instructions to set up the hands-on sandbox.
Hands-on file format
All hands-ons are stored within the hands_on folder of the exercises repository.
They are represented by a single Python file whose name is the hands-on ID.
Hands-ons are not graded and progress is not tracked. They only help set up the student’s folder structure for a given lesson.
Git-Mastery uses the format hp-<hands-on-name> for hands-on names, for example hp-init-repo, to differentiate them from exercise names. Internally, the hands_on/ folder stores the Python files, for example hands_on/init_repo.py.
import os
from exercise_utils.file import append_to_file, create_or_update_file
from exercise_utils.git import add, init
__requires_git__ = True
__requires_github__ = False
def download(verbose: bool):
os.makedirs("things")
os.chdir("things")
init(verbose)
create_or_update_file(
"fruits.txt",
"""
apples
bananas
cherries
""",
)
add(["fruits.txt"], verbose)
append_to_file("fruits.txt", "dragon fruits")
The setup instructions go under the download function.
__requires_git__ and __requires_github__ tell the app whether to run automatic verification that the student has set up Git and GitHub CLI correctly.
We are currently working on doing a one-time migration to reposmith for download functions, tracked in this issue. For now, we will still use this current syntax.
For more information about how Git-Mastery downloads a hands-on, refer to the Download flow.
exercisescomes with a set of utility functions in theexercise_utilsmodule that are made available during the download flow. Prefer these abstractions over raw CLI calls — for example, useexercise_utils.file.create_or_update_fileto create or update files, andexercise_utils.git.committo commit changes. Fall back toexercise_utils.cli.run_commandonly when no suitable abstraction exists.For the full list of utility functions, refer to Exercise utilities reference.
These are some references for download setups for other hands-ons:
Conventions
- Any operations should use OS-agnostic options, for example
shutil.rmtreeinstead ofrun_command(["rm"]). - For any commands that require
gh, make sure that the__requires_github__variable in the download setup is set toTrueso that the app automatically checks that the student has set up GitHub CLI correctly.
Testing
Testing downloads without app
To test that your download script works locally without the app, use the provided script:
./test-download.sh <hands-on name>
You can find the sandbox created by the script under test-downloads/. Check it manually to verify that it is as expected.
Testing downloads using app
To test the full student workflow, push your changes to a branch in a repository and modify the .gitmastery.json file in your gitmastery-exercises directory such that exercises_source points to this branch.
{
"type": "remote",
"username": "your-github-username",
"repository": "your-repository-name",
"branch": "your-branch-name"
}
Run gitmastery download hp-<your-hands-on-name>. Check that the download is correct manually.
This will cause all subsequent gitmastery download commands run within this folder to pull exercises from your branch. After you are done testing, revert your .gitmastery.json file to its default state, where exercises_source is set to the Git-Mastery organisation repository.
Submitting the hands-on for review
Create a pull request from your fork using the provided pull request template.
Example
- Hands-on discussion: https://github.com/git-mastery/exercises/issues/44
- Remote repository request: https://github.com/git-mastery/exercises/issues/25
- Hands-on PR: https://github.com/git-mastery/exercises/pull/45