* _ to unused func options * rm useless brakets * rm trifial non used models functions * rm dead code * rm dead global vars * fix routers/api/v1/repo/issue.go * dont overload import moduletags/v1.15.0-rc1
return models.DeleteUser(user) | return models.DeleteUser(user) | ||||
} | } | ||||
func runRepoSyncReleases(c *cli.Context) error { | |||||
func runRepoSyncReleases(_ *cli.Context) error { | |||||
if err := initDB(); err != nil { | if err := initDB(); err != nil { | ||||
return err | return err | ||||
} | } | ||||
) | ) | ||||
} | } | ||||
func runRegenerateHooks(c *cli.Context) error { | |||||
func runRegenerateHooks(_ *cli.Context) error { | |||||
if err := initDB(); err != nil { | if err := initDB(); err != nil { | ||||
return err | return err | ||||
} | } | ||||
return repo_module.SyncRepositoryHooks(graceful.GetManager().ShutdownContext()) | return repo_module.SyncRepositoryHooks(graceful.GetManager().ShutdownContext()) | ||||
} | } | ||||
func runRegenerateKeys(c *cli.Context) error { | |||||
func runRegenerateKeys(_ *cli.Context) error { | |||||
if err := initDB(); err != nil { | if err := initDB(); err != nil { | ||||
return err | return err | ||||
} | } |
} | } | ||||
// the environment setted on serv command | // the environment setted on serv command | ||||
isWiki := (os.Getenv(models.EnvRepoIsWiki) == "true") | |||||
isWiki := os.Getenv(models.EnvRepoIsWiki) == "true" | |||||
username := os.Getenv(models.EnvRepoUsername) | username := os.Getenv(models.EnvRepoUsername) | ||||
reponame := os.Getenv(models.EnvRepoName) | reponame := os.Getenv(models.EnvRepoName) | ||||
userID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64) | userID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64) | ||||
// the environment setted on serv command | // the environment setted on serv command | ||||
repoUser := os.Getenv(models.EnvRepoUsername) | repoUser := os.Getenv(models.EnvRepoUsername) | ||||
isWiki := (os.Getenv(models.EnvRepoIsWiki) == "true") | |||||
isWiki := os.Getenv(models.EnvRepoIsWiki) == "true" | |||||
repoName := os.Getenv(models.EnvRepoName) | repoName := os.Getenv(models.EnvRepoName) | ||||
pusherID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64) | pusherID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64) | ||||
pusherName := os.Getenv(models.EnvPusherName) | pusherName := os.Getenv(models.EnvPusherName) |
return r | return r | ||||
} | } | ||||
// GetProtectedBranchByRepoID getting protected branch by repo ID | |||||
func GetProtectedBranchByRepoID(repoID int64) ([]*ProtectedBranch, error) { | |||||
protectedBranches := make([]*ProtectedBranch, 0) | |||||
return protectedBranches, x.Where("repo_id = ?", repoID).Desc("updated_unix").Find(&protectedBranches) | |||||
} | |||||
// GetProtectedBranchBy getting protected branch by ID/Name | // GetProtectedBranchBy getting protected branch by ID/Name | ||||
func GetProtectedBranchBy(repoID int64, branchName string) (*ProtectedBranch, error) { | func GetProtectedBranchBy(repoID int64, branchName string) (*ProtectedBranch, error) { | ||||
return getProtectedBranchBy(x, repoID, branchName) | return getProtectedBranchBy(x, repoID, branchName) | ||||
return rel, nil | return rel, nil | ||||
} | } | ||||
// GetProtectedBranchByID getting protected branch by ID | |||||
func GetProtectedBranchByID(id int64) (*ProtectedBranch, error) { | |||||
rel := &ProtectedBranch{} | |||||
has, err := x.ID(id).Get(rel) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
if !has { | |||||
return nil, nil | |||||
} | |||||
return rel, nil | |||||
} | |||||
// WhitelistOptions represent all sorts of whitelists used for protected branches | // WhitelistOptions represent all sorts of whitelists used for protected branches | ||||
type WhitelistOptions struct { | type WhitelistOptions struct { | ||||
UserIDs []int64 | UserIDs []int64 |
Find(&labelIDs) | Find(&labelIDs) | ||||
} | } | ||||
// GetLabelIDsInOrgsByNames returns a list of labelIDs by names in one of the given | |||||
// organization. | |||||
// it silently ignores label names that do not belong to the organization. | |||||
func GetLabelIDsInOrgsByNames(orgIDs []int64, labelNames []string) ([]int64, error) { | |||||
labelIDs := make([]int64, 0, len(labelNames)) | |||||
return labelIDs, x.Table("label"). | |||||
In("org_id", orgIDs). | |||||
In("name", labelNames). | |||||
Asc("name"). | |||||
Cols("id"). | |||||
Find(&labelIDs) | |||||
} | |||||
// GetLabelInOrgByID returns a label by ID in given organization. | // GetLabelInOrgByID returns a label by ID in given organization. | ||||
func GetLabelInOrgByID(orgID, labelID int64) (*Label, error) { | func GetLabelInOrgByID(orgID, labelID int64) (*Label, error) { | ||||
return getLabelInOrgByID(x, orgID, labelID) | return getLabelInOrgByID(x, orgID, labelID) |
func LFSObjectAccessible(user *User, oid string) (bool, error) { | func LFSObjectAccessible(user *User, oid string) (bool, error) { | ||||
if user.IsAdmin { | if user.IsAdmin { | ||||
count, err := x.Count(&LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}}) | count, err := x.Count(&LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}}) | ||||
return (count > 0), err | |||||
return count > 0, err | |||||
} | } | ||||
cond := accessibleRepositoryCondition(user) | cond := accessibleRepositoryCondition(user) | ||||
count, err := x.Where(cond).Join("INNER", "repository", "`lfs_meta_object`.repository_id = `repository`.id").Count(&LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}}) | count, err := x.Where(cond).Join("INNER", "repository", "`lfs_meta_object`.repository_id = `repository`.id").Count(&LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}}) | ||||
return (count > 0), err | |||||
return count > 0, err | |||||
} | } | ||||
// LFSAutoAssociate auto associates accessible LFSMetaObjects | // LFSAutoAssociate auto associates accessible LFSMetaObjects |
assert.NoError(t, err2) | assert.NoError(t, err2) | ||||
assert.NoError(t, err3) | assert.NoError(t, err3) | ||||
assert.Equal(t, int64(3), count) | assert.Equal(t, int64(3), count) | ||||
assert.Equal(t, (privateCount + publicCount), count) | |||||
assert.Equal(t, privateCount+publicCount, count) | |||||
} | } | ||||
func TestGetPublicRepositoryCount(t *testing.T) { | func TestGetPublicRepositoryCount(t *testing.T) { |
) | ) | ||||
var ( | var ( | ||||
// ErrUserNotKeyOwner user does not own this key error | |||||
ErrUserNotKeyOwner = errors.New("User does not own this public key") | |||||
// ErrEmailNotExist e-mail does not exist error | // ErrEmailNotExist e-mail does not exist error | ||||
ErrEmailNotExist = errors.New("E-mail does not exist") | ErrEmailNotExist = errors.New("E-mail does not exist") | ||||
Select(groupBy+" AS timestamp, count(user_id) as contributions"). | Select(groupBy+" AS timestamp, count(user_id) as contributions"). | ||||
Table("action"). | Table("action"). | ||||
Where(cond). | Where(cond). | ||||
And("created_unix > ?", (timeutil.TimeStampNow() - 31536000)). | |||||
And("created_unix > ?", timeutil.TimeStampNow()-31536000). | |||||
GroupBy(groupByName). | GroupBy(groupByName). | ||||
OrderBy("timestamp"). | OrderBy("timestamp"). | ||||
Find(&hdata) | Find(&hdata) |
return openids, nil | return openids, nil | ||||
} | } | ||||
// isOpenIDUsed returns true if the openid has been used. | |||||
func isOpenIDUsed(e Engine, uri string) (bool, error) { | func isOpenIDUsed(e Engine, uri string) (bool, error) { | ||||
if len(uri) == 0 { | if len(uri) == 0 { | ||||
return true, nil | return true, nil | ||||
return e.Get(&UserOpenID{URI: uri}) | return e.Get(&UserOpenID{URI: uri}) | ||||
} | } | ||||
// IsOpenIDUsed returns true if the openid has been used. | |||||
func IsOpenIDUsed(openid string) (bool, error) { | |||||
return isOpenIDUsed(x, openid) | |||||
} | |||||
// NOTE: make sure openid.URI is normalized already | // NOTE: make sure openid.URI is normalized already | ||||
func addUserOpenID(e Engine, openid *UserOpenID) error { | func addUserOpenID(e Engine, openid *UserOpenID) error { | ||||
used, err := isOpenIDUsed(e, openid.URI) | used, err := isOpenIDUsed(e, openid.URI) |
} | } | ||||
} | } | ||||
} | } | ||||
if m == nil { | |||||
return nil | |||||
} | |||||
if consumes != 0 { | if consumes != 0 { | ||||
s := segment.WithStop(segment.Start + 1) | s := segment.WithStop(segment.Start + 1) | ||||
ast.MergeOrAppendTextSegment(parent, s) | ast.MergeOrAppendTextSegment(parent, s) |
import ( | import ( | ||||
"bytes" | "bytes" | ||||
"context" | "context" | ||||
"errors" | |||||
"fmt" | "fmt" | ||||
"io" | "io" | ||||
"os/exec" | "os/exec" | ||||
// then we delete the singleton. | // then we delete the singleton. | ||||
var ( | var ( | ||||
// ErrExecTimeout represent a timeout error | |||||
ErrExecTimeout = errors.New("Process execution timeout") | |||||
manager *Manager | |||||
managerInit sync.Once | |||||
manager *Manager | |||||
managerInit sync.Once | |||||
// DefaultContext is the default context to run processing commands in | // DefaultContext is the default context to run processing commands in | ||||
DefaultContext = context.Background() | DefaultContext = context.Background() |
Has(data []byte) (bool, error) | Has(data []byte) (bool, error) | ||||
} | } | ||||
var _ (ByteFIFO) = &DummyByteFIFO{} | |||||
var _ ByteFIFO = &DummyByteFIFO{} | |||||
// DummyByteFIFO represents a dummy fifo | // DummyByteFIFO represents a dummy fifo | ||||
type DummyByteFIFO struct{} | type DummyByteFIFO struct{} | ||||
return 0 | return 0 | ||||
} | } | ||||
var _ (UniqueByteFIFO) = &DummyUniqueByteFIFO{} | |||||
var _ UniqueByteFIFO = &DummyUniqueByteFIFO{} | |||||
// DummyUniqueByteFIFO represents a dummy unique fifo | // DummyUniqueByteFIFO represents a dummy unique fifo | ||||
type DummyUniqueByteFIFO struct { | type DummyUniqueByteFIFO struct { |
var err error | var err error | ||||
configBytes, err = json.Marshal(cfg) | configBytes, err = json.Marshal(cfg) | ||||
ok = (err == nil) | |||||
ok = err == nil | |||||
} | } | ||||
if !ok { | if !ok { | ||||
// no ... we've tried hard enough at this point - throw an error! | // no ... we've tried hard enough at this point - throw an error! |
Name string | Name string | ||||
} | } | ||||
var _ (Queue) = &ByteFIFOQueue{} | |||||
var _ Queue = &ByteFIFOQueue{} | |||||
// ByteFIFOQueue is a Queue formed from a ByteFIFO and WorkerPool | // ByteFIFOQueue is a Queue formed from a ByteFIFO and WorkerPool | ||||
type ByteFIFOQueue struct { | type ByteFIFOQueue struct { | ||||
return q.terminated | return q.terminated | ||||
} | } | ||||
var _ (UniqueQueue) = &ByteFIFOUniqueQueue{} | |||||
var _ UniqueQueue = &ByteFIFOUniqueQueue{} | |||||
// ByteFIFOUniqueQueue represents a UniqueQueue formed from a UniqueByteFifo | // ByteFIFOUniqueQueue represents a UniqueQueue formed from a UniqueByteFifo | ||||
type ByteFIFOUniqueQueue struct { | type ByteFIFOUniqueQueue struct { |
return queue, nil | return queue, nil | ||||
} | } | ||||
var _ (ByteFIFO) = &LevelQueueByteFIFO{} | |||||
var _ ByteFIFO = &LevelQueueByteFIFO{} | |||||
// LevelQueueByteFIFO represents a ByteFIFO formed from a LevelQueue | // LevelQueueByteFIFO represents a ByteFIFO formed from a LevelQueue | ||||
type LevelQueueByteFIFO struct { | type LevelQueueByteFIFO struct { |
Close() error | Close() error | ||||
} | } | ||||
var _ (ByteFIFO) = &RedisByteFIFO{} | |||||
var _ ByteFIFO = &RedisByteFIFO{} | |||||
// RedisByteFIFO represents a ByteFIFO formed from a redisClient | // RedisByteFIFO represents a ByteFIFO formed from a redisClient | ||||
type RedisByteFIFO struct { | type RedisByteFIFO struct { |
return queue, nil | return queue, nil | ||||
} | } | ||||
var _ (UniqueByteFIFO) = &LevelUniqueQueueByteFIFO{} | |||||
var _ UniqueByteFIFO = &LevelUniqueQueueByteFIFO{} | |||||
// LevelUniqueQueueByteFIFO represents a ByteFIFO formed from a LevelUniqueQueue | // LevelUniqueQueueByteFIFO represents a ByteFIFO formed from a LevelUniqueQueue | ||||
type LevelUniqueQueueByteFIFO struct { | type LevelUniqueQueueByteFIFO struct { |
return queue, nil | return queue, nil | ||||
} | } | ||||
var _ (UniqueByteFIFO) = &RedisUniqueByteFIFO{} | |||||
var _ UniqueByteFIFO = &RedisUniqueByteFIFO{} | |||||
// RedisUniqueByteFIFO represents a UniqueByteFIFO formed from a redisClient | // RedisUniqueByteFIFO represents a UniqueByteFIFO formed from a redisClient | ||||
type RedisUniqueByteFIFO struct { | type RedisUniqueByteFIFO struct { |
// our new section has length endPos - match[3] | // our new section has length endPos - match[3] | ||||
// our old section has length match[9] - match[3] | // our old section has length match[9] - match[3] | ||||
(*contentBytes) = (*contentBytes)[:len((*contentBytes))-match[9]+endPos] | |||||
*contentBytes = (*contentBytes)[:len(*contentBytes)-match[9]+endPos] | |||||
pos = endPos | pos = endPos | ||||
} | } | ||||
} | } |
continue | continue | ||||
} | } | ||||
} | } | ||||
close := (ref.Action == references.XRefActionCloses) | |||||
close := ref.Action == references.XRefActionCloses | |||||
if close && len(ref.TimeLog) > 0 { | if close && len(ref.TimeLog) > 0 { | ||||
if err := issueAddTime(refIssue, doer, c.Timestamp, ref.TimeLog); err != nil { | if err := issueAddTime(refIssue, doer, c.Timestamp, ref.TimeLog); err != nil { | ||||
return err | return err |
LogRootPath string | LogRootPath string | ||||
DisableRouterLog bool | DisableRouterLog bool | ||||
RouterLogLevel log.Level | RouterLogLevel log.Level | ||||
RouterLogMode string | |||||
EnableAccessLog bool | EnableAccessLog bool | ||||
AccessLogTemplate string | AccessLogTemplate string | ||||
EnableXORMLog bool | EnableXORMLog bool | ||||
IsWindows bool | IsWindows bool | ||||
HasRobotsTxt bool | HasRobotsTxt bool | ||||
InternalToken string // internal access token | InternalToken string // internal access token | ||||
// UILocation is the location on the UI, so that we can display the time on UI. | |||||
// Currently only show the default time.Local, it could be added to app.ini after UI is ready | |||||
UILocation = time.Local | |||||
) | ) | ||||
// IsProd if it's a production mode | // IsProd if it's a production mode |
var err error | var err error | ||||
configBytes, err = json.Marshal(cfg) | configBytes, err = json.Marshal(cfg) | ||||
ok = (err == nil) | |||||
ok = err == nil | |||||
} | } | ||||
if !ok { | if !ok { | ||||
// no ... we've tried hard enough at this point - throw an error! | // no ... we've tried hard enough at this point - throw an error! |
var ( | var ( | ||||
// ErrURLNotSupported represents url is not supported | // ErrURLNotSupported represents url is not supported | ||||
ErrURLNotSupported = errors.New("url method not supported") | ErrURLNotSupported = errors.New("url method not supported") | ||||
// ErrIterateObjectsNotSupported represents IterateObjects not supported | |||||
ErrIterateObjectsNotSupported = errors.New("iterateObjects method not supported") | |||||
) | ) | ||||
// ErrInvalidConfiguration is called when there is invalid configuration for a storage | // ErrInvalidConfiguration is called when there is invalid configuration for a storage |
UserID: ctx.User.ID, | UserID: ctx.User.ID, | ||||
Keyword: strings.TrimSpace(ctx.Query("q")), | Keyword: strings.TrimSpace(ctx.Query("q")), | ||||
OrgID: ctx.Org.Organization.ID, | OrgID: ctx.Org.Organization.ID, | ||||
IncludeDesc: (ctx.Query("include_desc") == "" || ctx.QueryBool("include_desc")), | |||||
IncludeDesc: ctx.Query("include_desc") == "" || ctx.QueryBool("include_desc"), | |||||
ListOptions: listOptions, | ListOptions: listOptions, | ||||
} | } | ||||
keyword = "" | keyword = "" | ||||
} | } | ||||
var issueIDs []int64 | var issueIDs []int64 | ||||
var labelIDs []int64 | |||||
if len(keyword) > 0 && len(repoIDs) > 0 { | if len(keyword) > 0 && len(repoIDs) > 0 { | ||||
if issueIDs, err = issue_indexer.SearchIssuesByKeyword(repoIDs, keyword); err != nil { | if issueIDs, err = issue_indexer.SearchIssuesByKeyword(repoIDs, keyword); err != nil { | ||||
ctx.Error(http.StatusInternalServerError, "SearchIssuesByKeyword", err) | ctx.Error(http.StatusInternalServerError, "SearchIssuesByKeyword", err) | ||||
// Only fetch the issues if we either don't have a keyword or the search returned issues | // Only fetch the issues if we either don't have a keyword or the search returned issues | ||||
// This would otherwise return all issues if no issues were found by the search. | // This would otherwise return all issues if no issues were found by the search. | ||||
if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 { | |||||
if len(keyword) == 0 || len(issueIDs) > 0 || len(includedLabelNames) > 0 { | |||||
issuesOpt := &models.IssuesOptions{ | issuesOpt := &models.IssuesOptions{ | ||||
ListOptions: models.ListOptions{ | ListOptions: models.ListOptions{ | ||||
Page: ctx.QueryInt("page"), | Page: ctx.QueryInt("page"), | ||||
} | } | ||||
} | } | ||||
if form.State != nil { | if form.State != nil { | ||||
issue.IsClosed = (api.StateClosed == api.StateType(*form.State)) | |||||
issue.IsClosed = api.StateClosed == api.StateType(*form.State) | |||||
} | } | ||||
statusChangeComment, titleChanged, err := models.UpdateIssueByAPI(issue, ctx.User) | statusChangeComment, titleChanged, err := models.UpdateIssueByAPI(issue, ctx.User) | ||||
if err != nil { | if err != nil { |
} | } | ||||
if form.State != nil { | if form.State != nil { | ||||
issue.IsClosed = (api.StateClosed == api.StateType(*form.State)) | |||||
issue.IsClosed = api.StateClosed == api.StateType(*form.State) | |||||
} | } | ||||
statusChangeComment, titleChanged, err := models.UpdateIssueByAPI(issue, ctx.User) | statusChangeComment, titleChanged, err := models.UpdateIssueByAPI(issue, ctx.User) | ||||
if err != nil { | if err != nil { |
if !ctx.IsSigned { | if !ctx.IsSigned { | ||||
// Return unauthorized status event | // Return unauthorized status event | ||||
event := (&eventsource.Event{ | |||||
event := &eventsource.Event{ | |||||
Name: "close", | Name: "close", | ||||
Data: "unauthorized", | Data: "unauthorized", | ||||
}) | |||||
} | |||||
_, _ = event.WriteTo(ctx) | _, _ = event.WriteTo(ctx) | ||||
ctx.Resp.Flush() | ctx.Resp.Flush() | ||||
return | return | ||||
break loop | break loop | ||||
} | } | ||||
// Replace the event - we don't want to expose the session ID to the user | // Replace the event - we don't want to expose the session ID to the user | ||||
event = (&eventsource.Event{ | |||||
event = &eventsource.Event{ | |||||
Name: "logout", | Name: "logout", | ||||
Data: "elsewhere", | Data: "elsewhere", | ||||
}) | |||||
} | |||||
} | } | ||||
_, err := event.WriteTo(ctx.Resp) | _, err := event.WriteTo(ctx.Resp) |
ctx.Data["PageIsOrgTeams"] = true | ctx.Data["PageIsOrgTeams"] = true | ||||
ctx.Data["PageIsOrgTeamsNew"] = true | ctx.Data["PageIsOrgTeamsNew"] = true | ||||
ctx.Data["Units"] = models.Units | ctx.Data["Units"] = models.Units | ||||
var includesAllRepositories = (form.RepoAccess == "all") | |||||
var includesAllRepositories = form.RepoAccess == "all" | |||||
t := &models.Team{ | t := &models.Team{ | ||||
OrgID: ctx.Org.Organization.ID, | OrgID: ctx.Org.Organization.ID, | ||||
isAuthChanged := false | isAuthChanged := false | ||||
isIncludeAllChanged := false | isIncludeAllChanged := false | ||||
var includesAllRepositories = (form.RepoAccess == "all") | |||||
var includesAllRepositories = form.RepoAccess == "all" | |||||
if !t.IsOwnerTeam() { | if !t.IsOwnerTeam() { | ||||
// Validate permission level. | // Validate permission level. | ||||
auth := models.ParseAccessMode(form.Permission) | auth := models.ParseAccessMode(form.Permission) |
strings.HasSuffix(ctx.Req.URL.Path, "git-upload-archive") { | strings.HasSuffix(ctx.Req.URL.Path, "git-upload-archive") { | ||||
isPull = true | isPull = true | ||||
} else { | } else { | ||||
isPull = (ctx.Req.Method == "GET") | |||||
isPull = ctx.Req.Method == "GET" | |||||
} | } | ||||
var accessMode models.AccessMode | var accessMode models.AccessMode |
) | ) | ||||
var ( | var ( | ||||
// ErrTooManyFiles upload too many files | |||||
ErrTooManyFiles = errors.New("Maximum number of files to upload exceeded") | |||||
// IssueTemplateCandidates issue templates | // IssueTemplateCandidates issue templates | ||||
IssueTemplateCandidates = []string{ | IssueTemplateCandidates = []string{ | ||||
"ISSUE_TEMPLATE.md", | "ISSUE_TEMPLATE.md", |
c.Data["merge_whitelist_users"] = strings.Join(base.Int64sToStrings(protectBranch.MergeWhitelistUserIDs), ",") | c.Data["merge_whitelist_users"] = strings.Join(base.Int64sToStrings(protectBranch.MergeWhitelistUserIDs), ",") | ||||
c.Data["approvals_whitelist_users"] = strings.Join(base.Int64sToStrings(protectBranch.ApprovalsWhitelistUserIDs), ",") | c.Data["approvals_whitelist_users"] = strings.Join(base.Int64sToStrings(protectBranch.ApprovalsWhitelistUserIDs), ",") | ||||
contexts, _ := models.FindRepoRecentCommitStatusContexts(c.Repo.Repository.ID, 7*24*time.Hour) // Find last week status check contexts | contexts, _ := models.FindRepoRecentCommitStatusContexts(c.Repo.Repository.ID, 7*24*time.Hour) // Find last week status check contexts | ||||
for _, context := range protectBranch.StatusCheckContexts { | |||||
for _, ctx := range protectBranch.StatusCheckContexts { | |||||
var found bool | var found bool | ||||
for _, ctx := range contexts { | |||||
if ctx == context { | |||||
for i := range contexts { | |||||
if contexts[i] == ctx { | |||||
found = true | found = true | ||||
break | break | ||||
} | } | ||||
} | } | ||||
if !found { | if !found { | ||||
contexts = append(contexts, context) | |||||
contexts = append(contexts, ctx) | |||||
} | } | ||||
} | } | ||||
if team != nil { | if team != nil { | ||||
env = ctxUser.AccessibleTeamReposEnv(team) | env = ctxUser.AccessibleTeamReposEnv(team) | ||||
if err != nil { | |||||
return nil, fmt.Errorf("AccessibleTeamReposEnv: %v", err) | |||||
} | |||||
} else { | } else { | ||||
env, err = ctxUser.AccessibleReposEnv(ctxUser.ID) | env, err = ctxUser.AccessibleReposEnv(ctxUser.ID) | ||||
if err != nil { | if err != nil { |
if err = ref.Issue.LoadRepo(); err != nil { | if err = ref.Issue.LoadRepo(); err != nil { | ||||
return err | return err | ||||
} | } | ||||
close := (ref.RefAction == references.XRefActionCloses) | |||||
close := ref.RefAction == references.XRefActionCloses | |||||
if close != ref.Issue.IsClosed { | if close != ref.Issue.IsClosed { | ||||
if err = issue_service.ChangeStatus(ref.Issue, doer, close); err != nil { | if err = issue_service.ChangeStatus(ref.Issue, doer, close); err != nil { | ||||
return err | return err |