2019-10-26 09:54:11 +03:00
// Copyright 2019 The Gitea Authors. All rights reserved.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2019-10-26 09:54:11 +03:00
package repository
import (
2022-01-20 02:26:57 +03:00
"context"
2019-12-15 05:49:52 +03:00
"fmt"
2022-05-08 19:46:32 +03:00
"code.gitea.io/gitea/models/db"
2023-05-14 00:59:01 +03:00
"code.gitea.io/gitea/models/git"
2022-06-13 12:37:59 +03:00
issues_model "code.gitea.io/gitea/models/issues"
2022-03-29 09:29:02 +03:00
"code.gitea.io/gitea/models/organization"
2022-03-30 11:42:47 +03:00
packages_model "code.gitea.io/gitea/models/packages"
2021-12-10 04:27:50 +03:00
repo_model "code.gitea.io/gitea/models/repo"
2022-10-17 02:29:26 +03:00
system_model "code.gitea.io/gitea/models/system"
2022-06-06 11:01:49 +03:00
"code.gitea.io/gitea/models/unit"
2021-11-24 12:49:20 +03:00
user_model "code.gitea.io/gitea/models/user"
2023-06-29 13:03:20 +03:00
"code.gitea.io/gitea/modules/graceful"
2019-10-26 09:54:11 +03:00
"code.gitea.io/gitea/modules/log"
2020-01-12 15:11:17 +03:00
repo_module "code.gitea.io/gitea/modules/repository"
2022-05-08 19:46:32 +03:00
"code.gitea.io/gitea/modules/setting"
2023-05-14 00:59:01 +03:00
"code.gitea.io/gitea/modules/structs"
2023-09-05 21:37:47 +03:00
notify_service "code.gitea.io/gitea/services/notify"
2020-01-25 05:48:22 +03:00
pull_service "code.gitea.io/gitea/services/pull"
2019-10-26 09:54:11 +03:00
)
2023-05-14 00:59:01 +03:00
// WebSearchRepository represents a repository returned by web search
type WebSearchRepository struct {
2023-08-21 10:26:10 +03:00
Repository * structs . Repository ` json:"repository" `
LatestCommitStatus * git . CommitStatus ` json:"latest_commit_status" `
LocaleLatestCommitStatus string ` json:"locale_latest_commit_status" `
2023-05-14 00:59:01 +03:00
}
// WebSearchResults results of a successful web search
type WebSearchResults struct {
OK bool ` json:"ok" `
Data [ ] * WebSearchRepository ` json:"data" `
}
2019-10-26 09:54:11 +03:00
// CreateRepository creates a repository for the user/organization.
2023-09-06 15:08:51 +03:00
func CreateRepository ( ctx context . Context , doer , owner * user_model . User , opts CreateRepoOptions ) ( * repo_model . Repository , error ) {
2023-09-08 07:51:15 +03:00
repo , err := CreateRepositoryDirectly ( ctx , doer , owner , opts )
2019-10-26 09:54:11 +03:00
if err != nil {
2020-09-25 07:09:23 +03:00
// No need to rollback here we should do this in CreateRepository...
2019-10-26 09:54:11 +03:00
return nil , err
}
2023-09-05 21:37:47 +03:00
notify_service . CreateRepository ( ctx , doer , owner , repo )
2019-10-26 09:54:11 +03:00
return repo , nil
}
// DeleteRepository deletes a repository for a user or organization.
2022-01-20 02:26:57 +03:00
func DeleteRepository ( ctx context . Context , doer * user_model . User , repo * repo_model . Repository , notify bool ) error {
if err := pull_service . CloseRepoBranchesPulls ( ctx , doer , repo ) ; err != nil {
2020-01-25 05:48:22 +03:00
log . Error ( "CloseRepoBranchesPulls failed: %v" , err )
}
2021-12-10 11:14:24 +03:00
if notify {
// If the repo itself has webhooks, we need to trigger them before deleting it...
2023-09-05 21:37:47 +03:00
notify_service . DeleteRepository ( ctx , doer , repo )
2021-12-10 11:14:24 +03:00
}
2019-10-26 09:54:11 +03:00
2023-09-08 07:51:15 +03:00
if err := DeleteRepositoryDirectly ( ctx , doer , repo . OwnerID , repo . ID ) ; err != nil {
2022-03-30 11:42:47 +03:00
return err
}
return packages_model . UnlinkRepositoryFromAllPackages ( ctx , repo . ID )
2019-10-26 09:54:11 +03:00
}
2019-12-15 05:49:52 +03:00
// PushCreateRepo creates a repository when a new repository is pushed to an appropriate namespace
2023-03-01 01:17:51 +03:00
func PushCreateRepo ( ctx context . Context , authUser , owner * user_model . User , repoName string ) ( * repo_model . Repository , error ) {
2019-12-15 05:49:52 +03:00
if ! authUser . IsAdmin {
if owner . IsOrganization ( ) {
2023-03-01 01:17:51 +03:00
if ok , err := organization . CanCreateOrgRepo ( ctx , owner . ID , authUser . ID ) ; err != nil {
2019-12-15 05:49:52 +03:00
return nil , err
} else if ! ok {
return nil , fmt . Errorf ( "cannot push-create repository for org" )
}
} else if authUser . ID != owner . ID {
return nil , fmt . Errorf ( "cannot push-create repository for another user" )
}
}
2023-09-06 15:08:51 +03:00
repo , err := CreateRepository ( ctx , authUser , owner , CreateRepoOptions {
2019-12-15 05:49:52 +03:00
Name : repoName ,
2022-05-08 19:46:32 +03:00
IsPrivate : setting . Repository . DefaultPushCreatePrivate ,
2019-12-15 05:49:52 +03:00
} )
if err != nil {
return nil , err
}
return repo , nil
}
2020-09-11 17:14:48 +03:00
2022-05-08 19:46:32 +03:00
// Init start repository service
2023-09-16 17:39:12 +03:00
func Init ( ctx context . Context ) error {
2023-04-10 11:44:02 +03:00
if err := repo_module . LoadRepoConfig ( ) ; err != nil {
return err
}
2023-09-16 17:39:12 +03:00
system_model . RemoveAllWithNotice ( ctx , "Clean up temporary repository uploads" , setting . Repository . Upload . TempPath )
system_model . RemoveAllWithNotice ( ctx , "Clean up temporary repositories" , repo_module . LocalCopyPath ( ) )
2023-06-29 13:03:20 +03:00
if err := initPushQueue ( ) ; err != nil {
return err
}
return initBranchSyncQueue ( graceful . GetManager ( ) . ShutdownContext ( ) )
2020-09-11 17:14:48 +03:00
}
2022-06-06 11:01:49 +03:00
// UpdateRepository updates a repository
2023-03-01 01:17:51 +03:00
func UpdateRepository ( ctx context . Context , repo * repo_model . Repository , visibilityChanged bool ) ( err error ) {
ctx , committer , err := db . TxContext ( ctx )
2022-06-06 11:01:49 +03:00
if err != nil {
return err
}
defer committer . Close ( )
if err = repo_module . UpdateRepository ( ctx , repo , visibilityChanged ) ; err != nil {
2022-10-24 22:29:17 +03:00
return fmt . Errorf ( "updateRepository: %w" , err )
2022-06-06 11:01:49 +03:00
}
return committer . Commit ( )
}
// LinkedRepository returns the linked repo if any
2022-12-03 05:48:26 +03:00
func LinkedRepository ( ctx context . Context , a * repo_model . Attachment ) ( * repo_model . Repository , unit . Type , error ) {
2022-06-06 11:01:49 +03:00
if a . IssueID != 0 {
2022-12-03 05:48:26 +03:00
iss , err := issues_model . GetIssueByID ( ctx , a . IssueID )
2022-06-06 11:01:49 +03:00
if err != nil {
return nil , unit . TypeIssues , err
}
2022-12-03 05:48:26 +03:00
repo , err := repo_model . GetRepositoryByID ( ctx , iss . RepoID )
2022-06-06 11:01:49 +03:00
unitType := unit . TypeIssues
if iss . IsPull {
unitType = unit . TypePullRequests
}
return repo , unitType , err
} else if a . ReleaseID != 0 {
2022-12-03 05:48:26 +03:00
rel , err := repo_model . GetReleaseByID ( ctx , a . ReleaseID )
2022-06-06 11:01:49 +03:00
if err != nil {
return nil , unit . TypeReleases , err
}
2022-12-03 05:48:26 +03:00
repo , err := repo_model . GetRepositoryByID ( ctx , rel . RepoID )
2022-06-06 11:01:49 +03:00
return repo , unit . TypeReleases , err
}
return nil , - 1 , nil
}