mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-26 01:40:36 +00:00
#1657 allow forcing all private repos
This commit is contained in:
parent
d5fab7f1b9
commit
022820103d
15 changed files with 75 additions and 35 deletions
|
@ -5,7 +5,7 @@ Gogs - Go Git Service [![Build Status](https://travis-ci.org/gogits/gogs.svg?bra
|
||||||
|
|
||||||
![](public/img/gogs-large-resize.png)
|
![](public/img/gogs-large-resize.png)
|
||||||
|
|
||||||
##### Current version: 0.6.16 Beta
|
##### Current version: 0.6.18 Beta
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -11,7 +11,11 @@ RUN_MODE = dev
|
||||||
[repository]
|
[repository]
|
||||||
ROOT =
|
ROOT =
|
||||||
SCRIPT_TYPE = bash
|
SCRIPT_TYPE = bash
|
||||||
; Patch test queue length, make it as large as possible.
|
; Default ANSI charset
|
||||||
|
ANSI_CHARSET =
|
||||||
|
; Force every new repository to be private
|
||||||
|
FORCE_PRIVATE = false
|
||||||
|
; Patch test queue length, make it as large as possible
|
||||||
PULL_REQUEST_QUEUE_LENGTH = 10000
|
PULL_REQUEST_QUEUE_LENGTH = 10000
|
||||||
|
|
||||||
[ui]
|
[ui]
|
||||||
|
|
|
@ -334,6 +334,7 @@ repo_name = Repository Name
|
||||||
repo_name_helper = A good repository name is usually composed of short, memorable and unique keywords.
|
repo_name_helper = A good repository name is usually composed of short, memorable and unique keywords.
|
||||||
visibility = Visibility
|
visibility = Visibility
|
||||||
visiblity_helper = This repository is <span class="ui red text">Private</span>
|
visiblity_helper = This repository is <span class="ui red text">Private</span>
|
||||||
|
visiblity_helper_forced = Site admin has forced all new repositories to be <span class="ui red text">Private</span>
|
||||||
visiblity_fork_helper = (Change of this value will affect all forks)
|
visiblity_fork_helper = (Change of this value will affect all forks)
|
||||||
fork_repo = Fork Repository
|
fork_repo = Fork Repository
|
||||||
fork_from = Fork From
|
fork_from = Fork From
|
||||||
|
|
|
@ -334,6 +334,7 @@ repo_name=仓库名称
|
||||||
repo_name_helper=伟大的仓库名称一般都较短、令人深刻并且 <strong>独一无二</strong> 的。
|
repo_name_helper=伟大的仓库名称一般都较短、令人深刻并且 <strong>独一无二</strong> 的。
|
||||||
visibility=可见性
|
visibility=可见性
|
||||||
visiblity_helper=该仓库为 <span class="ui red text">私有的</span>
|
visiblity_helper=该仓库为 <span class="ui red text">私有的</span>
|
||||||
|
visiblity_helper_forced=网站管理员已强制要求所有新建仓库必须为 <span class="ui red text">私有的</span>
|
||||||
visiblity_fork_helper=(修改该值将会影响到所有派生仓库)
|
visiblity_fork_helper=(修改该值将会影响到所有派生仓库)
|
||||||
fork_repo=派生仓库
|
fork_repo=派生仓库
|
||||||
fork_from=派生自
|
fork_from=派生自
|
||||||
|
|
2
gogs.go
2
gogs.go
|
@ -17,7 +17,7 @@ import (
|
||||||
"github.com/gogits/gogs/modules/setting"
|
"github.com/gogits/gogs/modules/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
const APP_VER = "0.6.17.1025 Beta"
|
const APP_VER = "0.6.18.1025 Beta"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||||
|
|
|
@ -480,13 +480,21 @@ func MirrorRepository(repoId int64, userName, repoName, repoPath, url string) er
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MigrateRepoOptions struct {
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
IsPrivate bool
|
||||||
|
IsMirror bool
|
||||||
|
RemoteAddr string
|
||||||
|
}
|
||||||
|
|
||||||
// MigrateRepository migrates a existing repository from other project hosting.
|
// MigrateRepository migrates a existing repository from other project hosting.
|
||||||
func MigrateRepository(u *User, name, desc string, private, mirror bool, url string) (*Repository, error) {
|
func MigrateRepository(u *User, opts MigrateRepoOptions) (*Repository, error) {
|
||||||
repo, err := CreateRepository(u, CreateRepoOptions{
|
repo, err := CreateRepository(u, CreateRepoOptions{
|
||||||
Name: name,
|
Name: opts.Name,
|
||||||
Description: desc,
|
Description: opts.Description,
|
||||||
IsPrivate: private,
|
IsPrivate: opts.IsPrivate,
|
||||||
IsMirror: mirror,
|
IsMirror: opts.IsMirror,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -496,7 +504,7 @@ func MigrateRepository(u *User, name, desc string, private, mirror bool, url str
|
||||||
tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()))
|
tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()))
|
||||||
os.MkdirAll(tmpDir, os.ModePerm)
|
os.MkdirAll(tmpDir, os.ModePerm)
|
||||||
|
|
||||||
repoPath := RepoPath(u.Name, name)
|
repoPath := RepoPath(u.Name, opts.Name)
|
||||||
|
|
||||||
if u.IsOrganization() {
|
if u.IsOrganization() {
|
||||||
t, err := u.GetOwnerTeam()
|
t, err := u.GetOwnerTeam()
|
||||||
|
@ -509,8 +517,8 @@ func MigrateRepository(u *User, name, desc string, private, mirror bool, url str
|
||||||
}
|
}
|
||||||
|
|
||||||
repo.IsBare = false
|
repo.IsBare = false
|
||||||
if mirror {
|
if opts.IsMirror {
|
||||||
if err = MirrorRepository(repo.ID, u.Name, repo.Name, repoPath, url); err != nil {
|
if err = MirrorRepository(repo.ID, u.Name, repo.Name, repoPath, opts.RemoteAddr); err != nil {
|
||||||
return repo, err
|
return repo, err
|
||||||
}
|
}
|
||||||
repo.IsMirror = true
|
repo.IsMirror = true
|
||||||
|
@ -522,7 +530,7 @@ func MigrateRepository(u *User, name, desc string, private, mirror bool, url str
|
||||||
// FIXME: this command could for both migrate and mirror
|
// FIXME: this command could for both migrate and mirror
|
||||||
_, stderr, err := process.ExecTimeout(10*time.Minute,
|
_, stderr, err := process.ExecTimeout(10*time.Minute,
|
||||||
fmt.Sprintf("MigrateRepository: %s", repoPath),
|
fmt.Sprintf("MigrateRepository: %s", repoPath),
|
||||||
"git", "clone", "--mirror", "--bare", "--quiet", url, repoPath)
|
"git", "clone", "--mirror", "--bare", "--quiet", opts.RemoteAddr, repoPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return repo, fmt.Errorf("git clone --mirror --bare --quiet: %v", stderr)
|
return repo, fmt.Errorf("git clone --mirror --bare --quiet: %v", stderr)
|
||||||
} else if err = createUpdateHook(repoPath); err != nil {
|
} else if err = createUpdateHook(repoPath); err != nil {
|
||||||
|
|
|
@ -71,7 +71,7 @@ type User struct {
|
||||||
Created time.Time `xorm:"CREATED"`
|
Created time.Time `xorm:"CREATED"`
|
||||||
Updated time.Time `xorm:"UPDATED"`
|
Updated time.Time `xorm:"UPDATED"`
|
||||||
|
|
||||||
// Remember visibility choice for convenience.
|
// Remember visibility choice for convenience, true for private
|
||||||
LastRepoVisibility bool
|
LastRepoVisibility bool
|
||||||
|
|
||||||
// Permissions.
|
// Permissions.
|
||||||
|
|
|
@ -59,8 +59,8 @@ func ShortSha(sha1 string) string {
|
||||||
func DetectEncoding(content []byte) (string, error) {
|
func DetectEncoding(content []byte) (string, error) {
|
||||||
detector := chardet.NewTextDetector()
|
detector := chardet.NewTextDetector()
|
||||||
result, err := detector.DetectBest(content)
|
result, err := detector.DetectBest(content)
|
||||||
if result.Charset != "UTF-8" && len(setting.AnsiCharset) > 0 {
|
if result.Charset != "UTF-8" && len(setting.Repository.AnsiCharset) > 0 {
|
||||||
return setting.AnsiCharset, err
|
return setting.Repository.AnsiCharset, err
|
||||||
}
|
}
|
||||||
return result.Charset, err
|
return result.Charset, err
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -87,11 +87,12 @@ var (
|
||||||
|
|
||||||
// Repository settings.
|
// Repository settings.
|
||||||
Repository struct {
|
Repository struct {
|
||||||
|
AnsiCharset string
|
||||||
|
ForcePrivate bool
|
||||||
PullRequestQueueLength int
|
PullRequestQueueLength int
|
||||||
}
|
}
|
||||||
RepoRootPath string
|
RepoRootPath string
|
||||||
ScriptType string
|
ScriptType string
|
||||||
AnsiCharset string
|
|
||||||
|
|
||||||
// UI settings.
|
// UI settings.
|
||||||
ExplorePagingNum int
|
ExplorePagingNum int
|
||||||
|
@ -360,7 +361,6 @@ func NewContext() {
|
||||||
homeDir = strings.Replace(homeDir, "\\", "/", -1)
|
homeDir = strings.Replace(homeDir, "\\", "/", -1)
|
||||||
|
|
||||||
sec = Cfg.Section("repository")
|
sec = Cfg.Section("repository")
|
||||||
Repository.PullRequestQueueLength = sec.Key("PULL_REQUEST_QUEUE_LENGTH").MustInt(10000)
|
|
||||||
RepoRootPath = sec.Key("ROOT").MustString(path.Join(homeDir, "gogs-repositories"))
|
RepoRootPath = sec.Key("ROOT").MustString(path.Join(homeDir, "gogs-repositories"))
|
||||||
forcePathSeparator(RepoRootPath)
|
forcePathSeparator(RepoRootPath)
|
||||||
if !filepath.IsAbs(RepoRootPath) {
|
if !filepath.IsAbs(RepoRootPath) {
|
||||||
|
@ -369,7 +369,9 @@ func NewContext() {
|
||||||
RepoRootPath = path.Clean(RepoRootPath)
|
RepoRootPath = path.Clean(RepoRootPath)
|
||||||
}
|
}
|
||||||
ScriptType = sec.Key("SCRIPT_TYPE").MustString("bash")
|
ScriptType = sec.Key("SCRIPT_TYPE").MustString("bash")
|
||||||
AnsiCharset = sec.Key("ANSI_CHARSET").MustString("")
|
Repository.AnsiCharset = sec.Key("ANSI_CHARSET").String()
|
||||||
|
Repository.ForcePrivate = sec.Key("FORCE_PRIVATE").MustBool()
|
||||||
|
Repository.PullRequestQueueLength = sec.Key("PULL_REQUEST_QUEUE_LENGTH").MustInt(10000)
|
||||||
|
|
||||||
// UI settings.
|
// UI settings.
|
||||||
sec = Cfg.Section("ui")
|
sec = Cfg.Section("ui")
|
||||||
|
|
|
@ -237,7 +237,13 @@ func MigrateRepo(ctx *middleware.Context, form auth.MigrateRepoForm) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := models.MigrateRepository(ctxUser, form.RepoName, form.Description, form.Private, form.Mirror, remoteAddr)
|
repo, err := models.MigrateRepository(ctxUser, models.MigrateRepoOptions{
|
||||||
|
Name: form.RepoName,
|
||||||
|
Description: form.Description,
|
||||||
|
IsPrivate: form.Private || setting.Repository.ForcePrivate,
|
||||||
|
IsMirror: form.Mirror,
|
||||||
|
RemoteAddr: remoteAddr,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if repo != nil {
|
if repo != nil {
|
||||||
if errDelete := models.DeleteRepository(ctxUser.Id, repo.ID); errDelete != nil {
|
if errDelete := models.DeleteRepository(ctxUser.Id, repo.ID); errDelete != nil {
|
||||||
|
|
|
@ -46,7 +46,7 @@ func checkContextUser(ctx *middleware.Context, uid int64) *models.User {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Handle(500, "checkContextUser", fmt.Errorf("GetUserById(%d): %v", uid, err))
|
ctx.Handle(500, "GetUserByID", fmt.Errorf("[%d]: %v", uid, err))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ func Create(ctx *middleware.Context) {
|
||||||
ctx.Data["Readmes"] = models.Readmes
|
ctx.Data["Readmes"] = models.Readmes
|
||||||
ctx.Data["readme"] = "Default"
|
ctx.Data["readme"] = "Default"
|
||||||
ctx.Data["private"] = ctx.User.LastRepoVisibility
|
ctx.Data["private"] = ctx.User.LastRepoVisibility
|
||||||
|
ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate
|
||||||
|
|
||||||
ctxUser := checkContextUser(ctx, ctx.QueryInt64("org"))
|
ctxUser := checkContextUser(ctx, ctx.QueryInt64("org"))
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
|
@ -117,11 +118,11 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) {
|
||||||
Gitignores: form.Gitignores,
|
Gitignores: form.Gitignores,
|
||||||
License: form.License,
|
License: form.License,
|
||||||
Readme: form.Readme,
|
Readme: form.Readme,
|
||||||
IsPrivate: form.Private,
|
IsPrivate: form.Private || setting.Repository.ForcePrivate,
|
||||||
AutoInit: form.AutoInit,
|
AutoInit: form.AutoInit,
|
||||||
})
|
})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
log.Trace("Repository created: %s/%s", ctxUser.Name, repo.Name)
|
log.Trace("Repository created[%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name)
|
||||||
ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + repo.Name)
|
ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + repo.Name)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -138,6 +139,7 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) {
|
||||||
func Migrate(ctx *middleware.Context) {
|
func Migrate(ctx *middleware.Context) {
|
||||||
ctx.Data["Title"] = ctx.Tr("new_migrate")
|
ctx.Data["Title"] = ctx.Tr("new_migrate")
|
||||||
ctx.Data["private"] = ctx.User.LastRepoVisibility
|
ctx.Data["private"] = ctx.User.LastRepoVisibility
|
||||||
|
ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate
|
||||||
|
|
||||||
ctxUser := checkContextUser(ctx, ctx.QueryInt64("org"))
|
ctxUser := checkContextUser(ctx, ctx.QueryInt64("org"))
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
|
@ -185,9 +187,15 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := models.MigrateRepository(ctxUser, form.RepoName, form.Description, form.Private, form.Mirror, remoteAddr)
|
repo, err := models.MigrateRepository(ctxUser, models.MigrateRepoOptions{
|
||||||
|
Name: form.RepoName,
|
||||||
|
Description: form.Description,
|
||||||
|
IsPrivate: form.Private || setting.Repository.ForcePrivate,
|
||||||
|
IsMirror: form.Mirror,
|
||||||
|
RemoteAddr: remoteAddr,
|
||||||
|
})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName)
|
log.Trace("Repository migrated[%d]: %s/%s", repo.ID, ctxUser.Name, form.RepoName)
|
||||||
ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + form.RepoName)
|
ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + form.RepoName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
0.6.17.1025 Beta
|
0.6.18.1025 Beta
|
|
@ -41,8 +41,13 @@
|
||||||
<div class="inline field">
|
<div class="inline field">
|
||||||
<label>{{.i18n.Tr "repo.visibility"}}</label>
|
<label>{{.i18n.Tr "repo.visibility"}}</label>
|
||||||
<div class="ui checkbox">
|
<div class="ui checkbox">
|
||||||
|
{{if .IsForcedPrivate}}
|
||||||
|
<input name="private" type="checkbox" checked readonly>
|
||||||
|
<label>{{.i18n.Tr "repo.visiblity_helper_forced" | Safe}}</label>
|
||||||
|
{{else}}
|
||||||
<input name="private" type="checkbox" {{if .private}}checked{{end}}>
|
<input name="private" type="checkbox" {{if .private}}checked{{end}}>
|
||||||
<label>{{.i18n.Tr "repo.visiblity_helper" | Safe}}</label>
|
<label>{{.i18n.Tr "repo.visiblity_helper" | Safe}}</label>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="inline field {{if .Err_Description}}error{{end}}">
|
<div class="inline field {{if .Err_Description}}error{{end}}">
|
||||||
|
|
|
@ -65,8 +65,13 @@
|
||||||
<div class="inline field">
|
<div class="inline field">
|
||||||
<label>{{.i18n.Tr "repo.visibility"}}</label>
|
<label>{{.i18n.Tr "repo.visibility"}}</label>
|
||||||
<div class="ui checkbox">
|
<div class="ui checkbox">
|
||||||
|
{{if .IsForcedPrivate}}
|
||||||
|
<input name="private" type="checkbox" checked readonly>
|
||||||
|
<label>{{.i18n.Tr "repo.visiblity_helper_forced" | Safe}}</label>
|
||||||
|
{{else}}
|
||||||
<input name="private" type="checkbox" {{if .private}}checked{{end}}>
|
<input name="private" type="checkbox" {{if .private}}checked{{end}}>
|
||||||
<label>{{.i18n.Tr "repo.visiblity_helper" | Safe}}</label>
|
<label>{{.i18n.Tr "repo.visiblity_helper" | Safe}}</label>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="inline field">
|
<div class="inline field">
|
||||||
|
|
Loading…
Reference in a new issue