"strictMath": 0, | "strictMath": 0, | ||||
"strictUnits": 0 | "strictUnits": 0 | ||||
}, | }, | ||||
"\/public\/ng\/css\/font-awesome.min.css": { | |||||
"fileType": 16, | |||||
"ignore": 0, | |||||
"ignoreWasSetByUser": 0, | |||||
"inputAbbreviatedPath": "\/public\/ng\/css\/font-awesome.min.css", | |||||
"outputAbbreviatedPath": "No Output Path", | |||||
"outputPathIsOutsideProject": 0, | |||||
"outputPathIsSetByUser": 0 | |||||
}, | |||||
"\/public\/ng\/css\/gogs.css": { | "\/public\/ng\/css\/gogs.css": { | ||||
"fileType": 16, | "fileType": 16, | ||||
"ignore": 1, | "ignore": 1, |
package models | package models | ||||
import ( | import ( | ||||
"bytes" | |||||
"errors" | "errors" | ||||
"fmt" | "fmt" | ||||
"html/template" | "html/template" | ||||
// 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, name, desc string, private, mirror bool, url string) (*Repository, error) { | ||||
repo, err := CreateRepository(u, name, desc, "", "", private, mirror, false) | |||||
repo, err := CreateRepository(u, CreateRepoOptions{ | |||||
Name: name, | |||||
Description: desc, | |||||
IsPrivate: private, | |||||
IsMirror: mirror, | |||||
}) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } | ||||
[]byte(fmt.Sprintf(_TPL_UPDATE_HOOK, setting.ScriptType, "\""+appPath+"\"", setting.CustomConf)), 0777) | []byte(fmt.Sprintf(_TPL_UPDATE_HOOK, setting.ScriptType, "\""+appPath+"\"", setting.CustomConf)), 0777) | ||||
} | } | ||||
type CreateRepoOptions struct { | |||||
Name string | |||||
Description string | |||||
Gitignores string | |||||
License string | |||||
Readme string | |||||
IsPrivate bool | |||||
IsMirror bool | |||||
AutoInit bool | |||||
} | |||||
func getRepoInitFile(tp, name string) ([]byte, error) { | |||||
relPath := path.Join("conf", tp, name) | |||||
// Use custom file when available. | |||||
customPath := path.Join(setting.CustomPath, relPath) | |||||
if com.IsFile(customPath) { | |||||
return ioutil.ReadFile(customPath) | |||||
} | |||||
return bindata.Asset(relPath) | |||||
} | |||||
func prepareRepoCommit(repo *Repository, tmpDir, repoPath string, opts CreateRepoOptions) error { | |||||
// Clone to temprory path and do the init commit. | |||||
_, stderr, err := process.Exec( | |||||
fmt.Sprintf("initRepository(git clone): %s", repoPath), "git", "clone", repoPath, tmpDir) | |||||
if err != nil { | |||||
return fmt.Errorf("git clone: %v - %s", err, stderr) | |||||
} | |||||
// README | |||||
data, err := getRepoInitFile("readme", opts.Readme) | |||||
if err != nil { | |||||
return fmt.Errorf("getRepoInitFile[%s]: %v", opts.Readme, err) | |||||
} | |||||
match := map[string]string{ | |||||
"Name": repo.Name, | |||||
"Description": repo.Description, | |||||
} | |||||
if err = ioutil.WriteFile(filepath.Join(tmpDir, "README.md"), | |||||
[]byte(com.Expand(string(data), match)), 0644); err != nil { | |||||
return fmt.Errorf("write README.md: %v", err) | |||||
} | |||||
// .gitignore | |||||
if len(opts.Gitignores) > 0 { | |||||
var buf bytes.Buffer | |||||
names := strings.Split(opts.Gitignores, ",") | |||||
for _, name := range names { | |||||
data, err = getRepoInitFile("gitignore", name) | |||||
if err != nil { | |||||
return fmt.Errorf("getRepoInitFile[%s]: %v", name, err) | |||||
} | |||||
buf.WriteString("# ---> " + name + "\n") | |||||
buf.Write(data) | |||||
buf.WriteString("\n") | |||||
} | |||||
if buf.Len() > 0 { | |||||
if err = ioutil.WriteFile(filepath.Join(tmpDir, ".gitignore"), buf.Bytes(), 0644); err != nil { | |||||
return fmt.Errorf("write .gitignore: %v", err) | |||||
} | |||||
} | |||||
} | |||||
// LICENSE | |||||
if len(opts.License) > 0 { | |||||
data, err = getRepoInitFile("license", opts.License) | |||||
if err != nil { | |||||
return fmt.Errorf("getRepoInitFile[%s]: %v", opts.License, err) | |||||
} | |||||
if err = ioutil.WriteFile(filepath.Join(tmpDir, "LICENSE"), data, 0644); err != nil { | |||||
return fmt.Errorf("write LICENSE: %v", err) | |||||
} | |||||
} | |||||
return nil | |||||
} | |||||
// InitRepository initializes README and .gitignore if needed. | // InitRepository initializes README and .gitignore if needed. | ||||
func initRepository(e Engine, repoPath string, u *User, repo *Repository, initReadme bool, repoLang, license string) error { | |||||
func initRepository(e Engine, repoPath string, u *User, repo *Repository, opts CreateRepoOptions) error { | |||||
// Somehow the directory could exist. | // Somehow the directory could exist. | ||||
if com.IsExist(repoPath) { | if com.IsExist(repoPath) { | ||||
return fmt.Errorf("initRepository: path already exists: %s", repoPath) | return fmt.Errorf("initRepository: path already exists: %s", repoPath) | ||||
// Init bare new repository. | // Init bare new repository. | ||||
os.MkdirAll(repoPath, os.ModePerm) | os.MkdirAll(repoPath, os.ModePerm) | ||||
_, stderr, err := process.ExecDir(-1, repoPath, | _, stderr, err := process.ExecDir(-1, repoPath, | ||||
fmt.Sprintf("initRepository(git init --bare): %s", repoPath), | |||||
"git", "init", "--bare") | |||||
fmt.Sprintf("initRepository(git init --bare): %s", repoPath), "git", "init", "--bare") | |||||
if err != nil { | if err != nil { | ||||
return fmt.Errorf("git init --bare: %s", err) | |||||
return fmt.Errorf("git init --bare: %v - %s", err, stderr) | |||||
} | } | ||||
if err := createUpdateHook(repoPath); err != nil { | if err := createUpdateHook(repoPath); err != nil { | ||||
return err | return err | ||||
} | } | ||||
// Initialize repository according to user's choice. | |||||
fileName := map[string]string{} | |||||
if initReadme { | |||||
fileName["readme"] = "README.md" | |||||
} | |||||
if repoLang != "" { | |||||
fileName["gitign"] = ".gitignore" | |||||
} | |||||
if license != "" { | |||||
fileName["license"] = "LICENSE" | |||||
} | |||||
// Clone to temprory path and do the init commit. | |||||
tmpDir := filepath.Join(os.TempDir(), com.ToStr(time.Now().Nanosecond())) | tmpDir := filepath.Join(os.TempDir(), com.ToStr(time.Now().Nanosecond())) | ||||
os.MkdirAll(tmpDir, os.ModePerm) | |||||
defer os.RemoveAll(tmpDir) | |||||
_, stderr, err = process.Exec( | |||||
fmt.Sprintf("initRepository(git clone): %s", repoPath), | |||||
"git", "clone", repoPath, tmpDir) | |||||
if err != nil { | |||||
return errors.New("git clone: " + stderr) | |||||
} | |||||
// Initialize repository according to user's choice. | |||||
if opts.AutoInit { | |||||
os.MkdirAll(tmpDir, os.ModePerm) | |||||
defer os.RemoveAll(tmpDir) | |||||
// README | |||||
if initReadme { | |||||
defaultReadme := repo.Name + "\n" + strings.Repeat("=", | |||||
utf8.RuneCountInString(repo.Name)) + "\n\n" + repo.Description | |||||
if err := ioutil.WriteFile(filepath.Join(tmpDir, fileName["readme"]), | |||||
[]byte(defaultReadme), 0644); err != nil { | |||||
return err | |||||
if err = prepareRepoCommit(repo, tmpDir, repoPath, opts); err != nil { | |||||
return fmt.Errorf("prepareRepoCommit: %v", err) | |||||
} | } | ||||
} | |||||
// FIXME: following two can be merged. | |||||
// .gitignore | |||||
// Copy custom file when available. | |||||
customPath := path.Join(setting.CustomPath, "conf/gitignore", repoLang) | |||||
targetPath := path.Join(tmpDir, fileName["gitign"]) | |||||
if com.IsFile(customPath) { | |||||
if err := com.Copy(customPath, targetPath); err != nil { | |||||
return fmt.Errorf("copy gitignore: %v", err) | |||||
} | |||||
} else if com.IsSliceContainsStr(Gitignores, repoLang) { | |||||
if err = ioutil.WriteFile(targetPath, | |||||
bindata.MustAsset(path.Join("conf/gitignore", repoLang)), 0644); err != nil { | |||||
return fmt.Errorf("generate gitignore: %v", err) | |||||
// Apply changes and commit. | |||||
if err = initRepoCommit(tmpDir, u.NewGitSig()); err != nil { | |||||
return fmt.Errorf("initRepoCommit: %v", err) | |||||
} | } | ||||
} else { | } else { | ||||
delete(fileName, "gitign") | |||||
} | |||||
// LICENSE | |||||
customPath = path.Join(setting.CustomPath, "conf/license", license) | |||||
targetPath = path.Join(tmpDir, fileName["license"]) | |||||
if com.IsFile(customPath) { | |||||
if err = com.Copy(customPath, targetPath); err != nil { | |||||
return fmt.Errorf("copy license: %v", err) | |||||
} | |||||
} else if com.IsSliceContainsStr(Licenses, license) { | |||||
if err = ioutil.WriteFile(targetPath, | |||||
bindata.MustAsset(path.Join("conf/license", license)), 0644); err != nil { | |||||
return fmt.Errorf("generate license: %v", err) | |||||
} | |||||
} else { | |||||
delete(fileName, "license") | |||||
repo.IsBare = true | |||||
} | } | ||||
// Re-fetch the repository from database before updating it (else it would | // Re-fetch the repository from database before updating it (else it would | ||||
if repo, err = getRepositoryByID(e, repo.ID); err != nil { | if repo, err = getRepositoryByID(e, repo.ID); err != nil { | ||||
return fmt.Errorf("getRepositoryByID: %v", err) | return fmt.Errorf("getRepositoryByID: %v", err) | ||||
} | } | ||||
if len(fileName) == 0 { | |||||
repo.IsBare = true | |||||
} | |||||
repo.DefaultBranch = "master" | repo.DefaultBranch = "master" | ||||
if err = updateRepository(e, repo, false); err != nil { | if err = updateRepository(e, repo, false); err != nil { | ||||
return fmt.Errorf("updateRepository: %v", err) | return fmt.Errorf("updateRepository: %v", err) | ||||
} | } | ||||
// Ignore init process if user choose not to. | |||||
if len(fileName) == 0 { | |||||
return nil | |||||
} | |||||
// Apply changes and commit. | |||||
return initRepoCommit(tmpDir, u.NewGitSig()) | |||||
return nil | |||||
} | } | ||||
func createRepository(e *xorm.Session, u *User, repo *Repository) (err error) { | func createRepository(e *xorm.Session, u *User, repo *Repository) (err error) { | ||||
} | } | ||||
// CreateRepository creates a repository for given user or organization. | // CreateRepository creates a repository for given user or organization. | ||||
func CreateRepository(u *User, name, desc, lang, license string, isPrivate, isMirror, initReadme bool) (_ *Repository, err error) { | |||||
func CreateRepository(u *User, opts CreateRepoOptions) (_ *Repository, err error) { | |||||
repo := &Repository{ | repo := &Repository{ | ||||
OwnerID: u.Id, | OwnerID: u.Id, | ||||
Owner: u, | Owner: u, | ||||
Name: name, | |||||
LowerName: strings.ToLower(name), | |||||
Description: desc, | |||||
IsPrivate: isPrivate, | |||||
Name: opts.Name, | |||||
LowerName: strings.ToLower(opts.Name), | |||||
Description: opts.Description, | |||||
IsPrivate: opts.IsPrivate, | |||||
} | } | ||||
sess := x.NewSession() | sess := x.NewSession() | ||||
} | } | ||||
// No need for init mirror. | // No need for init mirror. | ||||
if !isMirror { | |||||
if !opts.IsMirror { | |||||
repoPath := RepoPath(u.Name, repo.Name) | repoPath := RepoPath(u.Name, repo.Name) | ||||
if err = initRepository(sess, repoPath, u, repo, initReadme, lang, license); err != nil { | |||||
if err = initRepository(sess, repoPath, u, repo, opts); err != nil { | |||||
if err2 := os.RemoveAll(repoPath); err2 != nil { | if err2 := os.RemoveAll(repoPath); err2 != nil { | ||||
log.Error(4, "initRepository: %v", err) | log.Error(4, "initRepository: %v", err) | ||||
return nil, fmt.Errorf( | return nil, fmt.Errorf( |
return getSize(field, "MaxSize(") | return getSize(field, "MaxSize(") | ||||
} | } | ||||
// FIXME: struct contains a struct | |||||
func validateStruct(obj interface{}) binding.Errors { | |||||
return nil | |||||
} | |||||
func validate(errs binding.Errors, data map[string]interface{}, f Form, l macaron.Locale) binding.Errors { | func validate(errs binding.Errors, data map[string]interface{}, f Form, l macaron.Locale) binding.Errors { | ||||
if errs.Len() == 0 { | if errs.Len() == 0 { | ||||
return errs | return errs |
// |____|_ /_______ / |____| \_______ /_______ /|___| |____| \_______ /____|_ // ______| | // |____|_ /_______ / |____| \_______ /_______ /|___| |____| \_______ /____|_ // ______| | ||||
// \/ \/ \/ \/ \/ \/ \/ | // \/ \/ \/ \/ \/ \/ \/ | ||||
type RepoForm struct { | |||||
type CreateRepoForm struct { | |||||
Uid int64 `binding:"Required"` | Uid int64 `binding:"Required"` | ||||
RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"` | RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"` | ||||
Private bool | Private bool | ||||
Description string `binding:"MaxSize(255)"` | Description string `binding:"MaxSize(255)"` | ||||
} | |||||
type CreateRepoForm struct { | |||||
RepoForm | |||||
AutoInit bool | |||||
Gitignores string | |||||
License string | |||||
Readme string | |||||
AutoInit bool | |||||
Gitignores string | |||||
License string | |||||
Readme string | |||||
} | } | ||||
func (f *CreateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | func (f *CreateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||
CloneAddr string `binding:"Required"` | CloneAddr string `binding:"Required"` | ||||
AuthUsername string | AuthUsername string | ||||
AuthPassword string | AuthPassword string | ||||
RepoForm | |||||
Mirror bool | |||||
Mirror bool | |||||
Uid int64 `binding:"Required"` | |||||
RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"` | |||||
Private bool | |||||
Description string `binding:"MaxSize(255)"` | |||||
} | } | ||||
func (f *MigrateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | func (f *MigrateRepoForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { |
font-size: 16px; | font-size: 16px; | ||||
line-height: 1.6; | line-height: 1.6; | ||||
word-wrap: break-word; | word-wrap: break-word; | ||||
padding: 0 2em 2em !important; | |||||
padding: 5px 2em 2em !important; | |||||
} | } | ||||
.markdown > *:first-child { | .markdown > *:first-child { | ||||
margin-top: 0 !important; | margin-top: 0 !important; |
font-size:16px; | font-size:16px; | ||||
line-height:1.6; | line-height:1.6; | ||||
word-wrap:break-word; | word-wrap:break-word; | ||||
padding: 0 2em 2em !important; | |||||
padding: 5px 2em 2em !important; | |||||
>*:first-child { | >*:first-child { | ||||
margin-top:0 !important; | margin-top:0 !important; |
} | } | ||||
func createRepo(ctx *middleware.Context, owner *models.User, opt api.CreateRepoOption) { | func createRepo(ctx *middleware.Context, owner *models.User, opt api.CreateRepoOption) { | ||||
repo, err := models.CreateRepository(owner, opt.Name, opt.Description, | |||||
opt.Gitignore, opt.License, opt.Private, false, opt.AutoInit) | |||||
repo, err := models.CreateRepository(owner, models.CreateRepoOptions{ | |||||
Name: opt.Name, | |||||
Description: opt.Description, | |||||
Gitignores: opt.Gitignore, | |||||
License: opt.License, | |||||
// Readme: form.Readme, | |||||
IsPrivate: opt.Private, | |||||
AutoInit: opt.AutoInit, | |||||
}) | |||||
if err != nil { | if err != nil { | ||||
if models.IsErrRepoAlreadyExist(err) || | if models.IsErrRepoAlreadyExist(err) || | ||||
models.IsErrNameReserved(err) || | models.IsErrNameReserved(err) || |
) | ) | ||||
func checkContextUser(ctx *middleware.Context, uid int64) *models.User { | func checkContextUser(ctx *middleware.Context, uid int64) *models.User { | ||||
if err := ctx.User.GetOrganizations(); err != nil { | |||||
ctx.Handle(500, "GetOrganizations", err) | |||||
return nil | |||||
} | |||||
ctx.Data["Orgs"] = ctx.User.Orgs | |||||
// Not equal means current user is an organization. | // Not equal means current user is an organization. | ||||
if uid == ctx.User.Id || uid == 0 { | if uid == ctx.User.Id || uid == 0 { | ||||
return ctx.User | return ctx.User | ||||
if err != nil { | if err != nil { | ||||
ctx.Handle(500, "checkContextUser", fmt.Errorf("GetUserById(%d): %v", uid, err)) | ctx.Handle(500, "checkContextUser", fmt.Errorf("GetUserById(%d): %v", uid, err)) | ||||
return nil | return nil | ||||
} else if !org.IsOrganization() { | |||||
} | |||||
// Check ownership of organization. | |||||
if !org.IsOrganization() || !org.IsOwnedBy(ctx.User.Id) { | |||||
ctx.Error(403) | ctx.Error(403) | ||||
return nil | return nil | ||||
} | } | ||||
} | } | ||||
ctx.Data["ContextUser"] = ctxUser | ctx.Data["ContextUser"] = ctxUser | ||||
if err := ctx.User.GetOrganizations(); err != nil { | |||||
ctx.Handle(500, "GetOrganizations", err) | |||||
return | |||||
} | |||||
ctx.Data["Orgs"] = ctx.User.Orgs | |||||
ctx.HTML(200, CREATE) | ctx.HTML(200, CREATE) | ||||
} | } | ||||
func handleCreateError(ctx *middleware.Context, err error, name string, tpl base.TplName, form interface{}) { | |||||
switch { | |||||
case models.IsErrRepoAlreadyExist(err): | |||||
ctx.Data["Err_RepoName"] = true | |||||
ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), tpl, form) | |||||
case models.IsErrNameReserved(err): | |||||
ctx.Data["Err_RepoName"] = true | |||||
ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), tpl, form) | |||||
case models.IsErrNamePatternNotAllowed(err): | |||||
ctx.Data["Err_RepoName"] = true | |||||
ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), tpl, form) | |||||
default: | |||||
ctx.Handle(500, name, err) | |||||
} | |||||
} | |||||
func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) { | func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) { | ||||
ctx.Data["Title"] = ctx.Tr("new_repo") | ctx.Data["Title"] = ctx.Tr("new_repo") | ||||
} | } | ||||
ctx.Data["ContextUser"] = ctxUser | ctx.Data["ContextUser"] = ctxUser | ||||
if err := ctx.User.GetOrganizations(); err != nil { | |||||
ctx.Handle(500, "GetOrganizations", err) | |||||
return | |||||
} | |||||
ctx.Data["Orgs"] = ctx.User.Orgs | |||||
if ctx.HasError() { | if ctx.HasError() { | ||||
ctx.HTML(200, CREATE) | ctx.HTML(200, CREATE) | ||||
return | return | ||||
} | } | ||||
if ctxUser.IsOrganization() { | |||||
// Check ownership of organization. | |||||
if !ctxUser.IsOwnedBy(ctx.User.Id) { | |||||
ctx.Error(403) | |||||
return | |||||
} | |||||
} | |||||
repo, err := models.CreateRepository(ctxUser, form.RepoName, form.Description, | |||||
form.Gitignores, form.License, form.Private, false, form.AutoInit) | |||||
repo, err := models.CreateRepository(ctxUser, models.CreateRepoOptions{ | |||||
Name: form.RepoName, | |||||
Description: form.Description, | |||||
Gitignores: form.Gitignores, | |||||
License: form.License, | |||||
Readme: form.Readme, | |||||
IsPrivate: form.Private, | |||||
AutoInit: form.AutoInit, | |||||
}) | |||||
if err == nil { | if err == nil { | ||||
log.Trace("Repository created: %s/%s", ctxUser.Name, repo.Name) | log.Trace("Repository created: %s/%s", ctxUser.Name, repo.Name) | ||||
ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + repo.Name) | ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + repo.Name) | ||||
} | } | ||||
} | } | ||||
switch { | |||||
case models.IsErrRepoAlreadyExist(err): | |||||
ctx.Data["Err_RepoName"] = true | |||||
ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), CREATE, &form) | |||||
case models.IsErrNameReserved(err): | |||||
ctx.Data["Err_RepoName"] = true | |||||
ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), CREATE, &form) | |||||
case models.IsErrNamePatternNotAllowed(err): | |||||
ctx.Data["Err_RepoName"] = true | |||||
ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), CREATE, &form) | |||||
default: | |||||
ctx.Handle(500, "CreatePost", err) | |||||
} | |||||
handleCreateError(ctx, err, "CreatePost", CREATE, &form) | |||||
} | } | ||||
func Migrate(ctx *middleware.Context) { | func Migrate(ctx *middleware.Context) { | ||||
} | } | ||||
ctx.Data["ContextUser"] = ctxUser | ctx.Data["ContextUser"] = ctxUser | ||||
if err := ctx.User.GetOrganizations(); err != nil { | |||||
ctx.Handle(500, "GetOrganizations", err) | |||||
return | |||||
} | |||||
ctx.Data["Orgs"] = ctx.User.Orgs | |||||
ctx.HTML(200, MIGRATE) | ctx.HTML(200, MIGRATE) | ||||
} | } | ||||
} | } | ||||
ctx.Data["ContextUser"] = ctxUser | ctx.Data["ContextUser"] = ctxUser | ||||
if err := ctx.User.GetOrganizations(); err != nil { | |||||
ctx.Handle(500, "GetOrganizations", err) | |||||
return | |||||
} | |||||
ctx.Data["Orgs"] = ctx.User.Orgs | |||||
if ctx.HasError() { | if ctx.HasError() { | ||||
ctx.HTML(200, MIGRATE) | ctx.HTML(200, MIGRATE) | ||||
return | return | ||||
} | } | ||||
if ctxUser.IsOrganization() { | |||||
// Check ownership of organization. | |||||
if !ctxUser.IsOwnedBy(ctx.User.Id) { | |||||
ctx.Error(403) | |||||
return | |||||
} | |||||
} | |||||
// Remote address can be HTTP/HTTPS/Git URL or local path. | // Remote address can be HTTP/HTTPS/Git URL or local path. | ||||
// Note: remember to change api/v1/repo.go: MigrateRepo | // Note: remember to change api/v1/repo.go: MigrateRepo | ||||
// FIXME: merge these two functions with better error handling | // FIXME: merge these two functions with better error handling | ||||
return | return | ||||
} | } | ||||
switch { | |||||
case models.IsErrRepoAlreadyExist(err): | |||||
ctx.Data["Err_RepoName"] = true | |||||
ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), MIGRATE, &form) | |||||
case models.IsErrNameReserved(err): | |||||
ctx.Data["Err_RepoName"] = true | |||||
ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), MIGRATE, &form) | |||||
case models.IsErrNamePatternNotAllowed(err): | |||||
ctx.Data["Err_RepoName"] = true | |||||
ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), MIGRATE, &form) | |||||
default: | |||||
ctx.Handle(500, "MigratePost", err) | |||||
} | |||||
handleCreateError(ctx, err, "MigratePost", MIGRATE, &form) | |||||
} | } | ||||
func Action(ctx *middleware.Context) { | func Action(ctx *middleware.Context) { |
<link rel="shortcut icon" href="{{AppSubUrl}}/img/favicon.png" /> | <link rel="shortcut icon" href="{{AppSubUrl}}/img/favicon.png" /> | ||||
<link rel="stylesheet" href="{{AppSubUrl}}/css/font-awesome.min.css"> | |||||
<link rel="stylesheet" href="{{AppSubUrl}}/ng/css/font-awesome.min.css"> | |||||
<script src="{{AppSubUrl}}/ng/js/lib/jquery-1.11.1.min.js"></script> | <script src="{{AppSubUrl}}/ng/js/lib/jquery-1.11.1.min.js"></script> | ||||
<div class="inline field"> | <div class="inline field"> | ||||
<label>{{.i18n.Tr "repo.repo_lang"}}</label> | <label>{{.i18n.Tr "repo.repo_lang"}}</label> | ||||
<div class="ui multiple search normal selection dropdown"> | <div class="ui multiple search normal selection dropdown"> | ||||
<input type="hidden" name="gitignores" value="{{.gitignoresValue}}"> | |||||
<input type="hidden" name="gitignores" value="{{.gitignores}}"> | |||||
<div class="default text">{{.i18n.Tr "repo.repo_lang_helper"}}</div> | <div class="default text">{{.i18n.Tr "repo.repo_lang_helper"}}</div> | ||||
<div class="menu"> | <div class="menu"> | ||||
{{range .Gitignores}} | {{range .Gitignores}} | ||||
<div class="inline field"> | <div class="inline field"> | ||||
<label>{{.i18n.Tr "repo.readme"}}</label> | <label>{{.i18n.Tr "repo.readme"}}</label> | ||||
<div class="ui selection dropdown"> | <div class="ui selection dropdown"> | ||||
<input type="hidden" name="license" value="{{.readme}}"> | |||||
<input type="hidden" name="readme" value="{{.readme}}"> | |||||
<div class="default text">{{.i18n.Tr "repo.readme_helper"}}</div> | <div class="default text">{{.i18n.Tr "repo.readme_helper"}}</div> | ||||
<div class="menu"> | <div class="menu"> | ||||
{{range .Readmes}} | {{range .Readmes}} |