pkg

package
v0.1.3 Latest Latest
Warning

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

Go to latest
Published: Feb 29, 2024 License: MIT Imports: 29 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// DefaultLogOptions will use text logs with timestamps shown.
	DefaultLogOptions = LogOptions{
		LogUseJSON:  false,
		LogVerbose:  false,
		LogShowTime: true,
	}
	// LogKeyError is used to set the standard key that should be used when providing an error in a log.
	LogKeyError = "err"
)
View Source
var (
	MetricNewSubscriptionTotal = promauto.NewCounter(
		prometheus.CounterOpts{
			Name: "watchinator_new_subscription_total",
			Help: "The total number of new items on GitHub the user has been subscribed to",
		},
	)
	MetricNewSubscriptionErrorTotal = promauto.NewCounter(
		prometheus.CounterOpts{
			Name: "watchinator_new_subscription_error_total",
			Help: "The total number of errors observed when subscribing to new items on GitHub",
		},
	)
	MetricFilteredTotal = promauto.NewCounter(
		prometheus.CounterOpts{
			Name: "watchinator_filtered_items_total",
			Help: "The total number of items on GitHub that were filtered out for a match",
		},
	)
	MetricConfigLoadTotal = promauto.NewCounter(
		prometheus.CounterOpts{
			Name: "watchinator_config_load_total",
			Help: "The total number of times the configuration has been loaded",
		},
	)
	MetricConfigLoadErrorTotal = promauto.NewCounter(
		prometheus.CounterOpts{
			Name: "watchinator_config_load_error_total",
			Help: "The total number of errors observed when loading configurations",
		},
	)
	MetricPollTickTotal = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "watchinator_poll_tick_total",
			Help: "The total number of times an update poll has ticked",
		},
		[]string{"watch"},
	)
	MetricPollErrorTotal = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "watchinator_poll_error_total",
			Help: "The total number of errors that have occurred during a poll tick",
		},
		[]string{"watch"},
	)
	MetricRepoQueryTotal = promauto.NewCounter(
		prometheus.CounterOpts{
			Name: "watchinator_repo_query_total",
			Help: "The total number of repo queries that have been made against GitHub",
		},
	)
	MetricRepoQueryErrorTotal = promauto.NewCounter(
		prometheus.CounterOpts{
			Name: "watchinator_repo_query_error_total",
			Help: "The total number of errors observed during repo queries against GitHub",
		},
	)
	MetricIssueQueryTotal = promauto.NewCounter(
		prometheus.CounterOpts{
			Name: "watchinator_issue_query_total",
			Help: "The total number of issue queries that have been made against GitHub",
		},
	)
	MetricIssueQueryErrorTotal = promauto.NewCounter(
		prometheus.CounterOpts{
			Name: "watchinator_issue_query_error_total",
			Help: "The total number of errors observed during issue queries against GitHub",
		},
	)
	MetricIssueLabelQueryTotal = promauto.NewCounter(
		prometheus.CounterOpts{
			Name: "watchinator_issue_label_query_total",
			Help: "The total number of issue label queries that have been made against GitHub",
		},
	)
	MetricIssueLabelQueryErrorTotal = promauto.NewCounter(
		prometheus.CounterOpts{
			Name: "watchinator_issue_label_query_error_total",
			Help: "The total number of errors observed during issue label queries against GitHub",
		},
	)
	MetricIssueBodyQueryTotal = promauto.NewCounter(
		prometheus.CounterOpts{
			Name: "watchinator_issue_body_query_total",
			Help: "The total number of issue body queries that have been made against GitHub",
		},
	)
	MetricIssueBodyQueryErrorTotal = promauto.NewCounter(
		prometheus.CounterOpts{
			Name: "watchinator_issue_body_query_error_total",
			Help: "The total number of errors observed during issue body queries against GitHub",
		},
	)
	MetricActionHandleTotal = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "watchinator_action_handle_total",
			Help: "The total number of times an action handler performed an action, labeled by action name",
		}, []string{"action"},
	)
	MetricActionHandleErrorTotal = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "watchinator_action_handle_error_total",
			Help: "The total number of times an error occurred during an action handler execution",
		}, []string{"action"},
	)
)

Functions

func GetAbsolutePath

func GetAbsolutePath(path string) (string, error)

GetAbsolutePath returns the absolute path for the given file system path. It handles replacing '~/' with the current users home directory, and passes the path through a `filepath.Abs` call.

func GitHubItemAsLabelSet

