607 lines
18 KiB
Go
607 lines
18 KiB
Go
package github
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
var ErrWorkspaceSettingsValidation = errors.New("invalid workspace settings")
|
|
|
|
// GetWorkspaceSettings returns the GitHub operational settings for a workspace.
|
|
func (s *Service) GetWorkspaceSettings(ctx context.Context, workspaceID string) (*WorkspaceSettings, error) {
|
|
if s.store == nil {
|
|
return defaultWorkspaceSettings(workspaceID), nil
|
|
}
|
|
return s.store.GetWorkspaceSettings(ctx, workspaceID)
|
|
}
|
|
|
|
// UpsertWorkspaceSettings stores the GitHub operational settings for a workspace.
|
|
func (s *Service) UpsertWorkspaceSettings(ctx context.Context, settings *WorkspaceSettings) error {
|
|
if s.store == nil {
|
|
return fmt.Errorf("github store not configured")
|
|
}
|
|
return s.store.UpsertWorkspaceSettings(ctx, settings)
|
|
}
|
|
|
|
// UpdateWorkspaceSettings applies a partial update over the existing workspace
|
|
// settings. Scope fields are intentionally updated as a set so switching to
|
|
// All repos clears org/repo selections. Direct struct callers must set
|
|
// SavedPresetsSet/DefaultQueriesSet when they intend to write those blobs;
|
|
// JSON-bound requests set those flags in UpdateWorkspaceSettingsRequest.UnmarshalJSON.
|
|
func (s *Service) UpdateWorkspaceSettings(ctx context.Context, req *UpdateWorkspaceSettingsRequest) (*WorkspaceSettings, error) {
|
|
if req == nil || strings.TrimSpace(req.WorkspaceID) == "" {
|
|
return nil, fmt.Errorf("%w: workspace_id is required", ErrWorkspaceSettingsValidation)
|
|
}
|
|
if req.RepoScopeMode != nil && !isValidRepoScopeMode(*req.RepoScopeMode) {
|
|
return nil, fmt.Errorf("%w: invalid repo_scope_mode %q", ErrWorkspaceSettingsValidation, *req.RepoScopeMode)
|
|
}
|
|
if s.store == nil {
|
|
return nil, fmt.Errorf("github store not configured")
|
|
}
|
|
return s.store.PatchWorkspaceSettings(ctx, req)
|
|
}
|
|
|
|
func (s *Service) SearchUserPRsPagedForWorkspace(
|
|
ctx context.Context,
|
|
workspaceID string,
|
|
filter string,
|
|
customQuery string,
|
|
page int,
|
|
perPage int,
|
|
) (*PRSearchPage, error) {
|
|
settings, err := s.GetWorkspaceSettings(ctx, workspaceID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if !workspaceSettingsHasScope(settings) {
|
|
return s.SearchUserPRsPaged(ctx, filter, customQuery, page, perPage)
|
|
}
|
|
return s.searchUserPRsPagedScoped(ctx, settings, filter, customQuery, page, perPage)
|
|
}
|
|
|
|
func (s *Service) SearchUserIssuesPagedForWorkspace(
|
|
ctx context.Context,
|
|
workspaceID string,
|
|
filter string,
|
|
customQuery string,
|
|
page int,
|
|
perPage int,
|
|
) (*IssueSearchPage, error) {
|
|
settings, err := s.GetWorkspaceSettings(ctx, workspaceID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if !workspaceSettingsHasScope(settings) {
|
|
return s.SearchUserIssuesPaged(ctx, filter, customQuery, page, perPage)
|
|
}
|
|
return s.searchUserIssuesPagedScoped(ctx, settings, filter, customQuery, page, perPage)
|
|
}
|
|
|
|
func (s *Service) searchUserPRsPagedScoped(
|
|
ctx context.Context,
|
|
settings *WorkspaceSettings,
|
|
filter string,
|
|
customQuery string,
|
|
page int,
|
|
perPage int,
|
|
) (*PRSearchPage, error) {
|
|
if workspaceSettingsHasEmptyScope(settings) {
|
|
return &PRSearchPage{PRs: []*PR{}, TotalCount: 0, Page: page, PerPage: perPage}, nil
|
|
}
|
|
qualifiers := workspaceScopeQualifiers(settings)
|
|
if len(qualifiers) > 1 {
|
|
return s.searchUserPRsPagedScopedAcrossQualifiers(ctx, settings, filter, customQuery, page, perPage, qualifiers)
|
|
}
|
|
filter, customQuery = appendWorkspaceScopeToSearch(filter, customQuery, settings)
|
|
v, err := s.searchUserPagedScoped("pr", settings, filter, customQuery, page, perPage, func(page, perPage int) (any, error) {
|
|
result, err := s.client.SearchPRsPaged(ctx, filter, customQuery, page, perPage)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return scopedPRSearchPage(result, settings, page, perPage), nil
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return v.(*PRSearchPage), nil
|
|
}
|
|
|
|
func (s *Service) searchUserIssuesPagedScoped(
|
|
ctx context.Context,
|
|
settings *WorkspaceSettings,
|
|
filter string,
|
|
customQuery string,
|
|
page int,
|
|
perPage int,
|
|
) (*IssueSearchPage, error) {
|
|
if workspaceSettingsHasEmptyScope(settings) {
|
|
return &IssueSearchPage{Issues: []*Issue{}, TotalCount: 0, Page: page, PerPage: perPage}, nil
|
|
}
|
|
qualifiers := workspaceScopeQualifiers(settings)
|
|
if len(qualifiers) > 1 {
|
|
return s.searchUserIssuesPagedScopedAcrossQualifiers(ctx, settings, filter, customQuery, page, perPage, qualifiers)
|
|
}
|
|
filter, customQuery = appendWorkspaceScopeToSearch(filter, customQuery, settings)
|
|
v, err := s.searchUserPagedScoped("issue", settings, filter, customQuery, page, perPage, func(page, perPage int) (any, error) {
|
|
result, err := s.client.ListIssuesPaged(ctx, filter, customQuery, page, perPage)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return scopedIssueSearchPage(result, settings, page, perPage), nil
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return v.(*IssueSearchPage), nil
|
|
}
|
|
|
|
func (s *Service) searchUserPagedScoped(
|
|
kind string,
|
|
settings *WorkspaceSettings,
|
|
filter string,
|
|
customQuery string,
|
|
page int,
|
|
perPage int,
|
|
fetch func(page int, perPage int) (any, error),
|
|
) (any, error) {
|
|
if s.client == nil {
|
|
return nil, fmt.Errorf("github client not available")
|
|
}
|
|
page, perPage = clampSearchPage(page, perPage)
|
|
scopeKey := workspaceSearchScopeKey(settings)
|
|
key := searchCacheKey(kind+":"+scopeKey, filter, customQuery, page, perPage)
|
|
return s.searchCache.doOrFetch(key, func() (any, error) {
|
|
return fetch(page, perPage)
|
|
})
|
|
}
|
|
|
|
func (s *Service) searchUserPRsPagedScopedAcrossQualifiers(
|
|
ctx context.Context,
|
|
settings *WorkspaceSettings,
|
|
filter string,
|
|
customQuery string,
|
|
page int,
|
|
perPage int,
|
|
qualifiers []string,
|
|
) (*PRSearchPage, error) {
|
|
result, err := cachedScopedSearchAcrossQualifiers(s.client, s.searchCache, "pr", settings, filter, customQuery, page, perPage, func(page, perPage int) ([]*PR, int, error) {
|
|
return s.fetchScopedPRsAcrossQualifiers(ctx, settings, filter, customQuery, page, perPage, qualifiers)
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &PRSearchPage{PRs: result.items, TotalCount: result.total, Page: result.page, PerPage: result.perPage}, nil
|
|
}
|
|
|
|
func (s *Service) searchUserIssuesPagedScopedAcrossQualifiers(
|
|
ctx context.Context,
|
|
settings *WorkspaceSettings,
|
|
filter string,
|
|
customQuery string,
|
|
page int,
|
|
perPage int,
|
|
qualifiers []string,
|
|
) (*IssueSearchPage, error) {
|
|
result, err := cachedScopedSearchAcrossQualifiers(s.client, s.searchCache, "issue", settings, filter, customQuery, page, perPage, func(page, perPage int) ([]*Issue, int, error) {
|
|
return s.fetchScopedIssuesAcrossQualifiers(ctx, settings, filter, customQuery, page, perPage, qualifiers)
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &IssueSearchPage{Issues: result.items, TotalCount: result.total, Page: result.page, PerPage: result.perPage}, nil
|
|
}
|
|
|
|
type scopedFanoutResult[T any] struct {
|
|
items []T
|
|
total int
|
|
page int
|
|
perPage int
|
|
}
|
|
|
|
func cachedScopedSearchAcrossQualifiers[T any](
|
|
client Client,
|
|
cache *ttlCache,
|
|
kind string,
|
|
settings *WorkspaceSettings,
|
|
filter string,
|
|
customQuery string,
|
|
page int,
|
|
perPage int,
|
|
fetch func(page int, perPage int) ([]T, int, error),
|
|
) (scopedFanoutResult[T], error) {
|
|
if client == nil {
|
|
return scopedFanoutResult[T]{}, fmt.Errorf("github client not available")
|
|
}
|
|
page, perPage = clampSearchPage(page, perPage)
|
|
scopeKey := workspaceSearchScopeKey(settings)
|
|
key := searchCacheKey(kind+":"+scopeKey+":fanout", filter, customQuery, page, perPage)
|
|
v, err := cache.doOrFetch(key, func() (any, error) {
|
|
items, total, err := fetch(page, perPage)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return scopedFanoutResult[T]{
|
|
items: paginateSearchResults(items, page, perPage),
|
|
total: total,
|
|
page: page,
|
|
perPage: perPage,
|
|
}, nil
|
|
})
|
|
if err != nil {
|
|
return scopedFanoutResult[T]{}, err
|
|
}
|
|
return v.(scopedFanoutResult[T]), nil
|
|
}
|
|
|
|
func (s *Service) fetchScopedPRsAcrossQualifiers(
|
|
ctx context.Context,
|
|
settings *WorkspaceSettings,
|
|
filter string,
|
|
customQuery string,
|
|
page int,
|
|
perPage int,
|
|
qualifiers []string,
|
|
) ([]*PR, int, error) {
|
|
return fetchScopedResultsAcrossQualifiers(settings, filter, customQuery, page, perPage, qualifiers, prScopeKey, func(scopedFilter, scopedCustomQuery string, providerPage, fetchPerPage int) ([]*PR, int, error) {
|
|
result, err := s.client.SearchPRsPaged(ctx, scopedFilter, scopedCustomQuery, providerPage, fetchPerPage)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if result == nil {
|
|
return []*PR{}, 0, nil
|
|
}
|
|
return filterPRsByWorkspaceScope(result.PRs, settings), result.TotalCount, nil
|
|
})
|
|
}
|
|
|
|
func (s *Service) fetchScopedIssuesAcrossQualifiers(
|
|
ctx context.Context,
|
|
settings *WorkspaceSettings,
|
|
filter string,
|
|
customQuery string,
|
|
page int,
|
|
perPage int,
|
|
qualifiers []string,
|
|
) ([]*Issue, int, error) {
|
|
return fetchScopedResultsAcrossQualifiers(settings, filter, customQuery, page, perPage, qualifiers, issueScopeKey, func(scopedFilter, scopedCustomQuery string, providerPage, fetchPerPage int) ([]*Issue, int, error) {
|
|
result, err := s.client.ListIssuesPaged(ctx, scopedFilter, scopedCustomQuery, providerPage, fetchPerPage)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if result == nil {
|
|
return []*Issue{}, 0, nil
|
|
}
|
|
return filterIssuesByWorkspaceScope(result.Issues, settings), result.TotalCount, nil
|
|
})
|
|
}
|
|
|
|
func fetchScopedResultsAcrossQualifiers[T any](
|
|
settings *WorkspaceSettings,
|
|
filter string,
|
|
customQuery string,
|
|
page int,
|
|
perPage int,
|
|
qualifiers []string,
|
|
resultKey func(T) string,
|
|
fetch func(scopedFilter string, scopedCustomQuery string, providerPage int, fetchPerPage int) ([]T, int, error),
|
|
) ([]T, int, error) {
|
|
seen := make(map[string]struct{})
|
|
all := make([]T, 0, perPage)
|
|
fetchPerPage := workspaceScopeFanoutFetchPerPage(page, perPage)
|
|
pagesToFetch := workspaceScopeFanoutPagesToFetch(page, perPage, fetchPerPage)
|
|
counts := make([]int, 0, len(qualifiers))
|
|
for _, qualifier := range qualifiers {
|
|
scopedFilter, scopedCustomQuery := appendWorkspaceScopeQualifierToSearch(filter, customQuery, qualifier)
|
|
qualifierCount := 0
|
|
for providerPage := 1; providerPage <= pagesToFetch; providerPage++ {
|
|
items, count, err := fetch(scopedFilter, scopedCustomQuery, providerPage, fetchPerPage)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if providerPage == 1 {
|
|
qualifierCount = count
|
|
}
|
|
for _, item := range items {
|
|
key := resultKey(item)
|
|
if key == "" {
|
|
continue
|
|
}
|
|
if _, ok := seen[key]; ok {
|
|
continue
|
|
}
|
|
seen[key] = struct{}{}
|
|
all = append(all, item)
|
|
}
|
|
if workspaceScopeFanoutFetchedAll(providerPage, fetchPerPage, count, len(items)) {
|
|
break
|
|
}
|
|
}
|
|
counts = append(counts, qualifierCount)
|
|
}
|
|
return all, workspaceScopeFanoutTotal(settings, counts, len(all)), nil
|
|
}
|
|
|
|
func workspaceScopeFanoutFetchPerPage(page, perPage int) int {
|
|
fetchPerPage := page * perPage
|
|
if fetchPerPage < perPage {
|
|
return perPage
|
|
}
|
|
if fetchPerPage > 100 {
|
|
return 100
|
|
}
|
|
return fetchPerPage
|
|
}
|
|
|
|
func workspaceScopeFanoutPagesToFetch(page, perPage, fetchPerPage int) int {
|
|
if fetchPerPage <= 0 {
|
|
return 1
|
|
}
|
|
target := page * perPage
|
|
if target < perPage {
|
|
target = perPage
|
|
}
|
|
pages := target / fetchPerPage
|
|
if target%fetchPerPage != 0 {
|
|
pages++
|
|
}
|
|
if pages < 1 {
|
|
return 1
|
|
}
|
|
return pages
|
|
}
|
|
|
|
func workspaceScopeFanoutFetchedAll(providerPage, fetchPerPage, totalCount, itemCount int) bool {
|
|
if itemCount == 0 {
|
|
return true
|
|
}
|
|
if itemCount < fetchPerPage {
|
|
return true
|
|
}
|
|
return totalCount > 0 && providerPage*fetchPerPage >= totalCount
|
|
}
|
|
|
|
func workspaceScopeFanoutTotal(settings *WorkspaceSettings, counts []int, uniqueFetched int) int {
|
|
settings = normalizeWorkspaceSettings(settings)
|
|
if settings == nil || settings.RepoScopeMode != RepoScopeModeOrgs {
|
|
return sumInts(counts)
|
|
}
|
|
total := 0
|
|
for i := 0; i < len(counts); i += 2 {
|
|
if i+1 >= len(counts) {
|
|
total += counts[i]
|
|
continue
|
|
}
|
|
total += max(counts[i], counts[i+1])
|
|
}
|
|
if uniqueFetched > total {
|
|
return uniqueFetched
|
|
}
|
|
return total
|
|
}
|
|
|
|
func sumInts(values []int) int {
|
|
total := 0
|
|
for _, value := range values {
|
|
total += value
|
|
}
|
|
return total
|
|
}
|
|
|
|
func paginateSearchResults[T any](items []T, page, perPage int) []T {
|
|
if len(items) == 0 {
|
|
return []T{}
|
|
}
|
|
start := (page - 1) * perPage
|
|
if start >= len(items) {
|
|
return []T{}
|
|
}
|
|
end := start + perPage
|
|
if end > len(items) {
|
|
end = len(items)
|
|
}
|
|
return append([]T(nil), items[start:end]...)
|
|
}
|
|
|
|
func prScopeKey(pr *PR) string {
|
|
if pr == nil {
|
|
return ""
|
|
}
|
|
return strings.ToLower(strings.TrimSpace(fmt.Sprintf("%s/%s#%d", pr.RepoOwner, pr.RepoName, pr.Number)))
|
|
}
|
|
|
|
func issueScopeKey(issue *Issue) string {
|
|
if issue == nil {
|
|
return ""
|
|
}
|
|
return strings.ToLower(strings.TrimSpace(fmt.Sprintf("%s/%s#%d", issue.RepoOwner, issue.RepoName, issue.Number)))
|
|
}
|
|
|
|
func scopedPRSearchPage(result *PRSearchPage, settings *WorkspaceSettings, page int, perPage int) *PRSearchPage {
|
|
if result == nil {
|
|
result = &PRSearchPage{Page: page, PerPage: perPage}
|
|
}
|
|
result.PRs = filterPRsByWorkspaceScope(result.PRs, settings)
|
|
result.Page = page
|
|
result.PerPage = perPage
|
|
return result
|
|
}
|
|
|
|
func scopedIssueSearchPage(result *IssueSearchPage, settings *WorkspaceSettings, page int, perPage int) *IssueSearchPage {
|
|
if result == nil {
|
|
result = &IssueSearchPage{Page: page, PerPage: perPage}
|
|
}
|
|
result.Issues = filterIssuesByWorkspaceScope(result.Issues, settings)
|
|
result.Page = page
|
|
result.PerPage = perPage
|
|
return result
|
|
}
|
|
|
|
func workspaceSettingsHasScope(settings *WorkspaceSettings) bool {
|
|
settings = normalizeWorkspaceSettings(settings)
|
|
if settings == nil {
|
|
return false
|
|
}
|
|
switch settings.RepoScopeMode {
|
|
case RepoScopeModeOrgs, RepoScopeModeRepos:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func workspaceSettingsHasEmptyScope(settings *WorkspaceSettings) bool {
|
|
return workspaceSettingsHasScope(settings) && len(workspaceScopeQualifiers(settings)) == 0
|
|
}
|
|
|
|
func isValidRepoScopeMode(mode string) bool {
|
|
switch strings.TrimSpace(strings.ToLower(mode)) {
|
|
case RepoScopeModeAll, RepoScopeModeOrgs, RepoScopeModeRepos:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func appendWorkspaceScopeToSearch(filter, customQuery string, settings *WorkspaceSettings) (string, string) {
|
|
qualifiers := workspaceScopeQualifiers(settings)
|
|
if len(qualifiers) == 0 {
|
|
return filter, customQuery
|
|
}
|
|
return appendWorkspaceScopeQualifierToSearch(filter, customQuery, qualifiers[0])
|
|
}
|
|
|
|
func appendWorkspaceScopeQualifierToSearch(filter, customQuery, qualifier string) (string, string) {
|
|
if strings.TrimSpace(customQuery) != "" {
|
|
return filter, appendWorkspaceScopeQualifier(customQuery, qualifier)
|
|
}
|
|
return appendWorkspaceScopeQualifier(filter, qualifier), customQuery
|
|
}
|
|
|
|
func appendWorkspaceScopeQualifier(query, qualifier string) string {
|
|
return strings.TrimSpace(strings.Join([]string{query, qualifier}, " "))
|
|
}
|
|
|
|
func workspaceScopeQualifiers(settings *WorkspaceSettings) []string {
|
|
settings = normalizeWorkspaceSettings(settings)
|
|
if settings == nil {
|
|
return nil
|
|
}
|
|
switch settings.RepoScopeMode {
|
|
case RepoScopeModeOrgs:
|
|
qualifiers := make([]string, 0, len(settings.RepoScopeOrgs)*2)
|
|
for _, org := range settings.RepoScopeOrgs {
|
|
if org = strings.TrimSpace(org); org != "" {
|
|
qualifiers = append(qualifiers, "org:"+org)
|
|
qualifiers = append(qualifiers, "user:"+org)
|
|
}
|
|
}
|
|
return qualifiers
|
|
case RepoScopeModeRepos:
|
|
qualifiers := make([]string, 0, len(settings.RepoScopeRepos))
|
|
for _, repo := range settings.RepoScopeRepos {
|
|
if repo.Owner != "" && repo.Name != "" {
|
|
qualifiers = append(qualifiers, repoFilterToQualifier(repo))
|
|
}
|
|
}
|
|
return qualifiers
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func workspaceScopeRepoFilters(settings *WorkspaceSettings) []RepoFilter {
|
|
settings = normalizeWorkspaceSettings(settings)
|
|
if settings == nil {
|
|
return nil
|
|
}
|
|
switch settings.RepoScopeMode {
|
|
case RepoScopeModeOrgs:
|
|
repos := make([]RepoFilter, 0, len(settings.RepoScopeOrgs))
|
|
for _, org := range settings.RepoScopeOrgs {
|
|
if org = strings.TrimSpace(org); org != "" {
|
|
repos = append(repos, RepoFilter{Owner: org})
|
|
}
|
|
}
|
|
return repos
|
|
case RepoScopeModeRepos:
|
|
return append([]RepoFilter(nil), settings.RepoScopeRepos...)
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func workspaceSearchScopeKey(settings *WorkspaceSettings) string {
|
|
settings = normalizeWorkspaceSettings(settings)
|
|
if settings == nil {
|
|
return RepoScopeModeAll
|
|
}
|
|
var parts []string
|
|
switch settings.RepoScopeMode {
|
|
case RepoScopeModeOrgs:
|
|
parts = append(parts, settings.RepoScopeOrgs...)
|
|
case RepoScopeModeRepos:
|
|
for _, repo := range settings.RepoScopeRepos {
|
|
parts = append(parts, repo.Owner+"/"+repo.Name)
|
|
}
|
|
}
|
|
return settings.RepoScopeMode + ":" + strings.Join(parts, ",")
|
|
}
|
|
|
|
func filterPRsByWorkspaceScope(prs []*PR, settings *WorkspaceSettings) []*PR {
|
|
if !workspaceSettingsHasScope(settings) {
|
|
if prs == nil {
|
|
return []*PR{}
|
|
}
|
|
return prs
|
|
}
|
|
out := make([]*PR, 0, len(prs))
|
|
for _, pr := range prs {
|
|
if pr != nil && repoAllowedByWorkspaceScope(pr.RepoOwner, pr.RepoName, settings) {
|
|
out = append(out, pr)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func filterIssuesByWorkspaceScope(issues []*Issue, settings *WorkspaceSettings) []*Issue {
|
|
if !workspaceSettingsHasScope(settings) {
|
|
if issues == nil {
|
|
return []*Issue{}
|
|
}
|
|
return issues
|
|
}
|
|
out := make([]*Issue, 0, len(issues))
|
|
for _, issue := range issues {
|
|
if issue != nil && repoAllowedByWorkspaceScope(issue.RepoOwner, issue.RepoName, settings) {
|
|
out = append(out, issue)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func repoAllowedByWorkspaceScope(owner, name string, settings *WorkspaceSettings) bool {
|
|
settings = normalizeWorkspaceSettings(settings)
|
|
if settings == nil || settings.RepoScopeMode == RepoScopeModeAll {
|
|
return true
|
|
}
|
|
owner = strings.ToLower(strings.TrimSpace(owner))
|
|
name = strings.ToLower(strings.TrimSpace(name))
|
|
switch settings.RepoScopeMode {
|
|
case RepoScopeModeOrgs:
|
|
for _, org := range settings.RepoScopeOrgs {
|
|
if strings.ToLower(org) == owner {
|
|
return true
|
|
}
|
|
}
|
|
case RepoScopeModeRepos:
|
|
for _, repo := range settings.RepoScopeRepos {
|
|
if strings.ToLower(repo.Owner) == owner && strings.ToLower(repo.Name) == name {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|