Skip to content

The repo is the .jira.d

 2 min jira-nice makes its own checkout the go-jira config directory with one symlink, and inherits a parent repo’s Jira defaults with one extra glob path.
Published

Jun 4, 2018

go-jira reads its configuration from a .jira.d/ directory. jira-nice, my go-jira personalization layer, makes the checkout itself be that directory, and three symlinks carry the whole architecture:

.jira.d -> .
config.yml -> config.sh
Makefile -> bin/jira-nice-installer

I used jira-nice heavily until another tool replaced it. I do not remember actually using this repository-local mode. It is a capability the code implemented, not a claim about how I configured my daily work.

.jira.d -> . means the repo root answers for the config directory. go-jira finds .jira.d and is satisfied; the installer can name every file by its installed path (.jira.d/config.sh resolves through the symlink to ./config.sh); and the install copy loop tests -ef first, so installing the repo into itself is a clean no-op—the checkout is its own install layout.

config.yml -> config.sh exploits go-jira executing any config file that has the exec bit and parsing its stdout: the “YAML file” is a bash program. What that program does is scan two roots:

DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
CONFIGS=($(set +f; printf '%s\n' $DIR/{,../.jira.}config/[0-9][0-9]-*))

$DIR is wherever config.sh lives—the .jira.d. The brace expansion yields config/ and ../.jira.config/: the repo’s own numbered fragments, then the parent directory’s. That second path is Embedded mode from the README: clone or submodule jira-nice inside a parent git repo and .jira.d/../.jira.config lands on the parent’s config directory, so the parent’s Jira defaults—endpoint, project, custom commands—merge in with no flag and no environment variable. Drop the same tool into a different repo and it answers for that repo’s project.

Fragments are named NN-name.* and folded in numeric order. Each numeric prefix is processed once—a stable numeric sort -u keeps the first root’s file when both define the same prefix—and each survivor is dispatched on what it is: executable, run it; .yml, convert it; anything else, jq -c . it. The stream folds with one jq program:

jq -c 'reduce (., inputs) as $config ({}; . * $config)'

* is jq’s recursive object merge, so later fragments deep-merge over earlier ones—a parent overrides a repo default by choosing a bigger prefix. The password or API token never rides in the fragments; password-source: keyring pushes that secret resolution to the OS.

The dependency is go-jira’s execute-the-config behavior staying stable. jira-nice as a whole ran as a daily driver for about six years. Two other pieces of the same repo are documented in atexit for bash and shutils.jq.