9f8c09a5598280167742268ca9d07a788ff9b7c6

Author
Ayman Bagabas <ayman.bagabas@gmail.com>
Committer
Ayman Bagabas <ayman.bagabas@gmail.com>
Date

Message

feat(config): per repo config

Diff

This diff is truncated to protect this page.

  1diff --git a/config/config.go b/config/config.go
  2index 40b77d1339cf425df810c4314135c7cde80e5621..1928bdbf513429008e38468b929dc28e7327d8d0 100644
  3--- a/config/config.go
  4+++ b/config/config.go
  5@@ -27,6 +27,11 @@ import (
  6 	"github.com/go-git/go-git/v5/storage/memory"
  7 )
  8 
  9+var (
 10+	// ErrNoConfig is returned when a repo has no config file.
 11+	ErrNoConfig = errors.New("no config file found")
 12+)
 13+
 14 // Config is the Soft Serve configuration.
 15 type Config struct {
 16 	Name         string         `yaml:"name" json:"name"`
 17@@ -124,31 +129,40 @@ func NewConfig(cfg *config.Config) (*Config, error) {
 18 	return c, nil
 19 }
 20 
 21+// readConfig reads the config file for the repo. All config files are stored in
 22+// the config repo.
 23 func (cfg *Config) readConfig(repo string, v interface{}) error {
 24-	cr, err := cfg.Source.GetRepo(repo)
 25+	cr, err := cfg.Source.GetRepo("config")
 26 	if err != nil {
 27 		return err
 28 	}
 29-	cy, _, err := cr.LatestFile(repo + ".yaml")
 30-	if err != nil && !errors.Is(err, git.ErrFileNotFound) {
 31-		return fmt.Errorf("error reading %s.yaml: %w", repo, err)
 32+	// Parse YAML files
 33+	var cy string
 34+	for _, ext := range []string{".yaml", ".yml"} {
 35+		cy, _, err = cr.LatestFile(repo + ext)
 36+		if err != nil && !errors.Is(err, git.ErrFileNotFound) {
 37+			return err
 38+		} else if err == nil {
 39+			break
 40+		}
 41 	}
 42+	// Parse JSON files
 43 	cj, _, err := cr.LatestFile(repo + ".json")
 44 	if err != nil && !errors.Is(err, git.ErrFileNotFound) {
 45-		return fmt.Errorf("error reading %s.json: %w", repo, err)
 46+		return err
 47 	}
 48 	if cy != "" {
 49 		err = yaml.Unmarshal([]byte(cy), v)
 50 		if err != nil {
 51-			return fmt.Errorf("bad yaml in %s.yaml: %s", repo, err)
 52+			return err
 53 		}
 54 	} else if cj != "" {
 55 		err = json.Unmarshal([]byte(cj), v)
 56 		if err != nil {
 57-			return fmt.Errorf("bad json in %s.json: %s", repo, err)
 58+			return err
 59 		}
 60 	} else {
 61-		return fmt.Errorf("no config file found for %q", repo)
 62+		return ErrNoConfig
 63 	}
 64 	return nil
 65 }
 66@@ -164,16 +178,41 @@ func (cfg *Config) Reload() error {
 67 	if err := cfg.readConfig("config", cfg); err != nil {
 68 		return fmt.Errorf("error reading config: %w", err)
 69 	}
 70+	// sanitize repo configs
 71+	repos := make(map[string]RepoConfig, 0)
 72+	for _, r := range cfg.Repos {
 73+		repos[r.Repo] = r
 74+	}
 75+	for _, r := range cfg.Source.AllRepos() {
 76+		var rc RepoConfig
 77+		repo := r.Repo()
 78+		if repo == "config" {
 79+			continue
 80+		}
 81+		if err := cfg.readConfig(repo, &rc); err != nil {
 82+			if !errors.Is(err, ErrNoConfig) {
 83+				log.Printf("error reading config: %v", err)
 84+			}
 85+			continue
 86+		}
 87+		repos[r.Repo()] = rc
 88+	}
 89+	cfg.Repos = make([]RepoConfig, 0, len(repos))
 90+	for n, r := range repos {
 91+		r.Repo = n
 92+		cfg.Repos = append(cfg.Repos, r)
 93+	}
 94+	// Populate readmes and descriptions
 95 	for _, r := range cfg.Source.AllRepos() {
 96-		name := r.Name()
 97+		repo := r.Repo()
 98 		err = r.UpdateServerInfo()
 99 		if err != nil {
100-			log.Printf("error updating server info for %s: %s", name, err)
101+			log.Printf("error updating server info for %s: %s", repo, err)
102 		}
103 		pat := "README*"
104 		rp := ""