Files
flow/README.md
2026-02-13 09:57:38 +02:00

267 lines
5.5 KiB
Markdown

# flow
`flow` is a CLI for managing development instances, containers, dotfiles, bootstrap profiles, and
binary packages.
This repository contains the Python implementation of the tool and its command modules.
## What is implemented
- Instance access via `flow enter`
- Container lifecycle commands under `flow dev` (`create`, `exec`, `connect`, `list`, `stop`,
`remove`, `respawn`)
- Dotfiles management (`dotfiles` / `dot`)
- Bootstrap planning and execution (`bootstrap` / `setup` / `provision`)
- Binary package installation from manifest definitions (`package` / `pkg`)
- Multi-repo sync checks (`sync`)
## Installation
Build and install a standalone binary (no pip install required for use):
```bash
make build
make install-local
```
This installs `flow` to `~/.local/bin/flow`.
## Configuration
`flow` uses XDG paths by default:
- `~/.config/devflow/config`
- `~/.config/devflow/manifest.yaml`
- `~/.local/share/devflow/`
- `~/.local/state/devflow/`
### `config` (INI)
```ini
[repository]
dotfiles_url = git@github.com:you/dotfiles.git
dotfiles_branch = main
[paths]
projects_dir = ~/projects
[defaults]
container_registry = registry.tomastm.com
container_tag = latest
tmux_session = default
[targets]
# Format A: namespace = platform ssh_host [ssh_identity]
personal = orb personal.orb
# Format B: namespace@platform = ssh_host [ssh_identity]
work@ec2 = work.internal ~/.ssh/id_work
```
## Manifest format
The manifest is YAML with these top-level sections used by the current code:
- `profiles` for bootstrap profiles
- `binaries` for package definitions
- `package-map` for cross-package-manager name mapping
`environments` is no longer supported.
Example:
```yaml
profiles:
linux-vm:
os: linux
hostname: "$HOSTNAME"
shell: zsh
locale: en_US.UTF-8
requires: [HOSTNAME]
packages:
standard: [git, tmux, zsh, fd]
binary: [neovim]
ssh_keygen:
- type: ed25519
comment: "$USER@$HOSTNAME"
runcmd:
- mkdir -p ~/projects
package-map:
fd:
apt: fd-find
dnf: fd-find
brew: fd
binaries:
neovim:
source: github:neovim/neovim
version: "0.10.4"
asset-pattern: "nvim-{{os}}-{{arch}}.tar.gz"
platform-map:
linux-amd64: { os: linux, arch: x86_64 }
linux-arm64: { os: linux, arch: arm64 }
macos-arm64: { os: macos, arch: arm64 }
install-script: |
curl -fL "{{downloadUrl}}" -o /tmp/nvim.tar.gz
tar -xzf /tmp/nvim.tar.gz -C /tmp
rm -rf ~/.local/bin/nvim
cp /tmp/nvim-*/bin/nvim ~/.local/bin/nvim
```
## Command overview
### Enter instances
```bash
flow enter personal@orb
flow enter root@personal@orb
flow enter personal@orb --dry-run
```
If your local terminal uses `xterm-ghostty` or `wezterm`, `flow enter` shows a terminfo warning and
a manual fix command before connecting. `flow` never installs terminfo on the target automatically.
### Containers
```bash
flow dev create api -i tm0/node -p ~/projects/api
flow dev connect api
flow dev exec api -- npm test
flow dev list
flow dev stop api
flow dev remove api
```
### Dotfiles
```bash
flow dotfiles init --repo git@github.com:you/dotfiles.git
flow dotfiles link
flow dotfiles status
flow dotfiles relink
flow dotfiles clean --dry-run
flow dotfiles repo status
flow dotfiles repo pull --relink
flow dotfiles repo push
```
### Bootstrap
```bash
flow bootstrap list
flow bootstrap show linux-vm
flow bootstrap packages --profile linux-vm
flow bootstrap packages --profile linux-vm --resolved
flow bootstrap run --profile linux-vm --var HOSTNAME=devbox
flow bootstrap run --profile linux-vm --dry-run
```
`flow bootstrap` auto-detects the package manager (`brew`, `apt`, `dnf`) when
`package-manager` is not set in a profile.
### Packages
```bash
flow package install neovim
flow package list
flow package list --all
flow package remove neovim
```
### Sync
```bash
flow sync check
flow sync check --no-fetch
flow sync fetch
flow sync summary
```
### Completion
```bash
flow completion install-zsh
flow completion zsh
```
## Self-hosted config priority
When present, `flow` prefers config from a linked dotfiles package:
1. `~/.local/share/devflow/dotfiles/flow/.config/flow/config`
2. `~/.config/devflow/config`
And for manifest:
1. `~/.local/share/devflow/dotfiles/flow/.config/flow/manifest.yaml`
2. `~/.config/devflow/manifest.yaml`
Passing an explicit file path to internal loaders bypasses this cascade.
## State format policy
`flow` currently supports only the v2 dotfiles link state format (`linked.json`). Older state
formats are intentionally not supported.
## CLI behavior
- User errors return non-zero exit codes.
- External command failures are surfaced as concise one-line errors (no traceback spam).
- `Ctrl+C` exits with code `130`.
## Zsh completion
Recommended one-shot install:
```bash
flow completion install-zsh
```
Manual install (equivalent):
```bash
mkdir -p ~/.zsh/completions
flow completion zsh > ~/.zsh/completions/_flow
```
Then ensure your `.zshrc` includes:
```bash
fpath=(~/.zsh/completions $fpath)
autoload -Uz compinit && compinit
```
Completion is dynamic and pulls values from your current config/manifest/state (for example
bootstrap profiles, package names, dotfiles packages, and configured `enter` targets).
## Development
Binary build (maintainers):
```bash
python3 -m pip install pyinstaller
make build
make install-local
```
Useful targets:
```bash
make clean
```
Run tests:
```bash
python3 -m pytest
```
Local development setup:
```bash
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest
```