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 }