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.8
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.8-py3-none-win_arm64.whl | Python 3 | none | Windows ARM64 | Details |
| hopper_cli-0.1.8-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| hopper_cli-0.1.8-py3-none-manylinux2014_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| hopper_cli-0.1.8-py3-none-manylinux2014_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64 | Details |
| hopper_cli-0.1.8-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
| hopper_cli-0.1.8-py3-none-macosx_10_9_x86_64.whl | Python 3 | none | macOS 10.9+ x86-64 | Details |
Total release size: 71.7 MB
Release files / hopper_cli-0.1.8-py3-none-win_arm64.whl
| Download URL | hopper_cli-0.1.8-py3-none-win_arm64.whl |
|---|---|
| Size | 14.3 MB |
| Tags | Python 3 Windows ARM64 |
|
SHA-256 checksum How to use checksums |
e4936c4bc824ae29477a60490031919c72f4a0d51703bf55a09d8e0f701b4844
|
|
BLAKE2b-256 checksum How to use checksums |
0b00b0c2674f6f447a6f3e1416ae8b7b24a1639c033daa8bc0b940e54e02d440
|
| 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.8-py3-none-win_amd64.whl
| Download URL | hopper_cli-0.1.8-py3-none-win_amd64.whl |
|---|---|
| Size | 15.0 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
c4e532148a0706f0d466144e34da7c0c1c6af7fcc991ead639ce2bb0a100e6d1
|
|
BLAKE2b-256 checksum How to use checksums |
a5885d509bd22f952000d0963217408c8b15cedf39e08e96e9fa66c9091c35cd
|
| 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.8-py3-none-manylinux2014_x86_64.whl
| Download URL | hopper_cli-0.1.8-py3-none-manylinux2014_x86_64.whl |
|---|---|
| Size | 7.4 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
2c399336c48d6ca869338c7518e8d7ed261b2bd47b4cd4584fdf8105346c3e58
|
|
BLAKE2b-256 checksum How to use checksums |
6cbe4e4faae84fdafe4366d5c580e01aef0032299455e18e1d09d7048b3891f2
|
| 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.8-py3-none-manylinux2014_aarch64.whl
| Download URL | hopper_cli-0.1.8-py3-none-manylinux2014_aarch64.whl |
|---|---|
| Size | 13.6 MB |
| Tags | Linux glibc 2.17+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
47984ab58e35d1cc3f3032c36b39c649e7a2595ac63dc685f1153ea761e9b934
|
|
BLAKE2b-256 checksum How to use checksums |
339e063cbeb73b3a781dc29bd136e2e1f7c683f701fdfd13246f509f30ccf6e3
|
| 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.8-py3-none-macosx_11_0_arm64.whl
| Download URL | hopper_cli-0.1.8-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 13.9 MB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
e77f3d982e6688a0dd9b9e49b5aabd4953e3d07f68bd5127643e43671d630a20
|
|
BLAKE2b-256 checksum How to use checksums |
433b460c896a380e6e73e66c198aa1c7d0a2f2e3eb89efdb74ae1c7373a03bc0
|
| 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.8-py3-none-macosx_10_9_x86_64.whl
| Download URL | hopper_cli-0.1.8-py3-none-macosx_10_9_x86_64.whl |
|---|---|
| Size | 7.5 MB |
| Tags | Python 3 macOS 10.9+ x86-64 |
|
SHA-256 checksum How to use checksums |
73f9b0f5920baefabbaa5e7a3be3171e2fccf5268fe6254111e7bf9cb2c60d0e
|
|
BLAKE2b-256 checksum How to use checksums |
e6b162122d273208fff362d6c43d6abf9afa5f2442bbcf88bf2749c78407cef3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.2
|