Documentation
¶
Overview ¶
Package standup groups one person's activity in a checkout by task: the commits they authored and the PRs or MRs they opened, reviewed or merged, collected by `f10 standup` from git and the host CLI. Group and Merge are pure functions, so the same history gives the same report byte for byte: Group reads one repository, Merge joins repositories on one tracker by task id.
The JSON shape (Standup) is a contract for the /f10:standup skill and outside consumers, documented in docs/cli.md. A breaking change bumps Schema.
Index ¶
- Constants
- func ActivityTimes(r Report) []time.Time
- func CheckGlob(pattern string) error
- func Days(times []time.Time, loc *time.Location) []string
- func FallbackFrom(now time.Time) time.Time
- func Glob(pattern, p string) bool
- func LastWorkingDay(now time.Time, w Workdays, activity []time.Time) time.Time
- func NeedsCI(c Commit, extra []string) bool
- func Resolve(now, since time.Time, week bool, last *Last) (time.Time, string)
- func SetDays(s *Standup, loc *time.Location)
- func UpkeepPath(p string) bool
- type Action
- type CI
- type Commit
- type Day
- type File
- type ForcePush
- type HostPR
- type Input
- type Last
- type Other
- type PR
- type PRCommit
- type Project
- type Repo
- type Report
- type Review
- type ReviewedPR
- type Standup
- type Task
- type Tracker
- type User
- type Workdays
Constants ¶
const ( PeriodLastStandup = "last_standup" PeriodLastWorkingDay = "last_working_day" PeriodSince = "since" PeriodWeek = "week" )
How a report's start was chosen, echoed as its period.
const ( StateStarted = "started" StateInProgress = "in progress" StateInReview = "in review" StateShipped = "shipped" StateClosed = "closed" )
Where a PR or a task ended the period, least advanced first. Closed is a PR closed unmerged; it never decides a task's state while anything else does.
const ( HostOpen = "open" HostMerged = "merged" HostClosed = "closed" )
The host states a PR arrives in, normalised from gh's and glab's spellings.
const ( ActionReviewed = "reviewed" ActionMerged = "merged" )
What the user did to someone else's PR.
const ( ClassWork = "work" ClassUpkeep = "upkeep" )
The class of one item of activity, and of a task as a whole.
const ( UpkeepBaseMerge = "base-merge" // a merge of the base branch into the task's UpkeepRebase = "rebase" // a force-push that kept every patch UpkeepFiles = "files" // only lockfiles, generated files or snapshots UpkeepCIFix = "ci-fix" // a small test-only change after red CI )
Why an item is upkeep.
const FallbackDays = 14
FallbackDays is how far back a run with no stored standup looks for the last working day with activity.
const Schema = 2
Schema is the version of the report's JSON shape.
Variables ¶
This section is empty.
Functions ¶
func ActivityTimes ¶
ActivityTimes is every time in a report the user did something within its period: commits, PRs opened or merged, force-pushes, reviews and merges of others'.
func CheckGlob ¶
CheckGlob refuses a pattern Glob cannot read: a malformed segment, or an absolute path, since paths are relative to the repository root.
func FallbackFrom ¶
FallbackFrom is the start of the window LastWorkingDay looks through.
func Glob ¶
Glob matches a slash-separated path the way .gitignore reads a pattern: one without a slash matches the base name in any directory, one with a slash the whole path, and a `**` segment any number of directories.
func LastWorkingDay ¶
LastWorkingDay is local midnight of the latest working day before today with activity at any of the times. With none in the window, it is the previous working day, so a first run never reaches back weeks.
func NeedsCI ¶
NeedsCI reports whether c is a CI fix if its parent's CI was red: the collector asks the host only for these.
func Resolve ¶
Resolve picks the period's start: an explicit since, the last week, or the last reported standup. A standup reported earlier today gives its own start again, so a second report the same day is not empty. With nothing stored it returns PeriodLastWorkingDay and a zero time, for the caller to settle with LastWorkingDay once it has the activity. Days are in now's location.
func SetDays ¶ added in v0.34.0
SetDays fills in the local dates with activity: the report's, across every project, each task's with that day's class, and each reviewed PR's. All three read the same times, so a task's day is always one of the report's. It runs after Merge, so a task merged across repositories gets the days of all of them.
func UpkeepPath ¶ added in v0.45.0
UpkeepPath reports whether a path is a lockfile, generated code or a snapshot: a change nobody wrote by hand.
Types ¶
type CI ¶
CI is how the checks on a commit ended: red when any failed, and when the last failure finished.
type Commit ¶
type Commit struct {
SHA string `json:"sha"`
Subject string `json:"subject"`
At time.Time `json:"at"` // author date
Branch string `json:"branch"` // the branch it was reached from, remote prefix dropped
Parents []string `json:"parents"`
Class string `json:"class"`
Upkeep string `json:"upkeep,omitempty"`
Repo string `json:"repo"`
// What upkeep.go decides the class from, collected beside the commit.
Files []File `json:"-"`
BaseMerge bool `json:"-"` // a merge whose second parent is on the base's first-parent line
ParentCI *CI `json:"-"` // nil unless asked and the host had checks
}
A Commit is one commit the user authored in the period.
type Day ¶ added in v0.34.0
A Day is a local date a task had activity on, and the class of that day's activity alone: a task worked on Monday and only caught up with its base on Tuesday is work on one and upkeep on the other.
type File ¶
type File struct {
Path string
Added int
Deleted int
Binary bool
Generated bool // marked linguist-generated, or carrying Go's generated header
}
A File is one path a commit changed, as numstat counts it.
type ForcePush ¶
type ForcePush struct {
At time.Time `json:"at"`
Before string `json:"before"`
After string `json:"after"`
Class string `json:"class"`
Upkeep string `json:"upkeep,omitempty"`
SamePatches *bool `json:"-"`
}
A ForcePush is one force-push the user made to their own PR. SamePatches is whether the commits before and after carry the same patches; nil is unknown, when either side is not in the local object store.
type HostPR ¶
type HostPR struct {
Number int
Title string
URL string
Status string // HostOpen, HostMerged or HostClosed
Draft bool
Empty bool // no changes yet: no changed files on GitHub, no commits on GitLab
Head string
Base string
Author string
CreatedAt time.Time
MergedAt time.Time // zero unless merged
MergedBy string
Commits []PRCommit // the commits the host lists for it; read for the user's own PRs only
MergeSHA []string // the merge and squash commits it landed as
Reviews []Review // read for other people's PRs only
ForcePushes []ForcePush // the user's own, on their own PRs
}
A HostPR is a PR or MR as the host reported it, before grouping.
type Input ¶
type Input struct {
Prefix string // task id prefix; empty matches no id
Since time.Time
Repo string // the repository's name, stamped on every PR and commit
Project string // the project Merge lists it under: the repo, or a shared tracker's prefix
Tracker Tracker // the tracker its task ids belong to
Checkout string
Host string // "gh", "glab", or "" with no host
DefaultBranch string // local name, "main"
User User
Commits []Commit // the user's, from git
PRs []HostPR // the user's own and the ones they reviewed or merged
Bases map[string]string // head branch to the base branch `f10 start --after` recorded
UpkeepPaths []string // the project's globs, on top of the default upkeep paths
}
Input is everything Group needs, already collected.
type PR ¶
type PR struct {
Repo string `json:"repo"`
Number int `json:"number"`
Title string `json:"title"`
URL string `json:"url"`
State string `json:"state"`
Draft bool `json:"draft"`
Head string `json:"head"`
Base string `json:"base"`
BasePR int `json:"base_pr,omitempty"`
CreatedAt time.Time `json:"created_at"`
MergedAt *time.Time `json:"merged_at,omitempty"`
Commits []Commit `json:"commits"`
ForcePushes []ForcePush `json:"force_pushes"`
}
PR is one of the user's PRs in the report.
type PRCommit ¶
A PRCommit is one commit a PR lists. A rebase merge lands it on the default branch under a new sha, keeping its author date and subject.
type Project ¶ added in v0.34.0
type Project struct {
Name string `json:"name"`
Tracker Tracker `json:"tracker"`
Repos []Repo `json:"repos"`
Tasks []Task `json:"tasks"`
Other Other `json:"other"`
Reviewed []ReviewedPR `json:"reviewed"`
}
A Project is the activity on one tracker, across its repositories.
type Repo ¶ added in v0.34.0
type Repo struct {
Name string `json:"name"`
Checkout string `json:"checkout"`
Host *string `json:"host"`
User User `json:"user"`
}
A Repo is one repository a project's activity came from.
type Report ¶
type Report struct {
Since time.Time
Repo string
Project string
Tracker Tracker
Checkout string
Host *string
User User
Tasks []Task
Other Other
Reviewed []ReviewedPR
}
Report is the activity in one repository, before Merge joins it to the others on its tracker.
type Review ¶
A Review is one review event on a PR: a submitted review, an approval or a comment, by anyone. Group keeps the user's.
type ReviewedPR ¶
type ReviewedPR struct {
Repo string `json:"repo"`
Number int `json:"number"`
Title string `json:"title"`
URL string `json:"url"`
State string `json:"state"`
Author string `json:"author"`
Actions []Action `json:"actions"`
Days []string `json:"days"` // local dates of the actions; the command sets it
}
ReviewedPR is someone else's PR the user reviewed or merged.
type Standup ¶ added in v0.34.0
type Standup struct {
Schema int `json:"schema"`
Since time.Time `json:"since"`
Period string `json:"period,omitempty"` // how since was chosen
Days []string `json:"days"` // local dates with activity; SetDays sets it
Projects []Project `json:"projects"`
}
Standup is the report `f10 standup --json` prints: one period, the projects in the order their first repository was given.
func Merge ¶ added in v0.34.0
Merge joins per-repository reports, read over one period, into projects, one per tracker key, and the tasks in a project by id. A task's PRs stay in chain order per repository, repository by repository: a base_pr is a number in one repository, so a chain never crosses two.
type Task ¶
type Task struct {
ID string `json:"id"`
Title string `json:"title"`
State string `json:"state"`
Class string `json:"class"`
After string `json:"after,omitempty"`
// Riders are the tasks a bundle's branch ships beside this one, its lead
Riders []string `json:"riders,omitempty"`
Days []Day `json:"days"` // the command sets it
PRs []PR `json:"prs"`
Commits []Commit `json:"commits"` // commits on no PR of the user's
}
Task is the activity carrying one task id.
type Tracker ¶ added in v0.34.0
type Tracker struct {
Kind string `json:"kind"`
Prefix string `json:"prefix"`
Key string `json:"-"`
}
A Tracker is where a repository's task ids live. Repositories with the same Key share their ids, so the same id in each is one task; the command sets the key, since only it knows whether a tracker is the repository's own issues.