hopper
A git-like CLI for tutors on the hopper platform. It wraps git and the
hopper orchestration services to safely pull, grade, and push all of a
tutor's assigned student repositories.
Install
pipx install hopper-cli
To update later:
pipx upgrade hopper-cli
Getting started
hopper auth # set up an instance profile + API key
hopper init <course> # create a workspace directory bound to a course
cd <course-uid>
hopper pull # clone/update all your assigned student repos
Concepts
Profiles
A profile is a set of service URLs plus your API key — typically one per
university. They live in the global config at os.UserConfigDir()/hopper/config.yaml
(~/.config/hopper/ on Linux, ~/Library/Application Support/hopper/ on
macOS, %AppData%\hopper\ on Windows).
hopper auth interactively creates a profile, offering known presets (e.g.
alu for Albert-Ludwigs-Universität Freiburg) or custom URLs. You can hold
several profiles and pick which one a workspace uses at init time.
Workspaces
hopper init [profile/]<course> creates a ./<course-uid>/ directory with a
.hopper.yaml inside. <course> may be a UID (2025WS-EidP) or numeric ID.
With multiple profiles, prefix the profile: hopper init alu/2025WS-EidP.
All commands run inside that directory and never write outside it.
Commands
| Command | Description |
|---|---|
hopper auth |
Interactively set up a profile (preset or custom). |
hopper auth list / status / remove <id> |
Manage profiles. |
hopper init [profile/]<course> |
Bind a new directory to a course. |
hopper pull |
Clone or pull --rebase --autostash every assigned student repo. |
hopper push [msg] |
Commit README changes, validate point schema, push. |
hopper commit <msg> |
Commit without pushing (recovery path). |
hopper status |
Per-student branch, ahead/behind, dirty state. |
hopper students |
List students assigned to you. |
hopper info |
Course info, your role, exercises. |
hopper version |
Print version. |
pull flags
--prune/--no-prune— remove local repos of students no longer assigned (default: prune, with preview + confirm).--student <name>— pull a single student.--only a,b,c— pull only the listed usernames.--jobs N/-j— concurrent git operations (default 4).
Safety vs. the legacy CLI
- Per-repo error isolation — one failed clone/pull is reported and skipped, not fatal.
- No shell — git runs via
exec.Commandwith argument slicing; no string interpolation. - No
git reset --hard— push rebases and surfaces conflicts instead of destroying local work. - No README mutation during pull — the grader bot already injects build logs; pull is pure pull.
- Point-schema validation blocks invalid pushes (
--allow-invalidto override).
Minimum-version gate
On every command (except auth/version/help), hopper asks the active
profile's orchestration server for the minimum allowed CLI version
(GET /api/cli/version, returns { "minimum": "vX.Y.Z" }):
- running version < minimum → the CLI refuses to run (upgrade via pip);
- running version >= minimum → proceeds;
- server unreachable → proceeds silently (can't check offline).
Orchestration endpoints used
Existing (no server changes): GET /api/users/me, GET /api/users/me/courses,
GET /api/courses/:id, GET /api/courses/:id/exercises.
Required additions to orchestration:
GET /api/courses/:id/students/mine—RequireStaff, scoped totutors.user_id = caller(admins/owners get all). Returns students withUser.PreferredUsername(the Forgejo repo name). Used bypull.GET /api/cli/version— public, returns{ "minimum": "vX.Y.Z" }from a Setting. Used by the minimum-version gate.
Build (developers only)
go build -o hopper ./cmd/hopper/
The version is injected at build time:
go build -ldflags "-X codeberg.org/hopper/cli/internal/cmd.Version=v0.2.0" -o hopper ./cmd/hopper/
Metadata
Release files for hopper-cli 0.1.10
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| hopper_cli-0.1.10-py3-none-win_arm64.whl | Python 3 | none | Windows ARM64 | Details |
| hopper_cli-0.1.10-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| hopper_cli-0.1.10-py3-none-manylinux2014_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| hopper_cli-0.1.10-py3-none-manylinux2014_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64 | Details |
| hopper_cli-0.1.10-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
| hopper_cli-0.1.10-py3-none-macosx_10_9_x86_64.whl | Python 3 | none | macOS 10.9+ x86-64 | Details |
Total release size: 74.9 MB
Release files / hopper_cli-0.1.10-py3-none-win_arm64.whl
| Download URL | hopper_cli-0.1.10-py3-none-win_arm64.whl |
|---|---|
| Size | 14.9 MB |
| Tags | Python 3 Windows ARM64 |
|
SHA-256 checksum How to use checksums |
31d9e5e13d9cfa74556c73c6c4be3fe8bbb336d099257aef4db0e45785560d43
|
|
BLAKE2b-256 checksum How to use checksums |
9e45ec10a0f0105863ccfca360069b29cf91b24b7d6823a4095a6c8581f6de9f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.2
|
Release files / hopper_cli-0.1.10-py3-none-win_amd64.whl
| Download URL | hopper_cli-0.1.10-py3-none-win_amd64.whl |
|---|---|
| Size | 15.6 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
830359551f6a7958be006ddf10aca1a920ae10578549c260bf4506b4473a4b1a
|
|
BLAKE2b-256 checksum How to use checksums |
44c20366f0ae57d6d6b8e78b2615349ca50acaf8a8f306748eea1acf591c8c81
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.2
|
Release files / hopper_cli-0.1.10-py3-none-manylinux2014_x86_64.whl
| Download URL | hopper_cli-0.1.10-py3-none-manylinux2014_x86_64.whl |
|---|---|
| Size | 7.7 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
0d74317d633cb374953e4fb84364dee4b0de3504d3cb12a15a653c96dbcbc734
|
|
BLAKE2b-256 checksum How to use checksums |
69225807573f3898ed2341f1682e425f3724ec90d38f89699a79f7259868835d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.2
|
Release files / hopper_cli-0.1.10-py3-none-manylinux2014_aarch64.whl
| Download URL | hopper_cli-0.1.10-py3-none-manylinux2014_aarch64.whl |
|---|---|
| Size | 14.2 MB |
| Tags | Linux glibc 2.17+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
c6fdf819b8df47469a0fd389a771d114b67deb6cb81a7a9af0d4ae9ba54063ab
|
|
BLAKE2b-256 checksum How to use checksums |
b13b16d747647117a530b12ca514dcc5023061c6542d1f1610a82dc6104d0dd1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.2
|
Release files / hopper_cli-0.1.10-py3-none-macosx_11_0_arm64.whl
| Download URL | hopper_cli-0.1.10-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 14.5 MB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
a8af0b4a1ee702343a7b7b4ee69b73b5c64a2320fd3a85fb03905ca7b6933909
|
|
BLAKE2b-256 checksum How to use checksums |
89f2f8715bbc22925754aa0610f56c1438a25aea37f3a1c8aaefd2e95bebd847
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.2
|
Release files / hopper_cli-0.1.10-py3-none-macosx_10_9_x86_64.whl
| Download URL | hopper_cli-0.1.10-py3-none-macosx_10_9_x86_64.whl |
|---|---|
| Size | 7.9 MB |
| Tags | Python 3 macOS 10.9+ x86-64 |
|
SHA-256 checksum How to use checksums |
70d642f357ad4208f1a5fc5ba19afbaf57091d452251b38827378950eb2880d0
|
|
BLAKE2b-256 checksum How to use checksums |
08aafbc48aa6cc382add5fa3890f3979f49dc8b6d475897acc0bad2ae2f7827a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.2
|