summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2021-11-16 21:30:11 +0800
committerGitHub <noreply@github.com>2021-11-16 21:30:11 +0800
commit48ccd325a1b81a58ac6d1d5d94fc4e90974599ea (patch)
treee7bb31d69343dd9845a1b0df013b093c8720f14b /modules
parent447428f44659cee0e94e1c444f6291defac2bda2 (diff)
downloadgitea-48ccd325a1b81a58ac6d1d5d94fc4e90974599ea.tar.gz
gitea-48ccd325a1b81a58ac6d1d5d94fc4e90974599ea.zip
Move some functions into services/repository (#17660)
Diffstat (limited to 'modules')
-rw-r--r--modules/cron/cron.go94
-rw-r--r--modules/cron/setting.go87
-rw-r--r--modules/cron/tasks.go169
-rw-r--r--modules/cron/tasks_basic.go141
-rw-r--r--modules/cron/tasks_extended.go165
-rw-r--r--modules/repository/adopt.go295
-rw-r--r--modules/repository/archive.go20
-rw-r--r--modules/repository/fork.go171
-rw-r--r--modules/repository/fork_test.go30
-rw-r--r--modules/repository/init.go86
10 files changed, 0 insertions, 1258 deletions
diff --git a/modules/cron/cron.go b/modules/cron/cron.go
deleted file mode 100644
index ae309bd866..0000000000
--- a/modules/cron/cron.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2014 The Gogs Authors. All rights reserved.
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package cron
-
-import (
- "context"
- "time"
-
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/sync"
-
- "github.com/gogs/cron"
-)
-
-var c = cron.New()
-
-// Prevent duplicate running tasks.
-var taskStatusTable = sync.NewStatusTable()
-
-// NewContext begins cron tasks
-// Each cron task is run within the shutdown context as a running server
-// AtShutdown the cron server is stopped
-func NewContext() {
- initBasicTasks()
- initExtendedTasks()
-
- lock.Lock()
- for _, task := range tasks {
- if task.IsEnabled() && task.DoRunAtStart() {
- go task.Run()
- }
- }
-
- c.Start()
- started = true
- lock.Unlock()
- graceful.GetManager().RunAtShutdown(context.Background(), func() {
- c.Stop()
- lock.Lock()
- started = false
- lock.Unlock()
- })
-
-}
-
-// TaskTableRow represents a task row in the tasks table
-type TaskTableRow struct {
- Name string
- Spec string
- Next time.Time
- Prev time.Time
- ExecTimes int64
-}
-
-// TaskTable represents a table of tasks
-type TaskTable []*TaskTableRow
-
-// ListTasks returns all running cron tasks.
-func ListTasks() TaskTable {
- entries := c.Entries()
- eMap := map[string]*cron.Entry{}
- for _, e := range entries {
- eMap[e.Description] = e
- }
- lock.Lock()
- defer lock.Unlock()
- tTable := make([]*TaskTableRow, 0, len(tasks))
- for _, task := range tasks {
- spec := "-"
- var (
- next time.Time
- prev time.Time
- )
- if e, ok := eMap[task.Name]; ok {
- spec = e.Spec
- next = e.Next
- prev = e.Prev
- }
- task.lock.Lock()
- tTable = append(tTable, &TaskTableRow{
- Name: task.Name,
- Spec: spec,
- Next: next,
- Prev: prev,
- ExecTimes: task.ExecTimes,
- })
- task.lock.Unlock()
- }
-
- return tTable
-}
diff --git a/modules/cron/setting.go b/modules/cron/setting.go
deleted file mode 100644
index d55e5b60ad..0000000000
--- a/modules/cron/setting.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package cron
-
-import (
- "time"
-
- "code.gitea.io/gitea/models"
- "github.com/unknwon/i18n"
-)
-
-// Config represents a basic configuration interface that cron task
-type Config interface {
- IsEnabled() bool
- DoRunAtStart() bool
- GetSchedule() string
- FormatMessage(name, status string, doer *models.User, args ...interface{}) string
- DoNoticeOnSuccess() bool
-}
-
-// BaseConfig represents the basic config for a Cron task
-type BaseConfig struct {
- Enabled bool
- RunAtStart bool
- Schedule string
- NoSuccessNotice bool
-}
-
-// OlderThanConfig represents a cron task with OlderThan setting
-type OlderThanConfig struct {
- BaseConfig
- OlderThan time.Duration
-}
-
-// UpdateExistingConfig represents a cron task with UpdateExisting setting
-type UpdateExistingConfig struct {
- BaseConfig
- UpdateExisting bool
-}
-
-// CleanupHookTaskConfig represents a cron task with settings to cleanup hook_task
-type CleanupHookTaskConfig struct {
- BaseConfig
- CleanupType string
- OlderThan time.Duration
- NumberToKeep int
-}
-
-// GetSchedule returns the schedule for the base config
-func (b *BaseConfig) GetSchedule() string {
- return b.Schedule
-}
-
-// IsEnabled returns the enabled status for the config
-func (b *BaseConfig) IsEnabled() bool {
- return b.Enabled
-}
-
-// DoRunAtStart returns whether the task should be run at the start
-func (b *BaseConfig) DoRunAtStart() bool {
- return b.RunAtStart
-}
-
-// DoNoticeOnSuccess returns whether a success notice should be posted
-func (b *BaseConfig) DoNoticeOnSuccess() bool {
- return !b.NoSuccessNotice
-}
-
-// FormatMessage returns a message for the task
-func (b *BaseConfig) FormatMessage(name, status string, doer *models.User, args ...interface{}) string {
- realArgs := make([]interface{}, 0, len(args)+2)
- realArgs = append(realArgs, i18n.Tr("en-US", "admin.dashboard."+name))
- if doer == nil {
- realArgs = append(realArgs, "(Cron)")
- } else {
- realArgs = append(realArgs, doer.Name)
- }
- if len(args) > 0 {
- realArgs = append(realArgs, args...)
- }
- if doer == nil || (doer.ID == -1 && doer.Name == "(Cron)") {
- return i18n.Tr("en-US", "admin.dashboard.cron."+status, realArgs...)
- }
- return i18n.Tr("en-US", "admin.dashboard.task."+status, realArgs...)
-}
diff --git a/modules/cron/tasks.go b/modules/cron/tasks.go
deleted file mode 100644
index 56c363e0b8..0000000000
--- a/modules/cron/tasks.go
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package cron
-
-import (
- "context"
- "fmt"
- "reflect"
- "sync"
-
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/setting"
-)
-
-var lock = sync.Mutex{}
-var started = false
-var tasks = []*Task{}
-var tasksMap = map[string]*Task{}
-
-// Task represents a Cron task
-type Task struct {
- lock sync.Mutex
- Name string
- config Config
- fun func(context.Context, *models.User, Config) error
- ExecTimes int64
-}
-
-// DoRunAtStart returns if this task should run at the start
-func (t *Task) DoRunAtStart() bool {
- return t.config.DoRunAtStart()
-}
-
-// IsEnabled returns if this task is enabled as cron task
-func (t *Task) IsEnabled() bool {
- return t.config.IsEnabled()
-}
-
-// GetConfig will return a copy of the task's config
-func (t *Task) GetConfig() Config {
- if reflect.TypeOf(t.config).Kind() == reflect.Ptr {
- // Pointer:
- return reflect.New(reflect.ValueOf(t.config).Elem().Type()).Interface().(Config)
- }
- // Not pointer:
- return reflect.New(reflect.TypeOf(t.config)).Elem().Interface().(Config)
-}
-
-// Run will run the task incrementing the cron counter with no user defined
-func (t *Task) Run() {
- t.RunWithUser(&models.User{
- ID: -1,
- Name: "(Cron)",
- LowerName: "(cron)",
- }, t.config)
-}
-
-// RunWithUser will run the task incrementing the cron counter at the time with User
-func (t *Task) RunWithUser(doer *models.User, config Config) {
- if !taskStatusTable.StartIfNotRunning(t.Name) {
- return
- }
- t.lock.Lock()
- if config == nil {
- config = t.config
- }
- t.ExecTimes++
- t.lock.Unlock()
- defer func() {
- taskStatusTable.Stop(t.Name)
- if err := recover(); err != nil {
- // Recover a panic within the
- combinedErr := fmt.Errorf("%s\n%s", err, log.Stack(2))
- log.Error("PANIC whilst running task: %s Value: %v", t.Name, combinedErr)
- }
- }()
- graceful.GetManager().RunWithShutdownContext(func(baseCtx context.Context) {
- ctx, cancel := context.WithCancel(baseCtx)
- defer cancel()
- pm := process.GetManager()
- pid := pm.Add(config.FormatMessage(t.Name, "process", doer), cancel)
- defer pm.Remove(pid)
- if err := t.fun(ctx, doer, config); err != nil {
- if db.IsErrCancelled(err) {
- message := err.(db.ErrCancelled).Message
- if err := models.CreateNotice(models.NoticeTask, config.FormatMessage(t.Name, "aborted", doer, message)); err != nil {
- log.Error("CreateNotice: %v", err)
- }
- return
- }
- if err := models.CreateNotice(models.NoticeTask, config.FormatMessage(t.Name, "error", doer, err)); err != nil {
- log.Error("CreateNotice: %v", err)
- }
- return
- }
- if config.DoNoticeOnSuccess() {
- if err := models.CreateNotice(models.NoticeTask, config.FormatMessage(t.Name, "finished", doer)); err != nil {
- log.Error("CreateNotice: %v", err)
- }
- }
- })
-}
-
-// GetTask gets the named task
-func GetTask(name string) *Task {
- lock.Lock()
- defer lock.Unlock()
- log.Info("Getting %s in %v", name, tasksMap[name])
-
- return tasksMap[name]
-}
-
-// RegisterTask allows a task to be registered with the cron service
-func RegisterTask(name string, config Config, fun func(context.Context, *models.User, Config) error) error {
- log.Debug("Registering task: %s", name)
- _, err := setting.GetCronSettings(name, config)
- if err != nil {
- log.Error("Unable to register cron task with name: %s Error: %v", name, err)
- return err
- }
-
- task := &Task{
- Name: name,
- config: config,
- fun: fun,
- }
- lock.Lock()
- locked := true
- defer func() {
- if locked {
- lock.Unlock()
- }
- }()
- if _, has := tasksMap[task.Name]; has {
- log.Error("A task with this name: %s has already been registered", name)
- return fmt.Errorf("duplicate task with name: %s", task.Name)
- }
-
- if config.IsEnabled() {
- // We cannot use the entry return as there is no way to lock it
- if _, err = c.AddJob(name, config.GetSchedule(), task); err != nil {
- log.Error("Unable to register cron task with name: %s Error: %v", name, err)
- return err
- }
- }
-
- tasks = append(tasks, task)
- tasksMap[task.Name] = task
- if started && config.IsEnabled() && config.DoRunAtStart() {
- lock.Unlock()
- locked = false
- task.Run()
- }
-
- return nil
-}
-
-// RegisterTaskFatal will register a task but if there is an error log.Fatal
-func RegisterTaskFatal(name string, config Config, fun func(context.Context, *models.User, Config) error) {
- if err := RegisterTask(name, config, fun); err != nil {
- log.Fatal("Unable to register cron task %s Error: %v", name, err)
- }
-}
diff --git a/modules/cron/tasks_basic.go b/modules/cron/tasks_basic.go
deleted file mode 100644
index a42c031b36..0000000000
--- a/modules/cron/tasks_basic.go
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package cron
-
-import (
- "context"
- "time"
-
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/webhook"
- "code.gitea.io/gitea/modules/migrations"
- repository_service "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/auth"
- mirror_service "code.gitea.io/gitea/services/mirror"
-)
-
-func registerUpdateMirrorTask() {
- RegisterTaskFatal("update_mirrors", &BaseConfig{
- Enabled: true,
- RunAtStart: false,
- Schedule: "@every 10m",
- NoSuccessNotice: true,
- }, func(ctx context.Context, _ *models.User, _ Config) error {
- return mirror_service.Update(ctx)
- })
-}
-
-func registerRepoHealthCheck() {
- type RepoHealthCheckConfig struct {
- BaseConfig
- Timeout time.Duration
- Args []string `delim:" "`
- }
- RegisterTaskFatal("repo_health_check", &RepoHealthCheckConfig{
- BaseConfig: BaseConfig{
- Enabled: true,
- RunAtStart: false,
- Schedule: "@midnight",
- },
- Timeout: 60 * time.Second,
- Args: []string{},
- }, func(ctx context.Context, _ *models.User, config Config) error {
- rhcConfig := config.(*RepoHealthCheckConfig)
- return repository_service.GitFsck(ctx, rhcConfig.Timeout, rhcConfig.Args)
- })
-}
-
-func registerCheckRepoStats() {
- RegisterTaskFatal("check_repo_stats", &BaseConfig{
- Enabled: true,
- RunAtStart: true,
- Schedule: "@midnight",
- }, func(ctx context.Context, _ *models.User, _ Config) error {
- return models.CheckRepoStats(ctx)
- })
-}
-
-func registerArchiveCleanup() {
- RegisterTaskFatal("archive_cleanup", &OlderThanConfig{
- BaseConfig: BaseConfig{
- Enabled: true,
- RunAtStart: true,
- Schedule: "@midnight",
- },
- OlderThan: 24 * time.Hour,
- }, func(ctx context.Context, _ *models.User, config Config) error {
- acConfig := config.(*OlderThanConfig)
- return models.DeleteOldRepositoryArchives(ctx, acConfig.OlderThan)
- })
-}
-
-func registerSyncExternalUsers() {
- RegisterTaskFatal("sync_external_users", &UpdateExistingConfig{
- BaseConfig: BaseConfig{
- Enabled: true,
- RunAtStart: false,
- Schedule: "@midnight",
- },
- UpdateExisting: true,
- }, func(ctx context.Context, _ *models.User, config Config) error {
- realConfig := config.(*UpdateExistingConfig)
- return auth.SyncExternalUsers(ctx, realConfig.UpdateExisting)
- })
-}
-
-func registerDeletedBranchesCleanup() {
- RegisterTaskFatal("deleted_branches_cleanup", &OlderThanConfig{
- BaseConfig: BaseConfig{
- Enabled: true,
- RunAtStart: true,
- Schedule: "@midnight",
- },
- OlderThan: 24 * time.Hour,
- }, func(ctx context.Context, _ *models.User, config Config) error {
- realConfig := config.(*OlderThanConfig)
- models.RemoveOldDeletedBranches(ctx, realConfig.OlderThan)
- return nil
- })
-}
-
-func registerUpdateMigrationPosterID() {
- RegisterTaskFatal("update_migration_poster_id", &BaseConfig{
- Enabled: true,
- RunAtStart: true,
- Schedule: "@midnight",
- }, func(ctx context.Context, _ *models.User, _ Config) error {
- return migrations.UpdateMigrationPosterID(ctx)
- })
-}
-
-func registerCleanupHookTaskTable() {
- RegisterTaskFatal("cleanup_hook_task_table", &CleanupHookTaskConfig{
- BaseConfig: BaseConfig{
- Enabled: true,
- RunAtStart: false,
- Schedule: "@midnight",
- },
- CleanupType: "OlderThan",
- OlderThan: 168 * time.Hour,
- NumberToKeep: 10,
- }, func(ctx context.Context, _ *models.User, config Config) error {
- realConfig := config.(*CleanupHookTaskConfig)
- return webhook.CleanupHookTaskTable(ctx, webhook.ToHookTaskCleanupType(realConfig.CleanupType), realConfig.OlderThan, realConfig.NumberToKeep)
- })
-}
-
-func initBasicTasks() {
- registerUpdateMirrorTask()
- registerRepoHealthCheck()
- registerCheckRepoStats()
- registerArchiveCleanup()
- registerSyncExternalUsers()
- registerDeletedBranchesCleanup()
- if !setting.Repository.DisableMigrations {
- registerUpdateMigrationPosterID()
- }
- registerCleanupHookTaskTable()
-}
diff --git a/modules/cron/tasks_extended.go b/modules/cron/tasks_extended.go
deleted file mode 100644
index 9a37c40faf..0000000000
--- a/modules/cron/tasks_extended.go
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package cron
-
-import (
- "context"
- "time"
-
- "code.gitea.io/gitea/models"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/updatechecker"
-)
-
-func registerDeleteInactiveUsers() {
- RegisterTaskFatal("delete_inactive_accounts", &OlderThanConfig{
- BaseConfig: BaseConfig{
- Enabled: false,
- RunAtStart: false,
- Schedule: "@annually",
- },
- OlderThan: 0 * time.Second,
- }, func(ctx context.Context, _ *models.User, config Config) error {
- olderThanConfig := config.(*OlderThanConfig)
- return models.DeleteInactiveUsers(ctx, olderThanConfig.OlderThan)
- })
-}
-
-func registerDeleteRepositoryArchives() {
- RegisterTaskFatal("delete_repo_archives", &BaseConfig{
- Enabled: false,
- RunAtStart: false,
- Schedule: "@annually",
- }, func(ctx context.Context, _ *models.User, _ Config) error {
- return repo_module.DeleteRepositoryArchives(ctx)
- })
-}
-
-func registerGarbageCollectRepositories() {
- type RepoHealthCheckConfig struct {
- BaseConfig
- Timeout time.Duration
- Args []string `delim:" "`
- }
- RegisterTaskFatal("git_gc_repos", &RepoHealthCheckConfig{
- BaseConfig: BaseConfig{
- Enabled: false,
- RunAtStart: false,
- Schedule: "@every 72h",
- },
- Timeout: time.Duration(setting.Git.Timeout.GC) * time.Second,
- Args: setting.Git.GCArgs,
- }, func(ctx context.Context, _ *models.User, config Config) error {
- rhcConfig := config.(*RepoHealthCheckConfig)
- return repo_module.GitGcRepos(ctx, rhcConfig.Timeout, rhcConfig.Args...)
- })
-}
-
-func registerRewriteAllPublicKeys() {
- RegisterTaskFatal("resync_all_sshkeys", &BaseConfig{
- Enabled: false,
- RunAtStart: false,
- Schedule: "@every 72h",
- }, func(_ context.Context, _ *models.User, _ Config) error {
- return models.RewriteAllPublicKeys()
- })
-}
-
-func registerRewriteAllPrincipalKeys() {
- RegisterTaskFatal("resync_all_sshprincipals", &BaseConfig{
- Enabled: false,
- RunAtStart: false,
- Schedule: "@every 72h",
- }, func(_ context.Context, _ *models.User, _ Config) error {
- return models.RewriteAllPrincipalKeys()
- })
-}
-
-func registerRepositoryUpdateHook() {
- RegisterTaskFatal("resync_all_hooks", &BaseConfig{
- Enabled: false,
- RunAtStart: false,
- Schedule: "@every 72h",
- }, func(ctx context.Context, _ *models.User, _ Config) error {
- return repo_module.SyncRepositoryHooks(ctx)
- })
-}
-
-func registerReinitMissingRepositories() {
- RegisterTaskFatal("reinit_missing_repos", &BaseConfig{
- Enabled: false,
- RunAtStart: false,
- Schedule: "@every 72h",
- }, func(ctx context.Context, _ *models.User, _ Config) error {
- return repo_module.ReinitMissingRepositories(ctx)
- })
-}
-
-func registerDeleteMissingRepositories() {
- RegisterTaskFatal("delete_missing_repos", &BaseConfig{
- Enabled: false,
- RunAtStart: false,
- Schedule: "@every 72h",
- }, func(ctx context.Context, user *models.User, _ Config) error {
- return repo_module.DeleteMissingRepositories(ctx, user)
- })
-}
-
-func registerRemoveRandomAvatars() {
- RegisterTaskFatal("delete_generated_repository_avatars", &BaseConfig{
- Enabled: false,
- RunAtStart: false,
- Schedule: "@every 72h",
- }, func(ctx context.Context, _ *models.User, _ Config) error {
- return models.RemoveRandomAvatars(ctx)
- })
-}
-
-func registerDeleteOldActions() {
- RegisterTaskFatal("delete_old_actions", &OlderThanConfig{
- BaseConfig: BaseConfig{
- Enabled: false,
- RunAtStart: false,
- Schedule: "@every 168h",
- },
- OlderThan: 365 * 24 * time.Hour,
- }, func(ctx context.Context, _ *models.User, config Config) error {
- olderThanConfig := config.(*OlderThanConfig)
- return models.DeleteOldActions(olderThanConfig.OlderThan)
- })
-}
-
-func registerUpdateGiteaChecker() {
- type UpdateCheckerConfig struct {
- BaseConfig
- HTTPEndpoint string
- }
- RegisterTaskFatal("update_checker", &UpdateCheckerConfig{
- BaseConfig: BaseConfig{
- Enabled: true,
- RunAtStart: false,
- Schedule: "@every 168h",
- },
- HTTPEndpoint: "https://dl.gitea.io/gitea/version.json",
- }, func(ctx context.Context, _ *models.User, config Config) error {
- updateCheckerConfig := config.(*UpdateCheckerConfig)
- return updatechecker.GiteaUpdateChecker(updateCheckerConfig.HTTPEndpoint)
- })
-}
-
-func initExtendedTasks() {
- registerDeleteInactiveUsers()
- registerDeleteRepositoryArchives()
- registerGarbageCollectRepositories()
- registerRewriteAllPublicKeys()
- registerRewriteAllPrincipalKeys()
- registerRepositoryUpdateHook()
- registerReinitMissingRepositories()
- registerDeleteMissingRepositories()
- registerRemoveRandomAvatars()
- registerDeleteOldActions()
- registerUpdateGiteaChecker()
-}
diff --git a/modules/repository/adopt.go b/modules/repository/adopt.go
deleted file mode 100644
index 3d895ac484..0000000000
--- a/modules/repository/adopt.go
+++ /dev/null
@@ -1,295 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package repository
-
-import (
- "context"
- "fmt"
- "os"
- "path/filepath"
- "strings"
-
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "github.com/gobwas/glob"
-)
-
-// AdoptRepository adopts a repository for the user/organization.
-func AdoptRepository(doer, u *models.User, opts models.CreateRepoOptions) (*models.Repository, error) {
- if !doer.IsAdmin && !u.CanCreateRepo() {
- return nil, models.ErrReachLimitOfRepo{
- Limit: u.MaxRepoCreation,
- }
- }
-
- if len(opts.DefaultBranch) == 0 {
- opts.DefaultBranch = setting.Repository.DefaultBranch
- }
-
- repo := &models.Repository{
- OwnerID: u.ID,
- Owner: u,
- OwnerName: u.Name,
- Name: opts.Name,
- LowerName: strings.ToLower(opts.Name),
- Description: opts.Description,
- OriginalURL: opts.OriginalURL,
- OriginalServiceType: opts.GitServiceType,
- IsPrivate: opts.IsPrivate,
- IsFsckEnabled: !opts.IsMirror,
- CloseIssuesViaCommitInAnyBranch: setting.Repository.DefaultCloseIssuesViaCommitsInAnyBranch,
- Status: opts.Status,
- IsEmpty: !opts.AutoInit,
- }
-
- if err := db.WithTx(func(ctx context.Context) error {
- repoPath := models.RepoPath(u.Name, repo.Name)
- isExist, err := util.IsExist(repoPath)
- if err != nil {
- log.Error("Unable to check if %s exists. Error: %v", repoPath, err)
- return err
- }
- if !isExist {
- return models.ErrRepoNotExist{
- OwnerName: u.Name,
- Name: repo.Name,
- }
- }
-
- if err := models.CreateRepository(ctx, doer, u, repo, true); err != nil {
- return err
- }
- if err := adoptRepository(ctx, repoPath, doer, repo, opts); err != nil {
- return fmt.Errorf("createDelegateHooks: %v", err)
- }
- if err := repo.CheckDaemonExportOK(ctx); err != nil {
- return fmt.Errorf("checkDaemonExportOK: %v", err)
- }
-
- // Initialize Issue Labels if selected
- if len(opts.IssueLabels) > 0 {
- if err := models.InitializeLabels(ctx, repo.ID, opts.IssueLabels, false); err != nil {
- return fmt.Errorf("InitializeLabels: %v", err)
- }
- }
-
- if stdout, err := git.NewCommand("update-server-info").
- SetDescription(fmt.Sprintf("CreateRepository(git update-server-info): %s", repoPath)).
- RunInDir(repoPath); err != nil {
- log.Error("CreateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err)
- return fmt.Errorf("CreateRepository(git update-server-info): %v", err)
- }
- return nil
- }); err != nil {
- return nil, err
- }
-
- return repo, nil
-}
-
-// DeleteUnadoptedRepository deletes unadopted repository files from the filesystem
-func DeleteUnadoptedRepository(doer, u *models.User, repoName string) error {
- if err := models.IsUsableRepoName(repoName); err != nil {
- return err
- }
-
- repoPath := models.RepoPath(u.Name, repoName)
- isExist, err := util.IsExist(repoPath)
- if err != nil {
- log.Error("Unable to check if %s exists. Error: %v", repoPath, err)
- return err
- }
- if !isExist {
- return models.ErrRepoNotExist{
- OwnerName: u.Name,
- Name: repoName,
- }
- }
-
- if exist, err := models.IsRepositoryExist(u, repoName); err != nil {
- return err
- } else if exist {
- return models.ErrRepoAlreadyExist{
- Uname: u.Name,
- Name: repoName,
- }
- }
-
- return util.RemoveAll(repoPath)
-}
-
-// ListUnadoptedRepositories lists all the unadopted repositories that match the provided query
-func ListUnadoptedRepositories(query string, opts *db.ListOptions) ([]string, int, error) {
- globUser, _ := glob.Compile("*")
- globRepo, _ := glob.Compile("*")
-
- qsplit := strings.SplitN(query, "/", 2)
- if len(qsplit) > 0 && len(query) > 0 {
- var err error
- globUser, err = glob.Compile(qsplit[0])
- if err != nil {
- log.Info("Invalid glob expression '%s' (skipped): %v", qsplit[0], err)
- }
- if len(qsplit) > 1 {
- globRepo, err = glob.Compile(qsplit[1])
- if err != nil {
- log.Info("Invalid glob expression '%s' (skipped): %v", qsplit[1], err)
- }
- }
- }
- start := (opts.Page - 1) * opts.PageSize
- end := start + opts.PageSize
-
- repoNamesToCheck := make([]string, 0, opts.PageSize)
-
- repoNames := make([]string, 0, opts.PageSize)
- var ctxUser *models.User
-
- count := 0
-
- // We're going to iterate by pagesize.
- root := filepath.Clean(setting.RepoRootPath)
- if err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
- if err != nil {
- return err
- }
- if !info.IsDir() || path == root {
- return nil
- }
-
- if !strings.ContainsRune(path[len(root)+1:], filepath.Separator) {
- // Got a new user
-
- // Clean up old repoNamesToCheck
- if len(repoNamesToCheck) > 0 {
- repos, _, err := models.GetUserRepositories(&models.SearchRepoOptions{
- Actor: ctxUser,
- Private: true,
- ListOptions: db.ListOptions{
- Page: 1,
- PageSize: opts.PageSize,
- }, LowerNames: repoNamesToCheck})
- if err != nil {
- return err
- }
- for _, name := range repoNamesToCheck {
- found := false
- repoLoopCatchup:
- for i, repo := range repos {
- if repo.LowerName == name {
- found = true
- repos = append(repos[:i], repos[i+1:]...)
- break repoLoopCatchup
- }
- }
- if !found {
- if count >= start && count < end {
- repoNames = append(repoNames, fmt.Sprintf("%s/%s", ctxUser.Name, name))
- }
- count++
- }
- }
- repoNamesToCheck = repoNamesToCheck[:0]
- }
-
- if !globUser.Match(info.Name()) {
- return filepath.SkipDir
- }
-
- ctxUser, err = models.GetUserByName(info.Name())
- if err != nil {
- if models.IsErrUserNotExist(err) {
- log.Debug("Missing user: %s", info.Name())
- return filepath.SkipDir
- }
- return err
- }
- return nil
- }
-
- name := info.Name()
-
- if !strings.HasSuffix(name, ".git") {
- return filepath.SkipDir
- }
- name = name[:len(name)-4]
- if models.IsUsableRepoName(name) != nil || strings.ToLower(name) != name || !globRepo.Match(name) {
- return filepath.SkipDir
- }
- if count < end {
- repoNamesToCheck = append(repoNamesToCheck, name)
- if len(repoNamesToCheck) >= opts.PageSize {
- repos, _, err := models.GetUserRepositories(&models.SearchRepoOptions{
- Actor: ctxUser,
- Private: true,
- ListOptions: db.ListOptions{
- Page: 1,
- PageSize: opts.PageSize,
- }, LowerNames: repoNamesToCheck})
- if err != nil {
- return err
- }
- for _, name := range repoNamesToCheck {
- found := false
- repoLoop:
- for i, repo := range repos {
- if repo.LowerName == name {
- found = true
- repos = append(repos[:i], repos[i+1:]...)
- break repoLoop
- }
- }
- if !found {
- if count >= start && count < end {
- repoNames = append(repoNames, fmt.Sprintf("%s/%s", ctxUser.Name, name))
- }
- count++
- }
- }
- repoNamesToCheck = repoNamesToCheck[:0]
- }
- return filepath.SkipDir
- }
- count++
- return filepath.SkipDir
- }); err != nil {
- return nil, 0, err
- }
-
- if len(repoNamesToCheck) > 0 {
- repos, _, err := models.GetUserRepositories(&models.SearchRepoOptions{
- Actor: ctxUser,
- Private: true,
- ListOptions: db.ListOptions{
- Page: 1,
- PageSize: opts.PageSize,
- }, LowerNames: repoNamesToCheck})
- if err != nil {
- return nil, 0, err
- }
- for _, name := range repoNamesToCheck {
- found := false
- repoLoop:
- for i, repo := range repos {
- if repo.LowerName == name {
- found = true
- repos = append(repos[:i], repos[i+1:]...)
- break repoLoop
- }
- }
- if !found {
- if count >= start && count < end {
- repoNames = append(repoNames, fmt.Sprintf("%s/%s", ctxUser.Name, name))
- }
- count++
- }
- }
- }
- return repoNames, count, nil
-}
diff --git a/modules/repository/archive.go b/modules/repository/archive.go
deleted file mode 100644
index bea636c579..0000000000
--- a/modules/repository/archive.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2021 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package repository
-
-import (
- "context"
-
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/modules/storage"
-)
-
-// DeleteRepositoryArchives deletes all repositories' archives.
-func DeleteRepositoryArchives(ctx context.Context) error {
- if err := models.DeleteAllRepoArchives(); err != nil {
- return err
- }
- return storage.Clean(storage.RepoArchives)
-}
diff --git a/modules/repository/fork.go b/modules/repository/fork.go
deleted file mode 100644
index df1dccc596..0000000000
--- a/modules/repository/fork.go
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package repository
-
-import (
- "context"
- "fmt"
- "strings"
- "time"
-
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
-)
-
-// ForkRepository forks a repository
-func ForkRepository(doer, owner *models.User, opts models.ForkRepoOptions) (_ *models.Repository, err error) {
- forkedRepo, err := opts.BaseRepo.GetUserFork(owner.ID)
- if err != nil {
- return nil, err
- }
- if forkedRepo != nil {
- return nil, models.ErrForkAlreadyExist{
- Uname: owner.Name,
- RepoName: opts.BaseRepo.FullName(),
- ForkName: forkedRepo.FullName(),
- }
- }
-
- repo := &models.Repository{
- OwnerID: owner.ID,
- Owner: owner,
- OwnerName: owner.Name,
- Name: opts.Name,
- LowerName: strings.ToLower(opts.Name),
- Description: opts.Description,
- DefaultBranch: opts.BaseRepo.DefaultBranch,
- IsPrivate: opts.BaseRepo.IsPrivate || opts.BaseRepo.Owner.Visibility == structs.VisibleTypePrivate,
- IsEmpty: opts.BaseRepo.IsEmpty,
- IsFork: true,
- ForkID: opts.BaseRepo.ID,
- }
-
- oldRepoPath := opts.BaseRepo.RepoPath()
-
- needsRollback := false
- rollbackFn := func() {
- if !needsRollback {
- return
- }
-
- repoPath := models.RepoPath(owner.Name, repo.Name)
-
- if exists, _ := util.IsExist(repoPath); !exists {
- return
- }
-
- // As the transaction will be failed and hence database changes will be destroyed we only need
- // to delete the related repository on the filesystem
- if errDelete := util.RemoveAll(repoPath); errDelete != nil {
- log.Error("Failed to remove fork repo")
- }
- }
-
- needsRollbackInPanic := true
- defer func() {
- panicErr := recover()
- if panicErr == nil {
- return
- }
-
- if needsRollbackInPanic {
- rollbackFn()
- }
- panic(panicErr)
- }()
-
- err = db.WithTx(func(ctx context.Context) error {
- if err = models.CreateRepository(ctx, doer, owner, repo, false); err != nil {
- return err
- }
-
- if err = models.IncrementRepoForkNum(ctx, opts.BaseRepo.ID); err != nil {
- return err
- }
-
- // copy lfs files failure should not be ignored
- if err = models.CopyLFS(ctx, repo, opts.BaseRepo); err != nil {
- return err
- }
-
- needsRollback = true
-
- repoPath := models.RepoPath(owner.Name, repo.Name)
- if stdout, err := git.NewCommandContext(ctx,
- "clone", "--bare", oldRepoPath, repoPath).
- SetDescription(fmt.Sprintf("ForkRepository(git clone): %s to %s", opts.BaseRepo.FullName(), repo.FullName())).
- RunInDirTimeout(10*time.Minute, ""); err != nil {
- log.Error("Fork Repository (git clone) Failed for %v (from %v):\nStdout: %s\nError: %v", repo, opts.BaseRepo, stdout, err)
- return fmt.Errorf("git clone: %v", err)
- }
-
- if err := repo.CheckDaemonExportOK(ctx); err != nil {
- return fmt.Errorf("checkDaemonExportOK: %v", err)
- }
-
- if stdout, err := git.NewCommandContext(ctx, "update-server-info").
- SetDescription(fmt.Sprintf("ForkRepository(git update-server-info): %s", repo.FullName())).
- RunInDir(repoPath); err != nil {
- log.Error("Fork Repository (git update-server-info) failed for %v:\nStdout: %s\nError: %v", repo, stdout, err)
- return fmt.Errorf("git update-server-info: %v", err)
- }
-
- if err = createDelegateHooks(repoPath); err != nil {
- return fmt.Errorf("createDelegateHooks: %v", err)
- }
- return nil
- })
- needsRollbackInPanic = false
- if err != nil {
- rollbackFn()
- return nil, err
- }
-
- // even if below operations failed, it could be ignored. And they will be retried
- ctx := db.DefaultContext
- if err := repo.UpdateSize(ctx); err != nil {
- log.Error("Failed to update size for repository: %v", err)
- }
- if err := models.CopyLanguageStat(opts.BaseRepo, repo); err != nil {
- log.Error("Copy language stat from oldRepo failed")
- }
-
- return repo, nil
-}
-
-// ConvertForkToNormalRepository convert the provided repo from a forked repo to normal repo
-func ConvertForkToNormalRepository(repo *models.Repository) error {
- err := db.WithTx(func(ctx context.Context) error {
- repo, err := models.GetRepositoryByIDCtx(ctx, repo.ID)
- if err != nil {
- return err
- }
-
- if !repo.IsFork {
- return nil
- }
-
- if err := models.DecrementRepoForkNum(ctx, repo.ForkID); err != nil {
- log.Error("Unable to decrement repo fork num for old root repo %d of repository %-v whilst converting from fork. Error: %v", repo.ForkID, repo, err)
- return err
- }
-
- repo.IsFork = false
- repo.ForkID = 0
-
- if err := models.UpdateRepositoryCtx(ctx, repo, false); err != nil {
- log.Error("Unable to update repository %-v whilst converting from fork. Error: %v", repo, err)
- return err
- }
-
- return nil
- })
-
- return err
-}
diff --git a/modules/repository/fork_test.go b/modules/repository/fork_test.go
deleted file mode 100644
index 197d76b056..0000000000
--- a/modules/repository/fork_test.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package repository
-
-import (
- "testing"
-
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/unittest"
- "github.com/stretchr/testify/assert"
-)
-
-func TestForkRepository(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
-
- // user 13 has already forked repo10
- user := unittest.AssertExistsAndLoadBean(t, &models.User{ID: 13}).(*models.User)
- repo := unittest.AssertExistsAndLoadBean(t, &models.Repository{ID: 10}).(*models.Repository)
-
- fork, err := ForkRepository(user, user, models.ForkRepoOptions{
- BaseRepo: repo,
- Name: "test",
- Description: "test",
- })
- assert.Nil(t, fork)
- assert.Error(t, err)
- assert.True(t, models.IsErrForkAlreadyExist(err))
-}
diff --git a/modules/repository/init.go b/modules/repository/init.go
index 5a1ff7e98b..076dbf748e 100644
--- a/modules/repository/init.go
+++ b/modules/repository/init.go
@@ -196,92 +196,6 @@ func checkInitRepository(owner, name string) (err error) {
return nil
}
-func adoptRepository(ctx context.Context, repoPath string, u *models.User, repo *models.Repository, opts models.CreateRepoOptions) (err error) {
- isExist, err := util.IsExist(repoPath)
- if err != nil {
- log.Error("Unable to check if %s exists. Error: %v", repoPath, err)
- return err
- }
- if !isExist {
- return fmt.Errorf("adoptRepository: path does not already exist: %s", repoPath)
- }
-
- if err := createDelegateHooks(repoPath); err != nil {
- return fmt.Errorf("createDelegateHooks: %v", err)
- }
-
- // Re-fetch the repository from database before updating it (else it would
- // override changes that were done earlier with sql)
- if repo, err = models.GetRepositoryByIDCtx(ctx, repo.ID); err != nil {
- return fmt.Errorf("getRepositoryByID: %v", err)
- }
-
- repo.IsEmpty = false
- gitRepo, err := git.OpenRepository(repo.RepoPath())
- if err != nil {
- return fmt.Errorf("openRepository: %v", err)
- }
- defer gitRepo.Close()
- if len(opts.DefaultBranch) > 0 {
- repo.DefaultBranch = opts.DefaultBranch
-
- if err = gitRepo.SetDefaultBranch(repo.DefaultBranch); err != nil {
- return fmt.Errorf("setDefaultBranch: %v", err)
- }
- } else {
- repo.DefaultBranch, err = gitRepo.GetDefaultBranch()
- if err != nil {
- repo.DefaultBranch = setting.Repository.DefaultBranch
- if err = gitRepo.SetDefaultBranch(repo.DefaultBranch); err != nil {
- return fmt.Errorf("setDefaultBranch: %v", err)
- }
- }
-
- repo.DefaultBranch = strings.TrimPrefix(repo.DefaultBranch, git.BranchPrefix)
- }
- branches, _, _ := gitRepo.GetBranches(0, 0)
- found := false
- hasDefault := false
- hasMaster := false
- hasMain := false
- for _, branch := range branches {
- if branch == repo.DefaultBranch {
- found = true
- break
- } else if branch == setting.Repository.DefaultBranch {
- hasDefault = true
- } else if branch == "master" {
- hasMaster = true
- } else if branch == "main" {
- hasMain = true
- }
- }
- if !found {
- if hasDefault {
- repo.DefaultBranch = setting.Repository.DefaultBranch
- } else if hasMaster {
- repo.DefaultBranch = "master"
- } else if hasMain {
- repo.DefaultBranch = "main"
- } else if len(branches) > 0 {
- repo.DefaultBranch = branches[0]
- } else {
- repo.IsEmpty = true
- repo.DefaultBranch = setting.Repository.DefaultBranch
- }
-
- if err = gitRepo.SetDefaultBranch(repo.DefaultBranch); err != nil {
- return fmt.Errorf("setDefaultBranch: %v", err)
- }
- }
-
- if err = models.UpdateRepositoryCtx(ctx, repo, false); err != nil {
- return fmt.Errorf("updateRepository: %v", err)
- }
-
- return nil
-}
-
// InitRepository initializes README and .gitignore if needed.
func initRepository(ctx context.Context, repoPath string, u *models.User, repo *models.Repository, opts models.CreateRepoOptions) (err error) {
if err = checkInitRepository(repo.OwnerName, repo.Name); err != nil {