func GitHubItemAsLabelSet(i *GitHubItem) labels.Set

GitHubItemAsLabelSet converts the given GitHubItem into a k8s.io/apimachinery/pkg/labels.Set, for applying label selectors specified in a Watch. Fields are convered into lowercase keys in the map, and values are converted into strings. Nested structs in a GitHubItem will have their fields writtin with dot-notation. For instance, GitHubItem.Repo.Name will have the key "repo.name" in the returned set. This function does not use reflect, and is therefore coupled with the GitHubItem definition.

func NewLogger

func NewLogger(_lo ...*LogOptions) *slog.Logger

NewLogger creates a new logger. It should be an inexpensive call. If no LogOptions are provided, then DefaultLogOptions are used. Only the first LogOptions provided to the function will be recognized, the rest will be ignored.

func ReadFirstLineFromFile

func ReadFirstLineFromFile(path string) (string, error)

ReadFirstLineFromFile grabs the first line from the given file. The main use case for this function is reading secrets from files.

func ServePromEndpoint

func ServePromEndpoint(ctx context.Context)

ServePromEndpoint creates a new http server which serves prometheus metrics at :2112/metrics.

Types

type ActionConfig

type ActionConfig struct {
	Subscribe SubscribeActionConfig `yaml:"subscribe"`
	Email     EmailActionConfig     `yaml:"email"`
}

func (*ActionConfig) LogValue

func (a *ActionConfig) LogValue() slog.Value

func (*ActionConfig) Validate

func (a *ActionConfig) Validate(ctx context.Context) error

type Actioninator

type Actioninator interface {
	WithAction(action GitHubItemAction) Actioninator
	Handle(ctx context.Context, item GitHubItem, logger *slog.Logger) error
}

func NewActioninator

func NewActioninator() Actioninator

type Config

type Config struct {
	// User is the GitHub username the watch will apply to.
	User string `yaml:"user"`
	// PATFile is the file containing the user's PAT used for authentication.
	PATFile string `yaml:"patFile"`
	// PAT is the PAT contained in the PATFile.
	PAT string `yaml:"-"`
	// Interval used to determine when to update watches.
	Interval time.Duration `yaml:"interval"`
	// Email sender configuration for email action.
	Email EmailConfig `yaml:"email"`
	// Watches is a list of Watch definitions.
	Watches []*Watch `yaml:"watches"`
}

Config specifies the list of Watches to create.

func NewConfigFromFile

func NewConfigFromFile(path string) (*Config, error)

NewConfigFromFile opens the given path and attempts to unmarshal it into a Config struct. Config.Validate is not called and still needs to be executed by the user.

func NewTestConfig

func NewTestConfig() (*Config, func(), error)

NewTestConfig creates a new Config struct with pre-populated fields. It can be used in unit tests.

func (*Config) GetWatch

func (c *Config) GetWatch(name string) *Watch

GetWatch returns a pointer to the Watch with the given name. If the Watch is not present in the config, nil is returned.

func (*Config) LoadPATFile added in v0.1.3

func (c *Config) LoadPATFile(ctx context.Context) error

LoadPATFile reads the Config's PATFile into the PAT field.

func (*Config) LogValue

func (c *Config) LogValue() slog.Value

func (*Config) Validate

func (c *Config) Validate(ctx context.Context, gh GitHubinator, e Emailinator) error

Validate ensures that the Config struct is populated correctly. If a field is not properly set, an error is returned explaining why.

type Configinator

type Configinator interface {
	// Watch will continually watch the given config path for changes.
	// If a change occurs, the new config will be validated and sent to the given callback.
	// If an error occurs, the watch stops and the error is returned.
	Watch(ctx context.Context, path string, callback func(*Config), gh GitHubinator, e Emailinator) error
}

Configinator handles loading a config from disk.

func NewConfiginator

func NewConfiginator(logger *slog.Logger) Configinator

NewConfiginator creates a new Configinator instance based on the packages internal implementation.

type EmailActionConfig

type EmailActionConfig struct {
	Enabled bool   `yaml:"enabled"`
	SendTo  string `yaml:"sendTo"`
}

func (*EmailActionConfig) LogValue

func (e *EmailActionConfig) LogValue() slog.Value

func (*EmailActionConfig) Validate

func (e *EmailActionConfig) Validate(_ context.Context) error

type EmailConfig

