|
@@ -9,7 +9,6 @@ import (
|
|
"net/mail"
|
|
"net/mail"
|
|
"net/url"
|
|
"net/url"
|
|
"os"
|
|
"os"
|
|
- "path"
|
|
|
|
"path/filepath"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strconv"
|
|
"strings"
|
|
"strings"
|
|
@@ -18,13 +17,12 @@ import (
|
|
_ "github.com/go-macaron/cache/memcache"
|
|
_ "github.com/go-macaron/cache/memcache"
|
|
_ "github.com/go-macaron/cache/redis"
|
|
_ "github.com/go-macaron/cache/redis"
|
|
_ "github.com/go-macaron/session/redis"
|
|
_ "github.com/go-macaron/session/redis"
|
|
|
|
+ "github.com/gogs/go-libravatar"
|
|
"github.com/mcuadros/go-version"
|
|
"github.com/mcuadros/go-version"
|
|
"github.com/pkg/errors"
|
|
"github.com/pkg/errors"
|
|
"gopkg.in/ini.v1"
|
|
"gopkg.in/ini.v1"
|
|
log "unknwon.dev/clog/v2"
|
|
log "unknwon.dev/clog/v2"
|
|
|
|
|
|
- "github.com/gogs/go-libravatar"
|
|
|
|
-
|
|
|
|
"gogs.io/gogs/internal/assets/conf"
|
|
"gogs.io/gogs/internal/assets/conf"
|
|
"gogs.io/gogs/internal/osutil"
|
|
"gogs.io/gogs/internal/osutil"
|
|
)
|
|
)
|
|
@@ -184,18 +182,18 @@ func Init(customConf string) error {
|
|
Repository.Root = ensureAbs(Repository.Root)
|
|
Repository.Root = ensureAbs(Repository.Root)
|
|
Repository.Upload.TempPath = ensureAbs(Repository.Upload.TempPath)
|
|
Repository.Upload.TempPath = ensureAbs(Repository.Upload.TempPath)
|
|
|
|
|
|
- // *******************************
|
|
|
|
|
|
+ // *****************************
|
|
// ----- Database settings -----
|
|
// ----- Database settings -----
|
|
- // *******************************
|
|
|
|
|
|
+ // *****************************
|
|
|
|
|
|
if err = File.Section("database").MapTo(&Database); err != nil {
|
|
if err = File.Section("database").MapTo(&Database); err != nil {
|
|
return errors.Wrap(err, "mapping [database] section")
|
|
return errors.Wrap(err, "mapping [database] section")
|
|
}
|
|
}
|
|
Database.Path = ensureAbs(Database.Path)
|
|
Database.Path = ensureAbs(Database.Path)
|
|
|
|
|
|
- // *******************************
|
|
|
|
|
|
+ // *****************************
|
|
// ----- Security settings -----
|
|
// ----- Security settings -----
|
|
- // *******************************
|
|
|
|
|
|
+ // *****************************
|
|
|
|
|
|
if err = File.Section("security").MapTo(&Security); err != nil {
|
|
if err = File.Section("security").MapTo(&Security); err != nil {
|
|
return errors.Wrap(err, "mapping [security] section")
|
|
return errors.Wrap(err, "mapping [security] section")
|
|
@@ -245,37 +243,40 @@ func Init(customConf string) error {
|
|
return errors.Wrap(err, "mapping [service] section")
|
|
return errors.Wrap(err, "mapping [service] section")
|
|
}
|
|
}
|
|
|
|
|
|
- // ***********************************
|
|
|
|
|
|
+ // *************************
|
|
// ----- User settings -----
|
|
// ----- User settings -----
|
|
- // ***********************************
|
|
|
|
|
|
+ // *************************
|
|
|
|
|
|
if err = File.Section("user").MapTo(&User); err != nil {
|
|
if err = File.Section("user").MapTo(&User); err != nil {
|
|
return errors.Wrap(err, "mapping [user] section")
|
|
return errors.Wrap(err, "mapping [user] section")
|
|
}
|
|
}
|
|
|
|
|
|
- // ***********************************
|
|
|
|
|
|
+ // ****************************
|
|
// ----- Session settings -----
|
|
// ----- Session settings -----
|
|
- // ***********************************
|
|
|
|
|
|
+ // ****************************
|
|
|
|
|
|
if err = File.Section("session").MapTo(&Session); err != nil {
|
|
if err = File.Section("session").MapTo(&Session); err != nil {
|
|
return errors.Wrap(err, "mapping [session] section")
|
|
return errors.Wrap(err, "mapping [session] section")
|
|
}
|
|
}
|
|
|
|
|
|
- handleDeprecated()
|
|
|
|
|
|
+ // *******************************
|
|
|
|
+ // ----- Attachment settings -----
|
|
|
|
+ // *******************************
|
|
|
|
+
|
|
|
|
+ if err = File.Section("attachment").MapTo(&Attachment); err != nil {
|
|
|
|
+ return errors.Wrap(err, "mapping [attachment] section")
|
|
|
|
+ }
|
|
|
|
+ Attachment.Path = ensureAbs(Attachment.Path)
|
|
|
|
|
|
- // TODO
|
|
|
|
|
|
+ // *************************
|
|
|
|
+ // ----- Time settings -----
|
|
|
|
+ // *************************
|
|
|
|
|
|
- sec := File.Section("attachment")
|
|
|
|
- AttachmentPath = sec.Key("PATH").MustString(filepath.Join(Server.AppDataPath, "attachments"))
|
|
|
|
- if !filepath.IsAbs(AttachmentPath) {
|
|
|
|
- AttachmentPath = path.Join(workDir, AttachmentPath)
|
|
|
|
|
|
+ if err = File.Section("time").MapTo(&Time); err != nil {
|
|
|
|
+ return errors.Wrap(err, "mapping [time] section")
|
|
}
|
|
}
|
|
- AttachmentAllowedTypes = strings.Replace(sec.Key("ALLOWED_TYPES").MustString("image/jpeg,image/png"), "|", ",", -1)
|
|
|
|
- AttachmentMaxSize = sec.Key("MAX_SIZE").MustInt64(4)
|
|
|
|
- AttachmentMaxFiles = sec.Key("MAX_FILES").MustInt(5)
|
|
|
|
- AttachmentEnabled = sec.Key("ENABLED").MustBool(true)
|
|
|
|
|
|
|
|
- TimeFormat = map[string]string{
|
|
|
|
|
|
+ Time.FormatLayout = map[string]string{
|
|
"ANSIC": time.ANSIC,
|
|
"ANSIC": time.ANSIC,
|
|
"UnixDate": time.UnixDate,
|
|
"UnixDate": time.UnixDate,
|
|
"RubyDate": time.RubyDate,
|
|
"RubyDate": time.RubyDate,
|
|
@@ -291,89 +292,104 @@ func Init(customConf string) error {
|
|
"StampMilli": time.StampMilli,
|
|
"StampMilli": time.StampMilli,
|
|
"StampMicro": time.StampMicro,
|
|
"StampMicro": time.StampMicro,
|
|
"StampNano": time.StampNano,
|
|
"StampNano": time.StampNano,
|
|
- }[File.Section("time").Key("FORMAT").MustString("RFC1123")]
|
|
|
|
-
|
|
|
|
- sec = File.Section("picture")
|
|
|
|
- AvatarUploadPath = sec.Key("AVATAR_UPLOAD_PATH").MustString(filepath.Join(Server.AppDataPath, "avatars"))
|
|
|
|
- if !filepath.IsAbs(AvatarUploadPath) {
|
|
|
|
- AvatarUploadPath = path.Join(workDir, AvatarUploadPath)
|
|
|
|
|
|
+ }[Time.Format]
|
|
|
|
+ if Time.FormatLayout == "" {
|
|
|
|
+ return fmt.Errorf("unrecognized '[time] FORMAT': %s", Time.Format)
|
|
}
|
|
}
|
|
- RepositoryAvatarUploadPath = sec.Key("REPOSITORY_AVATAR_UPLOAD_PATH").MustString(filepath.Join(Server.AppDataPath, "repo-avatars"))
|
|
|
|
- if !filepath.IsAbs(RepositoryAvatarUploadPath) {
|
|
|
|
- RepositoryAvatarUploadPath = path.Join(workDir, RepositoryAvatarUploadPath)
|
|
|
|
|
|
+
|
|
|
|
+ // ****************************
|
|
|
|
+ // ----- Picture settings -----
|
|
|
|
+ // ****************************
|
|
|
|
+
|
|
|
|
+ if err = File.Section("picture").MapTo(&Picture); err != nil {
|
|
|
|
+ return errors.Wrap(err, "mapping [picture] section")
|
|
}
|
|
}
|
|
- switch source := sec.Key("GRAVATAR_SOURCE").MustString("gravatar"); source {
|
|
|
|
- case "duoshuo":
|
|
|
|
- GravatarSource = "http://gravatar.duoshuo.com/avatar/"
|
|
|
|
|
|
+ Picture.AvatarUploadPath = ensureAbs(Picture.AvatarUploadPath)
|
|
|
|
+ Picture.RepositoryAvatarUploadPath = ensureAbs(Picture.RepositoryAvatarUploadPath)
|
|
|
|
+
|
|
|
|
+ switch Picture.GravatarSource {
|
|
case "gravatar":
|
|
case "gravatar":
|
|
- GravatarSource = "https://secure.gravatar.com/avatar/"
|
|
|
|
|
|
+ Picture.GravatarSource = "https://secure.gravatar.com/avatar/"
|
|
case "libravatar":
|
|
case "libravatar":
|
|
- GravatarSource = "https://seccdn.libravatar.org/avatar/"
|
|
|
|
- default:
|
|
|
|
- GravatarSource = source
|
|
|
|
|
|
+ Picture.GravatarSource = "https://seccdn.libravatar.org/avatar/"
|
|
}
|
|
}
|
|
- DisableGravatar = sec.Key("DISABLE_GRAVATAR").MustBool()
|
|
|
|
- EnableFederatedAvatar = sec.Key("ENABLE_FEDERATED_AVATAR").MustBool(true)
|
|
|
|
|
|
+
|
|
if Server.OfflineMode {
|
|
if Server.OfflineMode {
|
|
- DisableGravatar = true
|
|
|
|
- EnableFederatedAvatar = false
|
|
|
|
|
|
+ Picture.DisableGravatar = true
|
|
|
|
+ Picture.EnableFederatedAvatar = false
|
|
}
|
|
}
|
|
- if DisableGravatar {
|
|
|
|
- EnableFederatedAvatar = false
|
|
|
|
|
|
+ if Picture.DisableGravatar {
|
|
|
|
+ Picture.EnableFederatedAvatar = false
|
|
}
|
|
}
|
|
|
|
+ if Picture.EnableFederatedAvatar {
|
|
|
|
+ gravatarURL, err := url.Parse(Picture.GravatarSource)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return errors.Wrapf(err, "parse Gravatar source %q", Picture.GravatarSource)
|
|
|
|
+ }
|
|
|
|
|
|
- if EnableFederatedAvatar {
|
|
|
|
- LibravatarService = libravatar.New()
|
|
|
|
- parts := strings.Split(GravatarSource, "/")
|
|
|
|
- if len(parts) >= 3 {
|
|
|
|
- if parts[0] == "https:" {
|
|
|
|
- LibravatarService.SetUseHTTPS(true)
|
|
|
|
- LibravatarService.SetSecureFallbackHost(parts[2])
|
|
|
|
- } else {
|
|
|
|
- LibravatarService.SetUseHTTPS(false)
|
|
|
|
- LibravatarService.SetFallbackHost(parts[2])
|
|
|
|
- }
|
|
|
|
|
|
+ Picture.LibravatarService = libravatar.New()
|
|
|
|
+ if gravatarURL.Scheme == "https" {
|
|
|
|
+ Picture.LibravatarService.SetUseHTTPS(true)
|
|
|
|
+ Picture.LibravatarService.SetSecureFallbackHost(gravatarURL.Host)
|
|
|
|
+ } else {
|
|
|
|
+ Picture.LibravatarService.SetUseHTTPS(false)
|
|
|
|
+ Picture.LibravatarService.SetFallbackHost(gravatarURL.Host)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if err = File.Section("http").MapTo(&HTTP); err != nil {
|
|
|
|
- log.Fatal("Failed to map HTTP settings: %v", err)
|
|
|
|
|
|
+ // ***************************
|
|
|
|
+ // ----- Mirror settings -----
|
|
|
|
+ // ***************************
|
|
|
|
+
|
|
|
|
+ if err = File.Section("mirror").MapTo(&Mirror); err != nil {
|
|
|
|
+ return errors.Wrap(err, "mapping [mirror] section")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if Mirror.DefaultInterval <= 0 {
|
|
|
|
+ Mirror.DefaultInterval = 8
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // *************************
|
|
|
|
+ // ----- I18n settings -----
|
|
|
|
+ // *************************
|
|
|
|
+
|
|
|
|
+ I18n = new(i18n)
|
|
|
|
+ if err = File.Section("i18n").MapTo(I18n); err != nil {
|
|
|
|
+ return errors.Wrap(err, "mapping [i18n] section")
|
|
|
|
+ }
|
|
|
|
+ I18n.dateLangs = File.Section("i18n.datelang").KeysHash()
|
|
|
|
+
|
|
|
|
+ handleDeprecated()
|
|
|
|
+
|
|
|
|
+ if err = File.Section("cache").MapTo(&Cache); err != nil {
|
|
|
|
+ return errors.Wrap(err, "mapping [cache] section")
|
|
|
|
+ } else if err = File.Section("http").MapTo(&HTTP); err != nil {
|
|
|
|
+ return errors.Wrap(err, "mapping [http] section")
|
|
|
|
+ } else if err = File.Section("release").MapTo(&Release); err != nil {
|
|
|
|
+ return errors.Wrap(err, "mapping [release] section")
|
|
} else if err = File.Section("webhook").MapTo(&Webhook); err != nil {
|
|
} else if err = File.Section("webhook").MapTo(&Webhook); err != nil {
|
|
- log.Fatal("Failed to map Webhook settings: %v", err)
|
|
|
|
- } else if err = File.Section("release.attachment").MapTo(&Release.Attachment); err != nil {
|
|
|
|
- log.Fatal("Failed to map Release.Attachment settings: %v", err)
|
|
|
|
|
|
+ return errors.Wrap(err, "mapping [webhook] section")
|
|
} else if err = File.Section("markdown").MapTo(&Markdown); err != nil {
|
|
} else if err = File.Section("markdown").MapTo(&Markdown); err != nil {
|
|
- log.Fatal("Failed to map Markdown settings: %v", err)
|
|
|
|
|
|
+ return errors.Wrap(err, "mapping [markdown] section")
|
|
} else if err = File.Section("smartypants").MapTo(&Smartypants); err != nil {
|
|
} else if err = File.Section("smartypants").MapTo(&Smartypants); err != nil {
|
|
- log.Fatal("Failed to map Smartypants settings: %v", err)
|
|
|
|
|
|
+ return errors.Wrap(err, "mapping [smartypants] section")
|
|
} else if err = File.Section("admin").MapTo(&Admin); err != nil {
|
|
} else if err = File.Section("admin").MapTo(&Admin); err != nil {
|
|
- log.Fatal("Failed to map Admin settings: %v", err)
|
|
|
|
|
|
+ return errors.Wrap(err, "mapping [admin] section")
|
|
} else if err = File.Section("cron").MapTo(&Cron); err != nil {
|
|
} else if err = File.Section("cron").MapTo(&Cron); err != nil {
|
|
- log.Fatal("Failed to map Cron settings: %v", err)
|
|
|
|
|
|
+ return errors.Wrap(err, "mapping [cron] section")
|
|
} else if err = File.Section("git").MapTo(&Git); err != nil {
|
|
} else if err = File.Section("git").MapTo(&Git); err != nil {
|
|
- log.Fatal("Failed to map Git settings: %v", err)
|
|
|
|
- } else if err = File.Section("mirror").MapTo(&Mirror); err != nil {
|
|
|
|
- log.Fatal("Failed to map Mirror settings: %v", err)
|
|
|
|
|
|
+ return errors.Wrap(err, "mapping [git] section")
|
|
} else if err = File.Section("api").MapTo(&API); err != nil {
|
|
} else if err = File.Section("api").MapTo(&API); err != nil {
|
|
- log.Fatal("Failed to map API settings: %v", err)
|
|
|
|
|
|
+ return errors.Wrap(err, "mapping [api] section")
|
|
} else if err = File.Section("ui").MapTo(&UI); err != nil {
|
|
} else if err = File.Section("ui").MapTo(&UI); err != nil {
|
|
- log.Fatal("Failed to map UI settings: %v", err)
|
|
|
|
|
|
+ return errors.Wrap(err, "mapping [ui] section")
|
|
} else if err = File.Section("prometheus").MapTo(&Prometheus); err != nil {
|
|
} else if err = File.Section("prometheus").MapTo(&Prometheus); err != nil {
|
|
- log.Fatal("Failed to map Prometheus settings: %v", err)
|
|
|
|
|
|
+ return errors.Wrap(err, "mapping [prometheus] section")
|
|
|
|
+ } else if err = File.Section("other").MapTo(&Other); err != nil {
|
|
|
|
+ return errors.Wrap(err, "mapping [other] section")
|
|
}
|
|
}
|
|
|
|
|
|
- if Mirror.DefaultInterval <= 0 {
|
|
|
|
- Mirror.DefaultInterval = 24
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- Langs = File.Section("i18n").Key("LANGS").Strings(",")
|
|
|
|
- Names = File.Section("i18n").Key("NAMES").Strings(",")
|
|
|
|
- dateLangs = File.Section("i18n.datelang").KeysHash()
|
|
|
|
-
|
|
|
|
- ShowFooterBranding = File.Section("other").Key("SHOW_FOOTER_BRANDING").MustBool()
|
|
|
|
- ShowFooterTemplateLoadTime = File.Section("other").Key("SHOW_FOOTER_TEMPLATE_LOAD_TIME").MustBool()
|
|
|
|
-
|
|
|
|
- HasRobotsTxt = osutil.IsFile(path.Join(CustomDir(), "robots.txt"))
|
|
|
|
|
|
+ HasRobotsTxt = osutil.IsFile(filepath.Join(CustomDir(), "robots.txt"))
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
@@ -384,325 +400,3 @@ func MustInit(customConf string) {
|
|
panic(err)
|
|
panic(err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
-// TODO
|
|
|
|
-
|
|
|
|
-var (
|
|
|
|
- HTTP struct {
|
|
|
|
- AccessControlAllowOrigin string
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Database settings
|
|
|
|
- UseSQLite3 bool
|
|
|
|
- UseMySQL bool
|
|
|
|
- UsePostgreSQL bool
|
|
|
|
- UseMSSQL bool
|
|
|
|
-
|
|
|
|
- // Webhook settings
|
|
|
|
- Webhook struct {
|
|
|
|
- Types []string
|
|
|
|
- QueueLength int
|
|
|
|
- DeliverTimeout int
|
|
|
|
- SkipTLSVerify bool `ini:"SKIP_TLS_VERIFY"`
|
|
|
|
- PagingNum int
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Release settigns
|
|
|
|
- Release struct {
|
|
|
|
- Attachment struct {
|
|
|
|
- Enabled bool
|
|
|
|
- TempPath string
|
|
|
|
- AllowedTypes []string `delim:"|"`
|
|
|
|
- MaxSize int64
|
|
|
|
- MaxFiles int
|
|
|
|
- } `ini:"-"`
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Markdown sttings
|
|
|
|
- Markdown struct {
|
|
|
|
- EnableHardLineBreak bool
|
|
|
|
- CustomURLSchemes []string `ini:"CUSTOM_URL_SCHEMES"`
|
|
|
|
- FileExtensions []string
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Smartypants settings
|
|
|
|
- Smartypants struct {
|
|
|
|
- Enabled bool
|
|
|
|
- Fractions bool
|
|
|
|
- Dashes bool
|
|
|
|
- LatexDashes bool
|
|
|
|
- AngledQuotes bool
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Admin settings
|
|
|
|
- Admin struct {
|
|
|
|
- DisableRegularOrgCreation bool
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Picture settings
|
|
|
|
- AvatarUploadPath string
|
|
|
|
- RepositoryAvatarUploadPath string
|
|
|
|
- GravatarSource string
|
|
|
|
- DisableGravatar bool
|
|
|
|
- EnableFederatedAvatar bool
|
|
|
|
- LibravatarService *libravatar.Libravatar
|
|
|
|
-
|
|
|
|
- // Log settings
|
|
|
|
- LogRootPath string
|
|
|
|
- LogModes []string
|
|
|
|
- LogConfigs []interface{}
|
|
|
|
-
|
|
|
|
- // Attachment settings
|
|
|
|
- AttachmentPath string
|
|
|
|
- AttachmentAllowedTypes string
|
|
|
|
- AttachmentMaxSize int64
|
|
|
|
- AttachmentMaxFiles int
|
|
|
|
- AttachmentEnabled bool
|
|
|
|
-
|
|
|
|
- // Time settings
|
|
|
|
- TimeFormat string
|
|
|
|
-
|
|
|
|
- // Cache settings
|
|
|
|
- CacheAdapter string
|
|
|
|
- CacheInterval int
|
|
|
|
- CacheConn string
|
|
|
|
-
|
|
|
|
- // Cron tasks
|
|
|
|
- Cron struct {
|
|
|
|
- UpdateMirror struct {
|
|
|
|
- Enabled bool
|
|
|
|
- RunAtStart bool
|
|
|
|
- Schedule string
|
|
|
|
- } `ini:"cron.update_mirrors"`
|
|
|
|
- RepoHealthCheck struct {
|
|
|
|
- Enabled bool
|
|
|
|
- RunAtStart bool
|
|
|
|
- Schedule string
|
|
|
|
- Timeout time.Duration
|
|
|
|
- Args []string `delim:" "`
|
|
|
|
- } `ini:"cron.repo_health_check"`
|
|
|
|
- CheckRepoStats struct {
|
|
|
|
- Enabled bool
|
|
|
|
- RunAtStart bool
|
|
|
|
- Schedule string
|
|
|
|
- } `ini:"cron.check_repo_stats"`
|
|
|
|
- RepoArchiveCleanup struct {
|
|
|
|
- Enabled bool
|
|
|
|
- RunAtStart bool
|
|
|
|
- Schedule string
|
|
|
|
- OlderThan time.Duration
|
|
|
|
- } `ini:"cron.repo_archive_cleanup"`
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Git settings
|
|
|
|
- Git struct {
|
|
|
|
- Version string `ini:"-"`
|
|
|
|
- DisableDiffHighlight bool
|
|
|
|
- MaxGitDiffLines int
|
|
|
|
- MaxGitDiffLineCharacters int
|
|
|
|
- MaxGitDiffFiles int
|
|
|
|
- GCArgs []string `ini:"GC_ARGS" delim:" "`
|
|
|
|
- Timeout struct {
|
|
|
|
- Migrate int
|
|
|
|
- Mirror int
|
|
|
|
- Clone int
|
|
|
|
- Pull int
|
|
|
|
- GC int `ini:"GC"`
|
|
|
|
- } `ini:"git.timeout"`
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Mirror settings
|
|
|
|
- Mirror struct {
|
|
|
|
- DefaultInterval int
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // API settings
|
|
|
|
- API struct {
|
|
|
|
- MaxResponseItems int
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // UI settings
|
|
|
|
- UI struct {
|
|
|
|
- ExplorePagingNum int
|
|
|
|
- IssuePagingNum int
|
|
|
|
- FeedMaxCommitNum int
|
|
|
|
- ThemeColorMetaTag string
|
|
|
|
- MaxDisplayFileSize int64
|
|
|
|
-
|
|
|
|
- Admin struct {
|
|
|
|
- UserPagingNum int
|
|
|
|
- RepoPagingNum int
|
|
|
|
- NoticePagingNum int
|
|
|
|
- OrgPagingNum int
|
|
|
|
- } `ini:"ui.admin"`
|
|
|
|
- User struct {
|
|
|
|
- RepoPagingNum int
|
|
|
|
- NewsFeedPagingNum int
|
|
|
|
- CommitsPagingNum int
|
|
|
|
- } `ini:"ui.user"`
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Prometheus settings
|
|
|
|
- Prometheus struct {
|
|
|
|
- Enabled bool
|
|
|
|
- EnableBasicAuth bool
|
|
|
|
- BasicAuthUsername string
|
|
|
|
- BasicAuthPassword string
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // I18n settings
|
|
|
|
- Langs []string
|
|
|
|
- Names []string
|
|
|
|
- dateLangs map[string]string
|
|
|
|
-
|
|
|
|
- // Highlight settings are loaded in modules/template/hightlight.go
|
|
|
|
-
|
|
|
|
- // Other settings
|
|
|
|
- ShowFooterBranding bool
|
|
|
|
- ShowFooterTemplateLoadTime bool
|
|
|
|
-
|
|
|
|
- // Global setting objects
|
|
|
|
- HasRobotsTxt bool
|
|
|
|
-)
|
|
|
|
-
|
|
|
|
-// DateLang transforms standard language locale name to corresponding value in datetime plugin.
|
|
|
|
-func DateLang(lang string) string {
|
|
|
|
- name, ok := dateLangs[lang]
|
|
|
|
- if ok {
|
|
|
|
- return name
|
|
|
|
- }
|
|
|
|
- return "en"
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// InitLogging initializes the logging service of the application.
|
|
|
|
-func InitLogging() {
|
|
|
|
- LogRootPath = File.Section("log").Key("ROOT_PATH").MustString(filepath.Join(WorkDir(), "log"))
|
|
|
|
-
|
|
|
|
- // Because we always create a console logger as the primary logger at init time,
|
|
|
|
- // we need to remove it in case the user doesn't configure to use it after the
|
|
|
|
- // logging service is initalized.
|
|
|
|
- hasConsole := false
|
|
|
|
-
|
|
|
|
- // Iterate over [log.*] sections to initialize individual logger.
|
|
|
|
- LogModes = strings.Split(File.Section("log").Key("MODE").MustString("console"), ",")
|
|
|
|
- LogConfigs = make([]interface{}, len(LogModes))
|
|
|
|
- levelMappings := map[string]log.Level{
|
|
|
|
- "trace": log.LevelTrace,
|
|
|
|
- "info": log.LevelInfo,
|
|
|
|
- "warn": log.LevelWarn,
|
|
|
|
- "error": log.LevelError,
|
|
|
|
- "fatal": log.LevelFatal,
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- type config struct {
|
|
|
|
- Buffer int64
|
|
|
|
- Config interface{}
|
|
|
|
- }
|
|
|
|
- for i, mode := range LogModes {
|
|
|
|
- mode = strings.ToLower(strings.TrimSpace(mode))
|
|
|
|
- secName := "log." + mode
|
|
|
|
- sec, err := File.GetSection(secName)
|
|
|
|
- if err != nil {
|
|
|
|
- log.Fatal("Missing configuration section [%s] for %q logger", secName, mode)
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- level := levelMappings[strings.ToLower(sec.Key("LEVEL").MustString("trace"))]
|
|
|
|
- buffer := sec.Key("BUFFER_LEN").MustInt64(100)
|
|
|
|
- c := new(config)
|
|
|
|
- switch mode {
|
|
|
|
- case log.DefaultConsoleName:
|
|
|
|
- hasConsole = true
|
|
|
|
- c = &config{
|
|
|
|
- Buffer: buffer,
|
|
|
|
- Config: log.ConsoleConfig{
|
|
|
|
- Level: level,
|
|
|
|
- },
|
|
|
|
- }
|
|
|
|
- err = log.NewConsole(c.Buffer, c.Config)
|
|
|
|
-
|
|
|
|
- case log.DefaultFileName:
|
|
|
|
- logPath := filepath.Join(LogRootPath, "gogs.log")
|
|
|
|
- logDir := filepath.Dir(logPath)
|
|
|
|
- err = os.MkdirAll(logDir, os.ModePerm)
|
|
|
|
- if err != nil {
|
|
|
|
- log.Fatal("Failed to create log directory %q: %v", logDir, err)
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- c = &config{
|
|
|
|
- Buffer: buffer,
|
|
|
|
- Config: log.FileConfig{
|
|
|
|
- Level: level,
|
|
|
|
- Filename: logPath,
|
|
|
|
- FileRotationConfig: log.FileRotationConfig{
|
|
|
|
- Rotate: sec.Key("LOG_ROTATE").MustBool(true),
|
|
|
|
- Daily: sec.Key("DAILY_ROTATE").MustBool(true),
|
|
|
|
- MaxSize: 1 << uint(sec.Key("MAX_SIZE_SHIFT").MustInt(28)),
|
|
|
|
- MaxLines: sec.Key("MAX_LINES").MustInt64(1000000),
|
|
|
|
- MaxDays: sec.Key("MAX_DAYS").MustInt64(7),
|
|
|
|
- },
|
|
|
|
- },
|
|
|
|
- }
|
|
|
|
- err = log.NewFile(c.Buffer, c.Config)
|
|
|
|
-
|
|
|
|
- case log.DefaultSlackName:
|
|
|
|
- c = &config{
|
|
|
|
- Buffer: buffer,
|
|
|
|
- Config: log.SlackConfig{
|
|
|
|
- Level: level,
|
|
|
|
- URL: sec.Key("URL").String(),
|
|
|
|
- },
|
|
|
|
- }
|
|
|
|
- err = log.NewSlack(c.Buffer, c.Config)
|
|
|
|
-
|
|
|
|
- case log.DefaultDiscordName:
|
|
|
|
- c = &config{
|
|
|
|
- Buffer: buffer,
|
|
|
|
- Config: log.DiscordConfig{
|
|
|
|
- Level: level,
|
|
|
|
- URL: sec.Key("URL").String(),
|
|
|
|
- Username: sec.Key("USERNAME").String(),
|
|
|
|
- },
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- default:
|
|
|
|
- continue
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if err != nil {
|
|
|
|
- log.Fatal("Failed to init %s logger: %v", mode, err)
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
- LogConfigs[i] = c
|
|
|
|
-
|
|
|
|
- log.Trace("Log mode: %s (%s)", strings.Title(mode), strings.Title(strings.ToLower(level.String())))
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if !hasConsole {
|
|
|
|
- log.Remove(log.DefaultConsoleName)
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-func newCacheService() {
|
|
|
|
- CacheAdapter = File.Section("cache").Key("ADAPTER").In("memory", []string{"memory", "redis", "memcache"})
|
|
|
|
- switch CacheAdapter {
|
|
|
|
- case "memory":
|
|
|
|
- CacheInterval = File.Section("cache").Key("INTERVAL").MustInt(60)
|
|
|
|
- case "redis", "memcache":
|
|
|
|
- CacheConn = strings.Trim(File.Section("cache").Key("HOST").String(), "\" ")
|
|
|
|
- default:
|
|
|
|
- log.Fatal("Unrecognized cache adapter %q", CacheAdapter)
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- log.Trace("Cache service is enabled")
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-func NewServices() {
|
|
|
|
- newCacheService()
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// HookMode indicates whether program starts as Git server-side hook callback.
|
|
|
|
-// All operations should be done synchronously to prevent program exits before finishing.
|
|
|
|
-var HookMode bool
|
|
|