add the Production flag, command-line options, and DebugMode computed flag, and put it in the main places I expect it to be used

This commit is contained in:
2026-03-05 14:50:20 -07:00
parent d09e693035
commit 1f450dcf14
6 changed files with 31 additions and 11 deletions
+20 -8
View File
@@ -39,6 +39,8 @@ const CONFIGFILE_NAME = "amsterdam.yaml"
// AmCLI is the command-line interface arguments structure. // AmCLI is the command-line interface arguments structure.
type AmCLI struct { type AmCLI struct {
ConfigFile string `arg:"-C,--config,env:AMSTERDAM_CONFIG" help:"Location of the configuration file."` ConfigFile string `arg:"-C,--config,env:AMSTERDAM_CONFIG" help:"Location of the configuration file."`
Debug bool `arg:"-D,--debug,env:AMSTERDAM_DEBUG" help:"Force Amsterdam to run in debug mode."`
Production bool `arg:"-P,--prod,--production,env:AMSTERDAM_PROD" help:"Force Amsterdam to run in production mode."`
DebugPanic bool `arg:"--debug-panic" help:"Development Only - disable Echo panic recovery"` DebugPanic bool `arg:"--debug-panic" help:"Development Only - disable Echo panic recovery"`
BuggyAttachments bool `arg:"--buggy-attachments" help:"Some attachments may be buggy - truncate data if necessary"` BuggyAttachments bool `arg:"--buggy-attachments" help:"Some attachments may be buggy - truncate data if necessary"`
} }
@@ -59,9 +61,10 @@ func (*AmCLI) Version() string {
// AmConfig holds the configuration of the application as read from YAML. // AmConfig holds the configuration of the application as read from YAML.
type AmConfig struct { type AmConfig struct {
Site struct { Site struct {
BaseURL string `yaml:"baseURL"` Production bool `yaml:"production"`
Title string `yaml:"title"` BaseURL string `yaml:"baseURL"`
SiteIcon struct { Title string `yaml:"title"`
SiteIcon struct {
Path string `yaml:"path"` Path string `yaml:"path"`
Type string `yaml:"type"` Type string `yaml:"type"`
} `yaml:"siteIcon"` } `yaml:"siteIcon"`
@@ -148,6 +151,7 @@ type AmConfig struct {
// AmConfigComputed is the configuration values which are "computed" based only on values in AmConfig. // AmConfigComputed is the configuration values which are "computed" based only on values in AmConfig.
type AmConfigComputed struct { type AmConfigComputed struct {
DebugMode bool // are we in debug mode?
UploadMaxSize int32 // maximum upload size in bytes UploadMaxSize int32 // maximum upload size in bytes
UploadNoCompress map[string]bool // which upload types are not compressed? UploadNoCompress map[string]bool // which upload types are not compressed?
} }
@@ -214,15 +218,16 @@ func overlayStructValue(dest, loaded, defaults reflect.Value) {
} else if fldDest.Kind() == reflect.Array || fldDest.Kind() == reflect.Slice { } else if fldDest.Kind() == reflect.Array || fldDest.Kind() == reflect.Slice {
// array of strings - merge the two arrays // array of strings - merge the two arrays
m := make(map[string]bool) m := make(map[string]bool)
rc := make([]string, 0, fldDefaults.Len()+fldLoaded.Len())
for i := 0; i < fldDefaults.Len(); i++ { for i := 0; i < fldDefaults.Len(); i++ {
m[fldDefaults.Index(i).String()] = true m[fldDefaults.Index(i).String()] = true
rc = append(rc, fldDefaults.Index(i).String())
} }
for i := 0; i < fldLoaded.Len(); i++ { for i := 0; i < fldLoaded.Len(); i++ {
m[fldLoaded.Index(i).String()] = true if !m[fldLoaded.Index(i).String()] {
} m[fldLoaded.Index(i).String()] = true
rc := make([]string, 0, len(m)) rc = append(rc, fldLoaded.Index(i).String())
for s := range m { }
rc = append(rc, s)
} }
fldDest.Set(reflect.ValueOf(rc)) fldDest.Set(reflect.ValueOf(rc))
} else if fldDest.Kind() == reflect.Bool { } else if fldDest.Kind() == reflect.Bool {
@@ -320,6 +325,13 @@ func SetupConfig() {
} }
// Compute additional values. // Compute additional values.
if CommandLine.Debug {
GlobalComputedConfig.DebugMode = true
} else if CommandLine.Production {
GlobalComputedConfig.DebugMode = false
} else {
GlobalComputedConfig.DebugMode = !GlobalConfig.Site.Production
}
tmp, err := parseDataSize(GlobalConfig.Posting.Uploads.MaxSize) tmp, err := parseDataSize(GlobalConfig.Posting.Uploads.MaxSize)
if err != nil { if err != nil {
panic(err.Error()) panic(err.Error())
+1
View File
@@ -7,6 +7,7 @@
# file, You can obtain one at https://mozilla.org/MPL/2.0/. # file, You can obtain one at https://mozilla.org/MPL/2.0/.
# #
site: site:
production: false
baseURL: "http://localhost:1323" baseURL: "http://localhost:1323"
title: "Amsterdam Web Communities System" title: "Amsterdam Web Communities System"
siteIcon: siteIcon:
+1 -1
View File
@@ -228,7 +228,7 @@ func SetupMailSender() func() {
templateLoaders = append(templateLoaders, embedfs.NewLoader("templates/", emailTemplates)) templateLoaders = append(templateLoaders, embedfs.NewLoader("templates/", emailTemplates))
// Initialize the template engine. // Initialize the template engine.
emailRenderer = jet.NewSet(multi.NewLoader(templateLoaders...), jet.DevelopmentMode(true)) emailRenderer = jet.NewSet(multi.NewLoader(templateLoaders...), jet.DevelopmentMode(config.GlobalComputedConfig.DebugMode))
emailRenderer.AddGlobal("AmsterdamVersion", config.AMSTERDAM_VERSION) emailRenderer.AddGlobal("AmsterdamVersion", config.AMSTERDAM_VERSION)
emailRenderer.AddGlobal("AmsterdamCopyright", config.AMSTERDAM_COPYRIGHT) emailRenderer.AddGlobal("AmsterdamCopyright", config.AMSTERDAM_COPYRIGHT)
emailRenderer.AddGlobal("GlobalConfig", config.GlobalConfig) emailRenderer.AddGlobal("GlobalConfig", config.GlobalConfig)
+2
View File
@@ -16,6 +16,7 @@ import (
"net/http" "net/http"
"time" "time"
"git.erbosoft.com/amy/amsterdam/config"
"git.erbosoft.com/amy/amsterdam/database" "git.erbosoft.com/amy/amsterdam/database"
"github.com/klauspost/lctime" "github.com/klauspost/lctime"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
@@ -141,6 +142,7 @@ func AmSendPageData(ctxt echo.Context, amctxt AmContext, command string, data an
} }
} }
amctxt.VarMap().Set("__bannerad", ad) amctxt.VarMap().Set("__bannerad", ad)
amctxt.VarMap().Set("__debugMode", config.GlobalComputedConfig.DebugMode)
if tmp := amctxt.GetScratch("frame_suppressLogin"); tmp != nil { if tmp := amctxt.GetScratch("frame_suppressLogin"); tmp != nil {
amctxt.VarMap().Set("__suppressLogin", true) amctxt.VarMap().Set("__suppressLogin", true)
} }
+1 -1
View File
@@ -302,7 +302,7 @@ func setupTemplates() {
templateLoaders = append(templateLoaders, embedfs.NewLoader("views/", static_views)) templateLoaders = append(templateLoaders, embedfs.NewLoader("views/", static_views))
// Create the template renderer and add our globals to it. // Create the template renderer and add our globals to it.
views = jet.NewSet(multi.NewLoader(templateLoaders...), jet.DevelopmentMode(true)) views = jet.NewSet(multi.NewLoader(templateLoaders...), jet.DevelopmentMode(config.GlobalComputedConfig.DebugMode))
views.AddGlobal("AmsterdamVersion", config.AMSTERDAM_VERSION) views.AddGlobal("AmsterdamVersion", config.AMSTERDAM_VERSION)
views.AddGlobal("AmsterdamCopyright", config.AMSTERDAM_COPYRIGHT) views.AddGlobal("AmsterdamCopyright", config.AMSTERDAM_COPYRIGHT)
views.AddGlobal("GlobalConfig", config.GlobalConfig) views.AddGlobal("GlobalConfig", config.GlobalConfig)
+6 -1
View File
@@ -18,7 +18,12 @@
{{ range k, v := .FrameMetadata(0) }} {{ range k, v := .FrameMetadata(0) }}
<meta http-equiv="{{ k }}" content="{{ v }}"> <meta http-equiv="{{ k }}" content="{{ v }}">
{{ end }} {{ end }}
<script src="https://cdn.tailwindcss.com"></script> {{ if __debugMode }}
<script src="https://cdn.tailwindcss.com"></script>
{{ else }}
{* TODO - replace with reference to generated Tailwind CSS file *}
<script src="https://cdn.tailwindcss.com"></script>
{{ end }}
<link rel="stylesheet" href="/static/css/ams_style.css" /> <link rel="stylesheet" href="/static/css/ams_style.css" />
</head> </head>