type EmailConfig struct {
	// Username to login to SMTP service with. Should be the same as the
	// sender email address.
	Username string `yaml:"username"`
	// PasswordFile containing the password used to login to the SMTP service.
	PasswordFile string `yaml:"passwordFile"`
	// Password contained within the PasswordFile
	Password string `yaml:"-"`
	// Host address of the SMTP service (ie smtp.gmail.com).
	Host string `yaml:"host"`
	// Port of the SMTP service to connect to.
	Port int `yaml:"port"`
}

func (*EmailConfig) LogValue

func (e *EmailConfig) LogValue() slog.Value

func (*EmailConfig) Validate

func (e *EmailConfig) Validate(ctx context.Context, emailinator Emailinator) error

type Emailinator

type Emailinator interface {
	TestConnection(ctx context.Context) error
	Send(ctx context.Context, msg *mail.Msg) error
	WithConfig(cfg *EmailConfig) Emailinator
	NewMsg() (*mail.Msg, error)
}

func NewEmailinator

func NewEmailinator(logger *slog.Logger) Emailinator

type GitHubActor

type GitHubActor struct {
	Login string `json:"login"`
}

GitHubActor represents something that can take actions on GitHub (ie a user or bot). It is associated with the following GraphQL interface: https://docs.github.com/en/graphql/reference/interfaces#actor.

func (GitHubActor) LogValue

func (a GitHubActor) LogValue() slog.Value

type GitHubIssue

type GitHubIssue struct {
	Author       GitHubActor                `json:"author"`
	Body         string                     `json:"body"`
	Labels       []string                   `json:"labels"`
	Number       int                        `json:"number"`
	State        githubv4.IssueState        `json:"state"`
	Subscription githubv4.SubscriptionState `json:"Subscription"`
	Title        string                     `json:"title"`
	UpdatedAt    time.Time                  `json:"updatedAt"`
}

GitHubIssue represents an issue on GitHub. It is associated with the following GraphQL object: https://docs.github.com/en/graphql/reference/objects#issue.

func NewTestGitHubIssue

func NewTestGitHubIssue() *GitHubIssue

NewTestGitHubIssue creates a new GitHubIssue struct with pre-populated fields. It can be used in unit tests.

func (GitHubIssue) LogValue

func (i GitHubIssue) LogValue() slog.Value

type GitHubIssueFilter

type GitHubIssueFilter struct {
	Labels []string
	States []string
}

GitHubIssueFilter is a filter that can be used when listing issues on GitHub. It is associated with (but decoupled from) the following GraphQL input object: https://docs.github.com/en/graphql/reference/input-objects#issuefilters.

type GitHubItem

type GitHubItem struct {
	GitHubIssue
	Type GitHubItemType   `json:"type"`
	Repo GitHubRepository `json:"repo"`
	ID   githubv4.ID      `json:"id"`
}

GitHubItem is a container sturct holding different items that can be queried on GitHub. It is used to provide a common format for label selectors.

func NewTestGitHubItem

func NewTestGitHubItem() *GitHubItem

NewTestGitHubItem creates a new instance of a GitHubItem with pre-populated fields. It can be used in unit tests.

func (GitHubItem) LogValue

func (i GitHubItem) LogValue() slog.Value

type GitHubItemAction

type GitHubItemAction struct {
	Handle func(ctx context.Context, i GitHubItem, logger *slog.Logger) error
	Name   string
}

func NewEmailAction

func NewEmailAction(emailinator Emailinator, to string) GitHubItemAction

func NewSubscribeAction

func NewSubscribeAction(gh GitHubinator) GitHubItemAction

type GitHubItemMatcher

type GitHubItemMatcher struct {
	// Matcher is a function that takes in a GitHubItem and returns a boolean specifying if the item was matched.
	Matcher func(i *GitHubItem) bool
	// Name is used to identify the above Matcher; helpful for debug logs.
	Name string
}

GitHubItemMatcher is used to select GitHubItem structs based on a specific criteria encoded in the Matcher field.

func BodyRegexAsGitHubItemMatcher

func BodyRegexAsGitHubItemMatcher(bodyRegex *regexp.Regexp) GitHubItemMatcher

BodyRegexAsGitHubItemMatcher creates a new GitHubItemMatcher from the given bodyRegex. If the given bodyRegex matches on the GitHubItem's Body field, then the matcher returns true.

func RequiredLabelAsGitHubItemMatcher

func RequiredLabelAsGitHubItemMatcher(requiredLabel string) GitHubItemMatcher

