mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	#1487 Readme Template
This commit is contained in:
		@@ -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,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										188
									
								
								models/repo.go
									
									
									
									
									
								
							
							
						
						
									
										188
									
								
								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()))
 | 
			
		||||
 | 
			
		||||
	// Initialize repository according to user's choice.
 | 
			
		||||
	if opts.AutoInit {
 | 
			
		||||
		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)
 | 
			
		||||
		if err = prepareRepoCommit(repo, tmpDir, repoPath, opts); err != nil {
 | 
			
		||||
			return fmt.Errorf("prepareRepoCommit: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	// 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
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 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,23 +618,15 @@ 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())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func createRepository(e *xorm.Session, u *User, repo *Repository) (err error) {
 | 
			
		||||
	if err = IsUsableName(repo.Name); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
@@ -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(
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -16,15 +16,11 @@ 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
 | 
			
		||||
@@ -39,8 +35,11 @@ type MigrateRepoForm struct {
 | 
			
		||||
	CloneAddr    string `binding:"Required"`
 | 
			
		||||
	AuthUsername string
 | 
			
		||||
	AuthPassword string
 | 
			
		||||
	RepoForm
 | 
			
		||||
	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 {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								public/ng/css/font-awesome.min.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								public/ng/css/font-awesome.min.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -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;
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								public/ng/fonts/fontawesome-webfont.eot
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/ng/fonts/fontawesome-webfont.eot
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										1064
									
								
								public/ng/fonts/fontawesome-webfont.svg
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										1064
									
								
								public/ng/fonts/fontawesome-webfont.svg
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
		 Before Width: | Height: | Size: 248 KiB After Width: | Height: | Size: 348 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								public/ng/fonts/fontawesome-webfont.ttf
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/ng/fonts/fontawesome-webfont.ttf
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								public/ng/fonts/fontawesome-webfont.woff
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/ng/fonts/fontawesome-webfont.woff
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								public/ng/fonts/fontawesome-webfont.woff2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/ng/fonts/fontawesome-webfont.woff2
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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) ||
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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}}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user