Skip to content

dotbrains/set-me-up-universal-modules

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

'set-me-up' Universal Modules

License: PolyForm Shield 1.0.0

This repository is designed to be used as a submodule to the set-me-up blueprint repository. It contains modules that work on any supported OS — primarily polyglot version managers and language-specific tooling.

Structure

Modules are organized by language or tool family. Most language families offer multiple version-manager choices side-by-side (e.g. node/{mise,n,nodenv,nvm,npm}) so a blueprint can pick whichever fits the user's workflow:

universal/
├── ai/               # claude-code, codex, copilot-cli, docker-sandboxes,
│                     #   gemini-cli, herdr, opencode, pi-coding-agent, superset
├── base/             # Bootstraps the smu environment (rcm, dotfile sync, etc.)
├── homebrew/         # Homebrew itself (cross-OS)
├── mise/             # Polyglot version manager (entry point)
├── go/               # goenv, mise
├── java/             # jenv, mise, sdkman
├── neovim/           # lazyvim, nvchad presets
├── node/             # mise, n, nodenv, npm, nvm
├── nushell/          # Nushell shell
├── php/              # composer, mise, phpenv
├── python/           # mise, pip
├── ruby/             # mise, rbenv
└── rust/             # cargo, mise

A module name passed to smu -m is the path relative to the universal/ bucket — e.g. node/n runs node/n/n.sh, and python/pip runs python/pip/pip.sh.

Module kinds

Each module directory contains one of:

  • <name>.sh — most common. Runs custom install logic (curl-piped installers, GitHub-cloned version managers, post-install configuration). Many ship a sibling brewfile or packages file for shared dependencies (e.g. node/n/brewfile declares n itself, while n.sh configures the prefix).
  • brewfile — a few modules are pure brewfiles that the install can be expressed declaratively (e.g. mise/brewfile).
  • packages — used when an install is fully expressible via the Debian DSL (rare here; see node/npm/packages for an npm-on-Debian variant).

The smu installer resolves a module by name and runs whichever artifact it finds. See the installer README for the full module-resolution rules and the -p / -i / -l flags.

Cross-platform handling

Unlike the OS-specific module trees, universal modules don't refuse to run on the wrong host — they detect the OS internally and adapt. For example, homebrew/homebrew.sh calls apt_install_from_file packages only when is_debian, runs Arch-specific pacman setup only when is_arch_linux, and otherwise falls through to the standard installer. This lets a single module name (homebrew) work across macOS, Debian/Ubuntu, and Arch without per-OS forks.

When authoring a new universal module, prefer this branching style (if is_debian; then …; elif is_macos; then …; fi) over a hard is_macos guard.

Auditing and uninstalling

The smu installer ships read-only auditing (smu --status) and reversal (smu --uninstall) for every module:

smu --status                                 # what's currently installed
smu -u -m node/n                             # uninstall (prompts [y/N])
smu -iu                                      # interactive uninstall via fzf

For brewfile and packages modules, detection and uninstall are automatic via brew bundle check / cleanup and apt_install_from_file / apt_remove_from_file. No per-module work is required.

For *.sh modules smu only acts when the module ships two opt-in sibling files:

  • <name>.installed — sourced by smu --status. Exit 0 means installed; non-zero means missing. Without this file, the module reports unknown (smu never guesses).
  • <name>.uninstall.sh — sourced by smu --uninstall. Without this file, the module is reported as "cannot auto-uninstall — manual cleanup required" and skipped.

If a *.sh module shares its directory with a brewfile or packages file, smu --uninstall runs both inverses in order: the per-module <name>.uninstall.sh first (custom install side-effects), then the declarative cleanup (shared dependencies). Authors can therefore keep each <name>.uninstall.sh focused on what its install script did beyond the declarative file.

Note: at the time of writing, none of the universal *.sh modules ship sibling .installed / .uninstall.sh files. Authoring them is an opt-in, per-module choice; modules without them install as before but report unknown under --status and are skipped by --uninstall. Contributions welcome.

See the installer README for the full status/uninstall reference and authoring examples.

Why abstract these modules to an external repository?

When installing the blueprint configuration, we need to be able to obtain our custom modules defined in your blueprint as well as the set of universal modules that set-me-up provides.

License

This project is licensed under the PolyForm Shield License 1.0.0 — see LICENSE for details.

About

Universal modules for 'set-me-up' setups.

Resources

License

Stars

Watchers

Forks

Contributors

Languages