Documentation tweaks

This commit is contained in:
Reid 'arrdem' McKenzie 2021-10-31 11:53:28 -06:00
parent d07eeb9199
commit 61b781206b
2 changed files with 55 additions and 22 deletions

View file

@ -4,23 +4,20 @@
An alternative to GNU Stow, more some notion of packages with dependencies and install scripts. An alternative to GNU Stow, more some notion of packages with dependencies and install scripts.
## Usage Think an Ansible or Puppet but anyarch and lite enough to check in with your dotfiles.
## Overview
Somewhat like Stow, Cram operates in terms of packages, which are directories with the following structure -
``` ```
# cram [--dry-run | --execute] <configdir> <destdir> /REQUIRES # A list of other packages this one requires.
$ cram ~/conf ~/ # --dry-run is the default /BUILD # 1. Perform any compile or package management tasks.
``` /PRE_INSTALL # 2. Any other tasks required before installation occurs.
/INSTALL # 3. Do whatever constitutes installation.
Cram operates in terms of packages, which are directories with the following structure - # This supercedes the default copying of files.
```
/REQUIRES # A list of other packages this one requires
/BUILD # 1. Perform any compile or package management tasks
/PRE_INSTALL # 2. Any other tasks required before installation occurs
/INSTALL # 3. Do whatever constitutes installation
/POST_INSTALL # 4. Any cleanup or other tasks following installation /POST_INSTALL # 4. Any cleanup or other tasks following installation
... # Any other files are treated as package contents.
... # Any other files are treated as package contents
``` ```
@ -34,3 +31,34 @@ Cram reads a config dir with three groups of packages
The intent of this tool is to keep GNU Stow's intuitive model of deploying configs via symlinks, and augment it with a useful pattern for talking about "layers" / "packages" of related configs. The intent of this tool is to keep GNU Stow's intuitive model of deploying configs via symlinks, and augment it with a useful pattern for talking about "layers" / "packages" of related configs.
Cram installs the package `hosts.d/$(hostname)`, and `profiles.d/default` by default. Cram installs the package `hosts.d/$(hostname)`, and `profiles.d/default` by default.
## Usage
```
$ cram apply [--dry-run|--execute] [--optimize] <configdir> <destdir>
```
The `apply` task applies a configuration to a destination directory.
The most common uses of this would be `--dry-run`, which functions as a `diff` or `--execute ~/conf ~/` for emulating Stow and installing dotfiles.
Cram always reads the `.cram.log` state file and diffs the current state against the configured state.
Files and directories no longer defined by the configured state are cleaned up automatically.
```
$ cram show <configdir>
```
The `list` task loads up and prints the `.cram.log` state file generated by any previous `cram apply --execute` so you can read a manifest of what cram thinks it did.
```
$ cram list <configdir>
```
The `show` task lists out all available packages (eg. packages, profiles, hosts, and subpackages) as a dependency graph.
## License
Copyright Reid 'arrdem' McKenzie, 31/10/2021.
Published under the terms of the MIT license.
See the included `LICENSE` file for more.

View file

@ -201,7 +201,7 @@ def cli():
@cli.command() @cli.command()
@click.option("--execute/--dry-run", default=False) @click.option("--execute/--dry-run", default=False)
@click.option("--state-file", default=".cram.log") @click.option("--state-file", default=".cram.log", type=Path)
@click.option("--optimize/--no-optimize", default=False) @click.option("--optimize/--no-optimize", default=False)
@click.argument("confdir", type=Path) @click.argument("confdir", type=Path)
@click.argument("destdir", type=Path) @click.argument("destdir", type=Path)
@ -211,10 +211,11 @@ def apply(confdir, destdir, state_file, execute, optimize):
# Resolve the two input paths to absolutes # Resolve the two input paths to absolutes
root = confdir.resolve() root = confdir.resolve()
dest = destdir.resolve() dest = destdir.resolve()
statef = root / state_file if not state_file.is_absolute():
state_file = root / state_file
new_fs = build_fs(root, dest) new_fs = build_fs(root, dest)
old_fs = load_fs(statef) old_fs = load_fs(state_file)
# Middleware processing of the resulting filesystem(s) # Middleware processing of the resulting filesystem(s)
executable_fs = scrub(old_fs, new_fs) executable_fs = scrub(old_fs, new_fs)
@ -226,7 +227,7 @@ def apply(confdir, destdir, state_file, execute, optimize):
if execute: if execute:
executable_fs.execute() executable_fs.execute()
with open(statef, "wb") as fp: with open(state_file, "wb") as fp:
pickle.dump(new_fs._log, fp) pickle.dump(new_fs._log, fp)
else: else:
@ -235,12 +236,14 @@ def apply(confdir, destdir, state_file, execute, optimize):
@cli.command() @cli.command()
@click.option("--state-file", default=".cram.log") @click.option("--state-file", default=".cram.log", type=Path)
@click.argument("confdir", type=Path) @click.argument("confdir", type=Path)
def show(confdir, state_file): def show(confdir, state_file):
"""List out the last `apply` state in the <confdir>/.cram.log or --state-file."""
root = confdir.resolve() root = confdir.resolve()
statef = root / state_file if not state_file.is_absolute():
fs = load_fs(statef) state_file = root / state_file
fs = load_fs(state_file)
for e in fs._log: for e in fs._log:
print(*e) print(*e)
@ -248,12 +251,14 @@ def show(confdir, state_file):
@cli.command() @cli.command()
@click.argument("confdir", type=Path) @click.argument("confdir", type=Path)
def list(confdir): def list(confdir):
"""List out packages, profiles, hosts and subpackages in the <confdir>."""
packages = load_config(confdir) packages = load_config(confdir)
for pname in sorted(packages.keys()): for pname in sorted(packages.keys()):
p = packages[pname] p = packages[pname]
print(f"{pname}:") print(f"{pname}:")
for d in p.requires(): for d in p.requires():
print(f" - {d}") print(f"- {d}")
if __name__ == "__main__" or 1: if __name__ == "__main__" or 1:
logging.basicConfig( logging.basicConfig(