| src/forge | ||
| tests | ||
| forge | ||
| pyproject.toml | ||
| README.md | ||
| tmpcfg.toml | ||
| uv.lock | ||
Forge - A Home-Manager Like Tool for Fedora
A lightweight Python CLI (managed with uv) for Fedora that provides COPR repository management, dotfile management and package installation functionality through a centralized TOML configuration.
Overview
Forge is a Python CLI that helps you manage your Fedora system configuration by:
- Managing COPR repositories (enable/disable automatically)
- Installing and managing system packages via dnf
- Managing dotfiles through symlinks to actual files
- Centralized configuration via a single
forge.tomlfile - User-level configuration similar to home-manager/nixos
- Automatic backup of existing files before replacement
Installation
- Clone or download this repository.
- Install dependencies with
uv(none beyond the standard library, but this sets up the venv):uv sync - Run with
uv:uv run forge --help - Or use the local shim directly:
./forge --help - Optionally install globally via
uv:uv tool install .
Quick Start
# Initialize the configuration structure
uv run forge init
# Edit the configuration file to add packages and dotfiles
nano ~/.config/forge/forge.toml
# Apply configuration
uv run forge switch
# Check status
uv run forge status
You can swap uv run forge ... for ./forge ... if you prefer the local shim.
Commands
init
Initialize the configuration structure and create forge.toml.
uv run forge init
# or ./forge init
Creates:
~/.config/forge/- Main configuration directory~/.config/forge/forge.toml- Central configuration file
switch
Apply the current configuration (enable COPR, install packages, deploy dotfiles).
uv run forge switch
# or ./forge switch
This command:
- Enables all COPR repositories listed in
forge.toml - Disables COPR repositories that are no longer configured
- Installs all packages listed in
forge.toml - Creates symlinks for all configured dotfiles
- Creates backups of existing files before replacing them
- Updates the last switch timestamp
status
Show current configuration status and information.
uv run forge status
# or ./forge status
Displays:
- Configuration directory paths
- Last switch timestamp
- List of configured COPR repositories, packages and dotfiles
help
Show help message with all available commands.
uv run forge help
# or ./forge help
Configuration
forge.toml
The central configuration file located at ~/.config/forge/forge.toml:
# Forge Configuration File
# User-level configuration similar to home-manager/nixos
copr = [
# "copr.fedorainfracloud.org/username/repository",
# "copr.fedorainfracloud.org/anotheruser/anotherrepo",
]
packages = [
# "git",
# "vim",
# "curl",
# "wget",
]
[forge]
version = "1.0"
last_switch = ""
[dotfiles]
# Dotfiles to manage with symlinks
# Format: "target_path" = "source_path"
# target_path: where the symlink should be created (relative to home directory)
# source_path: where the actual file is stored (relative to dotfiles directory)
".bashrc" = ".bashrc"
".config/vimrc" = "vimrc"
".config/alacritty/alacritty.yml" = "alacritty.yml"
[options]
# Additional options
backup = true
backup_dir = "backup"
Configuration Sections
[forge]
version: Configuration file versionlast_switch: Timestamp of last switch operation (auto-updated)
copr
Array of COPR repositories to enable via dnf copr enable. Just list COPR repository names - presence means enable, absence means don't enable.
Examples:
copr = [
"copr.fedorainfracloud.org/username/repository",
"copr.fedorainfracloud.org/anotheruser/anotherrepo",
]
To remove a COPR repository, simply delete the line containing the repository name. Forge will automatically disable it during the next switch.
packages
Array of packages to install via dnf. Just list package names - presence means install, absence means don't install.
Examples:
packages = [
"git",
"vim",
"curl",
"wget",
"nodejs",
"npm",
]
To remove a package, simply delete the line containing the package name.
[dotfiles]
Dotfile mappings using symlinks:
- Key: Target path where symlink should be created (relative to home directory)
- Value: Source path where actual file is stored (relative to dotfiles directory)
- Note: Source path automatically prefixed with "dotfiles/" if not present
[options]
Additional configuration options:
backup: Enable/disable backup of existing files (default: true)backup_dir: Directory name for backups (relative to forge directory)
File Structure
~/.config/forge/
├── forge.toml # Main configuration file
├── dotfiles/ # Your actual dotfiles (source files)
│ ├── .bashrc
│ ├── vimrc
│ └── alacritty.yml
└── backup/ # Backups of replaced files
├── .bashrc.20231121_143022.bak
└── vimrc.20231121_143022.bak
How It Works
COPR Repository Management
COPR repositories are managed through the copr array in forge.toml:
- Add COPR repo: Add the repository name to the array
- Remove COPR repo: Remove the entry from the array
- Automatic cleanup: Forge automatically disables COPR repos that are removed from configuration
- No flags needed: Just presence/absence of the repository name matters
- Forge stores the previous configuration at
~/.config/forge/forge.toml.prevand compares it to the current file duringswitch; newly added repos are enabled, removed repos are disabled.
Package Management
Packages are managed through the packages array in forge.toml:
- Add package: Add the package name to the array
- Remove package: Remove the entry from the array
- No flags needed: Just presence/absence of the package name matters
- The previous configuration snapshot (
forge.toml.prev) is used to detect additions/removals on eachswitch; added packages are installed and removed packages are uninstalled.
Dotfile Management
Forge uses symlinks to manage dotfiles:
- Your actual dotfiles are stored in
~/.config/forge/dotfiles/ - Symlinks are created from your home directory to these files using relative paths
- This allows you to version control your dotfiles in one place
- Changes to the source files are immediately reflected in your home directory
- Source paths are automatically prefixed with "dotfiles/" for convenience
Backup System
Before creating symlinks, Forge:
- Checks if the target file exists and is not a symlink
- Creates a timestamped backup in the backup directory
- Removes the original file
- Creates the symlink to your managed dotfile
forge.toml is also backed up before the last switch timestamp is updated.
The previously applied configuration is stored separately as ~/.config/forge/forge.toml.prev to compute diffs for COPR and package changes.
Examples
Basic Setup
# Initialize forge
uv run forge init
# Edit forge.toml to add COPR repos and packages
nano ~/.config/forge/forge.toml
# Add to the arrays:
# copr = [
# "copr.fedorainfracloud.org/username/cool-repo",
# ]
# packages = [
# "git",
# "vim",
# "curl",
# ]
# Create your dotfiles directory and add files
mkdir -p ~/.config/forge/dotfiles
echo "export EDITOR=vim" > ~/.config/forge/dotfiles/.bashrc
# Add to [dotfiles] section:
".bashrc" = ".bashrc"
# Apply configuration
uv run forge switch
Managing Application Configurations
# Add alacritty configuration
mkdir -p ~/.config/forge/dotfiles
cp ~/.config/alacritty/alacritty.yml ~/.config/forge/dotfiles/
# Edit forge.toml
nano ~/.config/forge/forge.toml
# Add to [dotfiles] section:
".config/alacritty/alacritty.yml" = "alacritty.yml"
# Apply changes
uv run forge switch
COPR Repository Management Examples
copr = [
# Development tools COPR
"copr.fedorainfracloud.org/development/tools",
"copr.fedorainfracloud.org/user/neovim-nightly",
]
# To remove a COPR repo, just delete the entry
# Forge will automatically disable it during the next switch
Package Management Examples
packages = [
# Development tools
"git",
"vim",
"nodejs",
"npm",
# System utilities
"curl",
"wget",
"tree",
"htop",
]
# To remove a package, just delete the entry
Version Control Your Configuration
# Initialize git repository in forge directory
cd ~/.config/forge
git init
git add .
git commit -m "Initial configuration"
# Now you can version control your entire system configuration
git add forge.toml dotfiles/
git commit -m "Updated vim configuration"
Environment Variables
FORGE_DIR: Override the default configuration directory (default:~/.config/forge)
Dependencies
- Python 3.11+
tomlkit(installed automatically viauv sync)uvfor environment and script managementdnf- Fedora package managerdnf-plugins-core- For COPR repository management
Migration from Previous Version
If you were using the old version of forge with git = true or bare keys under [packages]/[copr]:
- Your existing configuration will not be automatically migrated, but the CLI will still read the legacy format.
- Run
uv run forge init(or./forge init) to create the newforge.tomlstructure. - Convert to arrays:
# Old formats [packages] git = true vim = true # or [packages] git vim # New format packages = ["git", "vim"] copr = ["copr.fedorainfracloud.org/username/repository"] - Move your existing dotfiles from the old directory to
~/.config/forge/dotfiles/
License
This project is open source. Feel free to contribute or report issues.