allow us to specify paths and files in the configuration relative to the directory the configuration file is in
This commit is contained in:
+22
-7
@@ -156,6 +156,15 @@ type AmConfig struct {
|
|||||||
UserProps int `yaml:"userProps"`
|
UserProps int `yaml:"userProps"`
|
||||||
} `yaml:"caches"`
|
} `yaml:"caches"`
|
||||||
} `yaml:"tuning"`
|
} `yaml:"tuning"`
|
||||||
|
baseDir string // the base directory to evaluate relative paths to.
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExPath expands a path relative to the baseDir (the location of the config file).
|
||||||
|
func (c *AmConfig) ExPath(path string) string {
|
||||||
|
if path == "" || c.baseDir == "" || filepath.IsAbs(path) {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
return filepath.Join(c.baseDir, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
@@ -213,6 +222,10 @@ func locateConfigFile() (string, *os.File) {
|
|||||||
func overlayStructValue(dest, loaded, defaults reflect.Value) {
|
func overlayStructValue(dest, loaded, defaults reflect.Value) {
|
||||||
typ := dest.Type()
|
typ := dest.Type()
|
||||||
for i := 0; i < dest.NumField(); i++ {
|
for i := 0; i < dest.NumField(); i++ {
|
||||||
|
structField := typ.Field(i)
|
||||||
|
if !structField.IsExported() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
fldDest := dest.Field(i)
|
fldDest := dest.Field(i)
|
||||||
fldLoaded := loaded.Field(i)
|
fldLoaded := loaded.Field(i)
|
||||||
fldDefaults := defaults.Field(i)
|
fldDefaults := defaults.Field(i)
|
||||||
@@ -257,8 +270,7 @@ func overlayStructValue(dest, loaded, defaults reflect.Value) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if we see this message, this function needs more work
|
// if we see this message, this function needs more work
|
||||||
errField := typ.Field(i)
|
log.Errorf("*** unable to deal with field %s of type %s", structField.Name, typ.Name())
|
||||||
log.Errorf("*** unable to deal with field %s of type %s", errField.Name, typ.Name())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -290,19 +302,20 @@ func parseDataSize(s string) (int32, error) {
|
|||||||
|
|
||||||
// AmOpenExternalContentPath opens the "external content path" specified in the configuration as a root filesystem.
|
// AmOpenExternalContentPath opens the "external content path" specified in the configuration as a root filesystem.
|
||||||
func AmOpenExternalContentPath() (fs.FS, error) {
|
func AmOpenExternalContentPath() (fs.FS, error) {
|
||||||
if GlobalConfig.Resources.ExternalContentPath == "" {
|
path := GlobalConfig.ExPath(GlobalConfig.Resources.ExternalContentPath)
|
||||||
|
if path == "" {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
finfo, err := os.Stat(GlobalConfig.Resources.ExternalContentPath)
|
finfo, err := os.Stat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("external content path \"%s\" is not valid, ignored (%v)", GlobalConfig.Resources.ExternalContentPath, err)
|
log.Errorf("external content path \"%s\" is not valid, ignored (%v)", path, err)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
if !finfo.IsDir() {
|
if !finfo.IsDir() {
|
||||||
log.Errorf("external content path \"%s\" is not a directory, ignored", GlobalConfig.Resources.ExternalContentPath)
|
log.Errorf("external content path \"%s\" is not a directory, ignored", path)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
root, err := os.OpenRoot(GlobalConfig.Resources.ExternalContentPath)
|
root, err := os.OpenRoot(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -331,9 +344,11 @@ func SetupConfig() {
|
|||||||
panic(fmt.Sprintf("unable to load configuration file %s: %v", name, err))
|
panic(fmt.Sprintf("unable to load configuration file %s: %v", name, err))
|
||||||
}
|
}
|
||||||
overlayStructValue(reflect.ValueOf(&GlobalConfig).Elem(), reflect.ValueOf(&loadedConfig).Elem(), reflect.ValueOf(&defaultConfig).Elem())
|
overlayStructValue(reflect.ValueOf(&GlobalConfig).Elem(), reflect.ValueOf(&loadedConfig).Elem(), reflect.ValueOf(&defaultConfig).Elem())
|
||||||
|
GlobalConfig.baseDir = filepath.Dir(name)
|
||||||
} else {
|
} else {
|
||||||
log.Info("SetupConfig(): using default configs only")
|
log.Info("SetupConfig(): using default configs only")
|
||||||
GlobalConfig = defaultConfig // just copy over the defaults
|
GlobalConfig = defaultConfig // just copy over the defaults
|
||||||
|
GlobalConfig.baseDir = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute additional values.
|
// Compute additional values.
|
||||||
|
|||||||
+6
-5
@@ -213,16 +213,17 @@ func SetupMailSender() func() {
|
|||||||
|
|
||||||
// Locate the external template directory and build the loaders.
|
// Locate the external template directory and build the loaders.
|
||||||
templateLoaders := make([]jet.Loader, 0, 2)
|
templateLoaders := make([]jet.Loader, 0, 2)
|
||||||
if config.GlobalConfig.Resources.EmailTemplateDir != "" {
|
etDir := config.GlobalConfig.ExPath(config.GlobalConfig.Resources.EmailTemplateDir)
|
||||||
finfo, err := os.Stat(config.GlobalConfig.Resources.EmailTemplateDir)
|
if etDir != "" {
|
||||||
|
finfo, err := os.Stat(etDir)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if finfo.IsDir() {
|
if finfo.IsDir() {
|
||||||
templateLoaders = append(templateLoaders, jet.NewOSFileSystemLoader(config.GlobalConfig.Resources.EmailTemplateDir))
|
templateLoaders = append(templateLoaders, jet.NewOSFileSystemLoader(etDir))
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("email template directory %s is not a directory, ignored", config.GlobalConfig.Resources.EmailTemplateDir)
|
log.Errorf("email template directory %s is not a directory, ignored", etDir)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("email template directory %s is not valid, ignored (%v)", config.GlobalConfig.Resources.EmailTemplateDir, err)
|
log.Errorf("email template directory %s is not valid, ignored (%v)", etDir, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
templateLoaders = append(templateLoaders, embedfs.NewLoader("templates/", emailTemplates))
|
templateLoaders = append(templateLoaders, embedfs.NewLoader("templates/", emailTemplates))
|
||||||
|
|||||||
+6
-5
@@ -88,20 +88,21 @@ var extDialogs fs.FS = nil
|
|||||||
// setupDialogs sets up the external dialog filesystem.
|
// setupDialogs sets up the external dialog filesystem.
|
||||||
func setupDialogs() {
|
func setupDialogs() {
|
||||||
// Open the external dialog path.
|
// Open the external dialog path.
|
||||||
if config.GlobalConfig.Resources.DialogTemplateDir != "" {
|
dtDir := config.GlobalConfig.ExPath(config.GlobalConfig.Resources.DialogTemplateDir)
|
||||||
finfo, err := os.Stat(config.GlobalConfig.Resources.DialogTemplateDir)
|
if dtDir != "" {
|
||||||
|
finfo, err := os.Stat(dtDir)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if finfo.IsDir() {
|
if finfo.IsDir() {
|
||||||
root, err := os.OpenRoot(config.GlobalConfig.Resources.DialogTemplateDir)
|
root, err := os.OpenRoot(dtDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
extDialogs = root.FS()
|
extDialogs = root.FS()
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("external resource path \"%s\" is not a directory, ignored", config.GlobalConfig.Resources.DialogTemplateDir)
|
log.Errorf("external resource path \"%s\" is not a directory, ignored", dtDir)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("external resource path \"%s\" is not valid, ignored (%v)", config.GlobalConfig.Resources.DialogTemplateDir, err)
|
log.Errorf("external resource path \"%s\" is not valid, ignored (%v)", dtDir, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-4
@@ -164,8 +164,9 @@ func setupMenus() {
|
|||||||
if menuCache, err = lru.New(config.GlobalConfig.Tuning.Caches.Menus); err != nil {
|
if menuCache, err = lru.New(config.GlobalConfig.Tuning.Caches.Menus); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if config.GlobalConfig.Resources.ExternalMenuDefinitions != "" {
|
mfile := config.GlobalConfig.ExPath(config.GlobalConfig.Resources.ExternalMenuDefinitions)
|
||||||
b, err := os.ReadFile(config.GlobalConfig.Resources.ExternalMenuDefinitions)
|
if mfile != "" {
|
||||||
|
b, err := os.ReadFile(mfile)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
md := new(MenuDefs)
|
md := new(MenuDefs)
|
||||||
err = yaml.Unmarshal(b, md)
|
err = yaml.Unmarshal(b, md)
|
||||||
@@ -177,10 +178,10 @@ func setupMenus() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("cannot parse external menu definition file %s, ignored (%v)", config.GlobalConfig.Resources.ExternalMenuDefinitions, err)
|
log.Errorf("cannot parse external menu definition file %s, ignored (%v)", mfile, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("cannot read external menu definition file %s, ignored (%v)", config.GlobalConfig.Resources.ExternalMenuDefinitions, err)
|
log.Errorf("cannot read external menu definition file %s, ignored (%v)", mfile, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-4
@@ -85,8 +85,9 @@ func init() {
|
|||||||
|
|
||||||
// setupMessageBoxes loads external message box definitions.
|
// setupMessageBoxes loads external message box definitions.
|
||||||
func setupMessageBoxes() {
|
func setupMessageBoxes() {
|
||||||
if config.GlobalConfig.Resources.ExternalMessageDefinitions != "" {
|
mbfile := config.GlobalConfig.ExPath(config.GlobalConfig.Resources.ExternalMessageDefinitions)
|
||||||
b, err := os.ReadFile(config.GlobalConfig.Resources.ExternalMessageDefinitions)
|
if mbfile != "" {
|
||||||
|
b, err := os.ReadFile(mbfile)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
mb := new(MessageBoxDefs)
|
mb := new(MessageBoxDefs)
|
||||||
err = yaml.Unmarshal(b, mb)
|
err = yaml.Unmarshal(b, mb)
|
||||||
@@ -102,10 +103,10 @@ func setupMessageBoxes() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("cannot parse external message definition file %s, ignored (%v)", config.GlobalConfig.Resources.ExternalMessageDefinitions, err)
|
log.Errorf("cannot parse external message definition file %s, ignored (%v)", mbfile, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("cannot read external message definition file %s, ignored (%v)", config.GlobalConfig.Resources.ExternalMessageDefinitions, err)
|
log.Errorf("cannot read external message definition file %s, ignored (%v)", mbfile, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-5
@@ -37,20 +37,21 @@ var external_resources fs.FS = nil
|
|||||||
|
|
||||||
func setupResources() {
|
func setupResources() {
|
||||||
// Open the external resource path.
|
// Open the external resource path.
|
||||||
if config.GlobalConfig.Resources.ExternalResourcePath != "" {
|
rpath := config.GlobalConfig.ExPath(config.GlobalConfig.Resources.ExternalResourcePath)
|
||||||
finfo, err := os.Stat(config.GlobalConfig.Resources.ExternalResourcePath)
|
if rpath != "" {
|
||||||
|
finfo, err := os.Stat(rpath)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if finfo.IsDir() {
|
if finfo.IsDir() {
|
||||||
root, err := os.OpenRoot(config.GlobalConfig.Resources.ExternalResourcePath)
|
root, err := os.OpenRoot(rpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
external_resources = root.FS()
|
external_resources = root.FS()
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("external resource path \"%s\" is not a directory, ignored", config.GlobalConfig.Resources.ExternalResourcePath)
|
log.Errorf("external resource path \"%s\" is not a directory, ignored", rpath)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("external resource path \"%s\" is not valid, ignored (%v)", config.GlobalConfig.Resources.ExternalResourcePath, err)
|
log.Errorf("external resource path \"%s\" is not valid, ignored (%v)", rpath, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-5
@@ -287,16 +287,17 @@ func postRewrite(a jet.Arguments) reflect.Value {
|
|||||||
func setupTemplates() {
|
func setupTemplates() {
|
||||||
// Set up the template loaders: the optional filesystem loader, then the embedded loader.
|
// Set up the template loaders: the optional filesystem loader, then the embedded loader.
|
||||||
templateLoaders := make([]jet.Loader, 0, 2)
|
templateLoaders := make([]jet.Loader, 0, 2)
|
||||||
if config.GlobalConfig.Resources.ViewTemplateDir != "" {
|
vtDir := config.GlobalConfig.ExPath(config.GlobalConfig.Resources.ViewTemplateDir)
|
||||||
finfo, err := os.Stat(config.GlobalConfig.Resources.ViewTemplateDir)
|
if vtDir != "" {
|
||||||
|
finfo, err := os.Stat(vtDir)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if finfo.IsDir() {
|
if finfo.IsDir() {
|
||||||
templateLoaders = append(templateLoaders, jet.NewOSFileSystemLoader(config.GlobalConfig.Resources.ViewTemplateDir))
|
templateLoaders = append(templateLoaders, jet.NewOSFileSystemLoader(vtDir))
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("view template directory %s is not a directory, ignored", config.GlobalConfig.Resources.ViewTemplateDir)
|
log.Errorf("view template directory %s is not a directory, ignored", vtDir)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("view template directory %s is not valid, ignored (%v)", config.GlobalConfig.Resources.ViewTemplateDir, err)
|
log.Errorf("view template directory %s is not valid, ignored (%v)", vtDir, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
templateLoaders = append(templateLoaders, embedfs.NewLoader("views/", static_views))
|
templateLoaders = append(templateLoaders, embedfs.NewLoader("views/", static_views))
|
||||||
|
|||||||
Reference in New Issue
Block a user