reviews

package
v0.0.0-...-a0408b4 Latest Latest
Warning

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

Go to latest
Published: Feb 28, 2026 License: BSD-3-Clause Imports: 19 Imported by: 0

Documentation

Overview

Package reviews contains tools for project maintainers to categorize incoming changes, to help them decide what to review next.

Index

Constants

View Source
const (
	ScoreImportant     = 10  // change is important
	ScoreSuggested     = 1   // change is worth looking at
	ScoreUninteresting = -1  // change is not interesting
	ScoreUnimportant   = -10 // change is not important
)

Some Predicate default scores.

Variables

This section is empty.

Functions

func Display

func Display(ctx context.Context, lg *slog.Logger, doc template.HTML, defaultCategoriesJSON, endpoint string, cps []ChangePreds, w http.ResponseWriter, r *http.Request)

Display is an HTTP handler function that displays the changes to review.

func GerritChanges

func GerritChanges(cl *gerrit.Client, accounts AccountLookup, it iter.Seq[*gerrit.Change]) iter.Seq[*GerritChange]

GerritChanges converts from an iterator over gerrit.Change values into an iterator over GerritChange values.

Types

type Account

type Account interface {
	// The unique account name, such as an e-mail address.
	Name(context.Context) string
	// The display name of the account, such as a person's full name.
	DisplayName(context.Context) string
	// The authority of this account in the project.
	Authority(context.Context) Authority
	// Number of commits made by this account to the project.
	Commits(context.Context) int
}

An Account describes a person or agent.

type AccountLookup

type AccountLookup interface {
	Lookup(context.Context, string) Account
}

AccountLookup looks up account information by name. If there is no such account, this returns nil. At least for Gerrit, account information is stored differently by different Gerrit instances, so we need an interface.

type Authority

type Authority int

Authority describes what authority a person has in a project.

const (
	// Person is unknown or has no particular status.
	AuthorityUnknown Authority = iota
	// Person has contributed changes.
	AuthorityContributor
	// Person has reviewed changes.
	AuthorityReviewer
	// Person is a maintainer who can review and commit patches by others.
	AuthorityMaintainer
	// Person is a project owner/admin.
	AuthorityOwner
)

type CP

type CP struct {
	ChangePreds
}

CP is a list of changes. This is not just ChangePreds because we give the template a FormattedLastUpdate method.

func (*CP) FormattedLastUpdate

func (cp *CP) FormattedLastUpdate(ctx context.Context) string

FormattedLastUpdate returns the time of the last update as YYYY-MM-DD.

type Change

type Change interface {
	// The change ID, which is unique for a given project.
	// This is something like a Git revision or a Gerrit change number.
	ID(context.Context) string
	// The change status.
	Status(context.Context) Status
	// The person or agent who wrote the change.
	Author(context.Context) Account
	// When the change was created.
	Created(context.Context) time.Time
	// When the change was last updated.
	Updated(context.Context) time.Time
	// When the change was last updated by the change author.
	UpdatedByAuthor(context.Context) time.Time
	// The change subject: the first line of the description.
	Subject(context.Context) string
	// The complete change description.
	Description(context.Context) string
	// The list of people whose review is requested.
	Reviewers(context.Context) []Account
	// The list of people who have reviewed the change.
	Reviewed(context.Context) []Account
	// What the change needs in order to be submitted.
	Needs(context.Context) Needs
}

A Change is a change suggested for a project. This is something like a GitHub pull request or a Gerrit change.

For example, users of a Gerrit repo will read data using the gerrit package, and produce a GerritChange which implements Change. They can then use the general purpose scoring algorithms to categorize the changes.

type ChangePreds

type ChangePreds struct {
	Change     Change
	Predicates []*Predicate
}

ChangePreds is a Change with a list of predicates that apply to that change.

func ApplyPredicates

func ApplyPredicates(ctx context.Context, change Change, predicates []Predicate, rejects []Reject) (ChangePreds, bool, error)

ApplyPredicates takes a Change and applies predicates to it. The reject predicates are used to determine if the change is reviewable; the bool result will be false if the change should not be reviewed, for example because it has already been committed.

func CollectChangePreds

func CollectChangePreds(ctx context.Context, lg *slog.Logger, it iter.Seq[Change], predicates []Predicate, rejects []Reject) []ChangePreds

