mirror of
https://github.com/Xevion/glance.git
synced 2025-12-17 12:12:06 -06:00
Refactor 1/2 + new stuff
* Refactor CLI * Add config:print command * Add diagnose command * Allow including other files in config * Watch for file changes and automatically restart server
This commit is contained in:
@@ -2,45 +2,120 @@ package glance
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"log"
|
||||
)
|
||||
|
||||
func Main() int {
|
||||
options, err := ParseCliOptions()
|
||||
options, err := parseCliOptions()
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return 1
|
||||
}
|
||||
|
||||
configFile, err := os.Open(options.ConfigPath)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("failed opening config file: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
config, err := NewConfigFromYml(configFile)
|
||||
configFile.Close()
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("failed parsing config file: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
if options.Intent == CliIntentServe {
|
||||
app, err := NewApplication(config)
|
||||
|
||||
switch options.intent {
|
||||
case cliIntentServe:
|
||||
if err := serveApp(options.configPath); err != nil {
|
||||
fmt.Println(err)
|
||||
return 1
|
||||
}
|
||||
case cliIntentConfigValidate:
|
||||
contents, _, err := parseYAMLIncludes(options.configPath)
|
||||
if err != nil {
|
||||
fmt.Printf("failed creating application: %v\n", err)
|
||||
fmt.Printf("failed to parse config file: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
if err := app.Serve(); err != nil {
|
||||
fmt.Printf("http server error: %v\n", err)
|
||||
if _, err := newConfigFromYAML(contents); err != nil {
|
||||
fmt.Printf("config file is invalid: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
case cliIntentConfigPrint:
|
||||
contents, _, err := parseYAMLIncludes(options.configPath)
|
||||
if err != nil {
|
||||
fmt.Printf("failed to parse config file: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
|
||||
fmt.Println(string(contents))
|
||||
case cliIntentDiagnose:
|
||||
runDiagnostic()
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func serveApp(configPath string) error {
|
||||
exitChannel := make(chan struct{})
|
||||
// the onChange method gets called at most once per 500ms due to debouncing so we shouldn't
|
||||
// need to use atomic.Bool here unless newConfigFromYAML is very slow for some reason
|
||||
hadValidConfigOnStartup := false
|
||||
var stopServer func() error
|
||||
|
||||
onChange := func(newContents []byte) {
|
||||
if stopServer != nil {
|
||||
log.Println("Config file changed, attempting to restart server")
|
||||
}
|
||||
|
||||
config, err := newConfigFromYAML(newContents)
|
||||
if err != nil {
|
||||
log.Printf("Config file is invalid: %v", err)
|
||||
|
||||
if !hadValidConfigOnStartup {
|
||||
close(exitChannel)
|
||||
}
|
||||
|
||||
return
|
||||
} else if !hadValidConfigOnStartup {
|
||||
hadValidConfigOnStartup = true
|
||||
}
|
||||
|
||||
app := newApplication(config)
|
||||
|
||||
if stopServer != nil {
|
||||
if err := stopServer(); err != nil {
|
||||
log.Printf("Error while trying to stop server: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
go func() {
|
||||
var startServer func() error
|
||||
startServer, stopServer = app.Server()
|
||||
|
||||
if err := startServer(); err != nil {
|
||||
log.Printf("Failed to start server: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
onErr := func(err error) {
|
||||
log.Printf("Error watching config files: %v", err)
|
||||
}
|
||||
|
||||
configContents, configIncludes, err := parseYAMLIncludes(configPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse config file: %w", err)
|
||||
}
|
||||
|
||||
stopWatching, err := configFilesWatcher(configPath, configContents, configIncludes, onChange, onErr)
|
||||
if err == nil {
|
||||
defer stopWatching()
|
||||
} else {
|
||||
log.Printf("Error starting file watcher, config file changes will require a manual restart. (%v)", err)
|
||||
|
||||
config, err := newConfigFromYAML(configContents)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse config file: %w", err)
|
||||
}
|
||||
|
||||
app := newApplication(config)
|
||||
|
||||
startServer, _ := app.Server()
|
||||
if err := startServer(); err != nil {
|
||||
return fmt.Errorf("failed to start server: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
<-exitChannel
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user