Skip to content

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.

Terminal window
ghchronicle -config /etc/ghchronicle/config.yaml
FlagDefaultWhat it does
-setupoffAsk what a working configuration needs, check each answer against the thing it names, and write it
-configconfig.yamlPath to the configuration file
-onceoffRun one sweep and exit instead of scheduling; a family that is not due by its cadence is still skipped
-listoffPrint the repositories that would be collected, and which are set aside, then exit
-versionoffPrint the version, the commit and the build date, then exit
-groupsoffPrint the groups with the families in each, then exit
-backfilloffReach as far back as each surface allows, waiting for the rate limit to reset rather than stopping
-backfill-sincenoneBound the backfill: a date (2024-01-01), a duration (720h), days (90d) or years (2y)
-backfill-statusoffPrint 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-retry0After 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
-familiesnoneWith -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-dashboardoffPublish the Grafana dashboard and the datasource it reads from, then exit; it needs the grafana section, asks GitHub nothing and needs no token
-uninstallnoneRemove what this put in place and exit: dashboard, data, state, all, comma separated; it lists and removes nothing without -yes
-yesoffGo ahead with -uninstall or -migrate rather than only listing what it would do
-migrateoffPrint, 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-othersoffWith -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
-cardnoneRun one sweep and write a summary SVG to this path; that sweep runs every family, whatever the cadences say
-card-onlyoffWith -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-themeautodark, light, auto, or both: the light card at -card and the dark one beside it with _dark before the extension, from one sweep
-card-motiononceonce, loop or off; loop changes only terminal and ticker
-card-layoutsummaryWhich of the thirteen layouts to draw
-card-fieldsnoneComma-separated fields the card shows, from the fields; empty means the layout’s own default
-card-widththe layout’sCard 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-speed0.5How 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-layoutsoffPrint the layouts with the fields and the widths each draws, then 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.

Terminal window
ghchronicle -version
ghchronicle -groups
ghchronicle -card-layouts
ghchronicle -config config.yaml -list
ghchronicle -config config.yaml -backfill-status
Terminal window
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.

Terminal window
ghchronicle -config config.yaml -migrate -yes

With -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.

ExitWhen
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
2A command line that does not parse, -migrate-others without -migrate among them
Terminal window
ghchronicle -config config.yaml # the loop: each family on its cadence
ghchronicle -config config.yaml -once # one sweep, in the foreground, then exit
ghchronicle -config config.yaml -backfill # the history walk, once

The 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.

Terminal window
ghchronicle -config config.yaml -backfill -backfill-since 2y

-families narrows a backfill to the families named, into every configured store: some families only.

Terminal window
ghchronicle -config config.yaml -backfill -families discussions,outbound
Terminal window
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.

Terminal window
ghchronicle -config config.yaml -card calendar.svg -card-only \
-card-layout activity-heatmap -card-width 700

-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.

Terminal window
ghchronicle -config config.yaml -card slow.svg -card-only \
-card-layout ticker -card-motion loop -card-speed 0.25

Everything that is not in that table is a configuration key, not a flag: the file is the map of them.

Written and maintained by
MIT licenceRelease history