-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
internal/labels: Labeler, constructor and config
First of several CLs implementing Labeler, akin to related.Poster. For #64. Change-Id: I621b882cf6a779f8e81042e6d5654c0b2a51c8fc Reviewed-on: https://go-review.googlesource.com/c/oscar/+/637096 Reviewed-by: Tatiana Bradley <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Hyang-Ah Hana Kim <[email protected]>
- Loading branch information
Showing
1 changed file
with
103 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// Copyright 2024 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package labels | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"log/slog" | ||
"time" | ||
|
||
"golang.org/x/oscar/internal/actions" | ||
"golang.org/x/oscar/internal/github" | ||
"golang.org/x/oscar/internal/storage" | ||
"golang.org/x/oscar/internal/storage/timed" | ||
) | ||
|
||
// A Labeler labels GitHub issues. | ||
type Labeler struct { | ||
slog *slog.Logger | ||
db storage.DB | ||
github *github.Client | ||
projects map[string]bool | ||
watcher *timed.Watcher[*github.Event] | ||
name string | ||
timeLimit time.Time | ||
ignores []func(*github.Issue) bool | ||
label bool | ||
// For the action log. | ||
requireApproval bool | ||
actionKind string | ||
logAction actions.BeforeFunc | ||
} | ||
|
||
// New creates and returns a new Labeler. It logs to lg, stores state in db, | ||
// | ||
// and watches for new GitHub issues using gh. | ||
// | ||
// For the purposes of storing its own state, it uses the given name. | ||
// Future calls to New with the same name will use the same state. | ||
// | ||
// Use the [Labeler] methods to configure the posting parameters | ||
// (especially [Labeler.EnableProject] and [Labeler.EnableLabels]) | ||
// before calling [Labeler.Run]. | ||
func New(lg *slog.Logger, db storage.DB, gh *github.Client, name string) *Labeler { | ||
l := &Labeler{ | ||
slog: lg, | ||
db: db, | ||
github: gh, | ||
projects: make(map[string]bool), | ||
watcher: gh.EventWatcher("labels.Labeler:" + name), | ||
name: name, | ||
timeLimit: time.Now().Add(-defaultTooOld), | ||
} | ||
// TODO: Perhaps the action kind should include name, but perhaps not. | ||
// This makes sure we only ever label each issue once. | ||
l.actionKind = "labels.Labeler" | ||
l.logAction = actions.Register(l.actionKind, &actioner{l}) | ||
return l | ||
} | ||
|
||
// SetTimeLimit controls how old an issue can be for the Labeler to label it. | ||
// Issues created before time t will be skipped. | ||
// The default is not to post to issues that are more than 48 hours old | ||
// at the time of the call to [New]. | ||
func (l *Labeler) SetTimeLimit(t time.Time) { | ||
l.timeLimit = t | ||
} | ||
|
||
const defaultTooOld = 48 * time.Hour | ||
|
||
// EnableProject enables the Labeler to post on issues in the given GitHub project (for example "golang/go"). | ||
// See also [Labeler.EnableLabels], which must also be called to post anything to GitHub. | ||
func (l *Labeler) EnableProject(project string) { | ||
l.projects[project] = true | ||
} | ||
|
||
// EnableLabels enables the Labeler to label GitHub issues. | ||
// If EnableLabels has not been called, [Labeler.Run] logs what it would post but does not post the messages. | ||
// See also [Labeler.EnableProject], which must also be called to set the projects being considered. | ||
func (l *Labeler) EnableLabels() { | ||
l.label = true | ||
} | ||
|
||
// RequireApproval configures the Labeler to log actions that require approval. | ||
func (l *Labeler) RequireApproval() { | ||
l.requireApproval = true | ||
} | ||
|
||
type actioner struct { | ||
l *Labeler | ||
} | ||
|
||
func (ar *actioner) Run(ctx context.Context, data []byte) ([]byte, error) { | ||
// TODO: implement | ||
return nil, errors.New("unimplemented") | ||
} | ||
|
||
func (ar *actioner) ForDisplay(data []byte) string { | ||
// TODO: implement | ||
return "" | ||
} |