godman (formerly Godot Manager) is a .NET 10 console/TUI tool to install, manage, and activate Godot Engine builds (Standard and .NET) on Linux and Windows.
- Install from official URLs (auto-built) or local archives; supports Linux and Windows, Standard or .NET editions.
- Scope-aware installs: user or global (requires administrator privileges for global scope).
- Each install is extracted into its own subfolder under the install root, based on downloaded archive name (with deterministic fallback when source URL has no archive filename).
- Registry of installs with activation; sets
GODOT_HOMEand writes shims (godotorgodot.cmd). - Interactive TUI (
tui) and CLI commands (list,fetch,install,activate,deactivate,remove,doctor,clean,version). - An application-launcher entry for every install: a GNOME/XDG
.desktopfile on Linux, a Start Menu shortcut on Windows. - Dry-run mode to preview install/activate operations without making changes.
- Cleanup command to remove installs, shims, and config.
- Downloads are verified against Godot's published SHA-512 checksums, resume automatically if interrupted, and are cleaned up after install.
Pre-built releases are self-contained — no runtime needed. Just download and run.
Building from source requires:
The interactive TUI (godman tui) — installs on the left, details for the selected one on the right, with the active install marked and the per-install actions listed underneath.
F1 opens Browse Versions, which lists what is available upstream. Filter as you type, or tick Stable only to hide pre-releases.
F2 opens the Install dialog: pick a version, Standard or .NET, and user or global scope. On Windows, choosing Global raises a UAC prompt when you confirm.
? shows the keyboard shortcuts.
winget install --id JanMesarc.GodMancurl -fsSL https://raw.githubusercontent.com/jame581/GodotManager/main/install.sh | bashDownload the latest .tar.gz from Releases and extract:
mkdir -p ~/.local/bin
tar -xzf godman-linux-x64-*.tar.gz -C ~/.local/bin
chmod +x ~/.local/bin/godmanNote: If
~/.local/binis not in your PATH, add it:echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc source ~/.bashrcThe one-liner installer above does this automatically.
sudo godmanand PATH.sudodoes not use your PATH — it replaces it withsecure_pathfrom/etc/sudoers, which never contains~/.local/bin. So a godman installed there works fine as your own user but fails undersudowithsudo: godman: command not found. Global-scope commands needsudoon Linux, so either call it by path:sudo ~/.local/bin/godman install --version 4.5.1 --scope Global --activateor install the binary into a directory root's
secure_pathalready covers. Check which those are withsudo grep secure_path /etc/sudoers—/usr/local/binis on it for most distributions, though some ship a narrower list — then:curl -fsSL https://raw.githubusercontent.com/jame581/GodotManager/main/install.sh | sudo GODMAN_INSTALL_DIR=/usr/local/bin bashThe RPM package installs to
/usr/bin/godman, which is on everysecure_path, so it is unaffected either way.
# List installs
godman list
# Browse available versions from GitHub
godman fetch --stable --limit 10
# Preview installation (dry-run)
godman install --version 4.5.1 --edition Standard --platform windows --scope User --dry-run
# Install latest 4.5.1 Windows Standard (auto URL) to user scope and activate
godman install --version 4.5.1 --edition Standard --platform windows --scope User --activate
# Install .NET edition for Windows from auto URL, global scope (UAC prompt)
godman install --version 4.5.1 --edition DotNet --platform windows --scope Global --activate
# Install on Linux global scope (requires sudo; use the full path unless godman is
# on root's secure_path -- see the note under "Install on Linux (manual)")
sudo ~/.local/bin/godman install --version 4.5.1 --edition Standard --platform linux --scope Global --activate
# Preview activation (dry-run)
godman activate <id> --dry-run
# Run TUI
godman tui
# Doctor and cleanup
godman doctor
godman clean --yes
# Enable diagnostic warnings for troubleshooting
godman activate <id> --verbose
godman install --version 4.5.1 --edition Standard --platform linux --activate --verboselist— show registered installs, active marker.fetch— browse available Godot versions from GitHub; options:--stable,--filter <VERSION>,--limit <COUNT>,--no-cache.install— download (auto URL) or use--archive; options:--version,--edition,--platform,--scope,--path,--activate,--force,--dry-run,--no-shortcut(skip creating an application-launcher entry).activate <id>— switch active install; options:--dry-run,--create-desktop-shortcut(Windows only — adds a desktop shortcut for the newly active install; no-op elsewhere).deactivate— deactivate the current active install (clearsGODOT_HOME, removes shims).remove <id> [--delete] [--dry-run]— unregister (optionally delete files);--dry-runpreviews without changes.doctor— check registry/env/shim.tui— interactive menu for the above.clean [--yes]— remove installs, shims, launcher entries, config. Launcher entries do not followGODMAN_HOME/GODMAN_GLOBAL_ROOT, socleanunder a sandboxGODMAN_HOMEstill deletes godman's entries from your real application menu.version— show the godman, .NET runtime, and OS versions.--version— show the current godman version.
All commands accept the following global options:
--verbose/-V— enable diagnostic warnings for best-effort operations (shim cleanup, PATH updates, shortcut creation, cache I/O, etc.). By default these operations fail silently; with--verbosethey printwarn:messages to the console.
- Config:
~/.config/godman/ - Download cache:
~/.config/godman/downloads/ - User installs:
~/.local/share/godman/installs/ - Global installs:
/usr/local/lib/godman/ - User shim:
~/.local/bin/godot - Global shim:
/usr/local/bin/godot - User launcher entries:
~/.local/share/applications/godman-godot-*.desktop(one per install, plus the shared icon at~/.local/share/icons/hicolor/scalable/apps/godman-godot.svg) - Global launcher entries:
/usr/local/share/applications/godman-godot-*.desktop(plus the icon under/usr/local/share/icons/hicolor/scalable/apps/godman-godot.svg)
Global installs deliberately sit outside the shim directory. They used to live in
/usr/local/bin/godman/, which took the one filename the godman binary itself needs
if sudo godman is ever to resolve. godman migrates that directory to
/usr/local/lib/godman/ on the first privileged run of a command that sets up its paths
(e.g. sudo ~/.local/bin/godman list, or doctor, install, fetch; version and
--help do not; under a GODMAN_GLOBAL_ROOT prefix it moves <prefix>/bin/godman
instead), rebases the recorded
install paths to match, and rewrites the global godot shim and the env.sh it sources
(root's, under a HOME-resetting sudo -- the default on Fedora, Debian and Ubuntu) that
pointed into the old directory.
Until then nothing is lost: godman still reads the machine-wide registry from its old
location, so list, doctor and the TUI keep showing your global installs, and
clean removes them from there too. Run godman doctor to check whether anything was
left behind.
- Config:
%APPDATA%\godman\ - Download cache:
%APPDATA%\godman\downloads\ - User installs:
%APPDATA%\godman\installs\ - Global installs:
C:\Program Files\godman\installs\ - User shim:
%APPDATA%\godman\bin\godot.cmd - Global shim:
C:\Program Files\godman\bin\godot.cmd - Launcher entries (Start Menu):
Programs\godman\Godot <version> (<edition>).lnk, one per install — under the per-user Start Menu for user scope, the common Start Menu for global scope.
# Build the project
dotnet build
# Run all tests
dotnet test -v minimal
# Run integration tests only
dotnet test --filter "FullyQualifiedName~InstallerServiceIntegrationTests"
# Run with detailed output
dotnet test -v detailedTest Coverage:
- Unit tests for path resolution and configuration
- Integration tests for download/install flows with mocked HTTP
- Cross-platform validation (Windows/Linux)
- Isolated test environments with temporary directories
-
Anything touching a global-scope install requires elevated privileges, because it writes machine-wide state — the shared install root, the machine-wide registry, system environment variables, and the shared shim.
- Linux: run the command with
sudo— by full path if godman lives in~/.local/bin, sincesudowill not find it there. A globalinstall,activate,removeorcleanyou can't write stops before changing anything and prints the exactsudocommand to run. What counts is whether the global locations are writable, not whether you're root, so aGODMAN_GLOBAL_ROOTyou own needs no sudo. Switching away from or deactivating a global install proceeds without sudo, because sudo would act on root's registry rather than yours. If the globalgodotshim couldn't be removed, godman names the file. - Windows: a UAC prompt appears automatically. This covers
install,activate,deactivate,remove, andclean, from both the CLI and the TUI — you never need to quit and relaunch from an elevated shell. - On Windows,
activateneeds elevation when the install you are switching away from is global, even if the one you are switching to is not; deactivating a global install has to clear machine-wide state either way.
- Linux: run the command with
-
Global scope sets system-wide environment variables and shims accessible to all users.
-
A global install's shim takes precedence over a user one. Windows searches the machine
PATHbefore the userPATH, so agodotshim left behind by an earlier global activation keeps winning even after you activate a user-scope install.activatewarns when it detects this and names the file to remove; removing it needs administrator rights, so godman reports the condition rather than silently failing to fix it. -
The
fetchcommand queries GitHub API to discover available Godot versions. -
Auto-URL construction for known Godot version patterns.
-
Environment variable overrides available:
GODMAN_HOME,GODMAN_GLOBAL_ROOT. On LinuxGODMAN_GLOBAL_ROOTis a prefix: the shim goes to<prefix>/binand installs to<prefix>/lib/godman. Before 1.4.0 it named the shim directory itself, with installs in<value>/godman:/usr/local/bin→ set/usr/local, or unset it.<X>/bin→ set<X>; the next run that can write there moves<X>/bin/godmanto<X>/lib/godman. For a system directory that run is under sudo, which drops the variable by default: usesudo GODMAN_GLOBAL_ROOT=<X> <full path to godman> list(orsudo -E), since a plainsudo … listwould migrate/usr/localinstead. Everysudocommand godman prints includes the variable. A restricted sudoers rule withoutSETENVrejects thatVAR=valueform ("not allowed to set the following environment variables"); addGODMAN_GLOBAL_ROOTtoenv_keepinstead.- any other value
<V>→ godman does not move<V>/godman; pick a prefix<P>, move it to<P>/lib/godmanyourself and update the paths in itsinstalls.json(or reinstall).
While a value still looks like the old meaning (
<value>/godmanholds installs and<value>/lib/godman/installs.jsondoes not exist),listanddoctorwarn, and globalinstall,activateandremoverefuse to run until it is fixed. An empty value counts as unset; a relative one is never migrated or created. On Windows it stands in for%ProgramFiles%, as it always has. -
Windows environment variables: After activation,
GODOT_HOMEis set in the registry and current process. New terminal sessions will automatically load it; existing sessions can verify withdoctorcommand. -
Windows PATH: The shim directory is automatically added to your PATH during activation. Restart your terminal after activation to use the
godotcommand. -
Troubleshooting: If something seems off after install/activate, run the command again with
--verbose(-V) to see diagnostic warnings for any best-effort operations that failed silently. -
Checksum verification: installs from auto-built URLs are checked against
SHA512-SUMS.txtpublished ongodotengine/godot-builds. A mismatch aborts the install and deletes the downloaded archive. Verification is skipped silently — not an error, no warning — in two cases: a custom--urlor a local--archive, which have no upstream release to check against; and a release that publishes no sums file at all, which is normal for a number of Godot versions. Only when verification was genuinely attempted and could not be completed (a network failure, an HTTP error other than "not published", or an archive missing from the published list) does the install continue with a warning — and that warning names the specific reason, so--verboseis not needed to see it. -
Interrupted downloads resume: partial downloads are kept under the download cache and resumed on the next
install. Rungodman doctorto see how much space they use, orgodman cleanto discard them. -
--forcemerges, it does not replace: installing over an existing directory overwrites the files godman extracts and leaves anything else in that directory untouched. This matters when--pathpoints at a directory you also use for other things. -
Application-launcher entries:
installcreates one per install (skip with--no-shortcut), named for its version, edition, scope, and a short id so two installs never collide — except see the Windows limitation below.activatebackfills the entry for installs made before 1.4.0.removeandcleandelete it;deactivateleaves it in place, since the install itself is still there.doctorreports any install that's missing its entry (installs opted out with--no-shortcutare not reported). -
Known limitation (Windows): two installs of the same version and edition in the same scope at different
--paths share one Start Menu name — the file has no per-install id like the Linux.desktopentry does, so the second install's shortcut overwrites the first's. Removing either of the two then deletes that shared Start Menu shortcut too; re-rungodman activate <id>on the surviving install to restore it. The optional desktop shortcut (activate --create-desktop-shortcut) belongs to the active install and is only removed with it. -
The Godot logo used for Linux launcher entries is by Andrea Calabró, licensed CC BY 4.0.
- Jan Mesarč - Programmer - Portfolio
- Do you want support my work, my dreams? - Buy me a coffee
- Take a look on my other games - itch.io



