arnaucube
arnaucube/gitviewPublic Self-hosted repository
gitview/internal/config/config.go
internal/config/config.goRaw
 1package config
 2
 3import (
 4	"fmt"
 5	"path/filepath"
 6	"strings"
 7
 8	"github.com/spf13/viper"
 9)
10
11type Config struct {
12	Repo struct {
13		ScanPath   string   `mapstructure:"scanPath"`
14		Pinned     []string `mapstructure:"pinned,omitempty"`
15		Readme     []string `mapstructure:"readme"`
16		MainBranch []string `mapstructure:"mainBranch"`
17		Ignore     []string `mapstructure:"ignore,omitempty"`
18		Unlisted   []string `mapstructure:"unlisted,omitempty"`
19	} `mapstructure:"repo"`
20	Dirs struct {
21		Templates string `mapstructure:"templates"`
22		Static    string `mapstructure:"static"`
23	} `mapstructure:"dirs"`
24	Meta struct {
25		Title           string `mapstructure:"title"`
26		Username        string `mapstructure:"username"`
27		Description     string `mapstructure:"description"`
28		SyntaxHighlight string `mapstructure:"syntaxHighlight"`
29		Logo            string `mapstructure:"logo"`
30		Favicon         string `mapstructure:"favicon"`
31
32		FaviconHref string
33		FaviconType string
34	} `mapstructure:"meta"`
35	Server struct {
36		Name string `mapstructure:"name,omitempty"`
37		Host string `mapstructure:"host"`
38		Port int    `mapstructure:"port"`
39	} `mapstructure:"server"`
40}
41
42func Read(f string) (*Config, error) {
43	v := viper.New()
44	v.SetConfigFile(f)
45	v.SetEnvPrefix("GITVIEW")
46	v.AutomaticEnv()
47
48	if err := v.ReadInConfig(); err != nil {
49		return nil, fmt.Errorf("reading config: %w", err)
50	}
51
52	c := &Config{}
53	if err := v.Unmarshal(c); err != nil {
54		return nil, fmt.Errorf("parsing config: %w", err)
55	}
56
57	var err error
58	if c.Repo.ScanPath, err = filepath.Abs(c.Repo.ScanPath); err != nil {
59		return nil, err
60	}
61	if c.Dirs.Templates, err = filepath.Abs(c.Dirs.Templates); err != nil {
62		return nil, err
63	}
64	if c.Dirs.Static, err = filepath.Abs(c.Dirs.Static); err != nil {
65		return nil, err
66	}
67
68	// Use one static asset for both the brand mark and favicon; retain legacy config.
69	if c.Meta.Logo != "" {
70		c.Meta.Favicon = c.Meta.Logo
71	}
72	if c.Meta.Favicon == "" {
73		c.Meta.Favicon = "favicon.svg"
74	}
75	c.Meta.FaviconHref = "/static/" + c.Meta.Favicon
76	switch strings.ToLower(filepath.Ext(c.Meta.Favicon)) {
77	case ".svg":
78		c.Meta.FaviconType = "image/svg+xml"
79	case ".png":
80		c.Meta.FaviconType = "image/png"
81	case ".jpg", ".jpeg":
82		c.Meta.FaviconType = "image/jpeg"
83	case ".gif":
84		c.Meta.FaviconType = "image/gif"
85	case ".webp":
86		c.Meta.FaviconType = "image/webp"
87	case ".avif":
88		c.Meta.FaviconType = "image/avif"
89	default:
90		c.Meta.FaviconType = "image/x-icon"
91	}
92
93	return c, nil
94}