cerrado @ ada6a68b4f25c912705542a6b03aae7ffffb5e99

feat: Make syntax highlight configurable

Now cerrado has configurable theme through "syntax-highlight".
  1diff --git a/config.example.scfg b/config.example.scfg
  2index f29e3ca5b3bcbece29c00645bacbcab4ec608416..0c27591435696f433122fed28814153e6e6edceb 100644
  3--- a/config.example.scfg
  4+++ b/config.example.scfg
  5@@ -5,6 +5,7 @@
  6 root-readme /srv/git/README.md
  7 passphrase $2a$14$VnB/ZcB1DUDkMnosRA6Y7.dj8h5eroslDxTeXlLwfQX/x86mh6WAq
  8 aes-key 8XHptZxSWCGs1m7QzztX5zNQ7D9NiQevVX0DaUTNMbDpRwFzoJiB0U7K6O/kqIt01jJVgzBUfiR8ES46ZLLb4w==
  9+syntax-highlight monokailight
 10 
 11 scan /srv/git/ {
 12     public true
 13diff --git a/main.go b/main.go
 14index 8bf5141a4094b15d635a968f715a10123e618bc6..918b7948a56dd1f13f744cf0965af8ffdae76e44 100644
 15--- a/main.go
 16+++ b/main.go
 17@@ -11,6 +11,7 @@ 	"os"
 18 	"os/signal"
 19 	"time"
 20 
 21+	"github.com/alecthomas/chroma/v2/styles"
 22 	"golang.org/x/crypto/bcrypt"
 23 
 24 	"git.gabrielgio.me/cerrado/pkg/config"
 25@@ -71,9 +72,7 @@ 	return nil
 26 }
 27 
 28 func run(ctx context.Context) error {
 29-	var (
 30-		configPath = flag.String("config", "/etc/cerrado.scfg", "File path for the configuration file")
 31-	)
 32+	configPath := flag.String("config", "/etc/cerrado.scfg", "File path for the configuration file")
 33 
 34 	flag.Parse()
 35 
 36@@ -81,6 +80,17 @@ 	// repositorie
 37 	configRepo, err := config.LoadConfigurationRepository(*configPath)
 38 	if err != nil {
 39 		return err
 40+	}
 41+
 42+	// checking chroma configurationo
 43+
 44+	if _, ok := styles.Registry[configRepo.GetSyntaxHighlight()]; !ok {
 45+		slog.Warn(
 46+			"Invalid Syntax highlight selected",
 47+			"invalid-style", configRepo.GetSyntaxHighlight(),
 48+			"using", "monokailight",
 49+		)
 50+		styles.Fallback = styles.Registry["monokailight"]
 51 	}
 52 
 53 	// services
 54diff --git a/pkg/config/config.go b/pkg/config/config.go
 55index 902ff0d991aeae4e7719555479ec574edd10ad57..812a06ef7ead3d270cd1b2d7d5d31a3033aabc5e 100644
 56--- a/pkg/config/config.go
 57+++ b/pkg/config/config.go
 58@@ -30,12 +30,13 @@
 59 	// configuration represents file configuration.
 60 	// fields needs to be exported to cmp to work
 61 	configuration struct {
 62-		Scan         *scan
 63-		RootReadme   string
 64-		ListenAddr   string
 65-		Passphrase   string
 66-		AESKey       string
 67-		Repositories []*GitRepositoryConfiguration
 68+		Scan            *scan
 69+		RootReadme      string
 70+		ListenAddr      string
 71+		Passphrase      string
 72+		SyntaxHighlight string
 73+		AESKey          string
 74+		Repositories    []*GitRepositoryConfiguration
 75 	}
 76 
 77 	// This is a per repository configuration.
 78@@ -52,11 +53,12 @@ 	// database repositories).
 79 	// This holds all the function necessary to ask for configuration
 80 	// information.
 81 	ConfigurationRepository struct {
 82-		rootReadme   string
 83-		listenAddr   string
 84-		passphrase   string
 85-		aesKey       string
 86-		repositories []*GitRepositoryConfiguration
 87+		rootReadme      string
 88+		listenAddr      string
 89+		passphrase      string
 90+		aesKey          string
 91+		syntaxHighlight string
 92+		repositories    []*GitRepositoryConfiguration
 93 	}
 94 )
 95 
 96@@ -72,11 +74,12 @@ 		return nil, err
 97 	}
 98 
 99 	repo := &ConfigurationRepository{
100-		rootReadme:   config.RootReadme,
101-		listenAddr:   config.ListenAddr,
102-		repositories: config.Repositories,
103-		passphrase:   config.Passphrase,
104-		aesKey:       config.AESKey,
105+		aesKey:          config.AESKey,
106+		listenAddr:      config.ListenAddr,
107+		passphrase:      config.Passphrase,
108+		repositories:    config.Repositories,
109+		rootReadme:      config.RootReadme,
110+		syntaxHighlight: config.SyntaxHighlight,
111 	}
112 
113 	if config.Scan.Path != "" {
114@@ -87,7 +90,6 @@ 		}
115 	}
116 
117 	return repo, nil
118-
119 }
120 
121 // GetRootReadme returns root read path
122@@ -95,6 +97,10 @@ func (c *ConfigurationRepository) GetRootReadme() string {
123 	return c.rootReadme
124 }
125 
126+func (c *ConfigurationRepository) GetSyntaxHighlight() string {
127+	return c.syntaxHighlight
128+}
129+
130 func (c *ConfigurationRepository) GetListenAddr() string {
131 	return c.listenAddr
132 }
133@@ -182,6 +188,11 @@ 		return nil, err
134 	}
135 
136 	err = setAESKey(block, &config.AESKey)
137+	if err != nil {
138+		return nil, err
139+	}
140+
141+	err = setSyntaxHighlight(block, &config.SyntaxHighlight)
142 	if err != nil {
143 		return nil, err
144 	}
145@@ -286,6 +297,11 @@ }
146 
147 func setAESKey(block scfg.Block, listenAddr *string) error {
148 	scanDir := block.Get("aes-key")
149+	return setString(scanDir, listenAddr)
150+}
151+
152+func setSyntaxHighlight(block scfg.Block, listenAddr *string) error {
153+	scanDir := block.Get("syntax-highlight")
154 	return setString(scanDir, listenAddr)
155 }
156 
157diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go
158index 0970cfa43f9e5b1bf6617d654e3abc6ae0e3257c..9080351a01193f3637fe3a501fb5c6b4b967a379 100644
159--- a/pkg/config/config_test.go
160+++ b/pkg/config/config_test.go
161@@ -105,6 +105,7 @@ 			config: `
162 listen-addr unix://var/run/cerrado/cerrado.sock
163 passphrase $2a$14$VnB/ZcB1DUDkMnosRA6Y7.dj8h5eroslDxTeXlLwfQX/x86mh6WAq
164 aes-key 8XHptZxSWCGs1m7QzztX5zNQ7D9NiQevVX0DaUTNMbDpRwFzoJiB0U7K6O/kqIt01jJVgzBUfiR8ES46ZLLb4w==
165+syntax-highlight monokailight
166 
167 scan "/srv/git" {
168 	public true
169@@ -123,9 +124,10 @@ 				Scan: &scan{
170 					Public: true,
171 					Path:   "/srv/git",
172 				},
173-				ListenAddr: "unix://var/run/cerrado/cerrado.sock",
174-				Passphrase: "$2a$14$VnB/ZcB1DUDkMnosRA6Y7.dj8h5eroslDxTeXlLwfQX/x86mh6WAq",
175-				AESKey:     "8XHptZxSWCGs1m7QzztX5zNQ7D9NiQevVX0DaUTNMbDpRwFzoJiB0U7K6O/kqIt01jJVgzBUfiR8ES46ZLLb4w==",
176+				ListenAddr:      "unix://var/run/cerrado/cerrado.sock",
177+				Passphrase:      "$2a$14$VnB/ZcB1DUDkMnosRA6Y7.dj8h5eroslDxTeXlLwfQX/x86mh6WAq",
178+				AESKey:          "8XHptZxSWCGs1m7QzztX5zNQ7D9NiQevVX0DaUTNMbDpRwFzoJiB0U7K6O/kqIt01jJVgzBUfiR8ES46ZLLb4w==",
179+				SyntaxHighlight: "monokailight",
180 				Repositories: []*GitRepositoryConfiguration{
181 					{
182 						Name:        "linux.git",
183@@ -158,6 +160,5 @@ 			if diff := cmp.Diff(tc.expectedConfig, config); diff != "" {
184 				t.Errorf("Wrong result given - wanted + got\n %s", diff)
185 			}
186 		})
187-
188 	}
189 }
190diff --git a/pkg/handler/git/handler.go b/pkg/handler/git/handler.go
191index 6fae1460391f93b827d8c6a6131976ebbde75a6b..5739c8e9dbca0c7b015224ed3af26f53118eb72c 100644
192--- a/pkg/handler/git/handler.go
193+++ b/pkg/handler/git/handler.go
194@@ -27,18 +27,19 @@
195 type (
196 	GitHandler struct {
197 		gitService *service.GitService
198-		readmePath string
199+		config     configurationRepository
200 	}
201 
202 	configurationRepository interface {
203 		GetRootReadme() string
204+		GetSyntaxHighlight() string
205 	}
206 )
207 
208 func NewGitHandler(gitService *service.GitService, confRepo configurationRepository) *GitHandler {
209 	return &GitHandler{
210 		gitService: gitService,
211-		readmePath: confRepo.GetRootReadme(),
212+		config:     confRepo,
213 	}
214 }
215 
216@@ -48,7 +49,7 @@ 	if err != nil {
217 		return err
218 	}
219 
220-	f, err := os.Open(g.readmePath)
221+	f, err := os.Open(g.config.GetRootReadme())
222 	if err != nil {
223 		return err
224 	}
225@@ -280,7 +281,8 @@ 	}
226 
227 	filename := filepath.Base(rest)
228 	lexer := GetLexers(filename)
229-	style := styles.Get("xcode")
230+	style := styles.Get(g.config.GetSyntaxHighlight())
231+
232 	formatter := html.New(
233 		html.WithLineNumbers(true),
234 		html.WithLinkableLineNumbers(true, "L"),