2019-03-16 08:42:44 +05:30
|
|
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
2022-11-27 23:50:29 +05:30
|
|
|
// SPDX-License-Identifier: MIT
|
2019-03-16 08:42:44 +05:30
|
|
|
|
|
|
|
package setting
|
|
|
|
|
|
|
|
import (
|
2022-01-30 22:03:36 +05:30
|
|
|
"os/exec"
|
2019-03-16 08:42:44 +05:30
|
|
|
"path"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"code.gitea.io/gitea/modules/log"
|
|
|
|
)
|
|
|
|
|
|
|
|
// enumerates all the policy repository creating
|
|
|
|
const (
|
|
|
|
RepoCreatingLastUserVisibility = "last"
|
|
|
|
RepoCreatingPrivate = "private"
|
|
|
|
RepoCreatingPublic = "public"
|
|
|
|
)
|
|
|
|
|
2022-06-12 21:21:54 +05:30
|
|
|
// ItemsPerPage maximum items per page in forks, watchers and stars of a repo
|
|
|
|
const ItemsPerPage = 40
|
|
|
|
|
2019-03-16 08:42:44 +05:30
|
|
|
// Repository settings
|
|
|
|
var (
|
|
|
|
Repository = struct {
|
2020-06-03 03:50:19 +05:30
|
|
|
DetectedCharsetsOrder []string
|
|
|
|
DetectedCharsetScore map[string]int `ini:"-"`
|
2019-03-16 08:42:44 +05:30
|
|
|
AnsiCharset string
|
|
|
|
ForcePrivate bool
|
|
|
|
DefaultPrivate string
|
2020-09-28 00:50:52 +05:30
|
|
|
DefaultPushCreatePrivate bool
|
2019-03-16 08:42:44 +05:30
|
|
|
MaxCreationLimit int
|
|
|
|
PreferredLicenses []string
|
|
|
|
DisableHTTPGit bool
|
|
|
|
AccessControlAllowOrigin string
|
|
|
|
UseCompatSSHURI bool
|
2023-05-12 15:14:37 +05:30
|
|
|
GoGetCloneURLProtocol string
|
2019-03-16 08:42:44 +05:30
|
|
|
DefaultCloseIssuesViaCommitsInAnyBranch bool
|
2019-12-15 08:19:52 +05:30
|
|
|
EnablePushCreateUser bool
|
|
|
|
EnablePushCreateOrg bool
|
2020-01-17 13:04:37 +05:30
|
|
|
DisabledRepoUnits []string
|
|
|
|
DefaultRepoUnits []string
|
2023-02-04 12:18:38 +05:30
|
|
|
DefaultForkRepoUnits []string
|
2020-01-23 05:16:46 +05:30
|
|
|
PrefixArchiveFiles bool
|
2020-12-21 20:09:41 +05:30
|
|
|
DisableMigrations bool
|
2021-04-15 22:23:57 +05:30
|
|
|
DisableStars bool `ini:"DISABLE_STARS"`
|
2020-06-18 02:23:55 +05:30
|
|
|
DefaultBranch string
|
2020-09-25 09:39:23 +05:30
|
|
|
AllowAdoptionOfUnadoptedRepositories bool
|
|
|
|
AllowDeleteOfUnadoptedRepositories bool
|
2022-07-31 22:27:02 +05:30
|
|
|
DisableDownloadSourceArchives bool
|
2022-12-28 02:51:14 +05:30
|
|
|
AllowForkWithoutMaximumLimit bool
|
2019-03-16 08:42:44 +05:30
|
|
|
|
|
|
|
// Repository editor settings
|
|
|
|
Editor struct {
|
2023-03-24 11:42:23 +05:30
|
|
|
LineWrapExtensions []string
|
2019-03-16 08:42:44 +05:30
|
|
|
} `ini:"-"`
|
|
|
|
|
|
|
|
// Repository upload settings
|
|
|
|
Upload struct {
|
|
|
|
Enabled bool
|
|
|
|
TempPath string
|
2020-10-05 11:19:33 +05:30
|
|
|
AllowedTypes string
|
2019-03-16 08:42:44 +05:30
|
|
|
FileMaxSize int64
|
|
|
|
MaxFiles int
|
|
|
|
} `ini:"-"`
|
|
|
|
|
|
|
|
// Repository local settings
|
|
|
|
Local struct {
|
|
|
|
LocalCopyPath string
|
|
|
|
} `ini:"-"`
|
|
|
|
|
|
|
|
// Pull request settings
|
|
|
|
PullRequest struct {
|
2019-12-31 05:04:11 +05:30
|
|
|
WorkInProgressPrefixes []string
|
|
|
|
CloseKeywords []string
|
|
|
|
ReopenKeywords []string
|
2022-06-03 09:15:54 +05:30
|
|
|
DefaultMergeStyle string
|
2019-12-31 05:04:11 +05:30
|
|
|
DefaultMergeMessageCommitsLimit int
|
|
|
|
DefaultMergeMessageSize int
|
|
|
|
DefaultMergeMessageAllAuthors bool
|
|
|
|
DefaultMergeMessageMaxApprovers int
|
|
|
|
DefaultMergeMessageOfficialApproversOnly bool
|
2021-06-19 03:38:22 +05:30
|
|
|
PopulateSquashCommentWithCommitMessages bool
|
2021-11-29 12:39:55 +05:30
|
|
|
AddCoCommitterTrailers bool
|
2022-12-19 17:07:15 +05:30
|
|
|
TestConflictingPatchesWithGitApply bool
|
2024-01-17 06:14:56 +05:30
|
|
|
RetargetChildrenOnMerge bool
|
2019-03-16 08:42:44 +05:30
|
|
|
} `ini:"repository.pull-request"`
|
|
|
|
|
|
|
|
// Issue Setting
|
|
|
|
Issue struct {
|
|
|
|
LockReasons []string
|
2023-05-25 18:47:19 +05:30
|
|
|
MaxPinned int
|
2019-03-16 08:42:44 +05:30
|
|
|
} `ini:"repository.issue"`
|
2019-10-16 19:12:42 +05:30
|
|
|
|
2020-10-05 11:19:33 +05:30
|
|
|
Release struct {
|
2021-08-29 21:55:16 +05:30
|
|
|
AllowedTypes string
|
|
|
|
DefaultPagingNum int
|
2020-10-05 11:19:33 +05:30
|
|
|
} `ini:"repository.release"`
|
|
|
|
|
2019-10-16 19:12:42 +05:30
|
|
|
Signing struct {
|
2020-09-19 22:14:55 +05:30
|
|
|
SigningKey string
|
|
|
|
SigningName string
|
|
|
|
SigningEmail string
|
|
|
|
InitialCommit []string
|
|
|
|
CRUDActions []string `ini:"CRUD_ACTIONS"`
|
|
|
|
Merges []string
|
|
|
|
Wiki []string
|
|
|
|
DefaultTrustModel string
|
2019-10-16 19:12:42 +05:30
|
|
|
} `ini:"repository.signing"`
|
2019-03-16 08:42:44 +05:30
|
|
|
}{
|
2020-06-03 03:50:19 +05:30
|
|
|
DetectedCharsetsOrder: []string{
|
|
|
|
"UTF-8",
|
|
|
|
"UTF-16BE",
|
|
|
|
"UTF-16LE",
|
|
|
|
"UTF-32BE",
|
|
|
|
"UTF-32LE",
|
|
|
|
"ISO-8859-1",
|
|
|
|
"windows-1252",
|
|
|
|
"ISO-8859-2",
|
|
|
|
"windows-1250",
|
|
|
|
"ISO-8859-5",
|
|
|
|
"ISO-8859-6",
|
|
|
|
"ISO-8859-7",
|
|
|
|
"windows-1253",
|
|
|
|
"ISO-8859-8-I",
|
|
|
|
"windows-1255",
|
|
|
|
"ISO-8859-8",
|
|
|
|
"windows-1251",
|
|
|
|
"windows-1256",
|
|
|
|
"KOI8-R",
|
|
|
|
"ISO-8859-9",
|
|
|
|
"windows-1254",
|
|
|
|
"Shift_JIS",
|
|
|
|
"GB18030",
|
|
|
|
"EUC-JP",
|
|
|
|
"EUC-KR",
|
|
|
|
"Big5",
|
|
|
|
"ISO-2022-JP",
|
|
|
|
"ISO-2022-KR",
|
|
|
|
"ISO-2022-CN",
|
|
|
|
"IBM424_rtl",
|
|
|
|
"IBM424_ltr",
|
|
|
|
"IBM420_rtl",
|
|
|
|
"IBM420_ltr",
|
|
|
|
},
|
|
|
|
DetectedCharsetScore: map[string]int{},
|
2019-03-16 08:42:44 +05:30
|
|
|
AnsiCharset: "",
|
|
|
|
ForcePrivate: false,
|
|
|
|
DefaultPrivate: RepoCreatingLastUserVisibility,
|
2020-09-28 00:50:52 +05:30
|
|
|
DefaultPushCreatePrivate: true,
|
2019-03-16 08:42:44 +05:30
|
|
|
MaxCreationLimit: -1,
|
2023-12-06 03:02:11 +05:30
|
|
|
PreferredLicenses: []string{"Apache-2.0", "MIT"},
|
2019-03-16 08:42:44 +05:30
|
|
|
DisableHTTPGit: false,
|
|
|
|
AccessControlAllowOrigin: "",
|
|
|
|
UseCompatSSHURI: false,
|
|
|
|
DefaultCloseIssuesViaCommitsInAnyBranch: false,
|
2019-12-15 08:19:52 +05:30
|
|
|
EnablePushCreateUser: false,
|
|
|
|
EnablePushCreateOrg: false,
|
2020-01-17 13:04:37 +05:30
|
|
|
DisabledRepoUnits: []string{},
|
|
|
|
DefaultRepoUnits: []string{},
|
2023-02-04 12:18:38 +05:30
|
|
|
DefaultForkRepoUnits: []string{},
|
2020-01-23 05:16:46 +05:30
|
|
|
PrefixArchiveFiles: true,
|
2020-12-21 20:09:41 +05:30
|
|
|
DisableMigrations: false,
|
2021-04-15 22:23:57 +05:30
|
|
|
DisableStars: false,
|
2022-04-09 09:56:48 +05:30
|
|
|
DefaultBranch: "main",
|
2022-12-28 02:51:14 +05:30
|
|
|
AllowForkWithoutMaximumLimit: true,
|
2019-03-16 08:42:44 +05:30
|
|
|
|
|
|
|
// Repository editor settings
|
|
|
|
Editor: struct {
|
2023-03-24 11:42:23 +05:30
|
|
|
LineWrapExtensions []string
|
2019-03-16 08:42:44 +05:30
|
|
|
}{
|
2023-04-26 20:52:54 +05:30
|
|
|
LineWrapExtensions: strings.Split(".txt,.md,.markdown,.mdown,.mkd,.livemd,", ","),
|
2019-03-16 08:42:44 +05:30
|
|
|
},
|
|
|
|
|
|
|
|
// Repository upload settings
|
|
|
|
Upload: struct {
|
|
|
|
Enabled bool
|
|
|
|
TempPath string
|
2020-10-05 11:19:33 +05:30
|
|
|
AllowedTypes string
|
2019-03-16 08:42:44 +05:30
|
|
|
FileMaxSize int64
|
|
|
|
MaxFiles int
|
|
|
|
}{
|
|
|
|
Enabled: true,
|
|
|
|
TempPath: "data/tmp/uploads",
|
2020-10-05 11:19:33 +05:30
|
|
|
AllowedTypes: "",
|
2023-11-17 17:12:00 +05:30
|
|
|
FileMaxSize: 50,
|
2019-03-16 08:42:44 +05:30
|
|
|
MaxFiles: 5,
|
|
|
|
},
|
|
|
|
|
|
|
|
// Repository local settings
|
|
|
|
Local: struct {
|
|
|
|
LocalCopyPath string
|
|
|
|
}{
|
|
|
|
LocalCopyPath: "tmp/local-repo",
|
|
|
|
},
|
|
|
|
|
|
|
|
// Pull request settings
|
|
|
|
PullRequest: struct {
|
2019-12-31 05:04:11 +05:30
|
|
|
WorkInProgressPrefixes []string
|
|
|
|
CloseKeywords []string
|
|
|
|
ReopenKeywords []string
|
2022-06-03 09:15:54 +05:30
|
|
|
DefaultMergeStyle string
|
2019-12-31 05:04:11 +05:30
|
|
|
DefaultMergeMessageCommitsLimit int
|
|
|
|
DefaultMergeMessageSize int
|
|
|
|
DefaultMergeMessageAllAuthors bool
|
|
|
|
DefaultMergeMessageMaxApprovers int
|
|
|
|
DefaultMergeMessageOfficialApproversOnly bool
|
2021-06-19 03:38:22 +05:30
|
|
|
PopulateSquashCommentWithCommitMessages bool
|
2021-11-29 12:39:55 +05:30
|
|
|
AddCoCommitterTrailers bool
|
2022-12-19 17:07:15 +05:30
|
|
|
TestConflictingPatchesWithGitApply bool
|
2024-01-17 06:14:56 +05:30
|
|
|
RetargetChildrenOnMerge bool
|
2019-03-16 08:42:44 +05:30
|
|
|
}{
|
|
|
|
WorkInProgressPrefixes: []string{"WIP:", "[WIP]"},
|
2019-10-30 18:13:59 +05:30
|
|
|
// Same as GitHub. See
|
|
|
|
// https://help.github.com/articles/closing-issues-via-commit-messages
|
2019-12-31 05:04:11 +05:30
|
|
|
CloseKeywords: strings.Split("close,closes,closed,fix,fixes,fixed,resolve,resolves,resolved", ","),
|
|
|
|
ReopenKeywords: strings.Split("reopen,reopens,reopened", ","),
|
2022-06-03 09:15:54 +05:30
|
|
|
DefaultMergeStyle: "merge",
|
2019-12-31 05:04:11 +05:30
|
|
|
DefaultMergeMessageCommitsLimit: 50,
|
|
|
|
DefaultMergeMessageSize: 5 * 1024,
|
|
|
|
DefaultMergeMessageAllAuthors: false,
|
|
|
|
DefaultMergeMessageMaxApprovers: 10,
|
|
|
|
DefaultMergeMessageOfficialApproversOnly: true,
|
2021-06-19 03:38:22 +05:30
|
|
|
PopulateSquashCommentWithCommitMessages: false,
|
2021-11-29 12:39:55 +05:30
|
|
|
AddCoCommitterTrailers: true,
|
2024-01-17 06:14:56 +05:30
|
|
|
RetargetChildrenOnMerge: true,
|
2019-03-16 08:42:44 +05:30
|
|
|
},
|
|
|
|
|
|
|
|
// Issue settings
|
|
|
|
Issue: struct {
|
|
|
|
LockReasons []string
|
2023-05-25 18:47:19 +05:30
|
|
|
MaxPinned int
|
2019-03-16 08:42:44 +05:30
|
|
|
}{
|
|
|
|
LockReasons: strings.Split("Too heated,Off-topic,Spam,Resolved", ","),
|
2023-05-25 18:47:19 +05:30
|
|
|
MaxPinned: 3,
|
2019-03-16 08:42:44 +05:30
|
|
|
},
|
2019-10-16 19:12:42 +05:30
|
|
|
|
2020-10-05 11:19:33 +05:30
|
|
|
Release: struct {
|
2021-08-29 21:55:16 +05:30
|
|
|
AllowedTypes string
|
|
|
|
DefaultPagingNum int
|
2020-10-05 11:19:33 +05:30
|
|
|
}{
|
2021-08-29 21:55:16 +05:30
|
|
|
AllowedTypes: "",
|
|
|
|
DefaultPagingNum: 10,
|
2020-10-05 11:19:33 +05:30
|
|
|
},
|
|
|
|
|
2019-10-16 19:12:42 +05:30
|
|
|
// Signing settings
|
|
|
|
Signing: struct {
|
2020-09-19 22:14:55 +05:30
|
|
|
SigningKey string
|
|
|
|
SigningName string
|
|
|
|
SigningEmail string
|
|
|
|
InitialCommit []string
|
|
|
|
CRUDActions []string `ini:"CRUD_ACTIONS"`
|
|
|
|
Merges []string
|
|
|
|
Wiki []string
|
|
|
|
DefaultTrustModel string
|
2019-10-16 19:12:42 +05:30
|
|
|
}{
|
2020-09-19 22:14:55 +05:30
|
|
|
SigningKey: "default",
|
|
|
|
SigningName: "",
|
|
|
|
SigningEmail: "",
|
|
|
|
InitialCommit: []string{"always"},
|
|
|
|
CRUDActions: []string{"pubkey", "twofa", "parentsigned"},
|
|
|
|
Merges: []string{"pubkey", "twofa", "basesigned", "commitssigned"},
|
|
|
|
Wiki: []string{"never"},
|
|
|
|
DefaultTrustModel: "collaborator",
|
2019-10-16 19:12:42 +05:30
|
|
|
},
|
2019-03-16 08:42:44 +05:30
|
|
|
}
|
|
|
|
RepoRootPath string
|
|
|
|
ScriptType = "bash"
|
|
|
|
)
|
|
|
|
|
2023-02-19 21:42:01 +05:30
|
|
|
func loadRepositoryFrom(rootCfg ConfigProvider) {
|
2020-12-16 03:22:59 +05:30
|
|
|
var err error
|
2019-03-16 08:42:44 +05:30
|
|
|
// Determine and create root git repository path.
|
2023-02-19 21:42:01 +05:30
|
|
|
sec := rootCfg.Section("repository")
|
2019-03-16 08:42:44 +05:30
|
|
|
Repository.DisableHTTPGit = sec.Key("DISABLE_HTTP_GIT").MustBool()
|
|
|
|
Repository.UseCompatSSHURI = sec.Key("USE_COMPAT_SSH_URI").MustBool()
|
2023-05-12 15:14:37 +05:30
|
|
|
Repository.GoGetCloneURLProtocol = sec.Key("GO_GET_CLONE_URL_PROTOCOL").MustString("https")
|
2019-03-16 08:42:44 +05:30
|
|
|
Repository.MaxCreationLimit = sec.Key("MAX_CREATION_LIMIT").MustInt(-1)
|
2020-09-25 09:39:23 +05:30
|
|
|
Repository.DefaultBranch = sec.Key("DEFAULT_BRANCH").MustString(Repository.DefaultBranch)
|
2020-12-16 03:22:59 +05:30
|
|
|
RepoRootPath = sec.Key("ROOT").MustString(path.Join(AppDataPath, "gitea-repositories"))
|
2019-03-16 08:42:44 +05:30
|
|
|
if !filepath.IsAbs(RepoRootPath) {
|
|
|
|
RepoRootPath = filepath.Join(AppWorkPath, RepoRootPath)
|
|
|
|
} else {
|
|
|
|
RepoRootPath = filepath.Clean(RepoRootPath)
|
|
|
|
}
|
2020-06-03 03:50:19 +05:30
|
|
|
defaultDetectedCharsetsOrder := make([]string, 0, len(Repository.DetectedCharsetsOrder))
|
|
|
|
for _, charset := range Repository.DetectedCharsetsOrder {
|
|
|
|
defaultDetectedCharsetsOrder = append(defaultDetectedCharsetsOrder, strings.ToLower(strings.TrimSpace(charset)))
|
|
|
|
}
|
2019-03-16 08:42:44 +05:30
|
|
|
ScriptType = sec.Key("SCRIPT_TYPE").MustString("bash")
|
|
|
|
|
2022-01-30 22:03:36 +05:30
|
|
|
if _, err := exec.LookPath(ScriptType); err != nil {
|
|
|
|
log.Warn("SCRIPT_TYPE %q is not on the current PATH. Are you sure that this is the correct SCRIPT_TYPE?", ScriptType)
|
|
|
|
}
|
|
|
|
|
2023-02-19 21:42:01 +05:30
|
|
|
if err = sec.MapTo(&Repository); err != nil {
|
2019-04-02 13:18:31 +05:30
|
|
|
log.Fatal("Failed to map Repository settings: %v", err)
|
2023-02-19 21:42:01 +05:30
|
|
|
} else if err = rootCfg.Section("repository.editor").MapTo(&Repository.Editor); err != nil {
|
2019-04-02 13:18:31 +05:30
|
|
|
log.Fatal("Failed to map Repository.Editor settings: %v", err)
|
2023-02-19 21:42:01 +05:30
|
|
|
} else if err = rootCfg.Section("repository.upload").MapTo(&Repository.Upload); err != nil {
|
2019-04-02 13:18:31 +05:30
|
|
|
log.Fatal("Failed to map Repository.Upload settings: %v", err)
|
2023-02-19 21:42:01 +05:30
|
|
|
} else if err = rootCfg.Section("repository.local").MapTo(&Repository.Local); err != nil {
|
2019-04-02 13:18:31 +05:30
|
|
|
log.Fatal("Failed to map Repository.Local settings: %v", err)
|
2023-02-19 21:42:01 +05:30
|
|
|
} else if err = rootCfg.Section("repository.pull-request").MapTo(&Repository.PullRequest); err != nil {
|
2019-04-02 13:18:31 +05:30
|
|
|
log.Fatal("Failed to map Repository.PullRequest settings: %v", err)
|
2019-03-16 08:42:44 +05:30
|
|
|
}
|
|
|
|
|
2023-05-19 17:05:12 +05:30
|
|
|
if !rootCfg.Section("packages").Key("ENABLED").MustBool(Packages.Enabled) {
|
2022-05-08 21:21:50 +05:30
|
|
|
Repository.DisabledRepoUnits = append(Repository.DisabledRepoUnits, "repo.packages")
|
|
|
|
}
|
|
|
|
|
2023-05-19 17:05:12 +05:30
|
|
|
if !rootCfg.Section("actions").Key("ENABLED").MustBool(Actions.Enabled) {
|
2023-05-05 17:32:30 +05:30
|
|
|
Repository.DisabledRepoUnits = append(Repository.DisabledRepoUnits, "repo.actions")
|
|
|
|
}
|
|
|
|
|
2020-09-19 22:14:55 +05:30
|
|
|
// Handle default trustmodel settings
|
|
|
|
Repository.Signing.DefaultTrustModel = strings.ToLower(strings.TrimSpace(Repository.Signing.DefaultTrustModel))
|
|
|
|
if Repository.Signing.DefaultTrustModel == "default" {
|
|
|
|
Repository.Signing.DefaultTrustModel = "collaborator"
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle preferred charset orders
|
2020-06-03 03:50:19 +05:30
|
|
|
preferred := make([]string, 0, len(Repository.DetectedCharsetsOrder))
|
|
|
|
for _, charset := range Repository.DetectedCharsetsOrder {
|
|
|
|
canonicalCharset := strings.ToLower(strings.TrimSpace(charset))
|
|
|
|
preferred = append(preferred, canonicalCharset)
|
|
|
|
// remove it from the defaults
|
|
|
|
for i, charset := range defaultDetectedCharsetsOrder {
|
|
|
|
if charset == canonicalCharset {
|
|
|
|
defaultDetectedCharsetsOrder = append(defaultDetectedCharsetsOrder[:i], defaultDetectedCharsetsOrder[i+1:]...)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
i := 0
|
|
|
|
for _, charset := range preferred {
|
|
|
|
// Add the defaults
|
|
|
|
if charset == "defaults" {
|
|
|
|
for _, charset := range defaultDetectedCharsetsOrder {
|
|
|
|
canonicalCharset := strings.ToLower(strings.TrimSpace(charset))
|
|
|
|
if _, has := Repository.DetectedCharsetScore[canonicalCharset]; !has {
|
|
|
|
Repository.DetectedCharsetScore[canonicalCharset] = i
|
|
|
|
i++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if _, has := Repository.DetectedCharsetScore[charset]; !has {
|
|
|
|
Repository.DetectedCharsetScore[charset] = i
|
|
|
|
i++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-16 08:42:44 +05:30
|
|
|
if !filepath.IsAbs(Repository.Upload.TempPath) {
|
|
|
|
Repository.Upload.TempPath = path.Join(AppWorkPath, Repository.Upload.TempPath)
|
|
|
|
}
|
2021-06-24 02:42:38 +05:30
|
|
|
|
2023-06-14 09:12:38 +05:30
|
|
|
if err := loadRepoArchiveFrom(rootCfg); err != nil {
|
|
|
|
log.Fatal("loadRepoArchiveFrom: %v", err)
|
|
|
|
}
|
2019-03-16 08:42:44 +05:30
|
|
|
}
|