Sofmani
Installs software from a declerative config on any system
Install / Use
/learn @chenasraf/SofmaniREADME
sofmani
sofmani stands for [Sof]tware [Mani]fest. It is a robust and flexible provisioning tool
written in Go, designed to simplify software installations, configuration syncing, and system
provisioning for both personal and work computers. With a single config file, sofmani automates
locating, installing, or updating software and configurations, making system setup quick and
reproducible.
Table of Contents
- Features
- Installation
- Getting Started
- Usage
- Configuration Reference
- Example Workflow
- Tips and Tricks
- Contributing
- License
🚀 Features
- Install and provision software using a declarative YAML/JSON configuration.
- Multi-platform support: macOS, Linux, or Windows.
- Modular and extendable installer types: shell scripts, rsync, Homebrew taps, and more.
- Configurable platform-specific behaviors.
- Automatic software updates using custom logic.
- Group software installations into logical "steps" with sophisticated orchestration.
- Category headers to visually organize your installers list.
- Template variables for dynamic values (architecture, OS, device ID) in commands and filenames.
🎯 Installation
Download Precompiled Binaries
Precompiled binaries for sofmani are available for Linux, macOS, and Windows:
- Visit the Releases Page to download the latest version for your platform.
Homebrew (macOS/Linux only)
Install from a custom tap:
brew install chenasraf/tap/sofmani
Linux
You can install sofmani by downloading the release tar, and extracting it to your preferred
location.
-
You can see an example script for install here: install.sh
-
The example script can be used for actual install, use this command to download and execute the file (use at your own discretion):
To change the install location, change the provided env variable
$INSTALL_DIRto the script:curl -fsSL https://raw.githubusercontent.com/chenasraf/sofmani/master/install.sh \ | env INSTALL_DIR="$HOME/.local/bin" bash -s --
✨ Getting Started
sofmani works based on a configuration file written in YAML or JSON. Below is an annotated
example configuration to demonstrate most of its options.
debug: true # Global debug mode (optional).
check_updates: true # Enable update checking (optional).
defaults: # Define default behaviors for installer types.
type:
brew:
platforms:
only: ['macos'] # Only run this installer type on macOS.
install: # Declare installation steps:
- name: nvim # Identifier for this step.
type: rsync
opts:
source: ~/.dotfiles/.config/nvim/
destination: ~/.config/nvim/
flags: --delete --exclude .git --exclude .DS_Store
- name: lazygit
type: group # Logical group of steps.
steps:
- name: lazygit
type: brew
opts:
tap: jesseduffield/lazygit
- name: lazygit # Additional step for Linux systems only.
type: shell
platforms:
only: ['linux']
opts:
command: |
cd $(mktemp -d)
latest_version=$(curl -s https://... )
...
🔧 Usage
Run sofmani with an optional configuration file or flags. Example:
sofmani my-config.yaml
See the documentation for more information and examples.
Command-Line Flags
The following flags are supported to customize behavior:
| Flag | Description |
| -------------------- | ----------------------------------------------------- |
| -d, --debug | Enable debug mode. |
| -D, --no-debug | Disable debug mode (default). |
| -u, --update | Enable update checking. |
| -U, --no-update | Disable update checking (default). |
| -s, --summary | Enable installation summary (default). |
| -S, --no-summary | Disable installation summary. |
| -f, --filter | Filter by installer name (can be used multiple times) |
| -h, --help | Display help information and exit. |
| -v, --version | Display version information and exit. |
If a configuration file is not explicitly provided, sofmani attempts to locate a sofmani.yaml,
sofmani.yml or sofmani.json in the following directories, in this order (first match is used):
- Current directory
$HOME/.configdirectory- Home directory
If no file is found or provided, sofmani will fail to start.
For more information, see Configuration Reference
📚 Configuration Reference
Here is a quick breakdown of all configuration options.
For a full breakdown with all the supported options, see the docs.
Global Options
| Field | Type | Description |
| ------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| debug | Boolean | Enable or disable debug mode. Default: false. |
| check_updates | Boolean | Enable or disable checking for updates before running operations. Default: false. |
| summary | Boolean | Enable or disable the installation summary at the end. Default: true. |
| category_display | String | Controls how category headers are rendered. Values: border (default), border-compact, minimal. |
| defaults | Object | Defaults to apply to all installer types, such as specifying supported platforms or commonly used flags. |
| env | Object | Environment variables that will be set for the context of the installer. OS env vars are passed, and may be overridden for this config and all of its installers here. |
| install | Array | Installation steps to execute. |
install Node
The install field describes the steps to execute. Each step represents an action or group of
actions. Steps can be of several types, such as brew, rsync, shell, and more.
You can also add category headers to organize your installers visually:
install:
- category: Development Tools
desc: Optional description for the category.
- name: neovim
type: brew
See Installer Configuration for more details.
| Field | Type | Description |
| ------------------ | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | String (required) | Identifier for the step. It does not have to be unique, but is usually used to check for the app's existence, if applicable (can be overridden using bin_name) |
| type | String (required) | Type of the step. See supported types for a comprehensive list of supported values. |
| platforms | Object (optional) | Platform-specific execution controls. See platforms subfields below.
