Skip to content

shall export: convert declaration files to a standalone script #67

Description

@SYKhayyat

Problem

Shall declaration files (modules/*.txt, profiles, etc.) describe what a machine should have, but there is no way to convert them to a standalone script without running shall sync. Users who want to share their setup, use it in CI, or bootstrap a machine before Shall is installed have no path.

Proposed behavior

A new verb: shall export --from-declaration

  1. Read the active Shall declarations (modules, profiles, active files)
  2. Resolve all packages, services, firewall rules, dotfiles, settings to concrete commands
  3. Generate a standalone script in one of three formats:
    • Bash: shell commands
    • Ansible: playbook tasks
    • Nix: NixOS/nix-darwin expression
  4. The script should reproduce the machine as declared, without requiring Shall

Design considerations

  • Resolution: bare names (e.g., ripgrep) must be resolved to a specific backend before generating script commands. Use the locked backend or fall back to priority.
  • Conditional declarations: when os == linux blocks should be handled — generate platform-specific sections or pick the current platform's branch.
  • Absent declarations: absent:apt:snap should generate sudo apt-get remove -y snap (or equivalent).
  • Options: @version=, @hold, @health= should map to appropriate flags.
  • Dotfiles/link: should generate symlink creation or copy commands, with the source path resolved.
  • Settings: should generate gsettings set, defaults write, or reg add commands.

Relationship to --from-scan

  • --from-scan reads the live machine (ground truth is the running system)
  • --from-declaration reads the Shall files (ground truth is the declarations)
  • They can complement each other: scan first, export, then manage going forward with Shall

Output example (bash, from a module)

Given:

# modules/tools.txt
apt:ripgrep
cargo:bat
npm:typescript@version=>=5.0.0
absent:snap:firefox

# modules/services.txt
service:nginx @enabled=true

Output:

#!/usr/bin/env bash
# Generated by shall export --from-declaration --format bash

# Packages (apt)
sudo apt-get install -y ripgrep

# Packages (cargo)
cargo install bat

# Packages (npm)
sudo npm install -g 'typescript@>=5.0.0'

# Removals
sudo apt-get remove -y snap firefox || true

# Services
sudo systemctl enable --now nginx

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions