Skip to main content

hopper

License: AGPL-3.0-or-later PyPI Python Forgejo

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.

Installation

Install via pipx or pip, or grab a prebuilt binary from the Forgejo releases page. Do not install via go install or build from source unless you are developing hopper — see Development for why.

pipx (recommended, installs an isolated executable):

pipx install hopper-cli

or with pip:

pip install hopper-cli

To upgrade later:

pipx upgrade hopper-cli    # or: pip install --upgrade hopper-cli

Prebuilt binaries

Prebuilt binaries for recent releases are available on the Forgejo releases page.

Requirements

  • git — hopper drives git under the hood
  • Python 3.8+ (only for the pip/pipx installation)
  • An account as tutor/staff/admin on a hopper instance

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.

Run hopper <command> --help for the full flag reference of each command.

auth

hopper auth            # interactive setup (preset picker or custom URLs)
hopper auth --custom   # skip the preset picker and enter custom URLs
hopper auth list       # list configured profiles
hopper auth status     # show the current authentication state
hopper auth remove alu # remove a profile

Authorization happens in your browser: hopper opens the instance's authorize page and receives the new API key via a local callback. If that fails, it falls back to asking you to paste a key manually.

init

hopper init 2025WS-EidP    # uses the only/default configured profile
hopper init alu/2025WS-EidP
hopper init alu/42         # numeric course ID also works
hopper init --force alu/2025WS-EidP   # overwrite an existing .hopper.yaml

pull

hopper pull                 # sync all assigned student repos
hopper pull --student alice # pull a single student by username
hopper pull --only a,b,c    # pull only the listed usernames
hopper pull --prune         # remove local repos of students no longer assigned
hopper pull -j 8            # 8 concurrent git operations (default 4)
  • --prune removes local repos of students no longer assigned to you, after showing a preview and asking for confirmation; --no-prune skips pruning.
  • Per-repo failures are reported and skipped — one bad repo does not abort the whole run.

push / commit

hopper push                     # commit */README.md changes and push (default msg: "Grade exercises")
hopper push "Grade exercise 3"  # custom commit message
hopper push --all               # stage all changes, not just */README.md
hopper push --allow-invalid     # push even when the README point schema is invalid
hopper commit "WIP grading"     # commit without pushing (recovery path)

Before pushing, hopper validates that each modified README's first line contains exactly one point schema like (12/15). Invalid pushes are blocked unless --allow-invalid is given. A conflicting rebase surfaces the conflict and halts that repo instead of destroying local work — hopper never runs git reset --hard.

status / students / info

hopper status    # table: student, branch, ahead/behind, dirty/clean
hopper students  # table: username, name, matrikel
hopper info      # course name/uid/id, profile, your user and role, exercises

Version gate