RequiredLabelAsGitHubItemMatcher creates a new GitHubItemMatcher from the givne requiredLabel. If the given requiredLabel is present in the GitHubItem's labels, then the matcher returns true.

func SelectorAsGitHubItemMatcher

func SelectorAsGitHubItemMatcher(s labels.Selector) GitHubItemMatcher

SelectorAsGitHubItemMatcher creates a new GitHubItemMatcher from the given k8s.io/apimachinery/pkg/labels.Selector. If the given selector matches the GitHubItem as a label set (see GitHubItemAsLabelSet), then the matcher returns true.

func TitleRegexAsGitHubItemMatcher added in v0.1.1

func TitleRegexAsGitHubItemMatcher(titleRegex *regexp.Regexp) GitHubItemMatcher

TitleRegexAsGitHubItemMatcher creates a new GitHubItemMatcher from the given titleRegex. If the given titleRegex matches on the GitHubItem's Title field, then the matcher returns true.

type GitHubItemType

type GitHubItemType string

GitHubItemType specifies the type of a GitHub item.

const (
	GitHubItemIssue GitHubItemType = "issue"
)

type GitHubLabel

type GitHubLabel struct {
	Name string `json:"name"`
}

GitHubLabel represents an issue or PR label on GitHub. Is is associated with the following GraphQL object: https://docs.github.com/en/graphql/reference/objects#label.

type GitHubNotFoundError

type GitHubNotFoundError error

GitHubNotFoundError is raised when a GitHubinator cannot find the given item. It is a special error that can be used to debug why a request failed.

type GitHubRepository

type GitHubRepository struct {
	Owner string `json:"owner" yaml:"owner"`
	Name  string `json:"name" yaml:"name"`
}

GitHubRepository represents a repository on GitHub. It is associated with the following GraphQL object: https://docs.github.com/en/graphql/reference/objects#repository.

func (GitHubRepository) LogValue

func (r GitHubRepository) LogValue() slog.Value

type GitHubinator

type GitHubinator interface {
	// WithRetries will set the number of retries the GitHubinator will use when fetching or updating data.
	WithRetries(retries int) GitHubinator

	// WithTimeout sets the amount of time per try that the GitHubinator will wait for success before assuming a
	// request has failed.
	WithTimeout(timeout time.Duration) GitHubinator

	// WithToken sets the authentication token to use for the GH API, such as a PAT.
	// A test request will be sent to GitHub to verify authentication.
	WithToken(token string) GitHubinator

	// WhoAmI will make a test query to GitHub to get the name and login for the given PAT.
	WhoAmI(ctx context.Context) (string, error)

	// CheckRepository checks if the given repository exists.
	CheckRepository(ctx context.Context, ghr GitHubRepository) error

	// ListIssues returns a list of issues for the given repository.
	ListIssues(
		ctx context.Context, ghr GitHubRepository, filter *GitHubIssueFilter, matcher Matchinator,
	) ([]*GitHubItem, error)

	// SetSubscription sets the subscription state of the given item for the viewer.
	SetSubscription(ctx context.Context, id githubv4.ID, state githubv4.SubscriptionState) error
}

GitHubinator is used to fetch and update data from GitHub. The With* builder methods return a new instance of a GitHubinator.

func NewGitHubinator

func NewGitHubinator(logger *slog.Logger) GitHubinator

NewGitHubinator creates a new instance of a GitHubinator.

type LogOptions

type LogOptions struct {
	// LogUseJSON, if true, will output JSON-formatted logs. Otherwise, if false, text-formatted logs are outputted.
	LogUseJSON bool
	// LogVerbose, if true, sets the log level to Debug, increasing verbosity. Otherwise, if false, the log level is
	// set to Info.
	LogVerbose bool
	// LogShowTime, if true, will add timestamps to log messages. Otherwise, if false, timestamps will be omitted.
	LogShowTime bool
}

LogOptions represents the logging options available.

type Matchinator

type Matchinator interface {
	// WithMatchFunc as a new GitHubItemMatcher to the list of critieria.
	WithMatchFunc(match GitHubItemMatcher) Matchinator

	// WithSelectors adds the given k8s.io/apimachinery/pkg/labels.Selectors to the match criteria.
	WithSelectors(selectors ...labels.Selector) Matchinator

	// WithBodyRegexes adds the given bodyRegexes to the match critieria.
	WithBodyRegexes(bodyRegexes ...*regexp.Regexp) Matchinator

	// WithTitleRegexes adds the given titleRegexes to the match critieria.
	WithTitleRegexes(titleRegexes ...*regexp.Regexp) Matchinator

	// HasBodyRegex returns if a bodyRegex is part of the match criteria.
	HasBodyRegex() bool

	// WithRequiredLabels adds the given labels to the match criteria.
	WithRequiredLabels(labels ...string) Matchinator

	// HasRequiredLabels returns if a label is part of the match criteria.
	HasRequiredLabels() bool

	// Matches returns a boolean specifying if the GitHubItem matched the configured criteria. If no criteria is
	// configured, then this function always returns true.
	Matches(item *GitHubItem) (bool, string)
}

