The command line
The binary takes these flags and no subcommands. Everything else is in the configuration file, because a schedule is not something to retype.
ghchronicle -config /etc/ghchronicle/config.yamlEvery flag
Section titled “Every flag”| Flag | Default | What it does |
|---|---|---|
-setup | off | Ask what a working configuration needs, check each answer against the thing it names, and write it |
-config | config.yaml | Path to the configuration file |
-once | off | Run one sweep and exit instead of scheduling; a family that is not due by its cadence is still skipped |
-list | off | Print the repositories that would be collected, and which are set aside, then exit |
-version | off | Print the version, the commit and the build date, then exit |
-groups | off | Print the groups with the families in each, then exit |
-backfill | off | Reach as far back as each surface allows, waiting for the rate limit to reset rather than stopping |
-backfill- | none | Bound the backfill: a date (2024-01-01), a duration (720h), days (90d) or years (2y) |
-backfill- | off | Print how far the backfill in progress, and a migration’s refill, have got, then exit; it asks GitHub nothing, writes nothing, and needs no token |
-backfill- | 0 | After a backfill, or a migration’s refill, ends with families left, wait this long and go back for them, until a pass records nothing new; 0 does not go back |
-families | none | With -backfill, walk only these families, comma separated, the names -groups prints; a name that is not a family, or the flag without -backfill, is refused with 2 |
-publish- | off | Publish the Grafana dashboard and the datasource it reads from, then exit; it needs the grafana section, asks GitHub nothing and needs no token |
-uninstall | none | Remove what this put in place and exit: dashboard, data, state, all, comma separated; it lists and removes nothing without -yes |
-yes | off | Go ahead with -uninstall or -migrate rather than only listing what it would do |
-migrate | off | Print, for every configured store, what an earlier release left there in a shape this one no longer writes and what bringing it along would take, then exit; it changes nothing without -yes, and with it applies every pending change and reads what it cleared again |
-migrate- | off | With -migrate -yes, also apply a change to a store holding rows of accounts this configuration does not collect, or whose rows could not be compared with it; without -migrate it is refused with 2 |
-card | none | Run one sweep and write a summary SVG to this path; that sweep runs every family, whatever the cadences say |
-card- | off | With -card, write the SVG and nothing else: no sink is needed, none is written to, and the state file is left as it was |
-card- | auto | dark, light, auto, or both: the light card at -card and the dark one beside it with _dark before the extension, from one sweep |
-card- | once | once, loop or off; loop changes only terminal and ticker |
-card- | summary | Which of the thirteen layouts to draw |
-card- | none | Comma-separated fields the card shows, from the fields; empty means the layout’s own default |
-card- | the layout’s | Card width in pixels. Each layout draws between two ends of its own, which its section and -card-layouts both state; badge-row ignores it, its width following its pills |
-card- | 0.5 | How fast an animated layout plays, as a decimal from 0 to 1. 0 is the slowest animation and 1 the fastest; 0.5 is the pace every card has always been drawn at. 0 is not a still card, -card-motion off is |
-card- | off | Print the layouts with the fields and the widths each draws, then exit |
The five that print and exit
Section titled “The five that print and exit”-version, -groups, -card-layouts, -list and -backfill-status answer
and stop. The first three need no token and no configuration; -list reads the
configuration and asks GitHub which repositories the targets resolve to, which
is the cheap way to check a change before spending quota on a sweep.
-backfill-status reads the configuration to find the
backfill checkpoint
and prints how far that walk has got, and the refill of a migration after it
when one is in progress; it asks GitHub nothing, so it needs no token.
ghchronicle -versionghchronicle -groupsghchronicle -card-layoutsghchronicle -config config.yaml -listghchronicle -config config.yaml -backfill-statusWhat an upgrade left in the stores
Section titled “What an upgrade left in the stores”ghchronicle -config config.yaml -migrate-migrate checks every configured store against the list of changes the
binary carries, each a measurement an earlier release wrote under a key this
one no longer uses, and prints one block per store: what each change finds
there, the evidence, what bringing the store along would take and what would
be read again from GitHub. It changes nothing. The stores are asked questions,
GitHub is asked for the repository list alone, and the state file is read and
never written, so it exits 0 whatever it finds. Without a token it still runs
and says what it could not compare. Migrations
says how each store is decided and what each line means. When something is
pending, the plan ends with the command that applies it and with what a start
does about it under the migrate
setting.
That command, and every other one ghchronicle prints for you to run next (the
resume line of -backfill-status, the warnings of a start, the last line of
-setup), names the configuration as it was given, quoted when a shell would
read part of the path: in single quotes on Linux and macOS, and in double
quotes on Windows, the one form PowerShell and cmd both read as a single
argument.
ghchronicle -config config.yaml -migrate -yesWith -yes it prints the same plan and then applies every pending change, the
ones marked as needing somebody’s word too, reads what it cleared again from
GitHub, and says under the plan what happened to each. Reading it again is one
backfill of the families that write what was cleared, writing that alone into
the stores it was cleared from; -backfill-retry goes back for what it leaves,
and where a store kept a copy of the old rows, the report compares the two and
names what GitHub no longer serves. One cut short keeps a checkpoint of its
own, and the same command resumes it, even with nothing left to apply:
reading the history back.
A store holding rows of
accounts this configuration does not collect, or whose rows could not be
compared with it, is held back unless -migrate-others is given as well. It
needs a token and the repository list, and it takes the state file for as long
as it runs: with the service running it refuses, naming the process, and
changes nothing, so stop the service first, and pause a cron job running
-once. With the SQL sink on standard output, the plan and the report go to
standard error, so standard output is the SQL alone.
What it applies is recorded as it goes, so running it again after a failure
carries on without doing anything twice.
| Exit | When |
|---|---|
0 | -migrate, whatever it finds; -migrate -yes when everything pending was applied and read again, or nothing was |
1 | -migrate -yes left something: a store that refused or did not answer, one held back, a refill that did not finish; or it refused to start |
2 | A command line that does not parse, -migrate-others without -migrate among them |
The three ways to run a sweep
Section titled “The three ways to run a sweep”ghchronicle -config config.yaml # the loop: each family on its cadenceghchronicle -config config.yaml -once # one sweep, in the foreground, then exitghchronicle -config config.yaml -backfill # the history walk, onceThe loop is what a service runs. -once is what a scheduled job runs, and it
is also the quickest way to see what a configuration change does.
A backfill is a different intention and says so:
it walks every surface to the end and waits for a spent budget to refill rather
than giving up.
ghchronicle -config config.yaml -backfill -backfill-since 2y-families narrows a backfill to the families named, into every configured
store: some families only.
ghchronicle -config config.yaml -backfill -families discussions,outboundThe card, in one line
Section titled “The card, in one line”ghchronicle -config config.yaml -card profile.svg -card-only \ -card-layout github-stats -card-theme dark-card-only is the one combination worth remembering: it makes a run that
writes no points, so it needs no sink configured and a configuration that would
otherwise be refused at start-up is accepted.
The card has the layouts and the fields.
-card-width is the one flag that changes what a card says rather than only
how it looks, and on one layout only.
activity-heatmap spends the
room on data: sixteen weeks of the contribution calendar at its near end,
twenty-three at the width it declares, and the whole year the collector keeps
at its far end, which sits exactly where the year lands so the card is never
asked to fill space it has nothing for. Every other layout spreads the same
content over whatever width it is given, so widening one of those buys
proportions and not information, and its far end is only a guard against a
typo. A width outside a layout’s two ends is refused before the sweep runs,
naming both, and -card-layouts prints them for every layout.
ghchronicle -config config.yaml -card calendar.svg -card-only \ -card-layout activity-heatmap -card-width 700The speed, and what its slow end is not
Section titled “The speed, and what its slow end is not”-card-speed is one number for the whole card. Every animated layout scales
together, the continuous motions with the rest: the ticker’s band takes longer
to come round and the terminal’s cursor blinks more slowly at the same setting.
It is one knob and not one per layout because the motion the card has was paced
against itself, one layout’s cycle chosen beside another’s, and a reader who
finds the band slow finds the typing slow with it.
0.5 is the middle of the range and is exactly the card this renderer has
always drawn, to the byte, so leaving the flag out and asking for 0.5 are the
same command, and each end reaches the same distance from it: 0 draws the
animation twice as long as the default, 1 half as long as the default.
ghchronicle -config config.yaml -card slow.svg -card-only \ -card-layout ticker -card-motion loop -card-speed 0.25Where the rest lives
Section titled “Where the rest lives”Everything that is not in that table is a configuration key, not a flag: the file is the map of them.