Documentation
¶
Overview ¶
Package settings holds the few choices that belong to a person rather than to a board.
It exists because two of them arrived with the ticket refs: which remote the refs go to, and whether an assignment pops up a desktop notification. Neither belongs in the repository — one teammate wanting to be notified says nothing about another, and a remote name is a property of a clone, not of the project.
That last point is why the remote here is only a default. This file is read by every board opened on the machine, so "remote": "upstream" — right for the one checkout that has a fork as its origin — reached every other board too and took down every ref command on repositories that have no upstream at all. The name of a remote is a property of one clone, so that is where the answer for one board lives: git config jaira.remote <name>, in the clone's own config. Not a file in .jaira/, which would be committed and therefore wrong for the next person, whose clone may know the same repository by another name; and not a path-keyed section here, which git worktrees would split into several entries for one clone.
RemoteFor is the only way to ask: it resolves the two against each other. See its comment for the order and for why a per-board name never falls back. RemoteSourceFor is the same ladder when the caller also has to say which step answered.
The file is ~/.jaira/settings.json, beside projects.json, and every field has a working default: a missing file, an unreadable one and an empty one all mean "the defaults", because settings a user never opened must never be the reason a board does not start.
Index ¶
- Constants
- func Path() string
- func Save(s Settings) error
- type Settings
- func (s Settings) FetchInterval() time.Duration
- func (s Settings) Landing(remote string, remoteHead func() string) []string
- func (s Settings) LandingGraceInterval() time.Duration
- func (s Settings) LogbookWindow() int
- func (s Settings) NotifyEnabled() bool
- func (s Settings) RemoteFor(dir string) string
- func (s Settings) RemoteSourceFor(dir string) (name, source string)
- func (s Settings) SnapshotBranchName() string
- func (s Settings) SnapshotInterval() time.Duration
Constants ¶
const DefaultLandingGrace = 3 * 24 * time.Hour
DefaultLandingGrace is how long a finished ticket may take to arrive before it is worth mentioning.
Three days, chosen against how long a review actually takes here rather than as a round number: a week is long enough that a forgotten branch stops being news by the time anybody hears about it.
const DefaultLogbookDays = 28
DefaultLogbookDays is the logbook window nobody chose: four weeks, what 'jaira logbook' listed before the window became a setting.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Settings ¶
type Settings struct {
// Remote is where ticket refs are pushed and fetched. Empty means origin.
Remote string `json:"remote,omitempty"`
// Notify turns the desktop notification for an assignment off. It is
// phrased as the negative so that the zero value — a file that does not
// mention it, or no file at all — leaves notifications on: the feature was
// asked for, and a default that silently withholds it would answer the
// request with nothing.
NotifyOff bool `json:"notify-off,omitempty"`
// Hook is a script called when a ticket moves or is claimed, for immediate
// delivery through whatever the user already uses (a Slack webhook,
// ntfy.sh, Telegram). jaira only calls it and brings no dependency of its
// own; an empty value calls nothing.
Hook string `json:"hook,omitempty"`
// LandingBranches are the branches whose contents mean a ticket has
// arrived: filed away in one of them, it is finished for everybody and its
// ref has done its job.
//
// A list with globs rather than one "main branch", because there is no
// answer to what the important branch is called — main, master, develop, a
// release line — and a list turns a guess into a setting. Empty falls back
// to the remote's own HEAD, and if that cannot be resolved either, nothing
// is ever removed.
LandingBranches []string `json:"landing-branches,omitempty"`
// SnapshotBranch holds the board as files, as a backup for whoever clones
// for the first time and has no refs yet. Empty means jaira/board.
SnapshotBranch string `json:"snapshot-branch,omitempty"`
// SnapshotEvery is how old the backup may get, as a duration ("72h").
// Empty means three days: every participant's clone holds the refs, so the
// board survives any one machine, and this is for the slow cases only.
SnapshotEvery string `json:"snapshot-every,omitempty"`
// FetchEvery is how often the ticket refs are brought up to date in the
// background, as a duration ("10m"). Empty means ten minutes.
//
// One setting for the CLI and the board alike. They used to disagree — the
// board had its own hard-wired minute — and somebody who changed this would
// have found the board carrying on at its own pace.
FetchEvery string `json:"fetch-every,omitempty"`
// LandingGrace is how long a finished ticket may go without arriving in a
// landing branch before jaira mentions it, as a duration ("72h"). Empty
// means three days.
LandingGrace string `json:"landing-grace,omitempty"`
// LogbookDays is how many days back the board shows what went into the
// logbook, under the terminal lane, and how far 'jaira logbook' lists
// without --since. A pointer because 0 is a real answer — "show none" —
// and has to be told apart from a file that never mentions it, which
// means DefaultLogbookDays. Read it through LogbookWindow.
LogbookDays *int `json:"logbook-days,omitempty"`
}
Settings is the whole file.
func Load ¶
func Load() Settings
Load returns the settings, or the defaults for anything missing.
An unreadable or malformed file is deliberately not an error: it is one person's preferences, and refusing to open a board over it would trade a small annoyance for a total one.
func (Settings) FetchInterval ¶
FetchInterval returns how often the refs are refreshed in the background, for the CLI and the board alike.
func (Settings) Landing ¶
Landing returns the branches to check for a landed ticket, as revisions on the remote.
The configured list wins over the remote's HEAD, and that order matters: the HEAD is the hosting provider's default, not necessarily the branch a team cares about. Both are prefixed with the remote, since what counts is what has arrived where everybody can see it — not what has landed in somebody's local copy of a branch.
func (Settings) LandingGraceInterval ¶
LandingGraceInterval returns that, or whatever the settings say instead.
func (Settings) LogbookWindow ¶ added in v0.3.4
LogbookWindow returns how many days of the logbook the board shows and 'jaira logbook' lists: the setting, or DefaultLogbookDays when it is absent or negative. Zero means none on the board — and everything in the listing, which is what --since 0 already means there.
func (Settings) NotifyEnabled ¶
NotifyEnabled reports whether an assignment should raise a desktop notification.
func (Settings) RemoteFor ¶ added in v0.2.1
RemoteFor returns the remote this board's ticket refs travel on.
The order, and why each step is where it is:
- git config jaira.remote in the clone. Somebody decided this for this repository, so it is used as given and never falls back. If that remote is gone, the ref command stops and says so — see Repo.Usable. A silent fallback here would be the expensive kind of wrong: in a fork, origin is the fork, and quietly pushing a ticket ref there loses it exactly where nobody looks.
- The machine-wide "remote" in settings.json, if this repository has a remote by that name. It is a default for every board, so it applies here only when it is true here.
- The repository's only remote, when it has exactly one. There is nothing to get wrong: one remote is where anything can go. This is what makes a plain single-remote checkout work without anybody configuring anything, even while settings.json names a remote it has never heard of.
- Otherwise the configured name is returned unchanged, so the failure is loud and names it. Several remotes and none of them the one asked for is ambiguous, and guessing among them is the fork case again.
func (Settings) RemoteSourceFor ¶ added in v0.2.1
RemoteSourceFor is RemoteFor with the step of the ladder that answered, in words a person can read.
The two are one function because a command that explains which remote is used must not compute the name a second time: the ladder has four steps, it is changed as one thing, and a second copy of it means the command whose only job is to tell the truth about the remote is the command that names a different one than the code that failed.
func (Settings) SnapshotBranchName ¶
SnapshotBranchName returns the configured snapshot branch, or the default.
func (Settings) SnapshotInterval ¶
SnapshotInterval returns how old a snapshot may get.