diff options
Diffstat (limited to 'modules/repository/init.go')
-rw-r--r-- | modules/repository/init.go | 117 |
1 files changed, 69 insertions, 48 deletions
diff --git a/modules/repository/init.go b/modules/repository/init.go index f9a33cd4f6..38dd8a0c4f 100644 --- a/modules/repository/init.go +++ b/modules/repository/init.go @@ -8,7 +8,6 @@ import ( "context" "fmt" "os" - "path" "path/filepath" "sort" "strings" @@ -27,6 +26,11 @@ import ( asymkey_service "code.gitea.io/gitea/services/asymkey" ) +type OptionFile struct { + DisplayName string + Description string +} + var ( // Gitignores contains the gitiginore files Gitignores []string @@ -37,65 +41,73 @@ var ( // 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 + // LabelTemplateFiles contains the label template files, each item has its DisplayName and Description + LabelTemplateFiles []OptionFile + labelTemplateFileMap = map[string]string{} // DisplayName => FileName mapping ) +type optionFileList struct { + all []string // all files provided by bindata & custom-path. Sorted. + custom []string // custom files provided by custom-path. Non-sorted, internal use only. +} + +// mergeCustomLabelFiles merges the custom label files. Always use the file's main name (DisplayName) as the key to de-duplicate. +func mergeCustomLabelFiles(fl optionFileList) []string { + exts := map[string]int{"": 0, ".yml": 1, ".yaml": 2} // "yaml" file has the highest priority to be used. + + m := map[string]string{} + merge := func(list []string) { + sort.Slice(list, func(i, j int) bool { return exts[filepath.Ext(list[i])] < exts[filepath.Ext(list[j])] }) + for _, f := range list { + m[strings.TrimSuffix(f, filepath.Ext(f))] = f + } + } + merge(fl.all) + merge(fl.custom) + + files := make([]string, 0, len(m)) + for _, f := range m { + files = append(files, f) + } + sort.Strings(files) + return files +} + // 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) +func LoadRepoConfig() error { + types := []string{"gitignore", "license", "readme", "label"} // option file directories + typeFiles := make([]optionFileList, len(types)) for i, t := range types { - files, err := options.Dir(t) - if err != nil { - log.Fatal("Failed to get %s files: %v", t, err) + var err error + if typeFiles[i].all, err = options.Dir(t); err != nil { + return fmt.Errorf("failed to list %s files: %w", t, err) } - if t == "label" { - for i, f := range files { - ext := strings.ToLower(filepath.Ext(f)) - if ext == ".yaml" || ext == ".yml" { - files[i] = f[:len(f)-len(ext)] - } + sort.Strings(typeFiles[i].all) + customPath := filepath.Join(setting.CustomPath, "options", t) + if isDir, err := util.IsDir(customPath); err != nil { + return fmt.Errorf("failed to check custom %s dir: %w", t, err) + } else if isDir { + if typeFiles[i].custom, err = util.StatDir(customPath); err != nil { + return fmt.Errorf("failed to list custom %s files: %w", 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.SliceContainsString(files, f, 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) + Gitignores = typeFiles[0].all + Licenses = typeFiles[1].all + Readmes = typeFiles[2].all // Load label templates - LabelTemplates = make(map[string]string) - for _, templateFile := range LabelTemplatesFiles { - labels, err := label.LoadFormatted(templateFile) + LabelTemplateFiles = nil + labelTemplateFileMap = map[string]string{} + for _, file := range mergeCustomLabelFiles(typeFiles[3]) { + description, err := label.LoadTemplateDescription(file) if err != nil { - log.Error("Failed to load labels: %v", err) + return fmt.Errorf("failed to load labels: %w", err) } - LabelTemplates[templateFile] = labels + displayName := strings.TrimSuffix(file, filepath.Ext(file)) + labelTemplateFileMap[displayName] = file + LabelTemplateFiles = append(LabelTemplateFiles, OptionFile{DisplayName: displayName, Description: description}) } // Filter out invalid names and promote preferred licenses. @@ -111,6 +123,7 @@ func LoadRepoConfig() { } } Licenses = sortedLicenses + return nil } func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, repoPath string, opts CreateRepoOptions) error { @@ -344,7 +357,7 @@ func initRepository(ctx context.Context, repoPath string, u *user_model.User, re // 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 := label.GetTemplateFile(labelTemplate) + list, err := LoadTemplateLabelsByDisplayName(labelTemplate) if err != nil { return err } @@ -370,3 +383,11 @@ func InitializeLabels(ctx context.Context, id int64, labelTemplate string, isOrg } return nil } + +// LoadTemplateLabelsByDisplayName loads a label template by its display name +func LoadTemplateLabelsByDisplayName(displayName string) ([]*label.Label, error) { + if fileName, ok := labelTemplateFileMap[displayName]; ok { + return label.LoadTemplateFile(fileName) + } + return nil, label.ErrTemplateLoad{TemplateFile: displayName, OriginalError: fmt.Errorf("label template %q not found", displayName)} +} |