CollectChangePreds reads Change values from an iterator, applies predicates to the values, and collects the results into a slice of ChangePreds values, skipping changes that are rejected. The slice is sorted by the predicate default values.

type GerritChange

type GerritChange struct {
	Client *GerritReviewClient
	Change *gerrit.Change
}

GerritChange implements Change for a Gerrit CL.

func (*GerritChange) Author

func (gc *GerritChange) Author(ctx context.Context) Account

Author returns the change author.

func (*GerritChange) Created

func (gc *GerritChange) Created(ctx context.Context) time.Time

Created returns the time that the change was created.

func (*GerritChange) Description

func (gc *GerritChange) Description(ctx context.Context) string

Description returns the full change description.

func (*GerritChange) ID

func (gc *GerritChange) ID(ctx context.Context) string

ID returns the change ID.

func (*GerritChange) Needs

func (gc *GerritChange) Needs(ctx context.Context) Needs

Needs returns missing requirements for submittal. This implementation does what we can, but most projects will need their own version of this method.

func (*GerritChange) Reviewed

func (gc *GerritChange) Reviewed(ctx context.Context) []Account

Reviewed returns the accounts that have reviewed the change. We treat any account that has sent a message about the change as a reviewer.

func (*GerritChange) Reviewers

func (gc *GerritChange) Reviewers(ctx context.Context) []Account

Reviewers returns the assigned reviewers.

func (*GerritChange) Status

func (gc *GerritChange) Status(ctx context.Context) Status

Status returns the change status.

func (*GerritChange) Subject

func (gc *GerritChange) Subject(ctx context.Context) string

Subject returns the change subject.

func (*GerritChange) Updated

func (gc *GerritChange) Updated(ctx context.Context) time.Time

Updated returns the time that the change was last updated.

func (*GerritChange) UpdatedByAuthor

func (gc *GerritChange) UpdatedByAuthor(ctx context.Context) time.Time

UpdatedByAuthor returns the time that the change was updated by the original author.

type GerritReviewClient

type GerritReviewClient struct {
	GClient  *gerrit.Client
	Accounts AccountLookup
}

GerritReviewClient is a gerrit.Client with a mapping from account e-mail addresses to Account data. We do things this way because a lot of Gerrit change data is more or less the same for any Gerrit instance, but account information is not.

type Needs

type Needs int

Needs is a bitmask of missing requirements for a Change. The requirements may not be comprehensive; it's possible that when all these requirements are satisfied there will be more. If the Needs value is 0 then the change can be submitted.

const (
	// Change needs a review by someone.
	NeedsReview Needs = 1 << iota
	// Change needs to be approved.
	NeedsApproval
	// Change needs maintainer review,
	// but not necessarily approval.
	NeedsMaintainerReview
	// Change needs to resolve a reviewer comment.
	NeedsResolve
	// Change needs to resolve a merge conflict.
	NeedsConflictResolve
	// Change waiting for tests or other checks to pass.
	NeedsCheck
	// Some reviewer has this change on hold,
	// or change is marked as do not submit by author.
	NeedsHoldRemoval
	// Change waiting for next release to open.
	NeedsRelease
	// Change not submittable for some other reason.
	NeedsOther
)

type Predicate

type Predicate struct {
	Name        string // a short, one-word name
	Description string // a longer description
	Score       int    // default scoring value

	// The Applies function reports whether this Predicate
	// applies to a change.
	Applies func(context.Context, Change) (bool, error)
}

A Predicate is a categorization of a Change. An example of a Predicate would be "has been approved by a maintainer" or "author is a known contributor" or "waiting for response from author." The dashboard permits filtering and sorting CLs based on the different predicates they satisfy. A Predicate has a default score that indicates how important it is, but the dashboard permits using different sort orders.

func Predicates

func Predicates() []Predicate

Predicates returns a list of non-reject predicates that apply to a change.

type Reject

type Reject Predicate

A Reject is like a Predicate, but if the Reject applies to a Change then the Change is not put on the dashboard at all.

func Rejects

func Rejects() []Reject

Rejects returns a list of reject predicates that apply to a change.

type Status

type Status int

Status is the status of a change.

const (
	// Change is ready for review. The default.
	StatusReady Status = iota
	// Change is submitted.
	StatusSubmitted
	// Change is closed or abandoned.
	StatusClosed
	// Change is open but not ready for review.
	StatusDoNotReview
)

Jump to

Keyboard shortcuts

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