-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
180 lines (152 loc) · 4.88 KB
/
main.go
File metadata and controls
180 lines (152 loc) · 4.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
package main
import (
"bufio"
"context"
"flag"
"fmt"
"log"
"log/slog"
"os"
"os/signal"
"path/filepath"
"strconv"
"strings"
"syscall"
"github.com/GoCodeAlone/modular"
"github.com/GoCodeAlone/workflow"
"github.com/GoCodeAlone/workflow/config"
allplugins "github.com/GoCodeAlone/workflow/plugins/all"
)
func main() {
// Parse command line arguments
configFile := flag.String("config", "", "Path to workflow configuration file")
flag.Parse()
// If no configuration specified, provide a selection menu
if *configFile == "" {
selectedConfig, err := selectWorkflowConfig()
if err != nil {
log.Fatalf("Failed to select workflow configuration: %v", err)
}
*configFile = selectedConfig
}
// Load configuration
cfg, err := config.LoadFromFile(*configFile)
if err != nil {
log.Fatalf("Failed to load configuration: %v", err)
}
// Create application with basic logger
logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
AddSource: true,
Level: slog.LevelDebug,
}))
app := modular.NewStdApplication(nil, logger)
// Create workflow engine
engine := workflow.NewStdEngine(app, logger)
// Load all built-in plugins in one call.
// To use a custom set, call allplugins.DefaultPlugins(), modify the slice,
// and load each plugin individually with engine.LoadPlugin.
if err = allplugins.LoadAll(engine); err != nil {
log.Fatalf("Failed to load plugins: %v", err)
}
// Build and start the workflows
if err = engine.BuildFromConfig(cfg); err != nil {
log.Fatalf("Failed to build workflow: %v", err)
}
// Create context that can be canceled on signal
ctx, cancel := context.WithCancel(context.Background())
// Start the engine
if err := engine.Start(ctx); err != nil {
cancel()
log.Fatalf("Failed to start workflow: %v", err)
}
fmt.Printf("Workflow started successfully using configuration from %s\n", *configFile)
fmt.Println("Press Ctrl+C to stop...")
// Wait for termination signal
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
<-sigCh
fmt.Println("Shutting down...")
cancel()
if err := engine.Stop(ctx); err != nil {
log.Fatalf("Error during shutdown: %v", err)
}
fmt.Println("Shutdown complete")
}
// selectWorkflowConfig presents a list of available workflow configurations and returns the selected one
func selectWorkflowConfig() (string, error) {
// Find all YAML and YML files in the current directory
yamlFiles, err := findWorkflowConfigs()
if err != nil {
return "", fmt.Errorf("failed to find workflow configurations: %v", err)
}
if len(yamlFiles) == 0 {
return "", fmt.Errorf("no workflow configurations found")
}
// Print the menu of available configurations
fmt.Println("Available workflow configurations:")
fmt.Println("----------------------------------")
for i, file := range yamlFiles {
// Get just the filename without path
baseFile := filepath.Base(file)
fmt.Printf("%d. %s\n", i+1, baseFile)
}
fmt.Println("----------------------------------")
fmt.Print("Select a configuration (enter number): ")
// Read user input
reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')
if err != nil {
return "", fmt.Errorf("failed to read input: %v", err)
}
// Trim whitespace and convert to integer
input = strings.TrimSpace(input)
selection, err := strconv.Atoi(input)
if err != nil || selection < 1 || selection > len(yamlFiles) {
return "", fmt.Errorf("invalid selection: %s", input)
}
// Return the selected configuration file
selectedConfig := yamlFiles[selection-1]
fmt.Printf("Selected configuration: %s\n", selectedConfig)
return selectedConfig, nil
}
// findWorkflowConfigs finds all YAML and YML files in the example directory
func findWorkflowConfigs() ([]string, error) {
var configs []string
// Get the current directory
currentDir, err := os.Getwd()
if err != nil {
return nil, fmt.Errorf("failed to get current directory: %v", err)
}
// Check if we're in the example directory
dirName := filepath.Base(currentDir)
searchDir := currentDir
if dirName != "example" {
// If not in example dir, see if there's an example subdirectory
exampleDir := filepath.Join(currentDir, "example")
if _, err := os.Stat(exampleDir); err == nil {
searchDir = exampleDir
}
}
// Find all YAML files
yamlFiles, err := filepath.Glob(filepath.Join(searchDir, "*.yaml"))
if err != nil {
return nil, err
}
configs = append(configs, yamlFiles...)
// Find all YML files
ymlFiles, err := filepath.Glob(filepath.Join(searchDir, "*.yml"))
if err != nil {
return nil, err
}
configs = append(configs, ymlFiles...)
// Skip README and other non-config files
var filteredConfigs []string
for _, cfg := range configs {
baseName := strings.ToLower(filepath.Base(cfg))
if strings.Contains(baseName, "readme") || strings.Contains(baseName, "license") {
continue
}
filteredConfigs = append(filteredConfigs, cfg)
}
return filteredConfigs, nil
}