diff --git a/cmd/scripts.go b/cmd/scripts.go index 64614b869..5a5027032 100644 --- a/cmd/scripts.go +++ b/cmd/scripts.go @@ -25,7 +25,7 @@ import ( var scriptsCmd = &cobra.Command{ Use: "scripts", - Short: "Watch the `scripting.source` directory for changes and update the scripts", + Short: "Watch the `scripting.source` and/or `scripting.sources` folders for changes and update the scripts", RunE: func(cmd *cobra.Command, args []string) error { runScripts() return nil @@ -46,8 +46,8 @@ func init() { } func runScripts() { - if config.Config.Scripting.Source == "" { - log.Error().Msg("`scripting.source` field is empty.") + if config.Config.Scripting.Source == "" && len(config.Config.Scripting.Sources) == 0 { + log.Error().Msg("Both `scripting.source` and `scripting.sources` fields are empty.") return } @@ -296,7 +296,13 @@ func watchScripts(ctx context.Context, provider *kubernetes.Provider, block bool log.Error().Err(err).Send() } - log.Info().Str("directory", config.Config.Scripting.Source).Msg("Watching scripts against changes:") + for _, source := range config.Config.Scripting.Sources { + if err := watcher.Add(source); err != nil { + log.Error().Err(err).Send() + } + } + + log.Info().Str("folder", config.Config.Scripting.Source).Interface("folders", config.Config.Scripting.Sources).Msg("Watching scripts against changes:") if block { <-ctx.Done() diff --git a/cmd/tapRunner.go b/cmd/tapRunner.go index bff13e778..f4f46aae9 100644 --- a/cmd/tapRunner.go +++ b/cmd/tapRunner.go @@ -424,7 +424,8 @@ func postFrontStarted(ctx context.Context, kubernetesProvider *kubernetes.Provid time.Sleep(100 * time.Millisecond) } - if config.Config.Scripting.Source != "" && config.Config.Scripting.WatchScripts { + + if (config.Config.Scripting.Source != "" || len(config.Config.Scripting.Sources) > 0) && config.Config.Scripting.WatchScripts { watchScripts(ctx, kubernetesProvider, false) } diff --git a/config/configStructs/scriptingConfig.go b/config/configStructs/scriptingConfig.go index 488d1a98c..5093dabe5 100644 --- a/config/configStructs/scriptingConfig.go +++ b/config/configStructs/scriptingConfig.go @@ -1,6 +1,7 @@ package configStructs import ( + "fmt" "io/fs" "os" "path/filepath" @@ -13,41 +14,79 @@ import ( type ScriptingConfig struct { Env map[string]interface{} `yaml:"env" json:"env" default:"{}"` Source string `yaml:"source" json:"source" default:""` + Sources []string `yaml:"sources" json:"sources" default:"[]"` WatchScripts bool `yaml:"watchScripts" json:"watchScripts" default:"true"` Active []string `yaml:"active" json:"active" default:"[]"` Console bool `yaml:"console" json:"console" default:"true"` } func (config *ScriptingConfig) GetScripts() (scripts []*misc.Script, err error) { - if config.Source == "" { - return + // Check if both Source and Sources are empty + if config.Source == "" && len(config.Sources) == 0 { + return nil, fmt.Errorf("no script sources provided") } - var files []fs.DirEntry - files, err = os.ReadDir(config.Source) - if err != nil { - return + var allFiles []struct { + Source string + File fs.DirEntry } - for _, f := range files { - if f.IsDir() { + // Handle single Source directory + if config.Source != "" { + files, err := os.ReadDir(config.Source) + if err != nil { + return nil, fmt.Errorf("failed to read directory %s: %v", config.Source, err) + } + for _, file := range files { + allFiles = append(allFiles, struct { + Source string + File fs.DirEntry + }{Source: config.Source, File: file}) + } + } + + // Handle multiple Sources directories + if len(config.Sources) > 0 { + for _, source := range config.Sources { + files, err := os.ReadDir(source) + if err != nil { + return nil, fmt.Errorf("failed to read directory %s: %v", source, err) + } + for _, file := range files { + allFiles = append(allFiles, struct { + Source string + File fs.DirEntry + }{Source: source, File: file}) + } + } + } + + // Iterate over all collected files + for _, f := range allFiles { + if f.File.IsDir() { continue } - var script *misc.Script - path := filepath.Join(config.Source, f.Name()) - if !strings.HasSuffix(path, ".js") { + // Construct the full path based on the relevant source directory + path := filepath.Join(f.Source, f.File.Name()) + if !strings.HasSuffix(f.File.Name(), ".js") { // Use file name suffix for skipping non-JS files log.Info().Str("path", path).Msg("Skipping non-JS file") continue } + + // Read the script file + var script *misc.Script script, err = misc.ReadScriptFile(path) if err != nil { - return + return nil, fmt.Errorf("failed to read script file %s: %v", path, err) } + + // Append the valid script to the scripts slice scripts = append(scripts, script) log.Debug().Str("path", path).Msg("Found script:") } - return + // Return the collected scripts and nil error if successful + return scripts, nil }