Documentation
¶
Overview ¶
Package cli implements the ghp-sync command line interface.
Index ¶
- Variables
- func CmdAdd(cmd *cobra.Command, args []string) error
- func CmdIssues(_ *cobra.Command, _ []string) error
- func CmdPRs(_ *cobra.Command, _ []string) error
- func CmdPRsRefresh(_ *cobra.Command, _ []string) error
- func CmdRateLimit(_ *cobra.Command, _ []string) error
- func CmdSync(_ *cobra.Command, args []string) error
- func FilterByFlags(f FlagData, prs *[]gh.PullRequest) (matched *[]gh.PullRequest, matchReasons map[int]string)
- func GetStringSliceFixed(key string) []string
- func Make(cmdName string) (*cobra.Command, error)
- func ValidateParams(params []string) func(cmd *cobra.Command, args []string) error
- type Filter
- type Filters
- type FlagData
- type PRFieldContext
- type PRFieldDef
Constants ¶
This section is empty.
Variables ¶
var PRFields = map[string]PRFieldDef{ "PR#": { Type: gh.ItemValueTypeNumber, ComputeFn: func(ctx PRFieldContext) any { return ctx.PR.Number }, }, "Status": { Type: gh.ItemValueTypeSingleSelect, ComputeFn: func(ctx PRFieldContext) any { id, ok := ctx.Project.StatusIDs[ctx.Status] if !ok || id == "" { fmt.Printf("WARNING: status %q not found in project\n", ctx.Status) return nil } return id }, }, "User": { Type: gh.ItemValueTypeText, ComputeFn: func(ctx PRFieldContext) any { return ctx.PR.Author }, }, "Reviewed By": { Type: gh.ItemValueTypeText, ComputeFn: func(ctx PRFieldContext) any { if len(ctx.PR.ReviewedBy) == 0 { return nil } return strings.Join(ctx.PR.ReviewedBy, ", ") }, }, "Approved By": { Type: gh.ItemValueTypeText, ComputeFn: func(ctx PRFieldContext) any { if len(ctx.PR.ApprovedBy) == 0 { return nil } return strings.Join(ctx.PR.ApprovedBy, ", ") }, }, "Changes Requested By": { Type: gh.ItemValueTypeText, ComputeFn: func(ctx PRFieldContext) any { if len(ctx.PR.ChangesRequestedBy) == 0 { return nil } parts := make([]string, 0, len(ctx.PR.ChangesRequestedBy)) for _, reviewer := range ctx.PR.ChangesRequestedBy { parts = append(parts, fmt.Sprintf("%s(×%d ✎%d)", reviewer.Login, reviewer.Requests, reviewer.Comments)) } return strings.Join(parts, ", ") }, }, "Merged By": { Type: gh.ItemValueTypeText, ComputeFn: func(ctx PRFieldContext) any { if ctx.PR.MergedBy == "" { return nil } return ctx.PR.MergedBy }, }, "CI": { Type: gh.ItemValueTypeText, ComputeFn: func(ctx PRFieldContext) any { if !strings.EqualFold(ctx.PR.State, "open") { return "" } switch ctx.PR.CheckState { case "FAILURE", "ERROR": return "❌" case "PENDING", "EXPECTED": return "🕒" case "SUCCESS": return "✅" default: return "" } }, }, "Mergeable": { Type: gh.ItemValueTypeText, ComputeFn: func(ctx PRFieldContext) any { if !strings.EqualFold(ctx.PR.State, "open") { return "" } switch ctx.PR.Mergeable { case "CONFLICTING": return "❌" case "MERGEABLE": return "✅" default: return "?" } }, }, "Open Days": { Type: gh.ItemValueTypeNumber, ComputeFn: func(ctx PRFieldContext) any { return ctx.DaysOpen }, }, "Waiting Days": { Type: gh.ItemValueTypeNumber, ComputeFn: func(ctx PRFieldContext) any { return ctx.DaysWaiting }, }, "Comment Count": { Type: gh.ItemValueTypeNumber, ComputeFn: func(ctx PRFieldContext) any { return ctx.PR.TotalCommentCount }, }, "Review Count": { Type: gh.ItemValueTypeNumber, ComputeFn: func(ctx PRFieldContext) any { return ctx.PR.TotalReviewCount }, }, "Review Comment Count": { Type: gh.ItemValueTypeNumber, ComputeFn: func(ctx PRFieldContext) any { return ctx.PR.ReviewCommentCount }, }, "Created At": { Type: gh.ItemValueTypeDate, ComputeFn: func(ctx PRFieldContext) any { return ctx.PR.CreatedAt.Format(time.RFC3339) }, }, "Closed At": { Type: gh.ItemValueTypeDate, ComputeFn: func(ctx PRFieldContext) any { if strings.EqualFold(ctx.PR.State, "open") { return nil } return ctx.PR.ClosedAt.Format(time.RFC3339) }, }, "Merged At": { Type: gh.ItemValueTypeDate, ComputeFn: func(ctx PRFieldContext) any { if ctx.PR.MergedAt.IsZero() { return nil } return ctx.PR.MergedAt.Format(time.RFC3339) }, }, "Filtered Review Count": { Type: gh.ItemValueTypeNumber, ComputeFn: func(ctx PRFieldContext) any { if ctx.PR.FilteredReviewCount == 0 { return nil } return ctx.PR.FilteredReviewCount }, }, "Filtered Review Comment Count": { Type: gh.ItemValueTypeNumber, ComputeFn: func(ctx PRFieldContext) any { if ctx.PR.FilteredReviewCount == 0 { return nil } return ctx.PR.FilteredReviewCommentCount }, }, }
PRFields is the registry of all available PR fields, keyed by field name (matches GitHub Project field name)
Functions ¶
func CmdPRsRefresh ¶ added in v0.2.0
CmdPRsRefresh walks the project board itself and refreshes fields on PR items that are now closed or merged, rather than syncing PRs from a repo. This catches PRs that were added while open but have since closed, without crawling the repo's full PR history.
func FilterByFlags ¶
func FilterByFlags(f FlagData, prs *[]gh.PullRequest) (matched *[]gh.PullRequest, matchReasons map[int]string)
FilterByFlags returns the PRs matching the user filters along with a map of pr number -> why it matched. A nil map means no filters were active and everything was kept.
func GetStringSliceFixed ¶
GetStringSliceFixed works around viper not correctly handling string slices from env vars the same way it does commandline flags, see https://github.com/spf13/viper/issues/380
Types ¶
type Filter ¶
func GetFilterForAuthors ¶
func GetFilterForLabels ¶
func GetFilterForLabelsAnd ¶
func GetFilterForLabelsOr ¶
type FlagData ¶
type FlagData struct {
Token string
Repos []string
ProjectOwner string
ProjectNumber int
ItemLimit int
DryRun bool
Strict bool
Filters Filters
// PR field population control
PRPopulateFields []string // Only populate these fields (empty = all)
PRSkipFields []string // Skip these fields from population
PRFields []string // Resolved list of field names to populate
// Linked issue field syncing
SyncLinkedIssueFields []string // Copy these fields from linked issues
}
func (FlagData) GetFilters ¶
type PRFieldContext ¶
type PRFieldContext struct {
PR *gh.PullRequest
Project gh.Project
DaysOpen int
DaysWaiting int
Status string // The computed status text (e.g., "In Progress", "Approved")
}
PRFieldContext holds all the data needed to compute field values
type PRFieldDef ¶
type PRFieldDef struct {
Type gh.ItemValueType // Field type for GraphQL mutation
ComputeFn func(ctx PRFieldContext) any
}
PRFieldDef defines a field that can be populated on a GitHub Project item