code.gitea.io/gitea@v1.21.7/services/repository/repository.go (about)

     1  // Copyright 2019 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package repository
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  
    10  	"code.gitea.io/gitea/models/db"
    11  	"code.gitea.io/gitea/models/git"
    12  	issues_model "code.gitea.io/gitea/models/issues"
    13  	"code.gitea.io/gitea/models/organization"
    14  	packages_model "code.gitea.io/gitea/models/packages"
    15  	repo_model "code.gitea.io/gitea/models/repo"
    16  	system_model "code.gitea.io/gitea/models/system"
    17  	"code.gitea.io/gitea/models/unit"
    18  	user_model "code.gitea.io/gitea/models/user"
    19  	"code.gitea.io/gitea/modules/graceful"
    20  	"code.gitea.io/gitea/modules/log"
    21  	repo_module "code.gitea.io/gitea/modules/repository"
    22  	"code.gitea.io/gitea/modules/setting"
    23  	"code.gitea.io/gitea/modules/structs"
    24  	notify_service "code.gitea.io/gitea/services/notify"
    25  	pull_service "code.gitea.io/gitea/services/pull"
    26  )
    27  
    28  // WebSearchRepository represents a repository returned by web search
    29  type WebSearchRepository struct {
    30  	Repository               *structs.Repository `json:"repository"`
    31  	LatestCommitStatus       *git.CommitStatus   `json:"latest_commit_status"`
    32  	LocaleLatestCommitStatus string              `json:"locale_latest_commit_status"`
    33  }
    34  
    35  // WebSearchResults results of a successful web search
    36  type WebSearchResults struct {
    37  	OK   bool                   `json:"ok"`
    38  	Data []*WebSearchRepository `json:"data"`
    39  }
    40  
    41  // CreateRepository creates a repository for the user/organization.
    42  func CreateRepository(ctx context.Context, doer, owner *user_model.User, opts CreateRepoOptions) (*repo_model.Repository, error) {
    43  	repo, err := CreateRepositoryDirectly(ctx, doer, owner, opts)
    44  	if err != nil {
    45  		// No need to rollback here we should do this in CreateRepository...
    46  		return nil, err
    47  	}
    48  
    49  	notify_service.CreateRepository(ctx, doer, owner, repo)
    50  
    51  	return repo, nil
    52  }
    53  
    54  // DeleteRepository deletes a repository for a user or organization.
    55  func DeleteRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, notify bool) error {
    56  	if err := pull_service.CloseRepoBranchesPulls(ctx, doer, repo); err != nil {
    57  		log.Error("CloseRepoBranchesPulls failed: %v", err)
    58  	}
    59  
    60  	if notify {
    61  		// If the repo itself has webhooks, we need to trigger them before deleting it...
    62  		notify_service.DeleteRepository(ctx, doer, repo)
    63  	}
    64  
    65  	if err := DeleteRepositoryDirectly(ctx, doer, repo.OwnerID, repo.ID); err != nil {
    66  		return err
    67  	}
    68  
    69  	return packages_model.UnlinkRepositoryFromAllPackages(ctx, repo.ID)
    70  }
    71  
    72  // PushCreateRepo creates a repository when a new repository is pushed to an appropriate namespace
    73  func PushCreateRepo(ctx context.Context, authUser, owner *user_model.User, repoName string) (*repo_model.Repository, error) {
    74  	if !authUser.IsAdmin {
    75  		if owner.IsOrganization() {
    76  			if ok, err := organization.CanCreateOrgRepo(ctx, owner.ID, authUser.ID); err != nil {
    77  				return nil, err
    78  			} else if !ok {
    79  				return nil, fmt.Errorf("cannot push-create repository for org")
    80  			}
    81  		} else if authUser.ID != owner.ID {
    82  			return nil, fmt.Errorf("cannot push-create repository for another user")
    83  		}
    84  	}
    85  
    86  	repo, err := CreateRepository(ctx, authUser, owner, CreateRepoOptions{
    87  		Name:      repoName,
    88  		IsPrivate: setting.Repository.DefaultPushCreatePrivate,
    89  	})
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  
    94  	return repo, nil
    95  }
    96  
    97  // Init start repository service
    98  func Init(ctx context.Context) error {
    99  	if err := repo_module.LoadRepoConfig(); err != nil {
   100  		return err
   101  	}
   102  	system_model.RemoveAllWithNotice(ctx, "Clean up temporary repository uploads", setting.Repository.Upload.TempPath)
   103  	system_model.RemoveAllWithNotice(ctx, "Clean up temporary repositories", repo_module.LocalCopyPath())
   104  	if err := initPushQueue(); err != nil {
   105  		return err
   106  	}
   107  	return initBranchSyncQueue(graceful.GetManager().ShutdownContext())
   108  }
   109  
   110  // UpdateRepository updates a repository
   111  func UpdateRepository(ctx context.Context, repo *repo_model.Repository, visibilityChanged bool) (err error) {
   112  	ctx, committer, err := db.TxContext(ctx)
   113  	if err != nil {
   114  		return err
   115  	}
   116  	defer committer.Close()
   117  
   118  	if err = repo_module.UpdateRepository(ctx, repo, visibilityChanged); err != nil {
   119  		return fmt.Errorf("updateRepository: %w", err)
   120  	}
   121  
   122  	return committer.Commit()
   123  }
   124  
   125  // LinkedRepository returns the linked repo if any
   126  func LinkedRepository(ctx context.Context, a *repo_model.Attachment) (*repo_model.Repository, unit.Type, error) {
   127  	if a.IssueID != 0 {
   128  		iss, err := issues_model.GetIssueByID(ctx, a.IssueID)
   129  		if err != nil {
   130  			return nil, unit.TypeIssues, err
   131  		}
   132  		repo, err := repo_model.GetRepositoryByID(ctx, iss.RepoID)
   133  		unitType := unit.TypeIssues
   134  		if iss.IsPull {
   135  			unitType = unit.TypePullRequests
   136  		}
   137  		return repo, unitType, err
   138  	} else if a.ReleaseID != 0 {
   139  		rel, err := repo_model.GetReleaseByID(ctx, a.ReleaseID)
   140  		if err != nil {
   141  			return nil, unit.TypeReleases, err
   142  		}
   143  		repo, err := repo_model.GetRepositoryByID(ctx, rel.RepoID)
   144  		return repo, unit.TypeReleases, err
   145  	}
   146  	return nil, -1, nil
   147  }