Matchinator is used to provide custom criteria for filtering GitHubItems that may not be built in to GitHub's GraphQL API. It specifies a list of critieria which the GitHubItem MUST match in order to be selected. If any of the criteria is not met, then the GitHubItem is not matched. The With* builder methods always return a pointer to the same Matchinator.

func NewMatchinator

func NewMatchinator() Matchinator

NewMatchinator creates a new Matchinator instance.

type MockEmailinator

type MockEmailinator struct {
	TestConnectionError error
	SendError           error
	NewMsgError         error
}

func NewMockEmailinator

func NewMockEmailinator() *MockEmailinator

func (MockEmailinator) NewMsg

func (m MockEmailinator) NewMsg() (*mail.Msg, error)

func (MockEmailinator) Send

func (m MockEmailinator) Send(ctx context.Context, msg *mail.Msg) error

func (MockEmailinator) TestConnection

func (m MockEmailinator) TestConnection(ctx context.Context) error

func (MockEmailinator) WithConfig

func (m MockEmailinator) WithConfig(cfg *EmailConfig) Emailinator

type MockGitHubinator

type MockGitHubinator struct {
	// CheckRepositoryRequests holds th parameters to calls to CheckRepository.
	CheckRepositoryRequests []GitHubRepository

	// CheckRepositoryError holds the returned error for CheckRepository.
	CheckRepositoryError error

	// WhoAmIRequests holds the number of times WhoAmI has been called
	WhoAmIRequests int

	// WhoAmIReturn holds the user returned from calls to WhoAmI.
	WhoAmIReturn string

	// WhoAmIError holds the errors that will be returned from WhoAmI.
	WhoAmIError error

	// SetSubscriptionRequests holds the issue IDs passed to SetSubscription.
	SetSubscriptionRequests []githubv4.ID

	// SetSubscriptionError holds the returned error for SetSubscription
	SetSubscriptionError error
}

MockGitHubinator implements the GitHubinator interface. The returned values from its methods can be controlled, allowing for it to be used for unit testing.

func NewMockGitHubinator

func NewMockGitHubinator() *MockGitHubinator

NewMockGitHubinator creates a new MockGitHubinator instance with pre-populated, non-error return values.

func (*MockGitHubinator) CheckRepository

func (t *MockGitHubinator) CheckRepository(ctx context.Context, ghr GitHubRepository) error

func (*MockGitHubinator) ListIssues

func (t *MockGitHubinator) ListIssues(
	ctx context.Context, ghr GitHubRepository, filter *GitHubIssueFilter, matcher Matchinator,
) ([]*GitHubItem, error)

func (*MockGitHubinator) SetSubscription

func (t *MockGitHubinator) SetSubscription(
	ctx context.Context, id githubv4.ID, state githubv4.SubscriptionState,
) error

func (*MockGitHubinator) WhoAmI

func (t *MockGitHubinator) WhoAmI(_ context.Context) (string, error)

func (*MockGitHubinator) WithRetries

func (t *MockGitHubinator) WithRetries(_ int) GitHubinator

func (*MockGitHubinator) WithTimeout

func (t *MockGitHubinator) WithTimeout(_ time.Duration) GitHubinator

func (*MockGitHubinator) WithToken

func (t *MockGitHubinator) WithToken(_ string) GitHubinator

type Pollinator

type Pollinator interface {
	// Add creates a new poll, whose callback will be executed on the given interval.
	// If the given poll already exists, then it is updated with the given interval and callback.
	// The argument doInitialCallback can be used to toggle if the poll is executed for the first time after the
	// call to Add, or if the poll is executed for the first time after the given interval.
	Add(name string, interval time.Duration, callback func(t time.Time), doInitialCallback bool)

	// Delete removes the poll by the given name. If it doesn't exist, then this is a no-op.
	Delete(name string)

	// List returns a slice containing the names of all the polls currently running.
	List() []string

	// StopAll stops all the added polls, blocking until all exit. Use this as a cleanup.
	StopAll()
}

