Skip to content

Commit

Permalink
Move init repository related functions to modules (#19159)
Browse files Browse the repository at this point in the history
* Move init repository related functions to modules

* Fix lint

* Use ctx but db.DefaultContext

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
  • Loading branch information
lunny and wxiaoguang authored Mar 29, 2022
1 parent b06b9a0 commit 76aa33d
Show file tree
Hide file tree
Showing 15 changed files with 259 additions and 269 deletions.
16 changes: 0 additions & 16 deletions models/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
112 changes: 3 additions & 109 deletions models/issue_label.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
Expand All @@ -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
Expand All @@ -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
}
}
Expand Down
10 changes: 5 additions & 5 deletions models/issue_label_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
114 changes: 2 additions & 112 deletions models/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"fmt"
"os"
"path"
"sort"
"strconv"
"strings"
"unicode/utf8"
Expand All @@ -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"
Expand All @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion models/repo_generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand Down
4 changes: 2 additions & 2 deletions modules/repository/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 76aa33d

Please sign in to comment.