Hooks
Hooks allow you to run custom scripts before and after the dojang apply
command. This is useful for tasks such as:
- Installing dependencies before applying config files
- Reloading services after config changes
- Running setup scripts on first-time installation
- Cleaning up temporary files
Hook types
There are four types of hooks, executed in the following order:
| Hook type | When it runs |
|---|---|
pre-apply |
Before every apply, before file sync |
pre-first-apply |
Only on first apply, before file sync |
post-first-apply |
Only on first apply, after file sync |
post-apply |
After every apply, after file sync |
First apply is determined by the absence of the registry file (~/.dojang).
When you run dojang apply for the first time, all four hooks run in this
order:
pre-applypre-first-apply- (file synchronization)
post-first-applypost-apply
On subsequent applies, only pre-apply and post-apply run:
pre-apply- (file synchronization)
post-apply
Defining hooks
Hooks are defined in the hooks section of your dojang.toml manifest file.
Each hook type uses TOML's array of tables syntax ([[hooks.TYPE]]):
[[hooks.pre-apply]]
command = "/bin/echo"
args = ["Setting up..."]
[[hooks.post-apply]]
command = "/usr/bin/systemctl"
args = ["--user", "restart", "my-service"]
You can define multiple hooks of the same type. They will be executed in the order they are defined.
Hook fields
-
command(string, required): The path to the executable to run. This must be an absolute path or a command available in$PATH. -
args(array of strings, optional): Arguments to pass to the command. Defaults to an empty array. -
when(string, optional): An environment predicate expression. The hook only runs if the condition is satisfied. Defaults to always run. -
working-directory(string, optional): The working directory for the hook. Defaults to the repository directory. -
ignore-failure(boolean, optional): Iftrue, Dojang continues even if the hook exits with a non-zero status. Defaults tofalse.
Conditional hooks
You can use the when field to run hooks only on certain environments:
[[hooks.post-apply]]
command = "/usr/bin/systemctl"
args = ["--user", "restart", "dunst"]
when = "os = linux"
[[hooks.post-apply]]
command = "/usr/bin/killall"
args = ["NotificationCenter"]
when = "os = macos"
Environment variables
The following environment variables are available to hooks:
| Variable | Description |
|---|---|
DOJANG_REPOSITORY |
Absolute path to the repository directory |
DOJANG_MANIFEST |
Path to the manifest file (dojang.toml) |
DOJANG_DRY_RUN |
1 if running in dry-run mode, 0 otherwise |
DOJANG_OS |
Current operating system identifier |
DOJANG_ARCH |
Current processor architecture identifier |
Dry-run mode
When running dojang apply --dry-run, hooks are not executed. Instead,
Dojang prints what would be run:
Note: Would run hook: /bin/echo Setting up...
Error handling
If a hook exits with a non-zero status, Dojang stops and exits with
exit code 40 (hookFailedError). Use ignore-failure = true to continue
despite hook failures:
[[hooks.post-apply]]
command = "/usr/bin/optional-command"
args = []
ignore-failure = true
Examples
First-time setup
Run a setup script only on first apply:
[[hooks.pre-first-apply]]
command = "/bin/bash"
args = ["-c", "echo 'First time setup!' && ./setup.sh"]
Platform-specific hooks
Run different commands based on the operating system:
[[hooks.post-apply]]
command = "/usr/bin/brew"
args = ["bundle", "--file=Brewfile"]
when = "os = macos"
[[hooks.post-apply]]
command = "/usr/bin/apt"
args = ["install", "-y", "packages..."]
when = "os = linux"
Service reload
Reload a service after config changes:
[[hooks.post-apply]]
command = "/usr/bin/systemctl"
args = ["--user", "reload", "my-app"]
when = "os = linux"