Unknwon преди 9 години
родител
ревизия
bb3b90fcd6

+ 9 - 0
config.codekit

@@ -424,6 +424,15 @@
 		"strictMath": 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": {
 		"fileType": 16,
 		"ignore": 1,

+ 110 - 82
models/repo.go

@@ -5,6 +5,7 @@
 package models
 
 import (
+	"bytes"
 	"errors"
 	"fmt"
 	"html/template"
@@ -403,7 +404,12 @@ func MirrorRepository(repoId int64, userName, repoName, repoPath, url string) er
 
 // MigrateRepository migrates a existing repository from other project hosting.
 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 {
 		return nil, err
 	}
@@ -488,8 +494,89 @@ func createUpdateHook(repoPath string) error {
 		[]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.
-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.
 	if com.IsExist(repoPath) {
 		return fmt.Errorf("initRepository: path already exists: %s", repoPath)
@@ -498,83 +585,32 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, initRe
 	// Init bare new repository.
 	os.MkdirAll(repoPath, os.ModePerm)
 	_, 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 {
-		return fmt.Errorf("git init --bare: %s", err)
+		return fmt.Errorf("git init --bare: %v - %s", err, stderr)
 	}
 
 	if err := createUpdateHook(repoPath); err != nil {
 		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()))
-	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 {
-		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
@@ -582,21 +618,13 @@ func initRepository(e Engine, repoPath string, u *User, repo *Repository, initRe
 	if repo, err = getRepositoryByID(e, repo.ID); err != nil {
 		return fmt.Errorf("getRepositoryByID: %v", err)
 	}
-	if len(fileName) == 0 {
-		repo.IsBare = true
-	}
+
 	repo.DefaultBranch = "master"
 	if err = updateRepository(e, repo, false); err != nil {
 		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) {
@@ -642,14 +670,14 @@ func createRepository(e *xorm.Session, u *User, repo *Repository) (err error) {
 }
 
 // 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{
 		OwnerID:     u.Id,
 		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()
@@ -663,9 +691,9 @@ func CreateRepository(u *User, name, desc, lang, license string, isPrivate, isMi
 	}
 
 	// No need for init mirror.
-	if !isMirror {
+	if !opts.IsMirror {
 		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 {
 				log.Error(4, "initRepository: %v", err)
 				return nil, fmt.Errorf(

+ 6 - 0
modules/auth/auth.go

@@ -194,6 +194,12 @@ func GetMaxSize(field reflect.StructField) string {
 	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 {
 	if errs.Len() == 0 {
 		return errs

+ 10 - 11
modules/auth/repo_form.go

@@ -16,19 +16,15 @@ import (
 //  |____|_  /_______  / |____|   \_______  /_______  /|___| |____|   \_______  /____|_  // ______|
 //         \/        \/                   \/        \/                        \/       \/ \/
 
-type RepoForm struct {
+type CreateRepoForm struct {
 	Uid         int64  `binding:"Required"`
 	RepoName    string `binding:"Required;AlphaDashDot;MaxSize(100)"`
 	Private     bool
 	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 {
@@ -39,8 +35,11 @@ type MigrateRepoForm struct {
 	CloneAddr    string `binding:"Required"`
 	AuthUsername 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 {

Файловите разлики са ограничени, защото са твърде много
+ 3 - 0
public/ng/css/font-awesome.min.css


+ 1 - 1
public/ng/css/gogs.css

@@ -284,7 +284,7 @@ img.avatar-100 {
   font-size: 16px;
   line-height: 1.6;
   word-wrap: break-word;
-  padding: 0 2em 2em !important;
+  padding: 5px 2em 2em !important;
 }
 .markdown > *:first-child {
   margin-top: 0 !important;

BIN
public/ng/fonts/FontAwesome.otf


BIN
public/ng/fonts/fontawesome-webfont.eot


Файловите разлики са ограничени, защото са твърде много
+ 49 - 162
public/ng/fonts/fontawesome-webfont.svg


BIN
public/ng/fonts/fontawesome-webfont.ttf


BIN
public/ng/fonts/fontawesome-webfont.woff


BIN
public/ng/fonts/fontawesome-webfont.woff2


+ 1 - 1
public/ng/less/gogs/markdown.less

@@ -4,7 +4,7 @@
   font-size:16px;
   line-height:1.6;
   word-wrap:break-word;
-  padding: 0 2em 2em !important;
+  padding: 5px 2em 2em !important;
 
   >*:first-child {
     margin-top:0 !important;

+ 9 - 2
routers/api/v1/repo.go

@@ -101,8 +101,15 @@ func SearchRepos(ctx *middleware.Context) {
 }
 
 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 models.IsErrRepoAlreadyExist(err) ||
 			models.IsErrNameReserved(err) ||

+ 37 - 69
routers/repo/repo.go

@@ -28,6 +28,12 @@ const (
 )
 
 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.
 	if uid == ctx.User.Id || uid == 0 {
 		return ctx.User
@@ -41,7 +47,10 @@ func checkContextUser(ctx *middleware.Context, uid int64) *models.User {
 	if err != nil {
 		ctx.Handle(500, "checkContextUser", fmt.Errorf("GetUserById(%d): %v", uid, err))
 		return nil
-	} else if !org.IsOrganization() {
+	}
+
+	// Check ownership of organization.
+	if !org.IsOrganization() || !org.IsOwnedBy(ctx.User.Id) {
 		ctx.Error(403)
 		return nil
 	}
@@ -63,15 +72,25 @@ func Create(ctx *middleware.Context) {
 	}
 	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)
 }
 
+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) {
 	ctx.Data["Title"] = ctx.Tr("new_repo")
 
@@ -85,27 +104,20 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) {
 	}
 	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() {
 		ctx.HTML(200, CREATE)
 		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 {
 		log.Trace("Repository created: %s/%s", ctxUser.Name, repo.Name)
 		ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + repo.Name)
@@ -118,19 +130,7 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) {
 		}
 	}
 
-	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) {
@@ -142,12 +142,6 @@ func Migrate(ctx *middleware.Context) {
 	}
 	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)
 }
 
@@ -160,25 +154,11 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
 	}
 	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() {
 		ctx.HTML(200, MIGRATE)
 		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.
 	// Note: remember to change api/v1/repo.go: MigrateRepo
 	// FIXME: merge these two functions with better error handling
@@ -222,19 +202,7 @@ func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) {
 		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) {

+ 1 - 1
templates/ng/base/head.tmpl

@@ -13,7 +13,7 @@
 		<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>
 

+ 2 - 2
templates/repo/create.tmpl

@@ -57,7 +57,7 @@
           <div class="inline field">
             <label>{{.i18n.Tr "repo.repo_lang"}}</label>
             <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="menu">
                 {{range .Gitignores}}
@@ -82,7 +82,7 @@
           <div class="inline field">
             <label>{{.i18n.Tr "repo.readme"}}</label>
             <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="menu">  
                 {{range .Readmes}}

Някои файлове не бяха показани, защото твърде много файлове са промени