On every command that touches the server (everything except auth, version, and help), hopper asks the active profile's orchestration server for the minimum supported CLI version:

  • running version < minimum → the CLI refuses to run and tells you to upgrade;
  • running version >= minimum → proceeds;
  • server unreachable → proceeds silently (can't check offline).

License

Licensed under AGPL-3.0-or-later.

Development

Requires Go (see go.mod for the minimum version) and Task.

⚠️ Note: Building from source without injecting the version via ldflags produces a binary with a wrong/fallback version string (v0.1.0 or dev). This breaks hopper version, the CLI's self-upgrade check, and the server-side minimum-version gate. End users should install via pipx/pip or the prebuilt release binaries instead — see Installation. If you do build from source, always inject the version as shown below.

A plain go install works for quick local experiments only:

go install codeberg.org/hopper/cli/cmd/hopper@latest

Or clone the repository and build with Task (task build below produces bin/hopper). Useful tasks:

task build       # build the CLI binary to bin/hopper
task test        # run unit tests
task lint        # run golangci-lint
task fmt         # format Go code and imports
task default     # fmt, lint, vet, test, build
task ci          # strict CI gate: fmt, lint, vet, test, build, clean tree
task hooks:install  # point git at the versioned githooks directory

The version is injected at build time via ldflags:

go build -ldflags "-X codeberg.org/hopper/cli/internal/cmd.Version=vX.Y.Z" -o hopper ./cmd/hopper/

Metadata

Release files for hopper-cli 0.1.12

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hopper-cli 0.1.12
File Size Uploaded
hopper_cli-0.1.12.tar.gz 17.0 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for hopper-cli 0.1.12
File
hopper_cli-0.1.12-py3-none-win_arm64.whl Python 3 none Windows ARM64 Details
hopper_cli-0.1.12-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
hopper_cli-0.1.12-py3-none-manylinux2014_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details
hopper_cli-0.1.12-py3-none-manylinux2014_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details
hopper_cli-0.1.12-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details
hopper_cli-0.1.12-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.12.tar.gz

Download URL hopper_cli-0.1.12.tar.gz
Size 17.0 kB
Tags Source
SHA-256 checksum
How to use checksums
4348f8c6f9a534c15b1d9bab934643084788b660a5b8196be50f33f471f31e47
BLAKE2b-256 checksum
How to use checksums
d769d85d169f97005e1328d4af368bca8384220c0f9c94ca85d8df30a9191a76
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.12-py3-none-win_arm64.whl

Download URL hopper_cli-0.1.12-py3-none-win_arm64.whl
Size 14.9 MB
Tags Python 3 Windows ARM64
SHA-256 checksum
How to use checksums
418e847b456ab52530e60a890ec6d4b29256143133e6ac0fafea4a4080fc50a9
BLAKE2b-256 checksum
How to use checksums
df97018070f85bc91f1ec9ef9e33ce056642f1ed613af9ab3b27276e668bf50b
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.12-py3-none-win_amd64.whl

Download URL hopper_cli-0.1.12-py3-none-win_amd64.whl
Size 15.6 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
edffd11aecdb0e4c658c61ba80925e0c5358b4f155e582b1c4e20f05d1d7ae9e
BLAKE2b-256 checksum
How to use checksums
c8ad1d85f110b5cdbaabf1eac30487c2c9c77c7b982bebe764392cfbed5e4d98
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.12-py3-none-manylinux2014_x86_64.whl

Download URL hopper_cli-0.1.12-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
41d3ef01e744afbb70231e84c33b3cbeb5ceaa9ac161bb8a19ee82dbd6eab4b4
BLAKE2b-256 checksum
How to use checksums
aba04dc776c7ee64f7fe2d284eafaa6ac2e1fdcb51b63e357fb9a8f7f6e437dd
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.12-py3-none-manylinux2014_aarch64.whl

Download URL hopper_cli-0.1.12-py3-none-manylinux2014_aarch64.whl
Size 14.2 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
c9319620eadfdfc5b9644121a94a90183f5c74e8a8b6e3189dafe3ad8e92b618
BLAKE2b-256 checksum
How to use checksums
00b9a2db79c4ff92090cc8c8e219e80b49ff0ea5628d65d27d4e85f5a7481d86
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.12-py3-none-macosx_11_0_arm64.whl

Download URL hopper_cli-0.1.12-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
cf2576253849db6f72b415d2c8ad18ce84376ee56cf46f7c5a65e8363ab44174
BLAKE2b-256 checksum
How to use checksums
6151fbf1c111aa0c7d573d46270c7c276701246e262a8f7a82fc632ce8138c7a
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.12-py3-none-macosx_10_9_x86_64.whl

Download URL hopper_cli-0.1.12-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
2708960f2255f2a854a858a301cfbde5b6d133e41a2cdfda156ecdde8325b908
BLAKE2b-256 checksum
How to use checksums
d160384d8b84d244db6ddcbabcd428aec5a780a7126746fd8212d0dda07fc7b9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.2

Release history Release notifications | RSS feed

1.1.0

7 release files

1.0.1

7 release files

1.0.0

7 release files

This release

0.1.12 This release

7 release files

0.1.11

6 release files

0.1.9

6 release files

0.1.8

6 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page