This commit is contained in:
2026-05-13 23:02:47 +03:00
parent d0f8315cf1
commit 78f95bc88e
49 changed files with 2747 additions and 987 deletions

113
README.md
View File

@@ -1,66 +1,84 @@
# flow
`flow` is a CLI for managing development environments: dotfiles, packages, containers, remote targets, and system bootstrap.
CLI for managing development environments: dotfiles, packages, dev containers, remote targets, and system bootstrap.
## Installation
## Quick start
```bash
make build
make install-local
make build && make install-local # installs to ~/.local/bin/flow
flow setup run linux-work # bootstrap a machine
flow dotfiles link # symlink dotfiles
flow dev create api -i tm0/node # spin up a dev container
flow dev attach api # attach via tmux
```
This installs `flow` to `~/.local/bin/flow`.
## Architecture
Four-layer design: **core** (runtime, config, errors) -> **domain** (pure functions, frozen dataclasses) -> **services** (I/O orchestration) -> **commands** (thin CLI adapters).
- Domain layer is pure: no I/O, no side effects, fully testable
- Services perform all I/O and delegate logic to domain functions
- Commands are trivial dispatchers from argparse to services
## Commands
```bash
# Dotfiles
flow dotfiles link [--profile NAME] [--dry-run] [--skip PKG...]
flow dotfiles unlink [PACKAGES...] [--dry-run]
flow dotfiles status
flow dotfiles sync
flow dotfiles status [PACKAGES...]
flow dotfiles edit PACKAGE [--no-commit] # pull -> $EDITOR -> commit+push
# Dotfiles repos (unified: dotfiles repo + module repos)
flow dotfiles repos list
flow dotfiles repos status [--repo NAME]
flow dotfiles repos pull [--repo NAME] [--dry-run]
flow dotfiles repos push [--repo NAME] [--dry-run]
# Packages
flow packages install [NAMES...] [--profile NAME] [--dry-run]
flow packages remove NAMES... [--dry-run]
flow packages list
flow packages remove NAMES...
flow packages list [--all]
# Bootstrap
flow setup run PROFILE [--dry-run]
flow setup show PROFILE
flow setup run PROFILE [--dry-run] # run a full bootstrap profile
flow setup show PROFILE # preview profile steps
flow setup list
# Remote targets
flow remote enter NAMESPACE@PLATFORM [--dry-run]
flow remote enter TARGET [--dry-run] # ssh + tmux into a remote target
flow remote list
# Dev containers
flow dev create IMAGE [--namespace NS] [--dry-run]
flow dev enter NAME [--shell PATH]
flow dev stop NAME
flow dev remove NAME
# Dev containers (docker or podman)
flow dev create NAME -i IMAGE [-p PROJECT] [--dry-run]
flow dev attach NAME # tmux session into container
flow dev exec NAME [-- CMD...] # run a command in container
flow dev enter NAME # interactive shell
flow dev stop NAME [--kill]
flow dev remove NAME [-f]
flow dev respawn NAME # restart all tmux panes
flow dev list
# Projects
flow projects check [--fetch]
flow projects check [--fetch] # scan ~/projects for dirty repos
flow projects fetch # fetch all project remotes
flow projects summary # quick overview
# Other
# Shell completion
flow completion zsh # print zsh completion script
flow completion install-zsh # install to ~/.zsh/completions
# Global flags
flow --version
flow --quiet
flow completion
flow --quiet # suppress info output
flow --no-color # disable colored output
```
### Aliases
- `dotfiles` -> `dot`
- `dotfiles repos` -> `dotfiles repo`
- `packages` -> `package`, `pkg`
- `projects` -> `project`, `sync` (with `--fetch` default)
- `setup` -> `bootstrap`
- `dev attach` -> `dev connect`
- `dev remove` -> `dev rm`
## Configuration
Config is loaded from `~/.config/flow/config.yaml` and merged with self-hosted config from the dotfiles repo at `~/.local/share/flow/dotfiles/_shared/flow/.config/flow/`.
Loaded from `~/.config/flow/config.yaml`, merged with dotfiles repo overlay at `~/.local/share/flow/dotfiles/_shared/flow/.config/flow/`.
```yaml
repository:
@@ -71,7 +89,9 @@ paths:
projects: ~/projects
defaults:
container-runtime: auto # auto | docker | podman | podman-rootful
container-registry: registry.example.com
container-tag: latest
tmux-session: main
targets:
@@ -81,6 +101,17 @@ targets:
identity: ~/.ssh/id_work
```
### Container runtime
`container-runtime` controls which engine `flow dev` uses:
- `auto` -- detect docker or podman from PATH (default)
- `docker` -- force docker
- `podman` -- force podman, prefer rootless socket
- `podman-rootful` -- force podman, prefer rootful socket (`/run/podman/podman.sock`)
When using podman, `flow dev create` automatically adds `--security-opt label=disable` for engine socket access. The socket is always mounted to `/var/run/docker.sock` inside the container (Podman's Docker-compatible API).
## Dotfiles layout
```
@@ -103,7 +134,7 @@ linux-work/ # Profile-specific layer
### External modules
A `_module.yaml` inside a package mounts an external git repo at that location:
`_module.yaml` inside a package mounts an external git repo at that location:
```yaml
source: github:org/nvim-config
@@ -111,11 +142,11 @@ ref:
branch: main
```
Module files are linked from the clone cache, while local files outside the mount path are linked from the dotfiles repo.
Modules are regular git clones managed by flow (not git submodules). They appear alongside the dotfiles repo in `flow dotfiles repos list` and are pulled/pushed with the same commands.
## Manifest
Packages and profiles are defined in YAML files under the flow config directory.
Packages and profiles defined in YAML files under the flow config directory.
```yaml
packages:
@@ -148,15 +179,21 @@ profiles:
- echo "setup complete"
```
## Architecture
Four layers: **core** (runtime primitives, config, errors) -> **domain** (pure functions, frozen dataclasses) -> **services** (I/O orchestration) -> **commands** (thin CLI adapters).
Core primitives (`SystemRuntime`): `CommandRunner`, `FileSystem`, `GitClient`, `TmuxClient`, `ContainerRuntime`.
## Security
- `flow` must run as a regular user (root invocation is rejected)
- `_root/` files require sudo for linking
- Rejects root invocation
- `_root/` dotfile paths require sudo for linking
- Package post-install hooks run without sudo by default
## Development
```bash
make deps
.venv/bin/python -m pytest tests/ -v
make deps # create .venv + install deps
.venv/bin/python -m pytest tests/ -v # run tests
```