feat: Added a `Config` struct and `GetConfig` function in config-provider.go
- Introduced a `Config` struct for better configuration handling. - Created a `GetConfig` function to retrieve the configuration. fix: Improved error handling and removed debug prints in htmx-installer.go - Enhanced error handling in the Traefik installer. - Removed unnecessary debug print statements. refactor: Updated package dependencies and templates - Updated package-lock.json and package.json for tailwindcss. - Made template improvements in traefik-compose.goyml and traefik.goyml. misc: - Included the @catppuccin/tailwindcss plugin in the tailwind configuration.
- commit
- a921f708527c2b523a0569d2d7464fcdd84ff54d
- author
- bnema · · 2023-09-06 16:41 UTC
- parent
- a1ff1a2
- signature
- unsigned
12 files · +79 -17
M config/config-provider.go +10 -0
| @@ -7,3 +7,13 @@ type Provider interface { | |||
| 7 | 7 | GetPublicFS() fs.FS | |
| 8 | 8 | GetModelFS() fs.FS | |
| 9 | 9 | } | |
| 10 | + | ||
| 11 | + | type Config struct { | |
| 12 | + | TemplateFS fs.FS | |
| 13 | + | PublicFS fs.FS | |
| 14 | + | ModelFS fs.FS | |
| 15 | + | } | |
| 16 | + | ||
| 17 | + | func GetConfig() *Config { | |
| 18 | + | return &Config{} | |
| 19 | + | } | |
| @@ -7,3 +7,13 @@ type Provider interface { | |||||
| 7 | GetPublicFS() fs.FS | 7 | GetPublicFS() fs.FS | ||
| 8 | GetModelFS() fs.FS | 8 | GetModelFS() fs.FS | ||
| 9 | } | 9 | } | ||
| 10 | + | ||||
| 11 | + | type Config struct { | |||
| 12 | + | TemplateFS fs.FS | |||
| 13 | + | PublicFS fs.FS | |||
| 14 | + | ModelFS fs.FS | |||
| 15 | + | } | |||
| 16 | + | ||||
| 17 | + | func GetConfig() *Config { | |||
| 18 | + | return &Config{} | |||
| 19 | + | } | |||
M internal/app/app.go +12 -0
| @@ -111,3 +111,15 @@ func SetupLogging(config *Config) { | |||
| 111 | 111 | } | |
| 112 | 112 | } | |
| 113 | 113 | } | |
| 114 | + | ||
| 115 | + | func GetBuildDir() string { | |
| 116 | + | env := os.Getenv(EnvVarName) | |
| 117 | + | buildDir := os.Getenv(BuildDirEnvVarName) | |
| 118 | + | if buildDir == "" { | |
| 119 | + | buildDir = DefaultBuildDir | |
| 120 | + | } | |
| 121 | + | if env == ProdEnvValue { | |
| 122 | + | return "." | |
| 123 | + | } | |
| 124 | + | return "./" + buildDir | |
| 125 | + | } | |
| @@ -111,3 +111,15 @@ func SetupLogging(config *Config) { | |||||
| 111 | } | 111 | } | ||
| 112 | } | 112 | } | ||
| 113 | } | 113 | } | ||
| 114 | + | ||||
| 115 | + | func GetBuildDir() string { | |||
| 116 | + | env := os.Getenv(EnvVarName) | |||
| 117 | + | buildDir := os.Getenv(BuildDirEnvVarName) | |||
| 118 | + | if buildDir == "" { | |||
| 119 | + | buildDir = DefaultBuildDir | |||
| 120 | + | } | |||
| 121 | + | if env == ProdEnvValue { | |||
| 122 | + | return "." | |||
| 123 | + | } | |||
| 124 | + | return "./" + buildDir | |||
| 125 | + | } | |||
M internal/http/handlers/htmx-installer.go +1 -5
| @@ -1,8 +1,6 @@ | |||
| 1 | 1 | package handlers | |
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | - | "fmt" | |
| 5 | - | ||
| 6 | 4 | "github.com/labstack/echo/v4" | |
| 7 | 5 | "gogs.bnema.dev/gordon-echo/pkg/scripts" | |
| 8 | 6 | "gogs.bnema.dev/gordon-echo/pkg/utils" | |
| @@ -10,8 +8,8 @@ import ( | |||
| 10 | 8 | ||
| 11 | 9 | // TraefikInstallerHandler handles the installation of Traefik | |
| 12 | 10 | func TraefikInstallerHandler(c echo.Context) error { | |
| 13 | - | // Retrieve the logger from the context | |
| 14 | 11 | logger := c.Get("logger").(*utils.Logger) | |
| 12 | + | // Retrieve the logger from the context | |
| 15 | 13 | // Reject POST requests if they are not allowed with the RejectPOSTPolicy function | |
| 16 | 14 | if err := RejectPOSTPolicy(c); err != nil { | |
| 17 | 15 | logger.Error().Err(err).Msg("POST request rejected") | |
| @@ -30,8 +28,6 @@ func TraefikInstallerHandler(c echo.Context) error { | |||
| 30 | 28 | return err | |
| 31 | 29 | } | |
| 32 | 30 | ||
| 33 | - | fmt.Println("POST request PAYLOAD=", topDomain, adminEmail) | |
| 34 | - | ||
| 35 | 31 | // Call to create the YAML files | |
| 36 | 32 | err = scripts.CreateYAMLFiles(topDomain, adminEmail, logger) | |
| 37 | 33 | if err != nil { | |
| @@ -1,8 +1,6 @@ | |||||
| 1 | package handlers | 1 | package handlers | ||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | - | "fmt" | |||
| 5 | - | ||||
| 6 | "github.com/labstack/echo/v4" | 4 | "github.com/labstack/echo/v4" | ||
| 7 | "gogs.bnema.dev/gordon-echo/pkg/scripts" | 5 | "gogs.bnema.dev/gordon-echo/pkg/scripts" | ||
| 8 | "gogs.bnema.dev/gordon-echo/pkg/utils" | 6 | "gogs.bnema.dev/gordon-echo/pkg/utils" | ||
| @@ -10,8 +8,8 @@ import ( | |||||
| 10 | 8 | ||||
| 11 | // TraefikInstallerHandler handles the installation of Traefik | 9 | // TraefikInstallerHandler handles the installation of Traefik | ||
| 12 | func TraefikInstallerHandler(c echo.Context) error { | 10 | func TraefikInstallerHandler(c echo.Context) error { | ||
| 13 | - | // Retrieve the logger from the context | |||
| 14 | logger := c.Get("logger").(*utils.Logger) | 11 | logger := c.Get("logger").(*utils.Logger) | ||
| 12 | + | // Retrieve the logger from the context | |||
| 15 | // Reject POST requests if they are not allowed with the RejectPOSTPolicy function | 13 | // Reject POST requests if they are not allowed with the RejectPOSTPolicy function | ||
| 16 | if err := RejectPOSTPolicy(c); err != nil { | 14 | if err := RejectPOSTPolicy(c); err != nil { | ||
| 17 | logger.Error().Err(err).Msg("POST request rejected") | 15 | logger.Error().Err(err).Msg("POST request rejected") | ||
| @@ -30,8 +28,6 @@ func TraefikInstallerHandler(c echo.Context) error { | |||||
| 30 | return err | 28 | return err | ||
| 31 | } | 29 | } | ||
| 32 | 30 | ||||
| 33 | - | fmt.Println("POST request PAYLOAD=", topDomain, adminEmail) | |||
| 34 | - | ||||
| 35 | // Call to create the YAML files | 31 | // Call to create the YAML files | ||
| 36 | err = scripts.CreateYAMLFiles(topDomain, adminEmail, logger) | 32 | err = scripts.CreateYAMLFiles(topDomain, adminEmail, logger) | ||
| 37 | if err != nil { | 33 | if err != nil { | ||
M internal/http/routes/router.go +1 -0
| @@ -9,6 +9,7 @@ import ( | |||
| 9 | 9 | ) | |
| 10 | 10 | ||
| 11 | 11 | func ConfigureRouter(e *echo.Echo, app *app.App) *echo.Echo { | |
| 12 | + | ||
| 12 | 13 | // SetLogger is a middleware that sets the logger in the context | |
| 13 | 14 | e.Use(middlewares.SetLogger(app.HttpLogger)) | |
| 14 | 15 | // HTTPAccessLogger is a middleware that logs HTTP requests | |
| @@ -9,6 +9,7 @@ import ( | |||||
| 9 | ) | 9 | ) | ||
| 10 | 10 | ||||
| 11 | func ConfigureRouter(e *echo.Echo, app *app.App) *echo.Echo { | 11 | func ConfigureRouter(e *echo.Echo, app *app.App) *echo.Echo { | ||
| 12 | + | ||||
| 12 | // SetLogger is a middleware that sets the logger in the context | 13 | // SetLogger is a middleware that sets the logger in the context | ||
| 13 | e.Use(middlewares.SetLogger(app.HttpLogger)) | 14 | e.Use(middlewares.SetLogger(app.HttpLogger)) | ||
| 14 | // HTTPAccessLogger is a middleware that logs HTTP requests | 15 | // HTTPAccessLogger is a middleware that logs HTTP requests | ||
M internal/ui/templates/install.gohtml +4 -1
| @@ -20,7 +20,10 @@ | |||
| 20 | 20 | <script src="/assets/js/custom.js"></script> | |
| 21 | 21 | </head> | |
| 22 | 22 | ||
| 23 | - | <body class="IBMPlexSans bg-zinc-200 md:p-8 flex flex-col items-center"> | |
| 23 | + | <body | |
| 24 | + | class="IBMPlexSans bg-zinc-200 md:p-8 flex flex-col items-center" | |
| 25 | + | hx-boost="true" | |
| 26 | + | > | |
| 24 | 27 | <!-- Logo and Title --> | |
| 25 | 28 | <div | |
| 26 | 29 | id="logo-mascot" | |
| @@ -20,7 +20,10 @@ | |||||
| 20 | <script src="/assets/js/custom.js"></script> | 20 | <script src="/assets/js/custom.js"></script> | ||
| 21 | </head> | 21 | </head> | ||
| 22 | 22 | ||||
| 23 | - | <body class="IBMPlexSans bg-zinc-200 md:p-8 flex flex-col items-center"> | 23 | + | <body |
| 24 | + | class="IBMPlexSans bg-zinc-200 md:p-8 flex flex-col items-center" | |||
| 25 | + | hx-boost="true" | |||
| 26 | + | > | |||
| 24 | <!-- Logo and Title --> | 27 | <!-- Logo and Title --> | ||
| 25 | <div | 28 | <div | ||
| 26 | id="logo-mascot" | 29 | id="logo-mascot" | ||
M package-lock.json +10 -0 generated file: collapsed
M package.json +1 -0
| @@ -1,5 +1,6 @@ | |||
| 1 | 1 | { | |
| 2 | 2 | "devDependencies": { | |
| 3 | + | "@catppuccin/tailwindcss": "^0.1.6", | |
| 3 | 4 | "tailwindcss": "^3.3.3" | |
| 4 | 5 | }, | |
| 5 | 6 | "scripts": { | |
| @@ -1,5 +1,6 @@ | |||||
| 1 | { | 1 | { | ||
| 2 | "devDependencies": { | 2 | "devDependencies": { | ||
| 3 | + | "@catppuccin/tailwindcss": "^0.1.6", | |||
| 3 | "tailwindcss": "^3.3.3" | 4 | "tailwindcss": "^3.3.3" | ||
| 4 | }, | 5 | }, | ||
| 5 | "scripts": { | 6 | "scripts": { | ||
M pkg/scripts/install-traefik.go +27 -7
| @@ -1,15 +1,34 @@ | |||
| 1 | 1 | package scripts | |
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | + | "errors" | |
| 5 | + | "fmt" | |
| 4 | 6 | "os" | |
| 5 | 7 | ||
| 8 | + | root "gogs.bnema.dev/gordon-echo" | |
| 9 | + | "gogs.bnema.dev/gordon-echo/internal/app" | |
| 6 | 10 | "gogs.bnema.dev/gordon-echo/pkg/templating" | |
| 7 | 11 | "gogs.bnema.dev/gordon-echo/pkg/utils" | |
| 8 | 12 | ) | |
| 9 | 13 | ||
| 10 | 14 | func CreateYAMLFiles(topDomain, adminEmail string, logger *utils.Logger) error { | |
| 15 | + | path := app.GetBuildDir() + "/" | |
| 16 | + | modelFS := root.ModelFS | |
| 17 | + | if modelFS == nil { | |
| 18 | + | return errors.New("modelFS is nil") | |
| 19 | + | } | |
| 20 | + | ||
| 21 | + | // Check if directory traefik exists, if not create it | |
| 22 | + | if _, err := os.Stat(path + "traefik"); os.IsNotExist(err) { | |
| 23 | + | err = os.Mkdir(path+"traefik", 0755) | |
| 24 | + | if err != nil { | |
| 25 | + | return err | |
| 26 | + | } | |
| 27 | + | } | |
| 28 | + | ||
| 11 | 29 | // Setup the TXT renderer for traefik-compose.goyml | |
| 12 | - | rendererCompose, err := templating.GetTXTRenderer("traefik-compose.goyml", nil, logger) | |
| 30 | + | rendererCompose, err := templating.GetTXTRenderer("traefik-compose.goyml", modelFS, logger) | |
| 31 | + | fmt.Println("rendererCompose=", rendererCompose) | |
| 13 | 32 | if err != nil { | |
| 14 | 33 | return err | |
| 15 | 34 | } | |
| @@ -18,18 +37,18 @@ func CreateYAMLFiles(topDomain, adminEmail string, logger *utils.Logger) error { | |||
| 18 | 37 | composeContent, err := rendererCompose.TXTRender(map[string]string{ | |
| 19 | 38 | "topdomain": topDomain, | |
| 20 | 39 | }) | |
| 40 | + | fmt.Println("composeContent=", composeContent) | |
| 21 | 41 | if err != nil { | |
| 22 | 42 | return err | |
| 23 | 43 | } | |
| 24 | - | ||
| 25 | - | // Save the rendered content to a file | |
| 26 | - | err = os.WriteFile("traefik-compose.yml", []byte(composeContent), 0644) | |
| 44 | + | // Save the rendered content to a file at the env path | |
| 45 | + | err = os.WriteFile(path+"docker-compose.yml", []byte(composeContent), 0644) | |
| 27 | 46 | if err != nil { | |
| 28 | 47 | return err | |
| 29 | 48 | } | |
| 30 | 49 | ||
| 31 | 50 | // Setup the TXT renderer for traefik.goyml | |
| 32 | - | rendererTraefik, err := templating.GetTXTRenderer("traefik.goyml", nil, logger) | |
| 51 | + | rendererTraefik, err := templating.GetTXTRenderer("traefik.goyml", modelFS, logger) | |
| 33 | 52 | if err != nil { | |
| 34 | 53 | return err | |
| 35 | 54 | } | |
| @@ -42,11 +61,12 @@ func CreateYAMLFiles(topDomain, adminEmail string, logger *utils.Logger) error { | |||
| 42 | 61 | return err | |
| 43 | 62 | } | |
| 44 | 63 | ||
| 45 | - | // Save the rendered content to a file | |
| 46 | - | err = os.WriteFile("traefik/traefik.yml", []byte(traefikContent), 0644) | |
| 64 | + | // Save the rendered content to a file at the env path | |
| 65 | + | err = os.WriteFile(path+"traefik/traefik.yml", []byte(traefikContent), 0644) | |
| 47 | 66 | if err != nil { | |
| 48 | 67 | return err | |
| 49 | 68 | } | |
| 50 | 69 | ||
| 51 | 70 | return nil | |
| 71 | + | ||
| 52 | 72 | } | |
| @@ -1,15 +1,34 @@ | |||||
| 1 | package scripts | 1 | package scripts | ||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | + | "errors" | |||
| 5 | + | "fmt" | |||
| 4 | "os" | 6 | "os" | ||
| 5 | 7 | ||||
| 8 | + | root "gogs.bnema.dev/gordon-echo" | |||
| 9 | + | "gogs.bnema.dev/gordon-echo/internal/app" | |||
| 6 | "gogs.bnema.dev/gordon-echo/pkg/templating" | 10 | "gogs.bnema.dev/gordon-echo/pkg/templating" | ||
| 7 | "gogs.bnema.dev/gordon-echo/pkg/utils" | 11 | "gogs.bnema.dev/gordon-echo/pkg/utils" | ||
| 8 | ) | 12 | ) | ||
| 9 | 13 | ||||
| 10 | func CreateYAMLFiles(topDomain, adminEmail string, logger *utils.Logger) error { | 14 | func CreateYAMLFiles(topDomain, adminEmail string, logger *utils.Logger) error { | ||
| 15 | + | path := app.GetBuildDir() + "/" | |||
| 16 | + | modelFS := root.ModelFS | |||
| 17 | + | if modelFS == nil { | |||
| 18 | + | return errors.New("modelFS is nil") | |||
| 19 | + | } | |||
| 20 | + | ||||
| 21 | + | // Check if directory traefik exists, if not create it | |||
| 22 | + | if _, err := os.Stat(path + "traefik"); os.IsNotExist(err) { | |||
| 23 | + | err = os.Mkdir(path+"traefik", 0755) | |||
| 24 | + | if err != nil { | |||
| 25 | + | return err | |||
| 26 | + | } | |||
| 27 | + | } | |||
| 28 | + | ||||
| 11 | // Setup the TXT renderer for traefik-compose.goyml | 29 | // Setup the TXT renderer for traefik-compose.goyml | ||
| 12 | - | rendererCompose, err := templating.GetTXTRenderer("traefik-compose.goyml", nil, logger) | 30 | + | rendererCompose, err := templating.GetTXTRenderer("traefik-compose.goyml", modelFS, logger) |
| 31 | + | fmt.Println("rendererCompose=", rendererCompose) | |||
| 13 | if err != nil { | 32 | if err != nil { | ||
| 14 | return err | 33 | return err | ||
| 15 | } | 34 | } | ||
| @@ -18,18 +37,18 @@ func CreateYAMLFiles(topDomain, adminEmail string, logger *utils.Logger) error { | |||||
| 18 | composeContent, err := rendererCompose.TXTRender(map[string]string{ | 37 | composeContent, err := rendererCompose.TXTRender(map[string]string{ | ||
| 19 | "topdomain": topDomain, | 38 | "topdomain": topDomain, | ||
| 20 | }) | 39 | }) | ||
| 40 | + | fmt.Println("composeContent=", composeContent) | |||
| 21 | if err != nil { | 41 | if err != nil { | ||
| 22 | return err | 42 | return err | ||
| 23 | } | 43 | } | ||
| 24 | - | 44 | + | // Save the rendered content to a file at the env path | |
| 25 | - | // Save the rendered content to a file | 45 | + | err = os.WriteFile(path+"docker-compose.yml", []byte(composeContent), 0644) |
| 26 | - | err = os.WriteFile("traefik-compose.yml", []byte(composeContent), 0644) | |||
| 27 | if err != nil { | 46 | if err != nil { | ||
| 28 | return err | 47 | return err | ||
| 29 | } | 48 | } | ||
| 30 | 49 | ||||
| 31 | // Setup the TXT renderer for traefik.goyml | 50 | // Setup the TXT renderer for traefik.goyml | ||
| 32 | - | rendererTraefik, err := templating.GetTXTRenderer("traefik.goyml", nil, logger) | 51 | + | rendererTraefik, err := templating.GetTXTRenderer("traefik.goyml", modelFS, logger) |
| 33 | if err != nil { | 52 | if err != nil { | ||
| 34 | return err | 53 | return err | ||
| 35 | } | 54 | } | ||
| @@ -42,11 +61,12 @@ func CreateYAMLFiles(topDomain, adminEmail string, logger *utils.Logger) error { | |||||
| 42 | return err | 61 | return err | ||
| 43 | } | 62 | } | ||
| 44 | 63 | ||||
| 45 | - | // Save the rendered content to a file | 64 | + | // Save the rendered content to a file at the env path |
| 46 | - | err = os.WriteFile("traefik/traefik.yml", []byte(traefikContent), 0644) | 65 | + | err = os.WriteFile(path+"traefik/traefik.yml", []byte(traefikContent), 0644) |
| 47 | if err != nil { | 66 | if err != nil { | ||
| 48 | return err | 67 | return err | ||
| 49 | } | 68 | } | ||
| 50 | 69 | ||||
| 51 | return nil | 70 | return nil | ||
| 71 | + | ||||
| 52 | } | 72 | } | ||
M pkg/templating/models/traefik-compose.goyml +1 -1
| @@ -14,7 +14,7 @@ services: | |||
| 14 | 14 | - /home/brice/traefik/data/acme.json:/acme.json | |
| 15 | 15 | labels: | |
| 16 | 16 | - "traefik.enable=true" | |
| 17 | - | - "traefik.http.routers.api.rule=Host(`traefik.{{ topdomain }}`)" | |
| 17 | + | - "traefik.http.routers.api.rule=Host(`traefik.{{ .topdomain }}`)" | |
| 18 | 18 | - "traefik.http.routers.api.service=api@internal" | |
| 19 | 19 | - "traefik.http.routers.api.entrypoints=websecure" | |
| 20 | 20 | - "traefik.http.routers.api.tls.certresolver=myresolver" | |
| @@ -14,7 +14,7 @@ services: | |||||
| 14 | - /home/brice/traefik/data/acme.json:/acme.json | 14 | - /home/brice/traefik/data/acme.json:/acme.json | ||
| 15 | labels: | 15 | labels: | ||
| 16 | - "traefik.enable=true" | 16 | - "traefik.enable=true" | ||
| 17 | - | - "traefik.http.routers.api.rule=Host(`traefik.{{ topdomain }}`)" | 17 | + | - "traefik.http.routers.api.rule=Host(`traefik.{{ .topdomain }}`)" |
| 18 | - "traefik.http.routers.api.service=api@internal" | 18 | - "traefik.http.routers.api.service=api@internal" | ||
| 19 | - "traefik.http.routers.api.entrypoints=websecure" | 19 | - "traefik.http.routers.api.entrypoints=websecure" | ||
| 20 | - "traefik.http.routers.api.tls.certresolver=myresolver" | 20 | - "traefik.http.routers.api.tls.certresolver=myresolver" | ||
M pkg/templating/models/traefik.goyml +1 -1
| @@ -15,7 +15,7 @@ providers: | |||
| 15 | 15 | certificatesResolvers: | |
| 16 | 16 | myresolver: | |
| 17 | 17 | acme: | |
| 18 | - | email: {{ admin.email }} | |
| 18 | + | email: {{ .admin.email }} | |
| 19 | 19 | storage: acme.json | |
| 20 | 20 | httpChallenge: | |
| 21 | 21 | entryPoint: web | |
| @@ -15,7 +15,7 @@ providers: | |||||
| 15 | certificatesResolvers: | 15 | certificatesResolvers: | ||
| 16 | myresolver: | 16 | myresolver: | ||
| 17 | acme: | 17 | acme: | ||
| 18 | - | email: {{ admin.email }} | 18 | + | email: {{ .admin.email }} |
| 19 | storage: acme.json | 19 | storage: acme.json | ||
| 20 | httpChallenge: | 20 | httpChallenge: | ||
| 21 | entryPoint: web | 21 | entryPoint: web | ||
M pkg/templating/txt-render.go +10 -1
| @@ -3,6 +3,7 @@ package templating | |||
| 3 | 3 | import ( | |
| 4 | 4 | "bytes" | |
| 5 | 5 | "errors" | |
| 6 | + | "fmt" | |
| 6 | 7 | "io/fs" | |
| 7 | 8 | "text/template" | |
| 8 | 9 | ||
| @@ -24,7 +25,7 @@ func (r *TXTRenderer) TXTRender(data interface{}) (string, error) { | |||
| 24 | 25 | } | |
| 25 | 26 | ||
| 26 | 27 | if r.Models == nil { | |
| 27 | - | err := errors.New("invalid or nil template") | |
| 28 | + | err := errors.New("invalid or nil model") | |
| 28 | 29 | r.Logger.Error().Err(r.ParseError).Msg("Parse error") | |
| 29 | 30 | ||
| 30 | 31 | return "", err | |
| @@ -42,6 +43,14 @@ func (r *TXTRenderer) TXTRender(data interface{}) (string, error) { | |||
| 42 | 43 | ||
| 43 | 44 | // GetRenderer function returns a new Renderer instance | |
| 44 | 45 | func GetTXTRenderer(filename string, fs fs.FS, logger *utils.Logger) (*TXTRenderer, error) { | |
| 46 | + | fmt.Println(filename) | |
| 47 | + | // Check if the file exists in the provided fs.FS using fs.Open | |
| 48 | + | file, err := fs.Open(filename) | |
| 49 | + | if err != nil { | |
| 50 | + | logger.Error().Err(err).Msg("Template or model '%s' not found" + filename) | |
| 51 | + | return nil, err | |
| 52 | + | } | |
| 53 | + | file.Close() // Close the file after checking | |
| 45 | 54 | mdls, err := template.New(filename).ParseFS(fs, filename) | |
| 46 | 55 | if err != nil { | |
| 47 | 56 | logger.Error().Err(err).Msg("Failed to parse template") | |
| @@ -3,6 +3,7 @@ package templating | |||||
| 3 | import ( | 3 | import ( | ||
| 4 | "bytes" | 4 | "bytes" | ||
| 5 | "errors" | 5 | "errors" | ||
| 6 | + | "fmt" | |||
| 6 | "io/fs" | 7 | "io/fs" | ||
| 7 | "text/template" | 8 | "text/template" | ||
| 8 | 9 | ||||
| @@ -24,7 +25,7 @@ func (r *TXTRenderer) TXTRender(data interface{}) (string, error) { | |||||
| 24 | } | 25 | } | ||
| 25 | 26 | ||||
| 26 | if r.Models == nil { | 27 | if r.Models == nil { | ||
| 27 | - | err := errors.New("invalid or nil template") | 28 | + | err := errors.New("invalid or nil model") |
| 28 | r.Logger.Error().Err(r.ParseError).Msg("Parse error") | 29 | r.Logger.Error().Err(r.ParseError).Msg("Parse error") | ||
| 29 | 30 | ||||
| 30 | return "", err | 31 | return "", err | ||
| @@ -42,6 +43,14 @@ func (r *TXTRenderer) TXTRender(data interface{}) (string, error) { | |||||
| 42 | 43 | ||||
| 43 | // GetRenderer function returns a new Renderer instance | 44 | // GetRenderer function returns a new Renderer instance | ||
| 44 | func GetTXTRenderer(filename string, fs fs.FS, logger *utils.Logger) (*TXTRenderer, error) { | 45 | func GetTXTRenderer(filename string, fs fs.FS, logger *utils.Logger) (*TXTRenderer, error) { | ||
| 46 | + | fmt.Println(filename) | |||
| 47 | + | // Check if the file exists in the provided fs.FS using fs.Open | |||
| 48 | + | file, err := fs.Open(filename) | |||
| 49 | + | if err != nil { | |||
| 50 | + | logger.Error().Err(err).Msg("Template or model '%s' not found" + filename) | |||
| 51 | + | return nil, err | |||
| 52 | + | } | |||
| 53 | + | file.Close() // Close the file after checking | |||
| 45 | mdls, err := template.New(filename).ParseFS(fs, filename) | 54 | mdls, err := template.New(filename).ParseFS(fs, filename) | ||
| 46 | if err != nil { | 55 | if err != nil { | ||
| 47 | logger.Error().Err(err).Msg("Failed to parse template") | 56 | logger.Error().Err(err).Msg("Failed to parse template") | ||
M tailwind.config.js +1 -1
| @@ -14,5 +14,5 @@ module.exports = { | |||
| 14 | 14 | }, | |
| 15 | 15 | }, | |
| 16 | 16 | }, | |
| 17 | - | plugins: [], | |
| 17 | + | plugins: [require("@catppuccin/tailwindcss")], | |
| 18 | 18 | }⏎̸ | |
| @@ -14,5 +14,5 @@ module.exports = { | |||||
| 14 | }, | 14 | }, | ||
| 15 | }, | 15 | }, | ||
| 16 | }, | 16 | }, | ||
| 17 | - | plugins: [], | 17 | + | plugins: [require("@catppuccin/tailwindcss")], |
| 18 | }⏎̸ | 18 | }⏎̸ | ||