Pollinator handles executing functions on a ticker.

func NewPollinator

func NewPollinator(ctx context.Context, baseLogger *slog.Logger) Pollinator

NewPollinator creates a new pollinator. The given baseLogger and context will be used as the parent logger and context for all poll's created.

type SubscribeActionConfig

type SubscribeActionConfig struct {
	Enabled bool `yaml:"enabled"`
}

func (*SubscribeActionConfig) LogValue

func (s *SubscribeActionConfig) LogValue() slog.Value

func (*SubscribeActionConfig) Validate

func (s *SubscribeActionConfig) Validate(_ context.Context) error

type Watch

type Watch struct {
	// Name is a human-readable description of the watch.
	Name string `yaml:"name"`
	// Repositories to watch issues from.
	Repositories []GitHubRepository `yaml:"repos"`
	// Selectors are used to specify which items to watch, follows the k8s label selector syntax.
	// See the GitHubItem struct for valid keys and fields and
	// https://pkg.go.dev/k8s.io/apimachinery@v0.27.1/pkg/labels#Parse for the syntax.
	Selectors []string `yaml:"selectors"`

	// RequiredLabels are a list of labels that must be present for an item to be watched. An item must have all of
	// these labels to be watched.
	RequiredLabels []string `yaml:"requiredLabels"`
	// SearchLabels are a set of labels that will be used to find new items. They will not be used as criteria for if
	// an item is watched, but if an item is discovered from GitHub.
	SearchLabels []string `yaml:"searchLabels"`
	// BodyRegex is a list of regex expressions which must match the item's body.
	BodyRegex []string `yaml:"bodyRegex"`

	// TitleRegex is a list of regex expressions which must match the item's title.
	TitleRegex []string `yaml:"titleRegex"`

	// States are a list of issues states to filter by.
	States []string `yaml:"states"`
	// Actions are a list of actions to perform when an item matches the set of filters.
	Actions ActionConfig `yaml:"actions"`
	// contains filtered or unexported fields
}

Watch specifies which items in GitHub a user will be subscribed to. This struct uses private fields of some exported fields to perform further parsing and setup. After unmarshalling, you must calll ValidateAndPopulate.

func NewTestWatch

func NewTestWatch() *Watch

NewTestWatch creates a new Watch instance with pre-populated fields. It can be used in unit tests.

func (*Watch) GetActioninator

func (w *Watch) GetActioninator(gh GitHubinator, emailinator Emailinator) Actioninator

func (*Watch) GetIssueFilter

func (w *Watch) GetIssueFilter() *GitHubIssueFilter

GetIssueFilter returns a GitHubIssueFilter based on the Watch's specified SearchLabels and States. It can be passed to a GitHubinator for listing issues that match the Watch.

func (*Watch) GetMatchinator

func (w *Watch) GetMatchinator() Matchinator

GetMatchinator returns a Matchinator based on the Watch's specified BodyRegex, Selectors, and RequiredLabels fields. It can be passed to a GitHubinator for listing issues that match the Watch.

func (*Watch) LogValue

func (w *Watch) LogValue() slog.Value

func (*Watch) ValidateAndPopulate

func (w *Watch) ValidateAndPopulate(ctx context.Context, gh GitHubinator) error

ValidateAndPopulate ensures that the Watch struct has its fields properly set and populates fields as necessary when the struct was unmarshalled from a YAML config. For instance, the field BodyRegex has an associated unexported field bodyRegex of the type []string, which is populated during unmarshalling. After calling ValidateAndPopulate, the field BodyRegex of the type []*regex.Regexp will be populated with the parsed regex strings found in the bodyRegex field.

type Watchinator

type Watchinator interface {
	// Watch is the 'main' function of the Watchinator, which sets up both a Pollinator and a Configinator to
	// watch GitHub for new items and subscribe to them as needed.
	Watch(ctx context.Context, configFilePath string) error
}

Watchinator is used to periodically poll GitHub for new GitHubItems that should be subscribed to. It uses a Configinator to dynamically reload watches based on config changes.

func NewWatchinator

func NewWatchinator(
	logger *slog.Logger,
	gitHubinator GitHubinator,
	pollinator Pollinator,
	configinator Configinator,
	emailinator Emailinator,
) Watchinator

NewWatchinator creates a new Watchinator.

Jump to

Keyboard shortcuts

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