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