Commit b6f8e2b
Changed files (3)
docs/config.example.toml
@@ -66,6 +66,15 @@ site_name = "Gitmal"
+# Multi-repo sort order. Options:
+# "config" — as written in the config file (default)
+# "name-asc" — alphabetically by name A–Z
+# "name-desc" — alphabetically by name Z–A
+# "time-asc" — by last commit time, oldest first
+# "time-desc" — by last commit time, newest first
+# Has no effect in single-repo mode.
+# sort = "name-asc"
+
# -------- Global settings (optional, overrideable by CLI flags) --------
# These options can also be passed on the command line (higher priority).
# When omitted, the CLI flag default (or program default) is used.
@@ -108,3 +117,4 @@ site_name = "Gitmal"
# --git Generate Git dumb HTTP protocol files
# --inline-styles Embed CSS in HTML instead of external files
# --output Output directory (default "output")
+# --sort=str Multi-repo sort order: config, name[-asc|-desc], time[-asc|-desc]
config.go
@@ -29,6 +29,7 @@ type Config struct {
SiteName string `toml:"site_name"`
Repo *SingleRepoConfig `toml:"repo"`
Repos []RepoEntry `toml:"repos"`
+ Sort string `toml:"sort"`
Theme string `toml:"theme"`
ThemeLight string `toml:"theme_light"`
ThemeDark string `toml:"theme_dark"`
main.go
@@ -7,7 +7,9 @@ import (
"path/filepath"
"regexp"
"runtime/pprof"
+ "sort"
"strings"
+ "time"
"github.com/antonmedv/gitmal/pkg/git"
@@ -28,6 +30,7 @@ var (
flagGzip bool
flagGit bool
flagInlineStyles bool
+ flagSort string
)
type Params struct {
@@ -81,6 +84,7 @@ func main() {
flag.BoolVar(&flagGzip, "gzip", false, "Compress all generated HTML files")
flag.BoolVar(&flagGit, "git", false, "Generate static files for Git dumb HTTP protocol")
flag.BoolVar(&flagInlineStyles, "inline-styles", false, "Keep all CSS inline in HTML instead of external files")
+ flag.StringVar(&flagSort, "sort", "", "Multi-repo sort order: config, name[-asc|-desc], time[-asc|-desc]")
flag.Usage = usage
flag.Parse()
@@ -133,6 +137,13 @@ func main() {
DefaultBranch: repo.DefaultBranch,
})
}
+ sortMode := flagSort
+ if !flag.CommandLine.Changed("sort") && cfg.Sort != "" {
+ sortMode = cfg.Sort
+ }
+ if sortMode != "" && sortMode != "config" {
+ sortGeneratables(generatables, sortMode)
+ }
} else if cfg.Repo != nil {
repoPath := cfg.Repo.Path
if len(flag.Args()) > 0 {
@@ -452,6 +463,38 @@ func validateRepoPath(path string) error {
return nil
}
+func sortGeneratables(gs []repoGeneration, mode string) {
+ switch mode {
+ case "time-asc", "time", "time-desc":
+ case "name-asc", "name", "name-desc":
+ default:
+ fmt.Fprintf(os.Stderr, "warning: unknown sort mode %q, ignoring\n", mode)
+ return
+ }
+
+ if strings.HasPrefix(mode, "time") {
+ times := make(map[string]time.Time, len(gs))
+ for _, g := range gs {
+ times[g.RepoDir] = lastCommitTime(g.RepoDir, g.DefaultBranch)
+ }
+ asc := mode == "time-asc" || mode == "time"
+ sort.Slice(gs, func(i, j int) bool {
+ if asc {
+ return times[gs[i].RepoDir].Before(times[gs[j].RepoDir])
+ }
+ return times[gs[i].RepoDir].After(times[gs[j].RepoDir])
+ })
+ return
+ }
+ asc := mode == "name-asc" || mode == "name"
+ sort.Slice(gs, func(i, j int) bool {
+ if asc {
+ return strings.ToLower(gs[i].Name) < strings.ToLower(gs[j].Name)
+ }
+ return strings.ToLower(gs[i].Name) > strings.ToLower(gs[j].Name)
+ })
+}
+
func cfgReposToEntries(gs []repoGeneration) []RepoEntry {
entries := make([]RepoEntry, len(gs))
for i, g := range gs {