forked from gitea/gitea
		
	Move init repository related functions to modules (#19159)
* Move init repository related functions to modules * Fix lint * Use ctx but db.DefaultContext Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
		
							parent
							
								
									b06b9a056c
								
							
						
					
					
						commit
						76aa33d884
					
				| @ -703,22 +703,6 @@ func (err ErrIssueIsClosed) Error() string { | ||||
| 	return fmt.Sprintf("issue is closed [id: %d, repo_id: %d, index: %d]", err.ID, err.RepoID, err.Index) | ||||
| } | ||||
| 
 | ||||
| // ErrIssueLabelTemplateLoad represents a "ErrIssueLabelTemplateLoad" kind of error. | ||||
| type ErrIssueLabelTemplateLoad struct { | ||||
| 	TemplateFile  string | ||||
| 	OriginalError error | ||||
| } | ||||
| 
 | ||||
| // IsErrIssueLabelTemplateLoad checks if an error is a ErrIssueLabelTemplateLoad. | ||||
| func IsErrIssueLabelTemplateLoad(err error) bool { | ||||
| 	_, ok := err.(ErrIssueLabelTemplateLoad) | ||||
| 	return ok | ||||
| } | ||||
| 
 | ||||
| func (err ErrIssueLabelTemplateLoad) Error() string { | ||||
| 	return fmt.Sprintf("Failed to load label template file '%s': %v", err.TemplateFile, err.OriginalError) | ||||
| } | ||||
| 
 | ||||
| // ErrNewIssueInsert is used when the INSERT statement in newIssue fails | ||||
| type ErrNewIssueInsert struct { | ||||
| 	OriginalError error | ||||
|  | ||||
| @ -50,50 +50,6 @@ func init() { | ||||
| 	db.RegisterModel(new(IssueLabel)) | ||||
| } | ||||
| 
 | ||||
| // GetLabelTemplateFile loads the label template file by given name, | ||||
| // then parses and returns a list of name-color pairs and optionally description. | ||||
| func GetLabelTemplateFile(name string) ([][3]string, error) { | ||||
| 	data, err := GetRepoInitFile("label", name) | ||||
| 	if err != nil { | ||||
| 		return nil, ErrIssueLabelTemplateLoad{name, fmt.Errorf("GetRepoInitFile: %v", err)} | ||||
| 	} | ||||
| 
 | ||||
| 	lines := strings.Split(string(data), "\n") | ||||
| 	list := make([][3]string, 0, len(lines)) | ||||
| 	for i := 0; i < len(lines); i++ { | ||||
| 		line := strings.TrimSpace(lines[i]) | ||||
| 		if len(line) == 0 { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		parts := strings.SplitN(line, ";", 2) | ||||
| 
 | ||||
| 		fields := strings.SplitN(parts[0], " ", 2) | ||||
| 		if len(fields) != 2 { | ||||
| 			return nil, ErrIssueLabelTemplateLoad{name, fmt.Errorf("line is malformed: %s", line)} | ||||
| 		} | ||||
| 
 | ||||
| 		color := strings.Trim(fields[0], " ") | ||||
| 		if len(color) == 6 { | ||||
| 			color = "#" + color | ||||
| 		} | ||||
| 		if !LabelColorPattern.MatchString(color) { | ||||
| 			return nil, ErrIssueLabelTemplateLoad{name, fmt.Errorf("bad HTML color code in line: %s", line)} | ||||
| 		} | ||||
| 
 | ||||
| 		var description string | ||||
| 
 | ||||
| 		if len(parts) > 1 { | ||||
| 			description = strings.TrimSpace(parts[1]) | ||||
| 		} | ||||
| 
 | ||||
| 		fields[1] = strings.TrimSpace(fields[1]) | ||||
| 		list = append(list, [3]string{fields[1], color, description}) | ||||
| 	} | ||||
| 
 | ||||
| 	return list, nil | ||||
| } | ||||
| 
 | ||||
| // CalOpenIssues sets the number of open issues of a label based on the already stored number of closed issues. | ||||
| func (label *Label) CalOpenIssues() { | ||||
| 	label.NumOpenIssues = label.NumIssues - label.NumClosedIssues | ||||
| @ -191,70 +147,8 @@ func (label *Label) ForegroundColor() template.CSS { | ||||
| 	return template.CSS("#000") | ||||
| } | ||||
| 
 | ||||
| // .____          ___.          .__ | ||||
| // |    |   _____ \_ |__   ____ |  | | ||||
| // |    |   \__  \ | __ \_/ __ \|  | | ||||
| // |    |___ / __ \| \_\ \  ___/|  |__ | ||||
| // >_______ (____  /___  /\___  >____/ | ||||
| 
 | ||||
| func loadLabels(labelTemplate string) ([]string, error) { | ||||
| 	list, err := GetLabelTemplateFile(labelTemplate) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	labels := make([]string, len(list)) | ||||
| 	for i := 0; i < len(list); i++ { | ||||
| 		labels[i] = list[i][0] | ||||
| 	} | ||||
| 	return labels, nil | ||||
| } | ||||
| 
 | ||||
| // LoadLabelsFormatted loads the labels' list of a template file as a string separated by comma | ||||
| func LoadLabelsFormatted(labelTemplate string) (string, error) { | ||||
| 	labels, err := loadLabels(labelTemplate) | ||||
| 	return strings.Join(labels, ", "), err | ||||
| } | ||||
| 
 | ||||
| func initializeLabels(e db.Engine, id int64, labelTemplate string, isOrg bool) error { | ||||
| 	list, err := GetLabelTemplateFile(labelTemplate) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	labels := make([]*Label, len(list)) | ||||
| 	for i := 0; i < len(list); i++ { | ||||
| 		labels[i] = &Label{ | ||||
| 			Name:        list[i][0], | ||||
| 			Description: list[i][2], | ||||
| 			Color:       list[i][1], | ||||
| 		} | ||||
| 		if isOrg { | ||||
| 			labels[i].OrgID = id | ||||
| 		} else { | ||||
| 			labels[i].RepoID = id | ||||
| 		} | ||||
| 	} | ||||
| 	for _, label := range labels { | ||||
| 		if err = newLabel(e, label); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // InitializeLabels adds a label set to a repository using a template | ||||
| func InitializeLabels(ctx context.Context, repoID int64, labelTemplate string, isOrg bool) error { | ||||
| 	return initializeLabels(db.GetEngine(ctx), repoID, labelTemplate, isOrg) | ||||
| } | ||||
| 
 | ||||
| func newLabel(e db.Engine, label *Label) error { | ||||
| 	_, err := e.Insert(label) | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| // NewLabel creates a new label | ||||
| func NewLabel(label *Label) error { | ||||
| func NewLabel(ctx context.Context, label *Label) error { | ||||
| 	if !LabelColorPattern.MatchString(label.Color) { | ||||
| 		return fmt.Errorf("bad color code: %s", label.Color) | ||||
| 	} | ||||
| @ -275,7 +169,7 @@ func NewLabel(label *Label) error { | ||||
| 		label.Color = fmt.Sprintf("#%c%c%c%c%c%c", r, r, g, g, b, b) | ||||
| 	} | ||||
| 
 | ||||
| 	return newLabel(db.GetEngine(db.DefaultContext), label) | ||||
| 	return db.Insert(ctx, label) | ||||
| } | ||||
| 
 | ||||
| // NewLabels creates new labels | ||||
| @ -290,7 +184,7 @@ func NewLabels(labels ...*Label) error { | ||||
| 		if !LabelColorPattern.MatchString(label.Color) { | ||||
| 			return fmt.Errorf("bad color code: %s", label.Color) | ||||
| 		} | ||||
| 		if err := newLabel(db.GetEngine(ctx), label); err != nil { | ||||
| 		if err := db.Insert(ctx, label); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -42,11 +42,11 @@ func TestNewLabels(t *testing.T) { | ||||
| 		{RepoID: 4, Name: "labelName4", Color: "ABCDEF"}, | ||||
| 		{RepoID: 5, Name: "labelName5", Color: "DEF"}, | ||||
| 	} | ||||
| 	assert.Error(t, NewLabel(&Label{RepoID: 3, Name: "invalid Color", Color: ""})) | ||||
| 	assert.Error(t, NewLabel(&Label{RepoID: 3, Name: "invalid Color", Color: "#45G"})) | ||||
| 	assert.Error(t, NewLabel(&Label{RepoID: 3, Name: "invalid Color", Color: "#12345G"})) | ||||
| 	assert.Error(t, NewLabel(&Label{RepoID: 3, Name: "invalid Color", Color: "45G"})) | ||||
| 	assert.Error(t, NewLabel(&Label{RepoID: 3, Name: "invalid Color", Color: "12345G"})) | ||||
| 	assert.Error(t, NewLabel(db.DefaultContext, &Label{RepoID: 3, Name: "invalid Color", Color: ""})) | ||||
| 	assert.Error(t, NewLabel(db.DefaultContext, &Label{RepoID: 3, Name: "invalid Color", Color: "#45G"})) | ||||
| 	assert.Error(t, NewLabel(db.DefaultContext, &Label{RepoID: 3, Name: "invalid Color", Color: "#12345G"})) | ||||
| 	assert.Error(t, NewLabel(db.DefaultContext, &Label{RepoID: 3, Name: "invalid Color", Color: "45G"})) | ||||
| 	assert.Error(t, NewLabel(db.DefaultContext, &Label{RepoID: 3, Name: "invalid Color", Color: "12345G"})) | ||||
| 	for _, label := range labels { | ||||
| 		unittest.AssertNotExistsBean(t, label) | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										114
									
								
								models/repo.go
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								models/repo.go
									
									
									
									
									
								
							| @ -10,7 +10,6 @@ import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"path" | ||||
| 	"sort" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"unicode/utf8" | ||||
| @ -28,7 +27,6 @@ import ( | ||||
| 	"code.gitea.io/gitea/models/webhook" | ||||
| 	"code.gitea.io/gitea/modules/lfs" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/options" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/storage" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| @ -37,90 +35,11 @@ import ( | ||||
| 	"xorm.io/builder" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	// Gitignores contains the gitiginore files | ||||
| 	Gitignores []string | ||||
| 
 | ||||
| 	// Licenses contains the license files | ||||
| 	Licenses []string | ||||
| 
 | ||||
| 	// Readmes contains the readme files | ||||
| 	Readmes []string | ||||
| 
 | ||||
| 	// LabelTemplates contains the label template files and the list of labels for each file | ||||
| 	LabelTemplates map[string]string | ||||
| 
 | ||||
| 	// ItemsPerPage maximum items per page in forks, watchers and stars of a repo | ||||
| 	ItemsPerPage = 40 | ||||
| ) | ||||
| 
 | ||||
| // loadRepoConfig loads the repository config | ||||
| func loadRepoConfig() { | ||||
| 	// Load .gitignore and license files and readme templates. | ||||
| 	types := []string{"gitignore", "license", "readme", "label"} | ||||
| 	typeFiles := make([][]string, 4) | ||||
| 	for i, t := range types { | ||||
| 		files, err := options.Dir(t) | ||||
| 		if err != nil { | ||||
| 			log.Fatal("Failed to get %s files: %v", t, err) | ||||
| 		} | ||||
| 		customPath := path.Join(setting.CustomPath, "options", t) | ||||
| 		isDir, err := util.IsDir(customPath) | ||||
| 		if err != nil { | ||||
| 			log.Fatal("Failed to get custom %s files: %v", t, err) | ||||
| 		} | ||||
| 		if isDir { | ||||
| 			customFiles, err := util.StatDir(customPath) | ||||
| 			if err != nil { | ||||
| 				log.Fatal("Failed to get custom %s files: %v", t, err) | ||||
| 			} | ||||
| 
 | ||||
| 			for _, f := range customFiles { | ||||
| 				if !util.IsStringInSlice(f, files, true) { | ||||
| 					files = append(files, f) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		typeFiles[i] = files | ||||
| 	} | ||||
| 
 | ||||
| 	Gitignores = typeFiles[0] | ||||
| 	Licenses = typeFiles[1] | ||||
| 	Readmes = typeFiles[2] | ||||
| 	LabelTemplatesFiles := typeFiles[3] | ||||
| 	sort.Strings(Gitignores) | ||||
| 	sort.Strings(Licenses) | ||||
| 	sort.Strings(Readmes) | ||||
| 	sort.Strings(LabelTemplatesFiles) | ||||
| 
 | ||||
| 	// Load label templates | ||||
| 	LabelTemplates = make(map[string]string) | ||||
| 	for _, templateFile := range LabelTemplatesFiles { | ||||
| 		labels, err := LoadLabelsFormatted(templateFile) | ||||
| 		if err != nil { | ||||
| 			log.Error("Failed to load labels: %v", err) | ||||
| 		} | ||||
| 		LabelTemplates[templateFile] = labels | ||||
| 	} | ||||
| 
 | ||||
| 	// Filter out invalid names and promote preferred licenses. | ||||
| 	sortedLicenses := make([]string, 0, len(Licenses)) | ||||
| 	for _, name := range setting.Repository.PreferredLicenses { | ||||
| 		if util.IsStringInSlice(name, Licenses, true) { | ||||
| 			sortedLicenses = append(sortedLicenses, name) | ||||
| 		} | ||||
| 	} | ||||
| 	for _, name := range Licenses { | ||||
| 		if !util.IsStringInSlice(name, setting.Repository.PreferredLicenses, true) { | ||||
| 			sortedLicenses = append(sortedLicenses, name) | ||||
| 		} | ||||
| 	} | ||||
| 	Licenses = sortedLicenses | ||||
| } | ||||
| // ItemsPerPage maximum items per page in forks, watchers and stars of a repo | ||||
| var ItemsPerPage = 40 | ||||
| 
 | ||||
| // NewRepoContext creates a new repository context | ||||
| func NewRepoContext() { | ||||
| 	loadRepoConfig() | ||||
| 	unit.LoadUnitConfig() | ||||
| 
 | ||||
| 	admin_model.RemoveAllWithNotice(db.DefaultContext, "Clean up temporary repository uploads", setting.Repository.Upload.TempPath) | ||||
| @ -441,35 +360,6 @@ type CreateRepoOptions struct { | ||||
| 	MirrorInterval string | ||||
| } | ||||
| 
 | ||||
| // GetRepoInitFile returns repository init files | ||||
| func GetRepoInitFile(tp, name string) ([]byte, error) { | ||||
| 	cleanedName := strings.TrimLeft(path.Clean("/"+name), "/") | ||||
| 	relPath := path.Join("options", tp, cleanedName) | ||||
| 
 | ||||
| 	// Use custom file when available. | ||||
| 	customPath := path.Join(setting.CustomPath, relPath) | ||||
| 	isFile, err := util.IsFile(customPath) | ||||
| 	if err != nil { | ||||
| 		log.Error("Unable to check if %s is a file. Error: %v", customPath, err) | ||||
| 	} | ||||
| 	if isFile { | ||||
| 		return os.ReadFile(customPath) | ||||
| 	} | ||||
| 
 | ||||
| 	switch tp { | ||||
| 	case "readme": | ||||
| 		return options.Readme(cleanedName) | ||||
| 	case "gitignore": | ||||
| 		return options.Gitignore(cleanedName) | ||||
| 	case "license": | ||||
| 		return options.License(cleanedName) | ||||
| 	case "label": | ||||
| 		return options.Labels(cleanedName) | ||||
| 	default: | ||||
| 		return []byte{}, fmt.Errorf("Invalid init file type") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // CreateRepository creates a repository for the user/organization. | ||||
| func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository, overwriteOrAdopt bool) (err error) { | ||||
| 	if err = repo_model.IsUsableRepoName(repo.Name); err != nil { | ||||
|  | ||||
| @ -110,7 +110,7 @@ func GenerateIssueLabels(ctx context.Context, templateRepo, generateRepo *repo_m | ||||
| 			Description: templateLabel.Description, | ||||
| 			Color:       templateLabel.Color, | ||||
| 		} | ||||
| 		if err := newLabel(db.GetEngine(ctx), generateLabel); err != nil { | ||||
| 		if err := db.Insert(ctx, generateLabel); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -33,7 +33,7 @@ func CreateRepository(doer, u *user_model.User, opts models.CreateRepoOptions) ( | ||||
| 
 | ||||
| 	// Check if label template exist | ||||
| 	if len(opts.IssueLabels) > 0 { | ||||
| 		if _, err := models.GetLabelTemplateFile(opts.IssueLabels); err != nil { | ||||
| 		if _, err := GetLabelTemplateFile(opts.IssueLabels); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
| @ -100,7 +100,7 @@ func CreateRepository(doer, u *user_model.User, opts models.CreateRepoOptions) ( | ||||
| 
 | ||||
| 		// Initialize Issue Labels if selected | ||||
| 		if len(opts.IssueLabels) > 0 { | ||||
| 			if err = models.InitializeLabels(ctx, repo.ID, opts.IssueLabels, false); err != nil { | ||||
| 			if err = InitializeLabels(ctx, repo.ID, opts.IssueLabels, false); err != nil { | ||||
| 				rollbackRepo = repo | ||||
| 				rollbackRepo.OwnerID = u.ID | ||||
| 				return fmt.Errorf("InitializeLabels: %v", err) | ||||
|  | ||||
| @ -9,7 +9,9 @@ import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"path" | ||||
| 	"path/filepath" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| 
 | ||||
| @ -18,6 +20,7 @@ import ( | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
| 	"code.gitea.io/gitea/modules/git" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/options" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	asymkey_service "code.gitea.io/gitea/services/asymkey" | ||||
| @ -25,6 +28,192 @@ import ( | ||||
| 	"github.com/unknwon/com" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	// Gitignores contains the gitiginore files | ||||
| 	Gitignores []string | ||||
| 
 | ||||
| 	// Licenses contains the license files | ||||
| 	Licenses []string | ||||
| 
 | ||||
| 	// Readmes contains the readme files | ||||
| 	Readmes []string | ||||
| 
 | ||||
| 	// LabelTemplates contains the label template files and the list of labels for each file | ||||
| 	LabelTemplates map[string]string | ||||
| ) | ||||
| 
 | ||||
| // ErrIssueLabelTemplateLoad represents a "ErrIssueLabelTemplateLoad" kind of error. | ||||
| type ErrIssueLabelTemplateLoad struct { | ||||
| 	TemplateFile  string | ||||
| 	OriginalError error | ||||
| } | ||||
| 
 | ||||
| // IsErrIssueLabelTemplateLoad checks if an error is a ErrIssueLabelTemplateLoad. | ||||
| func IsErrIssueLabelTemplateLoad(err error) bool { | ||||
| 	_, ok := err.(ErrIssueLabelTemplateLoad) | ||||
| 	return ok | ||||
| } | ||||
| 
 | ||||
| func (err ErrIssueLabelTemplateLoad) Error() string { | ||||
| 	return fmt.Sprintf("Failed to load label template file '%s': %v", err.TemplateFile, err.OriginalError) | ||||
| } | ||||
| 
 | ||||
| // GetRepoInitFile returns repository init files | ||||
| func GetRepoInitFile(tp, name string) ([]byte, error) { | ||||
| 	cleanedName := strings.TrimLeft(path.Clean("/"+name), "/") | ||||
| 	relPath := path.Join("options", tp, cleanedName) | ||||
| 
 | ||||
| 	// Use custom file when available. | ||||
| 	customPath := path.Join(setting.CustomPath, relPath) | ||||
| 	isFile, err := util.IsFile(customPath) | ||||
| 	if err != nil { | ||||
| 		log.Error("Unable to check if %s is a file. Error: %v", customPath, err) | ||||
| 	} | ||||
| 	if isFile { | ||||
| 		return os.ReadFile(customPath) | ||||
| 	} | ||||
| 
 | ||||
| 	switch tp { | ||||
| 	case "readme": | ||||
| 		return options.Readme(cleanedName) | ||||
| 	case "gitignore": | ||||
| 		return options.Gitignore(cleanedName) | ||||
| 	case "license": | ||||
| 		return options.License(cleanedName) | ||||
| 	case "label": | ||||
| 		return options.Labels(cleanedName) | ||||
| 	default: | ||||
| 		return []byte{}, fmt.Errorf("Invalid init file type") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // GetLabelTemplateFile loads the label template file by given name, | ||||
| // then parses and returns a list of name-color pairs and optionally description. | ||||
| func GetLabelTemplateFile(name string) ([][3]string, error) { | ||||
| 	data, err := GetRepoInitFile("label", name) | ||||
| 	if err != nil { | ||||
| 		return nil, ErrIssueLabelTemplateLoad{name, fmt.Errorf("GetRepoInitFile: %v", err)} | ||||
| 	} | ||||
| 
 | ||||
| 	lines := strings.Split(string(data), "\n") | ||||
| 	list := make([][3]string, 0, len(lines)) | ||||
| 	for i := 0; i < len(lines); i++ { | ||||
| 		line := strings.TrimSpace(lines[i]) | ||||
| 		if len(line) == 0 { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		parts := strings.SplitN(line, ";", 2) | ||||
| 
 | ||||
| 		fields := strings.SplitN(parts[0], " ", 2) | ||||
| 		if len(fields) != 2 { | ||||
| 			return nil, ErrIssueLabelTemplateLoad{name, fmt.Errorf("line is malformed: %s", line)} | ||||
| 		} | ||||
| 
 | ||||
| 		color := strings.Trim(fields[0], " ") | ||||
| 		if len(color) == 6 { | ||||
| 			color = "#" + color | ||||
| 		} | ||||
| 		if !models.LabelColorPattern.MatchString(color) { | ||||
| 			return nil, ErrIssueLabelTemplateLoad{name, fmt.Errorf("bad HTML color code in line: %s", line)} | ||||
| 		} | ||||
| 
 | ||||
| 		var description string | ||||
| 
 | ||||
| 		if len(parts) > 1 { | ||||
| 			description = strings.TrimSpace(parts[1]) | ||||
| 		} | ||||
| 
 | ||||
| 		fields[1] = strings.TrimSpace(fields[1]) | ||||
| 		list = append(list, [3]string{fields[1], color, description}) | ||||
| 	} | ||||
| 
 | ||||
| 	return list, nil | ||||
| } | ||||
| 
 | ||||
| func loadLabels(labelTemplate string) ([]string, error) { | ||||
| 	list, err := GetLabelTemplateFile(labelTemplate) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	labels := make([]string, len(list)) | ||||
| 	for i := 0; i < len(list); i++ { | ||||
| 		labels[i] = list[i][0] | ||||
| 	} | ||||
| 	return labels, nil | ||||
| } | ||||
| 
 | ||||
| // LoadLabelsFormatted loads the labels' list of a template file as a string separated by comma | ||||
| func LoadLabelsFormatted(labelTemplate string) (string, error) { | ||||
| 	labels, err := loadLabels(labelTemplate) | ||||
| 	return strings.Join(labels, ", "), err | ||||
| } | ||||
| 
 | ||||
| // LoadRepoConfig loads the repository config | ||||
| func LoadRepoConfig() { | ||||
| 	// Load .gitignore and license files and readme templates. | ||||
| 	types := []string{"gitignore", "license", "readme", "label"} | ||||
| 	typeFiles := make([][]string, 4) | ||||
| 	for i, t := range types { | ||||
| 		files, err := options.Dir(t) | ||||
| 		if err != nil { | ||||
| 			log.Fatal("Failed to get %s files: %v", t, err) | ||||
| 		} | ||||
| 		customPath := path.Join(setting.CustomPath, "options", t) | ||||
| 		isDir, err := util.IsDir(customPath) | ||||
| 		if err != nil { | ||||
| 			log.Fatal("Failed to get custom %s files: %v", t, err) | ||||
| 		} | ||||
| 		if isDir { | ||||
| 			customFiles, err := util.StatDir(customPath) | ||||
| 			if err != nil { | ||||
| 				log.Fatal("Failed to get custom %s files: %v", t, err) | ||||
| 			} | ||||
| 
 | ||||
| 			for _, f := range customFiles { | ||||
| 				if !util.IsStringInSlice(f, files, true) { | ||||
| 					files = append(files, f) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		typeFiles[i] = files | ||||
| 	} | ||||
| 
 | ||||
| 	Gitignores = typeFiles[0] | ||||
| 	Licenses = typeFiles[1] | ||||
| 	Readmes = typeFiles[2] | ||||
| 	LabelTemplatesFiles := typeFiles[3] | ||||
| 	sort.Strings(Gitignores) | ||||
| 	sort.Strings(Licenses) | ||||
| 	sort.Strings(Readmes) | ||||
| 	sort.Strings(LabelTemplatesFiles) | ||||
| 
 | ||||
| 	// Load label templates | ||||
| 	LabelTemplates = make(map[string]string) | ||||
| 	for _, templateFile := range LabelTemplatesFiles { | ||||
| 		labels, err := LoadLabelsFormatted(templateFile) | ||||
| 		if err != nil { | ||||
| 			log.Error("Failed to load labels: %v", err) | ||||
| 		} | ||||
| 		LabelTemplates[templateFile] = labels | ||||
| 	} | ||||
| 
 | ||||
| 	// Filter out invalid names and promote preferred licenses. | ||||
| 	sortedLicenses := make([]string, 0, len(Licenses)) | ||||
| 	for _, name := range setting.Repository.PreferredLicenses { | ||||
| 		if util.IsStringInSlice(name, Licenses, true) { | ||||
| 			sortedLicenses = append(sortedLicenses, name) | ||||
| 		} | ||||
| 	} | ||||
| 	for _, name := range Licenses { | ||||
| 		if !util.IsStringInSlice(name, setting.Repository.PreferredLicenses, true) { | ||||
| 			sortedLicenses = append(sortedLicenses, name) | ||||
| 		} | ||||
| 	} | ||||
| 	Licenses = sortedLicenses | ||||
| } | ||||
| 
 | ||||
| func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, repoPath string, opts models.CreateRepoOptions) error { | ||||
| 	commitTimeStr := time.Now().Format(time.RFC3339) | ||||
| 	authorSig := repo.Owner.NewGitSig() | ||||
| @ -48,7 +237,7 @@ func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, | ||||
| 	} | ||||
| 
 | ||||
| 	// README | ||||
| 	data, err := models.GetRepoInitFile("readme", opts.Readme) | ||||
| 	data, err := GetRepoInitFile("readme", opts.Readme) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("GetRepoInitFile[%s]: %v", opts.Readme, err) | ||||
| 	} | ||||
| @ -71,7 +260,7 @@ func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, | ||||
| 		var buf bytes.Buffer | ||||
| 		names := strings.Split(opts.Gitignores, ",") | ||||
| 		for _, name := range names { | ||||
| 			data, err = models.GetRepoInitFile("gitignore", name) | ||||
| 			data, err = GetRepoInitFile("gitignore", name) | ||||
| 			if err != nil { | ||||
| 				return fmt.Errorf("GetRepoInitFile[%s]: %v", name, err) | ||||
| 			} | ||||
| @ -89,7 +278,7 @@ func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, | ||||
| 
 | ||||
| 	// LICENSE | ||||
| 	if len(opts.License) > 0 { | ||||
| 		data, err = models.GetRepoInitFile("license", opts.License) | ||||
| 		data, err = GetRepoInitFile("license", opts.License) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("GetRepoInitFile[%s]: %v", opts.License, err) | ||||
| 		} | ||||
| @ -257,3 +446,31 @@ func initRepository(ctx context.Context, repoPath string, u *user_model.User, re | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // InitializeLabels adds a label set to a repository using a template | ||||
| func InitializeLabels(ctx context.Context, id int64, labelTemplate string, isOrg bool) error { | ||||
| 	list, err := GetLabelTemplateFile(labelTemplate) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	labels := make([]*models.Label, len(list)) | ||||
| 	for i := 0; i < len(list); i++ { | ||||
| 		labels[i] = &models.Label{ | ||||
| 			Name:        list[i][0], | ||||
| 			Description: list[i][2], | ||||
| 			Color:       list[i][1], | ||||
| 		} | ||||
| 		if isOrg { | ||||
| 			labels[i].OrgID = id | ||||
| 		} else { | ||||
| 			labels[i].RepoID = id | ||||
| 		} | ||||
| 	} | ||||
| 	for _, label := range labels { | ||||
| 		if err = models.NewLabel(ctx, label); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -99,7 +99,7 @@ func CreateLabel(ctx *context.APIContext) { | ||||
| 		OrgID:       ctx.Org.Organization.ID, | ||||
| 		Description: form.Description, | ||||
| 	} | ||||
| 	if err := models.NewLabel(label); err != nil { | ||||
| 	if err := models.NewLabel(ctx, label); err != nil { | ||||
| 		ctx.Error(http.StatusInternalServerError, "NewLabel", err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| @ -161,7 +161,7 @@ func CreateLabel(ctx *context.APIContext) { | ||||
| 		RepoID:      ctx.Repo.Repository.ID, | ||||
| 		Description: form.Description, | ||||
| 	} | ||||
| 	if err := models.NewLabel(label); err != nil { | ||||
| 	if err := models.NewLabel(ctx, label); err != nil { | ||||
| 		ctx.Error(http.StatusInternalServerError, "NewLabel", err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| @ -10,6 +10,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/models" | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	"code.gitea.io/gitea/modules/context" | ||||
| 	repo_module "code.gitea.io/gitea/modules/repository" | ||||
| 	"code.gitea.io/gitea/modules/web" | ||||
| 	"code.gitea.io/gitea/services/forms" | ||||
| ) | ||||
| @ -48,7 +49,7 @@ func NewLabel(ctx *context.Context) { | ||||
| 		Description: form.Description, | ||||
| 		Color:       form.Color, | ||||
| 	} | ||||
| 	if err := models.NewLabel(l); err != nil { | ||||
| 	if err := models.NewLabel(ctx, l); err != nil { | ||||
| 		ctx.ServerError("NewLabel", err) | ||||
| 		return | ||||
| 	} | ||||
| @ -100,9 +101,9 @@ func InitializeLabels(ctx *context.Context) { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if err := models.InitializeLabels(ctx, ctx.Org.Organization.ID, form.TemplateName, true); err != nil { | ||||
| 		if models.IsErrIssueLabelTemplateLoad(err) { | ||||
| 			originalErr := err.(models.ErrIssueLabelTemplateLoad).OriginalError | ||||
| 	if err := repo_module.InitializeLabels(ctx, ctx.Org.Organization.ID, form.TemplateName, true); err != nil { | ||||
| 		if repo_module.IsErrIssueLabelTemplateLoad(err) { | ||||
| 			originalErr := err.(repo_module.ErrIssueLabelTemplateLoad).OriginalError | ||||
| 			ctx.Flash.Error(ctx.Tr("repo.issues.label_templates.fail_to_load_file", form.TemplateName, originalErr)) | ||||
| 			ctx.Redirect(ctx.Org.OrgLink + "/settings/labels") | ||||
| 			return | ||||
|  | ||||
| @ -18,6 +18,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/base" | ||||
| 	"code.gitea.io/gitea/modules/context" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	repo_module "code.gitea.io/gitea/modules/repository" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/web" | ||||
| 	user_setting "code.gitea.io/gitea/routers/web/user/setting" | ||||
| @ -232,6 +233,6 @@ func Labels(ctx *context.Context) { | ||||
| 	ctx.Data["PageIsOrgSettings"] = true | ||||
| 	ctx.Data["PageIsOrgSettingsLabels"] = true | ||||
| 	ctx.Data["RequireTribute"] = true | ||||
| 	ctx.Data["LabelTemplates"] = models.LabelTemplates | ||||
| 	ctx.Data["LabelTemplates"] = repo_module.LabelTemplates | ||||
| 	ctx.HTML(http.StatusOK, tplSettingsLabels) | ||||
| } | ||||
|  | ||||
| @ -13,6 +13,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/base" | ||||
| 	"code.gitea.io/gitea/modules/context" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	repo_module "code.gitea.io/gitea/modules/repository" | ||||
| 	"code.gitea.io/gitea/modules/web" | ||||
| 	"code.gitea.io/gitea/services/forms" | ||||
| 	issue_service "code.gitea.io/gitea/services/issue" | ||||
| @ -28,7 +29,7 @@ func Labels(ctx *context.Context) { | ||||
| 	ctx.Data["PageIsIssueList"] = true | ||||
| 	ctx.Data["PageIsLabels"] = true | ||||
| 	ctx.Data["RequireTribute"] = true | ||||
| 	ctx.Data["LabelTemplates"] = models.LabelTemplates | ||||
| 	ctx.Data["LabelTemplates"] = repo_module.LabelTemplates | ||||
| 	ctx.HTML(http.StatusOK, tplLabels) | ||||
| } | ||||
| 
 | ||||
| @ -40,9 +41,9 @@ func InitializeLabels(ctx *context.Context) { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if err := models.InitializeLabels(ctx, ctx.Repo.Repository.ID, form.TemplateName, false); err != nil { | ||||
| 		if models.IsErrIssueLabelTemplateLoad(err) { | ||||
| 			originalErr := err.(models.ErrIssueLabelTemplateLoad).OriginalError | ||||
| 	if err := repo_module.InitializeLabels(ctx, ctx.Repo.Repository.ID, form.TemplateName, false); err != nil { | ||||
| 		if repo_module.IsErrIssueLabelTemplateLoad(err) { | ||||
| 			originalErr := err.(repo_module.ErrIssueLabelTemplateLoad).OriginalError | ||||
| 			ctx.Flash.Error(ctx.Tr("repo.issues.label_templates.fail_to_load_file", form.TemplateName, originalErr)) | ||||
| 			ctx.Redirect(ctx.Repo.RepoLink + "/labels") | ||||
| 			return | ||||
| @ -116,7 +117,7 @@ func NewLabel(ctx *context.Context) { | ||||
| 		Description: form.Description, | ||||
| 		Color:       form.Color, | ||||
| 	} | ||||
| 	if err := models.NewLabel(l); err != nil { | ||||
| 	if err := models.NewLabel(ctx, l); err != nil { | ||||
| 		ctx.ServerError("NewLabel", err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| @ -22,6 +22,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/context" | ||||
| 	"code.gitea.io/gitea/modules/graceful" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	repo_module "code.gitea.io/gitea/modules/repository" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/storage" | ||||
| 	"code.gitea.io/gitea/modules/web" | ||||
| @ -129,10 +130,10 @@ func Create(ctx *context.Context) { | ||||
| 	ctx.Data["Title"] = ctx.Tr("new_repo") | ||||
| 
 | ||||
| 	// Give default value for template to render. | ||||
| 	ctx.Data["Gitignores"] = models.Gitignores | ||||
| 	ctx.Data["LabelTemplates"] = models.LabelTemplates | ||||
| 	ctx.Data["Licenses"] = models.Licenses | ||||
| 	ctx.Data["Readmes"] = models.Readmes | ||||
| 	ctx.Data["Gitignores"] = repo_module.Gitignores | ||||
| 	ctx.Data["LabelTemplates"] = repo_module.LabelTemplates | ||||
| 	ctx.Data["Licenses"] = repo_module.Licenses | ||||
| 	ctx.Data["Readmes"] = repo_module.Readmes | ||||
| 	ctx.Data["readme"] = "Default" | ||||
| 	ctx.Data["private"] = getRepoPrivate(ctx) | ||||
| 	ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate | ||||
| @ -197,10 +198,10 @@ func CreatePost(ctx *context.Context) { | ||||
| 	form := web.GetForm(ctx).(*forms.CreateRepoForm) | ||||
| 	ctx.Data["Title"] = ctx.Tr("new_repo") | ||||
| 
 | ||||
| 	ctx.Data["Gitignores"] = models.Gitignores | ||||
| 	ctx.Data["LabelTemplates"] = models.LabelTemplates | ||||
| 	ctx.Data["Licenses"] = models.Licenses | ||||
| 	ctx.Data["Readmes"] = models.Readmes | ||||
| 	ctx.Data["Gitignores"] = repo_module.Gitignores | ||||
| 	ctx.Data["LabelTemplates"] = repo_module.LabelTemplates | ||||
| 	ctx.Data["Licenses"] = repo_module.Licenses | ||||
| 	ctx.Data["Readmes"] = repo_module.Readmes | ||||
| 
 | ||||
| 	ctx.Data["CanCreateRepo"] = ctx.Doer.CanCreateRepo() | ||||
| 	ctx.Data["MaxCreationLimit"] = ctx.Doer.MaxCreationLimit() | ||||
|  | ||||
| @ -79,7 +79,7 @@ func AdoptRepository(doer, u *user_model.User, opts models.CreateRepoOptions) (* | ||||
| 
 | ||||
| 		// Initialize Issue Labels if selected | ||||
| 		if len(opts.IssueLabels) > 0 { | ||||
| 			if err := models.InitializeLabels(ctx, repo.ID, opts.IssueLabels, false); err != nil { | ||||
| 			if err := repo_module.InitializeLabels(ctx, repo.ID, opts.IssueLabels, false); err != nil { | ||||
| 				return fmt.Errorf("InitializeLabels: %v", err) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| @ -74,5 +74,6 @@ func PushCreateRepo(authUser, owner *user_model.User, repoName string) (*repo_mo | ||||
| 
 | ||||
| // NewContext start repository service | ||||
| func NewContext() error { | ||||
| 	repo_module.LoadRepoConfig() | ||||
| 	return initPushQueue() | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 GitHub
							GitHub