standup

package
v0.56.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 6, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package standup groups one person's activity in a checkout by task, for `f10 standup`. Group and Merge are pure, so the same history gives the same report byte for byte. The JSON shape (Standup) is a contract documented in docs/cli.md; a breaking change bumps Schema.

Index

Constants

View Source
const (
	PeriodLastStandup    = "last_standup"
	PeriodLastWorkingDay = "last_working_day"
	PeriodSince          = "since"
	PeriodWeek           = "week"
)

How a report's start was chosen, echoed as its period.

View Source
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 never decides a task's state while anything else does.

View Source
const (
	HostOpen   = "open"
	HostMerged = "merged"
	HostClosed = "closed"
)

The host states a PR arrives in, normalised from gh's and glab's spellings.

View Source
const (
	ActionReviewed = "reviewed"
	ActionMerged   = "merged"
)
View Source
const (
	ClassWork   = "work"
	ClassUpkeep = "upkeep"
)

The class of one item of activity, and of a task as a whole.

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

View Source
const FallbackDays = 14

FallbackDays is how far back a run with no stored standup looks for activity.

View Source
const Schema = 2

Schema is the version of the report's JSON shape.

Variables

This section is empty.

Functions

func ActivityTimes

func ActivityTimes(r Report) []time.Time

ActivityTimes is every time the user did something in the report's period.

func CheckGlob

func CheckGlob(pattern string) error

CheckGlob refuses a pattern Glob cannot read: a malformed segment, or an absolute path, since paths are relative to the repository root.

func Days

func Days(times []time.Time, loc *time.Location) []string

Days is the dates in loc the times fall on, ascending, each once.

func FallbackFrom

func FallbackFrom(now time.Time) time.Time

FallbackFrom is the start of the window LastWorkingDay looks through.

func Glob

func Glob(pattern, p string) bool

Glob matches the way .gitignore reads a pattern: no slash matches the base name anywhere, a slash the whole path, `**` any number of directories.

func LastWorkingDay

func LastWorkingDay(now time.Time, w Workdays, activity []time.Time) time.Time

LastWorkingDay is local midnight of the latest working day before today with activity; with none in the window, the previous working day, so a first run never reaches back weeks.

func NeedsCI

func NeedsCI(c Commit, extra []string) bool

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

func Resolve(now, since time.Time, week bool, last *Last) (time.Time, string)

Resolve picks the period's start. 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.

func SetDays added in v0.34.0

func SetDays(s *Standup, loc *time.Location)

SetDays fills in the local dates with activity, report-wide and per task and reviewed PR, from the same times, so a task's day is always one of the report's. It runs after Merge, so a merged task gets every repository's days.

func UpkeepPath added in v0.45.0

func UpkeepPath(p string) bool

UpkeepPath reports a path nobody writes by hand: a lockfile, generated code or a snapshot.

Types

type Action

type Action struct {
	Kind string    `json:"kind"`
	At   time.Time `json:"at"`
}

Action is one thing the user did to someone else's PR.

type CI

type CI struct {
	Red bool
	At  time.Time
}

CI is how the checks on a commit ended, 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

type Day struct {
	Date  string `json:"date"`
	Class string `json:"class"`
}

A Day is a local date a task had activity on, with that day's class alone: work on Monday and a base merge on Tuesday is work on one, 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 to the user's own PR. SamePatches is nil 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 Last

type Last struct {
	At    time.Time `json:"at"`
	Since time.Time `json:"since"`
}

Last is the standup the user last reported: when, and the start it used.

type Other

type Other struct {
	PRs     []PR     `json:"prs"`
	Commits []Commit `json:"commits"`
}

Other is the user's activity carrying no task id.

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

type PRCommit struct {
	SHA     string
	Subject string
	At      time.Time
}

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.

func Group

func Group(in Input) Report

Group sorts the collected activity into tasks.

type Review

type Review struct {
	Author string
	At     time.Time
}

A Review is one review event on a PR, 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

func Merge(since time.Time, period string, reports []Report) Standup

Merge joins per-repository reports into projects, one per tracker key, and tasks by id. PRs stay in chain order 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 ids. The command sets Key, since only it knows whether a tracker is the repository's own issues.

type User

type User struct {
	Email string `json:"email"`
	Login string `json:"login,omitempty"`
}

User is who the report is about: a git identity and a host login.

type Workdays

type Workdays [7]bool

Workdays is the working weekdays, indexed by time.Weekday.

func DefaultWorkdays

func DefaultWorkdays() Workdays

DefaultWorkdays is Monday to Friday.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL