code.gitea.io/gitea@v1.19.3/modules/setting/repository.go (about)

     1  // Copyright 2019 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package setting
     5  
     6  import (
     7  	"os/exec"
     8  	"path"
     9  	"path/filepath"
    10  	"strings"
    11  
    12  	"code.gitea.io/gitea/modules/log"
    13  )
    14  
    15  // enumerates all the policy repository creating
    16  const (
    17  	RepoCreatingLastUserVisibility = "last"
    18  	RepoCreatingPrivate            = "private"
    19  	RepoCreatingPublic             = "public"
    20  )
    21  
    22  // ItemsPerPage maximum items per page in forks, watchers and stars of a repo
    23  const ItemsPerPage = 40
    24  
    25  // Repository settings
    26  var (
    27  	Repository = struct {
    28  		DetectedCharsetsOrder                   []string
    29  		DetectedCharsetScore                    map[string]int `ini:"-"`
    30  		AnsiCharset                             string
    31  		ForcePrivate                            bool
    32  		DefaultPrivate                          string
    33  		DefaultPushCreatePrivate                bool
    34  		MaxCreationLimit                        int
    35  		PreferredLicenses                       []string
    36  		DisableHTTPGit                          bool
    37  		AccessControlAllowOrigin                string
    38  		UseCompatSSHURI                         bool
    39  		DefaultCloseIssuesViaCommitsInAnyBranch bool
    40  		EnablePushCreateUser                    bool
    41  		EnablePushCreateOrg                     bool
    42  		DisabledRepoUnits                       []string
    43  		DefaultRepoUnits                        []string
    44  		DefaultForkRepoUnits                    []string
    45  		PrefixArchiveFiles                      bool
    46  		DisableMigrations                       bool
    47  		DisableStars                            bool `ini:"DISABLE_STARS"`
    48  		DefaultBranch                           string
    49  		AllowAdoptionOfUnadoptedRepositories    bool
    50  		AllowDeleteOfUnadoptedRepositories      bool
    51  		DisableDownloadSourceArchives           bool
    52  		AllowForkWithoutMaximumLimit            bool
    53  
    54  		// Repository editor settings
    55  		Editor struct {
    56  			LineWrapExtensions   []string
    57  			PreviewableFileModes []string
    58  		} `ini:"-"`
    59  
    60  		// Repository upload settings
    61  		Upload struct {
    62  			Enabled      bool
    63  			TempPath     string
    64  			AllowedTypes string
    65  			FileMaxSize  int64
    66  			MaxFiles     int
    67  		} `ini:"-"`
    68  
    69  		// Repository local settings
    70  		Local struct {
    71  			LocalCopyPath string
    72  		} `ini:"-"`
    73  
    74  		// Pull request settings
    75  		PullRequest struct {
    76  			WorkInProgressPrefixes                   []string
    77  			CloseKeywords                            []string
    78  			ReopenKeywords                           []string
    79  			DefaultMergeStyle                        string
    80  			DefaultMergeMessageCommitsLimit          int
    81  			DefaultMergeMessageSize                  int
    82  			DefaultMergeMessageAllAuthors            bool
    83  			DefaultMergeMessageMaxApprovers          int
    84  			DefaultMergeMessageOfficialApproversOnly bool
    85  			PopulateSquashCommentWithCommitMessages  bool
    86  			AddCoCommitterTrailers                   bool
    87  			TestConflictingPatchesWithGitApply       bool
    88  		} `ini:"repository.pull-request"`
    89  
    90  		// Issue Setting
    91  		Issue struct {
    92  			LockReasons []string
    93  		} `ini:"repository.issue"`
    94  
    95  		Release struct {
    96  			AllowedTypes     string
    97  			DefaultPagingNum int
    98  		} `ini:"repository.release"`
    99  
   100  		Signing struct {
   101  			SigningKey        string
   102  			SigningName       string
   103  			SigningEmail      string
   104  			InitialCommit     []string
   105  			CRUDActions       []string `ini:"CRUD_ACTIONS"`
   106  			Merges            []string
   107  			Wiki              []string
   108  			DefaultTrustModel string
   109  		} `ini:"repository.signing"`
   110  	}{
   111  		DetectedCharsetsOrder: []string{
   112  			"UTF-8",
   113  			"UTF-16BE",
   114  			"UTF-16LE",
   115  			"UTF-32BE",
   116  			"UTF-32LE",
   117  			"ISO-8859-1",
   118  			"windows-1252",
   119  			"ISO-8859-2",
   120  			"windows-1250",
   121  			"ISO-8859-5",
   122  			"ISO-8859-6",
   123  			"ISO-8859-7",
   124  			"windows-1253",
   125  			"ISO-8859-8-I",
   126  			"windows-1255",
   127  			"ISO-8859-8",
   128  			"windows-1251",
   129  			"windows-1256",
   130  			"KOI8-R",
   131  			"ISO-8859-9",
   132  			"windows-1254",
   133  			"Shift_JIS",
   134  			"GB18030",
   135  			"EUC-JP",
   136  			"EUC-KR",
   137  			"Big5",
   138  			"ISO-2022-JP",
   139  			"ISO-2022-KR",
   140  			"ISO-2022-CN",
   141  			"IBM424_rtl",
   142  			"IBM424_ltr",
   143  			"IBM420_rtl",
   144  			"IBM420_ltr",
   145  		},
   146  		DetectedCharsetScore:                    map[string]int{},
   147  		AnsiCharset:                             "",
   148  		ForcePrivate:                            false,
   149  		DefaultPrivate:                          RepoCreatingLastUserVisibility,
   150  		DefaultPushCreatePrivate:                true,
   151  		MaxCreationLimit:                        -1,
   152  		PreferredLicenses:                       []string{"Apache License 2.0", "MIT License"},
   153  		DisableHTTPGit:                          false,
   154  		AccessControlAllowOrigin:                "",
   155  		UseCompatSSHURI:                         false,
   156  		DefaultCloseIssuesViaCommitsInAnyBranch: false,
   157  		EnablePushCreateUser:                    false,
   158  		EnablePushCreateOrg:                     false,
   159  		DisabledRepoUnits:                       []string{},
   160  		DefaultRepoUnits:                        []string{},
   161  		DefaultForkRepoUnits:                    []string{},
   162  		PrefixArchiveFiles:                      true,
   163  		DisableMigrations:                       false,
   164  		DisableStars:                            false,
   165  		DefaultBranch:                           "main",
   166  		AllowForkWithoutMaximumLimit:            true,
   167  
   168  		// Repository editor settings
   169  		Editor: struct {
   170  			LineWrapExtensions   []string
   171  			PreviewableFileModes []string
   172  		}{
   173  			LineWrapExtensions:   strings.Split(".txt,.md,.markdown,.mdown,.mkd,", ","),
   174  			PreviewableFileModes: []string{"markdown"},
   175  		},
   176  
   177  		// Repository upload settings
   178  		Upload: struct {
   179  			Enabled      bool
   180  			TempPath     string
   181  			AllowedTypes string
   182  			FileMaxSize  int64
   183  			MaxFiles     int
   184  		}{
   185  			Enabled:      true,
   186  			TempPath:     "data/tmp/uploads",
   187  			AllowedTypes: "",
   188  			FileMaxSize:  3,
   189  			MaxFiles:     5,
   190  		},
   191  
   192  		// Repository local settings
   193  		Local: struct {
   194  			LocalCopyPath string
   195  		}{
   196  			LocalCopyPath: "tmp/local-repo",
   197  		},
   198  
   199  		// Pull request settings
   200  		PullRequest: struct {
   201  			WorkInProgressPrefixes                   []string
   202  			CloseKeywords                            []string
   203  			ReopenKeywords                           []string
   204  			DefaultMergeStyle                        string
   205  			DefaultMergeMessageCommitsLimit          int
   206  			DefaultMergeMessageSize                  int
   207  			DefaultMergeMessageAllAuthors            bool
   208  			DefaultMergeMessageMaxApprovers          int
   209  			DefaultMergeMessageOfficialApproversOnly bool
   210  			PopulateSquashCommentWithCommitMessages  bool
   211  			AddCoCommitterTrailers                   bool
   212  			TestConflictingPatchesWithGitApply       bool
   213  		}{
   214  			WorkInProgressPrefixes: []string{"WIP:", "[WIP]"},
   215  			// Same as GitHub. See
   216  			// https://help.github.com/articles/closing-issues-via-commit-messages
   217  			CloseKeywords:                            strings.Split("close,closes,closed,fix,fixes,fixed,resolve,resolves,resolved", ","),
   218  			ReopenKeywords:                           strings.Split("reopen,reopens,reopened", ","),
   219  			DefaultMergeStyle:                        "merge",
   220  			DefaultMergeMessageCommitsLimit:          50,
   221  			DefaultMergeMessageSize:                  5 * 1024,
   222  			DefaultMergeMessageAllAuthors:            false,
   223  			DefaultMergeMessageMaxApprovers:          10,
   224  			DefaultMergeMessageOfficialApproversOnly: true,
   225  			PopulateSquashCommentWithCommitMessages:  false,
   226  			AddCoCommitterTrailers:                   true,
   227  		},
   228  
   229  		// Issue settings
   230  		Issue: struct {
   231  			LockReasons []string
   232  		}{
   233  			LockReasons: strings.Split("Too heated,Off-topic,Spam,Resolved", ","),
   234  		},
   235  
   236  		Release: struct {
   237  			AllowedTypes     string
   238  			DefaultPagingNum int
   239  		}{
   240  			AllowedTypes:     "",
   241  			DefaultPagingNum: 10,
   242  		},
   243  
   244  		// Signing settings
   245  		Signing: struct {
   246  			SigningKey        string
   247  			SigningName       string
   248  			SigningEmail      string
   249  			InitialCommit     []string
   250  			CRUDActions       []string `ini:"CRUD_ACTIONS"`
   251  			Merges            []string
   252  			Wiki              []string
   253  			DefaultTrustModel string
   254  		}{
   255  			SigningKey:        "default",
   256  			SigningName:       "",
   257  			SigningEmail:      "",
   258  			InitialCommit:     []string{"always"},
   259  			CRUDActions:       []string{"pubkey", "twofa", "parentsigned"},
   260  			Merges:            []string{"pubkey", "twofa", "basesigned", "commitssigned"},
   261  			Wiki:              []string{"never"},
   262  			DefaultTrustModel: "collaborator",
   263  		},
   264  	}
   265  	RepoRootPath string
   266  	ScriptType   = "bash"
   267  
   268  	RepoArchive = struct {
   269  		Storage
   270  	}{}
   271  )
   272  
   273  func loadRepositoryFrom(rootCfg ConfigProvider) {
   274  	var err error
   275  	// Determine and create root git repository path.
   276  	sec := rootCfg.Section("repository")
   277  	Repository.DisableHTTPGit = sec.Key("DISABLE_HTTP_GIT").MustBool()
   278  	Repository.UseCompatSSHURI = sec.Key("USE_COMPAT_SSH_URI").MustBool()
   279  	Repository.MaxCreationLimit = sec.Key("MAX_CREATION_LIMIT").MustInt(-1)
   280  	Repository.DefaultBranch = sec.Key("DEFAULT_BRANCH").MustString(Repository.DefaultBranch)
   281  	RepoRootPath = sec.Key("ROOT").MustString(path.Join(AppDataPath, "gitea-repositories"))
   282  	forcePathSeparator(RepoRootPath)
   283  	if !filepath.IsAbs(RepoRootPath) {
   284  		RepoRootPath = filepath.Join(AppWorkPath, RepoRootPath)
   285  	} else {
   286  		RepoRootPath = filepath.Clean(RepoRootPath)
   287  	}
   288  	defaultDetectedCharsetsOrder := make([]string, 0, len(Repository.DetectedCharsetsOrder))
   289  	for _, charset := range Repository.DetectedCharsetsOrder {
   290  		defaultDetectedCharsetsOrder = append(defaultDetectedCharsetsOrder, strings.ToLower(strings.TrimSpace(charset)))
   291  	}
   292  	ScriptType = sec.Key("SCRIPT_TYPE").MustString("bash")
   293  
   294  	if _, err := exec.LookPath(ScriptType); err != nil {
   295  		log.Warn("SCRIPT_TYPE %q is not on the current PATH. Are you sure that this is the correct SCRIPT_TYPE?", ScriptType)
   296  	}
   297  
   298  	if err = sec.MapTo(&Repository); err != nil {
   299  		log.Fatal("Failed to map Repository settings: %v", err)
   300  	} else if err = rootCfg.Section("repository.editor").MapTo(&Repository.Editor); err != nil {
   301  		log.Fatal("Failed to map Repository.Editor settings: %v", err)
   302  	} else if err = rootCfg.Section("repository.upload").MapTo(&Repository.Upload); err != nil {
   303  		log.Fatal("Failed to map Repository.Upload settings: %v", err)
   304  	} else if err = rootCfg.Section("repository.local").MapTo(&Repository.Local); err != nil {
   305  		log.Fatal("Failed to map Repository.Local settings: %v", err)
   306  	} else if err = rootCfg.Section("repository.pull-request").MapTo(&Repository.PullRequest); err != nil {
   307  		log.Fatal("Failed to map Repository.PullRequest settings: %v", err)
   308  	}
   309  
   310  	if !rootCfg.Section("packages").Key("ENABLED").MustBool(true) {
   311  		Repository.DisabledRepoUnits = append(Repository.DisabledRepoUnits, "repo.packages")
   312  	}
   313  
   314  	// Handle default trustmodel settings
   315  	Repository.Signing.DefaultTrustModel = strings.ToLower(strings.TrimSpace(Repository.Signing.DefaultTrustModel))
   316  	if Repository.Signing.DefaultTrustModel == "default" {
   317  		Repository.Signing.DefaultTrustModel = "collaborator"
   318  	}
   319  
   320  	// Handle preferred charset orders
   321  	preferred := make([]string, 0, len(Repository.DetectedCharsetsOrder))
   322  	for _, charset := range Repository.DetectedCharsetsOrder {
   323  		canonicalCharset := strings.ToLower(strings.TrimSpace(charset))
   324  		preferred = append(preferred, canonicalCharset)
   325  		// remove it from the defaults
   326  		for i, charset := range defaultDetectedCharsetsOrder {
   327  			if charset == canonicalCharset {
   328  				defaultDetectedCharsetsOrder = append(defaultDetectedCharsetsOrder[:i], defaultDetectedCharsetsOrder[i+1:]...)
   329  				break
   330  			}
   331  		}
   332  	}
   333  
   334  	i := 0
   335  	for _, charset := range preferred {
   336  		// Add the defaults
   337  		if charset == "defaults" {
   338  			for _, charset := range defaultDetectedCharsetsOrder {
   339  				canonicalCharset := strings.ToLower(strings.TrimSpace(charset))
   340  				if _, has := Repository.DetectedCharsetScore[canonicalCharset]; !has {
   341  					Repository.DetectedCharsetScore[canonicalCharset] = i
   342  					i++
   343  				}
   344  			}
   345  			continue
   346  		}
   347  		if _, has := Repository.DetectedCharsetScore[charset]; !has {
   348  			Repository.DetectedCharsetScore[charset] = i
   349  			i++
   350  		}
   351  	}
   352  
   353  	if !filepath.IsAbs(Repository.Upload.TempPath) {
   354  		Repository.Upload.TempPath = path.Join(AppWorkPath, Repository.Upload.TempPath)
   355  	}
   356  
   357  	RepoArchive.Storage = getStorage(rootCfg, "repo-archive", "", nil)
   358  }