Cram has graduated
This commit is contained in:
parent
983635eb4f
commit
88f35e4798
1 changed files with 0 additions and 127 deletions
|
@ -1,127 +0,0 @@
|
|||
# Cram
|
||||
|
||||
Cram has graduated [to its own repo](https://github.com/arrdem/cram)!
|
||||
|
||||
|
||||
------
|
||||
|
||||
|
||||
> To force (people or things) into a place or container that is or appears to be too small to contain them.
|
||||
|
||||
An alternative to GNU Stow, more some notion of packages with dependencies and install scripts.
|
||||
|
||||
Think an Ansible, Puppet or even NixOS but anyarch and lite enough to check in with your dotfiles.
|
||||
|
||||
## Overview
|
||||
|
||||
Cram operates on a directory of packages called `packages.d/`, and two directories of metapackages called `profiles.d` and `hosts.d`.
|
||||
|
||||
### Packages
|
||||
|
||||
A Cram package consists of a directory containing a `pkg.toml` file with the following format -
|
||||
|
||||
```toml
|
||||
[cram]
|
||||
version = 1
|
||||
|
||||
[package]
|
||||
# The package.require list names depended artifacts.
|
||||
[[package.require]]
|
||||
name = "packages.d/some-other-package"
|
||||
|
||||
# (optional) The package.build list enumerates either
|
||||
# inline scripts or script files. These are run as a
|
||||
# package is 'built' before it is installed.
|
||||
[[package.build]]
|
||||
run = "some-build-command"
|
||||
|
||||
# (optional) Hook script(s) which occur before installation.
|
||||
[[package.pre_install]]
|
||||
run = "some-hook"
|
||||
|
||||
# (optional) Override installation scrpt(s).
|
||||
# By default, everthing under the package directory
|
||||
# (the `pkg.toml` excepted) treated is as a file to be
|
||||
# installed and stow is emulated using symlinks.
|
||||
[[package.install]]
|
||||
run = "some-install-command"
|
||||
|
||||
# (optional) Hook script(s) which after installation.
|
||||
[[package.post_install]]
|
||||
run = "some-other-hook"
|
||||
```
|
||||
|
||||
To take a somewhat real example from my own dotfiles -
|
||||
|
||||
```shell
|
||||
$ tree -a packages.d/tmux
|
||||
packages.d/tmux
|
||||
├── pkg.toml
|
||||
└── .tmux.conf
|
||||
```
|
||||
|
||||
This TMUX package provides only my `.tmux.conf` file, and a stub `pkg.toml` that does nothing.
|
||||
A fancier setup could use `pkg.toml` to install TMUX either as a `pre_install` task or by using a separate TMUX package and providing the config in a profile.
|
||||
|
||||
### Metapackages
|
||||
|
||||
Writing lots of packages gets cumbersome quickly, as does managing long lists of explicit dependencies.
|
||||
To try and manage this, Cram provides metapackages - packages which contain no stowable files, but instad contain subpackages.
|
||||
|
||||
To take a somewhat real example from my own dotfiles -
|
||||
|
||||
```shell
|
||||
$ tree -a -L 1 profiles.d/macos
|
||||
profiles.d/macos
|
||||
├── pkg.toml
|
||||
├── emacs/
|
||||
├── homebrew/
|
||||
└── zsh/
|
||||
```
|
||||
|
||||
The `profiles.d/macos` package depends AUTOMATICALLY on the contents of the `profiles.d/macos/emacs`, `profiles.d/macos/homebrew` and `profiles.d/macos/zsh` packages, which are normal packages.
|
||||
These sub-packages can have normal dependencies on other packages both within and without the profile and install files or run scripts.
|
||||
|
||||
Profiles allow users to write groups of related packages, especially configs, which go together and allows for scoped reuse of meaningful names.
|
||||
|
||||
Likewise the `hosts.d/` tree allows users to store host-specific packages.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
$ cram apply [--dry-run|--execute] [--optimize] [--require <package>] <configdir> <destdir>
|
||||
```
|
||||
|
||||
The `apply` task applies a configuration to a destination directory.
|
||||
The most common uses of this would be `--dry-run` (the default), which functions as a `diff` or `--execute ~/conf ~/` for emulating Stow and installing dotfiles.
|
||||
|
||||
By default `cram` installs two packages - `profiles.d/default` and `hosts.d/$(hostname -s)`.
|
||||
This default can be overriden by providing `--require <package>` one or more times to enumerate specific packages to install.
|
||||
|
||||
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 state <configdir>
|
||||
```
|
||||
|
||||
The `state` 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.
|
||||
This is useful because `cram` attempts to optimize repeated executions and implement change detection using the state file.
|
||||
|
||||
This cache can be busted if needed by using `apply --execute --no-optimize`, which will cause cram to take all actions it deems presently required.
|
||||
This can result in dangling symlinks in the filesystem.
|
||||
|
||||
```
|
||||
$ cram list <configdir> [package]
|
||||
```
|
||||
|
||||
The `list` task lists out all available packages (eg. packages, profiles, hosts, and subpackages) as a dependency graph.
|
||||
When provided a specific package, the details of that package (its requirements and installation task log) will be printed.
|
||||
|
||||
## License
|
||||
|
||||
Copyright Reid 'arrdem' McKenzie, 15/02/2022.
|
||||
|
||||
Published under the terms of the Anticapitalist Software License (https://anticapitalist.software).
|
||||
|
||||
Unlimited commercial licensing is available at nominal pricing.
|
Loading…
Reference in a new issue