Rework modifiers to variables again

This commit is contained in:
2025-12-19 11:44:58 +01:00
parent 74394cbde9
commit 1df0263a42
5 changed files with 173 additions and 175 deletions

View File

@@ -1,5 +1,5 @@
# Global variables - available to all commands # Global variables - available to all commands
[modifiers] [variables]
foobar = 4 foobar = 4
multiply = 1.5 multiply = 1.5
prefix = 'NEW_' prefix = 'NEW_'

View File

@@ -190,15 +190,15 @@ func runModifier(args []string, cmd *cobra.Command) {
// Load all commands // Load all commands
mainLogger.Debug("Loading commands from arguments") mainLogger.Debug("Loading commands from arguments")
mainLogger.Trace("Arguments: %v", args) mainLogger.Trace("Arguments: %v", args)
commands, modifiers, err := utils.LoadCommands(args) commands, variables, err := utils.LoadCommands(args)
if err != nil || len(commands) == 0 { if err != nil || len(commands) == 0 {
mainLogger.Error("Failed to load commands: %v", err) mainLogger.Error("Failed to load commands: %v", err)
cmd.Usage() cmd.Usage()
return return
} }
if len(modifiers) > 0 { if len(variables) > 0 {
mainLogger.Info("Loaded %d global modifiers", len(modifiers)) mainLogger.Info("Loaded %d global variables", len(variables))
processor.SetVariables(modifiers) processor.SetVariables(variables)
} }
mainLogger.Info("Loaded %d commands", len(commands)) mainLogger.Info("Loaded %d commands", len(commands))

View File

@@ -69,8 +69,8 @@ func TestTOMLGlobalModifiers(t *testing.T) {
} }
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
// Create TOML content with global modifiers // Create TOML content with global variables
tomlContent := `[modifiers] tomlContent := `[variables]
multiplier = 3 multiplier = 3
prefix = "TEST_" prefix = "TEST_"
enabled = true enabled = true
@@ -94,15 +94,15 @@ files = ["test.txt"]
os.Chdir(tmpDir) os.Chdir(tmpDir)
// Test loading TOML commands // Test loading TOML commands
commands, modifiers, err := utils.LoadCommandsFromTomlFiles("test.toml") commands, variables, err := utils.LoadCommandsFromTomlFiles("test.toml")
assert.NoError(t, err, "Should load TOML commands without error") assert.NoError(t, err, "Should load TOML commands without error")
assert.Len(t, commands, 1, "Should load 1 command from TOML") assert.Len(t, commands, 1, "Should load 1 command from TOML")
assert.Len(t, modifiers, 3, "Should load 3 modifiers") assert.Len(t, variables, 3, "Should load 3 variables")
// Verify modifiers // Verify variables
assert.Equal(t, int64(3), modifiers["multiplier"], "Multiplier should be 3") assert.Equal(t, int64(3), variables["multiplier"], "Multiplier should be 3")
assert.Equal(t, "TEST_", modifiers["prefix"], "Prefix should be TEST_") assert.Equal(t, "TEST_", variables["prefix"], "Prefix should be TEST_")
assert.Equal(t, true, modifiers["enabled"], "Enabled should be true") assert.Equal(t, true, variables["enabled"], "Enabled should be true")
// Verify regular command // Verify regular command
assert.Equal(t, "UseGlobalModifiers", commands[0].Name, "Regular command name should match") assert.Equal(t, "UseGlobalModifiers", commands[0].Name, "Regular command name should match")
@@ -118,7 +118,7 @@ func TestTOMLMultilineRegex(t *testing.T) {
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
// Create TOML content with multiline regex using literal strings // Create TOML content with multiline regex using literal strings
tomlContent := `[modifiers] tomlContent := `[variables]
factor = 2.5 factor = 2.5
[[commands]] [[commands]]
@@ -164,10 +164,10 @@ isolate = true
os.Chdir(tmpDir) os.Chdir(tmpDir)
// Test loading TOML commands // Test loading TOML commands
commands, modifiers, err := utils.LoadCommandsFromTomlFiles("test.toml") commands, variables, err := utils.LoadCommandsFromTomlFiles("test.toml")
assert.NoError(t, err, "Should load TOML commands without error") assert.NoError(t, err, "Should load TOML commands without error")
assert.Len(t, commands, 1, "Should load 1 command from TOML") assert.Len(t, commands, 1, "Should load 1 command from TOML")
assert.Len(t, modifiers, 1, "Should load 1 modifier") assert.Len(t, variables, 1, "Should load 1 variable")
// Verify the multiline regex command // Verify the multiline regex command
multilineCmd := commands[0] multilineCmd := commands[0]
@@ -303,7 +303,7 @@ func TestTOMLEndToEndIntegration(t *testing.T) {
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
// Create comprehensive TOML content // Create comprehensive TOML content
tomlContent := `[modifiers] tomlContent := `[variables]
multiplier = 4 multiplier = 4
base_value = 100 base_value = 100
@@ -358,10 +358,10 @@ some_other_setting = enabled = true
os.Chdir(tmpDir) os.Chdir(tmpDir)
// Test the complete workflow using the main function // Test the complete workflow using the main function
commands, modifiers, err := utils.LoadCommands([]string{"test.toml"}) commands, variables, err := utils.LoadCommands([]string{"test.toml"})
assert.NoError(t, err, "Should load TOML commands without error") assert.NoError(t, err, "Should load TOML commands without error")
assert.Len(t, commands, 2, "Should load 2 commands") assert.Len(t, commands, 2, "Should load 2 commands")
assert.Len(t, modifiers, 2, "Should load 2 modifiers") assert.Len(t, variables, 2, "Should load 2 variables")
// Associate files with commands // Associate files with commands
files := []string{"test.txt"} files := []string{"test.txt"}
@@ -441,21 +441,20 @@ func TestYAMLToTOMLConversion(t *testing.T) {
os.Chdir(tmpDir) os.Chdir(tmpDir)
// Create a test YAML file // Create a test YAML file
yamlContent := `- name: "ConversionTest" yamlContent := `variables:
multiplier: 2.5
prefix: "CONV_"
commands:
- name: "ConversionTest"
regex: "value = !num" regex: "value = !num"
lua: "v1 * 3" lua: "v1 * 3"
files: ["test.txt"] files: ["test.txt"]
loglevel: DEBUG loglevel: DEBUG
- name: "AnotherTest" - name: "AnotherTest"
regex: "enabled = (true|false)" regex: "enabled = (true|false)"
lua: "= false" lua: "= false"
files: ["*.conf"] files: ["*.conf"]
- name: "GlobalModifiers"
modifiers:
multiplier: 2.5
prefix: "CONV_"
` `
yamlFile := filepath.Join(tmpDir, "test.yml") yamlFile := filepath.Join(tmpDir, "test.yml")
@@ -478,27 +477,17 @@ func TestYAMLToTOMLConversion(t *testing.T) {
tomlContent := string(tomlData) tomlContent := string(tomlData)
assert.Contains(t, tomlContent, `name = "ConversionTest"`, "TOML should contain first command name") assert.Contains(t, tomlContent, `name = "ConversionTest"`, "TOML should contain first command name")
assert.Contains(t, tomlContent, `name = "AnotherTest"`, "TOML should contain second command name") assert.Contains(t, tomlContent, `name = "AnotherTest"`, "TOML should contain second command name")
assert.Contains(t, tomlContent, `[modifiers]`, "TOML should contain modifiers section") assert.Contains(t, tomlContent, `[variables]`, "TOML should contain variables section")
assert.Contains(t, tomlContent, `multiplier = 2.5`, "TOML should contain multiplier") assert.Contains(t, tomlContent, `multiplier = 2.5`, "TOML should contain multiplier")
assert.Contains(t, tomlContent, `prefix = "CONV_"`, "TOML should contain prefix") assert.Contains(t, tomlContent, `prefix = "CONV_"`, "TOML should contain prefix")
// Test that converted TOML loads correctly // Test that converted TOML loads correctly
commands, modifiers, err := utils.LoadCommandsFromTomlFiles("test.toml") commands, variables, err := utils.LoadCommandsFromTomlFiles("test.toml")
assert.NoError(t, err, "Should load converted TOML without error") assert.NoError(t, err, "Should load converted TOML without error")
assert.Len(t, commands, 3, "Should load 3 commands from converted TOML") assert.Len(t, commands, 2, "Should load 2 commands from converted TOML")
assert.Len(t, modifiers, 0, "Should have no top-level modifiers") assert.Len(t, variables, 2, "Should have 2 variables")
// Find the modifier command entry // Variables are now loaded separately, not as part of commands
var modifierCmd *utils.ModifyCommand
for i := range commands {
if commands[i].Name == "GlobalModifiers" {
modifierCmd = &commands[i]
break
}
}
assert.NotNil(t, modifierCmd, "Should find GlobalModifiers command")
assert.Equal(t, 2.5, modifierCmd.Modifiers["multiplier"], "Should preserve multiplier value")
assert.Equal(t, "CONV_", modifierCmd.Modifiers["prefix"], "Should preserve prefix value")
// Test skip functionality - run conversion again // Test skip functionality - run conversion again
err = utils.ConvertYAMLToTOML("test.yml") err = utils.ConvertYAMLToTOML("test.yml")

View File

@@ -27,7 +27,6 @@ type ModifyCommand struct {
NoDedup bool `yaml:"nodedup,omitempty" toml:"nodedup,omitempty"` NoDedup bool `yaml:"nodedup,omitempty" toml:"nodedup,omitempty"`
Disabled bool `yaml:"disable,omitempty" toml:"disable,omitempty"` Disabled bool `yaml:"disable,omitempty" toml:"disable,omitempty"`
JSON bool `yaml:"json,omitempty" toml:"json,omitempty"` JSON bool `yaml:"json,omitempty" toml:"json,omitempty"`
Modifiers map[string]interface{} `yaml:"modifiers,omitempty" toml:"modifiers,omitempty"`
} }
type CookFile []ModifyCommand type CookFile []ModifyCommand
@@ -268,33 +267,36 @@ func LoadCommands(args []string) ([]ModifyCommand, map[string]interface{}, error
loadCommandsLogger.Debug("Loading commands from arguments (cook files or direct patterns)") loadCommandsLogger.Debug("Loading commands from arguments (cook files or direct patterns)")
loadCommandsLogger.Trace("Input arguments: %v", args) loadCommandsLogger.Trace("Input arguments: %v", args)
commands := []ModifyCommand{} commands := []ModifyCommand{}
modifiers := make(map[string]interface{}) variables := make(map[string]interface{})
for _, arg := range args { for _, arg := range args {
loadCommandsLogger.Debug("Processing argument for commands: %q", arg) loadCommandsLogger.Debug("Processing argument for commands: %q", arg)
var newCommands []ModifyCommand var newCommands []ModifyCommand
var newModifiers map[string]interface{} var newVariables map[string]interface{}
var err error var err error
// Check file extension to determine format // Check file extension to determine format
if strings.HasSuffix(arg, ".toml") { if strings.HasSuffix(arg, ".toml") {
loadCommandsLogger.Debug("Loading TOML commands from %q", arg) loadCommandsLogger.Debug("Loading TOML commands from %q", arg)
newCommands, newModifiers, err = LoadCommandsFromTomlFiles(arg) newCommands, newVariables, err = LoadCommandsFromTomlFiles(arg)
if err != nil { if err != nil {
loadCommandsLogger.Error("Failed to load TOML commands from argument %q: %v", arg, err) loadCommandsLogger.Error("Failed to load TOML commands from argument %q: %v", arg, err)
return nil, nil, fmt.Errorf("failed to load commands from TOML files: %w", err) return nil, nil, fmt.Errorf("failed to load commands from TOML files: %w", err)
} }
for k, v := range newModifiers { for k, v := range newVariables {
modifiers[k] = v variables[k] = v
} }
} else { } else {
// Default to YAML for .yml, .yaml, or any other extension // Default to YAML for .yml, .yaml, or any other extension
loadCommandsLogger.Debug("Loading YAML commands from %q", arg) loadCommandsLogger.Debug("Loading YAML commands from %q", arg)
newCommands, err = LoadCommandsFromCookFiles(arg) newCommands, newVariables, err = LoadCommandsFromCookFiles(arg)
if err != nil { if err != nil {
loadCommandsLogger.Error("Failed to load YAML commands from argument %q: %v", arg, err) loadCommandsLogger.Error("Failed to load YAML commands from argument %q: %v", arg, err)
return nil, nil, fmt.Errorf("failed to load commands from cook files: %w", err) return nil, nil, fmt.Errorf("failed to load commands from cook files: %w", err)
} }
for k, v := range newVariables {
variables[k] = v
}
} }
loadCommandsLogger.Debug("Successfully loaded %d commands from %q", len(newCommands), arg) loadCommandsLogger.Debug("Successfully loaded %d commands from %q", len(newCommands), arg)
@@ -308,20 +310,21 @@ func LoadCommands(args []string) ([]ModifyCommand, map[string]interface{}, error
} }
} }
loadCommandsLogger.Info("Finished loading commands. Total %d commands and %d modifiers loaded", len(commands), len(modifiers)) loadCommandsLogger.Info("Finished loading commands. Total %d commands and %d variables loaded", len(commands), len(variables))
return commands, modifiers, nil return commands, variables, nil
} }
func LoadCommandsFromCookFiles(pattern string) ([]ModifyCommand, error) { func LoadCommandsFromCookFiles(pattern string) ([]ModifyCommand, map[string]interface{}, error) {
loadCookFilesLogger := modifyCommandLogger.WithPrefix("LoadCommandsFromCookFiles").WithField("pattern", pattern) loadCookFilesLogger := modifyCommandLogger.WithPrefix("LoadCommandsFromCookFiles").WithField("pattern", pattern)
loadCookFilesLogger.Debug("Loading commands from cook files based on pattern") loadCookFilesLogger.Debug("Loading commands from cook files based on pattern")
loadCookFilesLogger.Trace("Input pattern: %q", pattern) loadCookFilesLogger.Trace("Input pattern: %q", pattern)
static, pattern := SplitPattern(pattern) static, pattern := SplitPattern(pattern)
commands := []ModifyCommand{} commands := []ModifyCommand{}
variables := make(map[string]interface{})
cookFiles, err := doublestar.Glob(os.DirFS(static), pattern) cookFiles, err := doublestar.Glob(os.DirFS(static), pattern)
if err != nil { if err != nil {
loadCookFilesLogger.Error("Failed to glob cook files for pattern %q: %v", pattern, err) loadCookFilesLogger.Error("Failed to glob cook files for pattern %q: %v", pattern, err)
return nil, fmt.Errorf("failed to glob cook files: %w", err) return nil, nil, fmt.Errorf("failed to glob cook files: %w", err)
} }
loadCookFilesLogger.Debug("Found %d cook files for pattern %q", len(cookFiles), pattern) loadCookFilesLogger.Debug("Found %d cook files for pattern %q", len(cookFiles), pattern)
loadCookFilesLogger.Trace("Cook files found: %v", cookFiles) loadCookFilesLogger.Trace("Cook files found: %v", cookFiles)
@@ -334,35 +337,44 @@ func LoadCommandsFromCookFiles(pattern string) ([]ModifyCommand, error) {
cookFileData, err := os.ReadFile(cookFile) cookFileData, err := os.ReadFile(cookFile)
if err != nil { if err != nil {
loadCookFilesLogger.Error("Failed to read cook file %q: %v", cookFile, err) loadCookFilesLogger.Error("Failed to read cook file %q: %v", cookFile, err)
return nil, fmt.Errorf("failed to read cook file: %w", err) return nil, nil, fmt.Errorf("failed to read cook file: %w", err)
} }
loadCookFilesLogger.Trace("Read %d bytes from cook file %q", len(cookFileData), cookFile) loadCookFilesLogger.Trace("Read %d bytes from cook file %q", len(cookFileData), cookFile)
newCommands, err := LoadCommandsFromCookFile(cookFileData) newCommands, newVariables, err := LoadCommandsFromCookFile(cookFileData)
if err != nil { if err != nil {
loadCookFilesLogger.Error("Failed to load commands from cook file data for %q: %v", cookFile, err) loadCookFilesLogger.Error("Failed to load commands from cook file data for %q: %v", cookFile, err)
return nil, fmt.Errorf("failed to load commands from cook file: %w", err) return nil, nil, fmt.Errorf("failed to load commands from cook file: %w", err)
} }
commands = append(commands, newCommands...) commands = append(commands, newCommands...)
loadCookFilesLogger.Debug("Added %d commands from cook file %q. Total commands now: %d", len(newCommands), cookFile, len(commands)) for k, v := range newVariables {
variables[k] = v
}
loadCookFilesLogger.Debug("Added %d commands and %d variables from cook file %q. Total commands now: %d", len(newCommands), len(newVariables), cookFile, len(commands))
} }
loadCookFilesLogger.Debug("Finished loading commands from cook files. Total %d commands", len(commands)) loadCookFilesLogger.Debug("Finished loading commands from cook files. Total %d commands and %d variables", len(commands), len(variables))
return commands, nil return commands, variables, nil
} }
func LoadCommandsFromCookFile(cookFileData []byte) ([]ModifyCommand, error) { func LoadCommandsFromCookFile(cookFileData []byte) ([]ModifyCommand, map[string]interface{}, error) {
loadCommandLogger := modifyCommandLogger.WithPrefix("LoadCommandsFromCookFile") loadCommandLogger := modifyCommandLogger.WithPrefix("LoadCommandsFromCookFile")
loadCommandLogger.Debug("Unmarshaling commands from cook file data") loadCommandLogger.Debug("Unmarshaling commands from cook file data")
loadCommandLogger.Trace("Cook file data length: %d", len(cookFileData)) loadCommandLogger.Trace("Cook file data length: %d", len(cookFileData))
commands := []ModifyCommand{}
err := yaml.Unmarshal(cookFileData, &commands) var cookFile struct {
Variables map[string]interface{} `yaml:"variables,omitempty"`
Commands []ModifyCommand `yaml:"commands"`
}
err := yaml.Unmarshal(cookFileData, &cookFile)
if err != nil { if err != nil {
loadCommandLogger.Error("Failed to unmarshal cook file data: %v", err) loadCommandLogger.Error("Failed to unmarshal cook file data: %v", err)
return nil, fmt.Errorf("failed to unmarshal cook file: %w", err) return nil, nil, fmt.Errorf("failed to unmarshal cook file: %w", err)
} }
loadCommandLogger.Debug("Successfully unmarshaled %d commands", len(commands)) loadCommandLogger.Debug("Successfully unmarshaled %d commands and %d variables", len(cookFile.Commands), len(cookFile.Variables))
loadCommandLogger.Trace("Unmarshaled commands: %v", commands) loadCommandLogger.Trace("Unmarshaled commands: %v", cookFile.Commands)
return commands, nil loadCommandLogger.Trace("Unmarshaled variables: %v", cookFile.Variables)
return cookFile.Commands, cookFile.Variables, nil
} }
// CountGlobsBeforeDedup counts the total number of glob patterns across all commands before deduplication // CountGlobsBeforeDedup counts the total number of glob patterns across all commands before deduplication
@@ -406,7 +418,7 @@ func LoadCommandsFromTomlFiles(pattern string) ([]ModifyCommand, map[string]inte
loadTomlFilesLogger.Trace("Input pattern: %q", pattern) loadTomlFilesLogger.Trace("Input pattern: %q", pattern)
static, pattern := SplitPattern(pattern) static, pattern := SplitPattern(pattern)
commands := []ModifyCommand{} commands := []ModifyCommand{}
modifiers := make(map[string]interface{}) variables := make(map[string]interface{})
tomlFiles, err := doublestar.Glob(os.DirFS(static), pattern) tomlFiles, err := doublestar.Glob(os.DirFS(static), pattern)
if err != nil { if err != nil {
loadTomlFilesLogger.Error("Failed to glob TOML files for pattern %q: %v", pattern, err) loadTomlFilesLogger.Error("Failed to glob TOML files for pattern %q: %v", pattern, err)
@@ -426,20 +438,20 @@ func LoadCommandsFromTomlFiles(pattern string) ([]ModifyCommand, map[string]inte
return nil, nil, fmt.Errorf("failed to read TOML file: %w", err) return nil, nil, fmt.Errorf("failed to read TOML file: %w", err)
} }
loadTomlFilesLogger.Trace("Read %d bytes from TOML file %q", len(tomlFileData), tomlFile) loadTomlFilesLogger.Trace("Read %d bytes from TOML file %q", len(tomlFileData), tomlFile)
newCommands, newModifiers, err := LoadCommandsFromTomlFile(tomlFileData) newCommands, newVariables, err := LoadCommandsFromTomlFile(tomlFileData)
if err != nil { if err != nil {
loadTomlFilesLogger.Error("Failed to load commands from TOML file data for %q: %v", tomlFile, err) loadTomlFilesLogger.Error("Failed to load commands from TOML file data for %q: %v", tomlFile, err)
return nil, nil, fmt.Errorf("failed to load commands from TOML file: %w", err) return nil, nil, fmt.Errorf("failed to load commands from TOML file: %w", err)
} }
commands = append(commands, newCommands...) commands = append(commands, newCommands...)
for k, v := range newModifiers { for k, v := range newVariables {
modifiers[k] = v variables[k] = v
} }
loadTomlFilesLogger.Debug("Added %d commands and %d modifiers from TOML file %q. Total commands now: %d", len(newCommands), len(newModifiers), tomlFile, len(commands)) loadTomlFilesLogger.Debug("Added %d commands and %d variables from TOML file %q. Total commands now: %d", len(newCommands), len(newVariables), tomlFile, len(commands))
} }
loadTomlFilesLogger.Debug("Finished loading commands from TOML files. Total %d commands and %d modifiers", len(commands), len(modifiers)) loadTomlFilesLogger.Debug("Finished loading commands from TOML files. Total %d commands and %d variables", len(commands), len(variables))
return commands, modifiers, nil return commands, variables, nil
} }
func LoadCommandsFromTomlFile(tomlFileData []byte) ([]ModifyCommand, map[string]interface{}, error) { func LoadCommandsFromTomlFile(tomlFileData []byte) ([]ModifyCommand, map[string]interface{}, error) {
@@ -447,9 +459,9 @@ func LoadCommandsFromTomlFile(tomlFileData []byte) ([]ModifyCommand, map[string]
loadTomlCommandLogger.Debug("Unmarshaling commands from TOML file data") loadTomlCommandLogger.Debug("Unmarshaling commands from TOML file data")
loadTomlCommandLogger.Trace("TOML file data length: %d", len(tomlFileData)) loadTomlCommandLogger.Trace("TOML file data length: %d", len(tomlFileData))
// TOML structure for commands array and top-level modifiers // TOML structure for commands array and top-level variables
var tomlData struct { var tomlData struct {
Modifiers map[string]interface{} `toml:"modifiers,omitempty"` Variables map[string]interface{} `toml:"variables,omitempty"`
Commands []ModifyCommand `toml:"commands"` Commands []ModifyCommand `toml:"commands"`
// Also support direct array without wrapper // Also support direct array without wrapper
DirectCommands []ModifyCommand `toml:"-"` DirectCommands []ModifyCommand `toml:"-"`
@@ -463,13 +475,13 @@ func LoadCommandsFromTomlFile(tomlFileData []byte) ([]ModifyCommand, map[string]
} }
var commands []ModifyCommand var commands []ModifyCommand
modifiers := make(map[string]interface{}) variables := make(map[string]interface{})
// Extract top-level modifiers // Extract top-level variables
if len(tomlData.Modifiers) > 0 { if len(tomlData.Variables) > 0 {
loadTomlCommandLogger.Debug("Found %d top-level modifiers", len(tomlData.Modifiers)) loadTomlCommandLogger.Debug("Found %d top-level variables", len(tomlData.Variables))
for k, v := range tomlData.Modifiers { for k, v := range tomlData.Variables {
modifiers[k] = v variables[k] = v
} }
} }
@@ -491,10 +503,10 @@ func LoadCommandsFromTomlFile(tomlFileData []byte) ([]ModifyCommand, map[string]
} }
} }
loadTomlCommandLogger.Debug("Successfully unmarshaled %d commands and %d modifiers", len(commands), len(modifiers)) loadTomlCommandLogger.Debug("Successfully unmarshaled %d commands and %d variables", len(commands), len(variables))
loadTomlCommandLogger.Trace("Unmarshaled commands: %v", commands) loadTomlCommandLogger.Trace("Unmarshaled commands: %v", commands)
loadTomlCommandLogger.Trace("Unmarshaled modifiers: %v", modifiers) loadTomlCommandLogger.Trace("Unmarshaled variables: %v", variables)
return commands, modifiers, nil return commands, variables, nil
} }
// ConvertYAMLToTOML converts YAML files to TOML format // ConvertYAMLToTOML converts YAML files to TOML format
@@ -502,20 +514,6 @@ func ConvertYAMLToTOML(yamlPattern string) error {
convertLogger := modifyCommandLogger.WithPrefix("ConvertYAMLToTOML").WithField("pattern", yamlPattern) convertLogger := modifyCommandLogger.WithPrefix("ConvertYAMLToTOML").WithField("pattern", yamlPattern)
convertLogger.Debug("Starting YAML to TOML conversion") convertLogger.Debug("Starting YAML to TOML conversion")
// Load YAML commands
yamlCommands, err := LoadCommandsFromCookFiles(yamlPattern)
if err != nil {
convertLogger.Error("Failed to load YAML commands: %v", err)
return fmt.Errorf("failed to load YAML commands: %w", err)
}
if len(yamlCommands) == 0 {
convertLogger.Info("No YAML commands found for pattern: %s", yamlPattern)
return nil
}
convertLogger.Debug("Loaded %d commands from YAML", len(yamlCommands))
// Find all YAML files matching the pattern // Find all YAML files matching the pattern
static, pattern := SplitPattern(yamlPattern) static, pattern := SplitPattern(yamlPattern)
yamlFiles, err := doublestar.Glob(os.DirFS(static), pattern) yamlFiles, err := doublestar.Glob(os.DirFS(static), pattern)
@@ -526,6 +524,11 @@ func ConvertYAMLToTOML(yamlPattern string) error {
convertLogger.Debug("Found %d YAML files to convert", len(yamlFiles)) convertLogger.Debug("Found %d YAML files to convert", len(yamlFiles))
if len(yamlFiles) == 0 {
convertLogger.Info("No YAML files found for pattern: %s", yamlPattern)
return nil
}
conversionCount := 0 conversionCount := 0
skippedCount := 0 skippedCount := 0
@@ -553,14 +556,14 @@ func ConvertYAMLToTOML(yamlPattern string) error {
} }
// Load YAML commands from this specific file // Load YAML commands from this specific file
fileCommands, err := LoadCommandsFromCookFile(yamlData) fileCommands, fileVariables, err := LoadCommandsFromCookFile(yamlData)
if err != nil { if err != nil {
convertLogger.Error("Failed to parse YAML file %s: %v", yamlFilePath, err) convertLogger.Error("Failed to parse YAML file %s: %v", yamlFilePath, err)
continue continue
} }
// Convert to TOML structure // Convert to TOML structure
tomlData, err := convertCommandsToTOML(fileCommands) tomlData, err := convertCommandsToTOML(fileCommands, fileVariables)
if err != nil { if err != nil {
convertLogger.Error("Failed to convert commands to TOML for %s: %v", yamlFilePath, err) convertLogger.Error("Failed to convert commands to TOML for %s: %v", yamlFilePath, err)
continue continue
@@ -582,14 +585,16 @@ func ConvertYAMLToTOML(yamlPattern string) error {
} }
// convertCommandsToTOML converts a slice of ModifyCommand to TOML format // convertCommandsToTOML converts a slice of ModifyCommand to TOML format
func convertCommandsToTOML(commands []ModifyCommand) ([]byte, error) { func convertCommandsToTOML(commands []ModifyCommand, variables map[string]interface{}) ([]byte, error) {
convertLogger := modifyCommandLogger.WithPrefix("convertCommandsToTOML") convertLogger := modifyCommandLogger.WithPrefix("convertCommandsToTOML")
convertLogger.Debug("Converting %d commands to TOML format", len(commands)) convertLogger.Debug("Converting %d commands to TOML format", len(commands))
// Create TOML structure // Create TOML structure
tomlData := struct { tomlData := struct {
Variables map[string]interface{} `toml:"variables,omitempty"`
Commands []ModifyCommand `toml:"commands"` Commands []ModifyCommand `toml:"commands"`
}{ }{
Variables: variables,
Commands: commands, Commands: commands,
} }
@@ -600,6 +605,6 @@ func convertCommandsToTOML(commands []ModifyCommand) ([]byte, error) {
return nil, fmt.Errorf("failed to marshal commands to TOML: %w", err) return nil, fmt.Errorf("failed to marshal commands to TOML: %w", err)
} }
convertLogger.Debug("Successfully converted %d commands to TOML (%d bytes)", len(commands), len(tomlBytes)) convertLogger.Debug("Successfully converted %d commands and %d variables to TOML (%d bytes)", len(commands), len(variables), len(tomlBytes))
return tomlBytes, nil return tomlBytes, nil
} }

View File

@@ -281,6 +281,7 @@ func TestAggregateGlobs(t *testing.T) {
func TestLoadCommandsFromCookFileSuccess(t *testing.T) { func TestLoadCommandsFromCookFileSuccess(t *testing.T) {
// Arrange // Arrange
yamlData := []byte(` yamlData := []byte(`
commands:
- name: command1 - name: command1
regex: "*.txt" regex: "*.txt"
lua: replace lua: replace
@@ -290,7 +291,7 @@ func TestLoadCommandsFromCookFileSuccess(t *testing.T) {
`) `)
// Act // Act
commands, err := LoadCommandsFromCookFile(yamlData) commands, _, err := LoadCommandsFromCookFile(yamlData)
// Assert // Assert
assert.NoError(t, err) assert.NoError(t, err)
@@ -308,6 +309,7 @@ func TestLoadCommandsFromCookFileWithComments(t *testing.T) {
// Arrange // Arrange
yamlData := []byte(` yamlData := []byte(`
# This is a comment # This is a comment
commands:
- name: command1 - name: command1
regex: "*.txt" regex: "*.txt"
lua: replace lua: replace
@@ -318,7 +320,7 @@ func TestLoadCommandsFromCookFileWithComments(t *testing.T) {
`) `)
// Act // Act
commands, err := LoadCommandsFromCookFile(yamlData) commands, _, err := LoadCommandsFromCookFile(yamlData)
// Assert // Assert
assert.NoError(t, err) assert.NoError(t, err)
@@ -334,10 +336,10 @@ func TestLoadCommandsFromCookFileWithComments(t *testing.T) {
// Handle different YAML formatting styles (flow vs block) // Handle different YAML formatting styles (flow vs block)
func TestLoadCommandsFromCookFileWithFlowStyle(t *testing.T) { func TestLoadCommandsFromCookFileWithFlowStyle(t *testing.T) {
// Arrange // Arrange
yamlData := []byte(`[ { name: command1, regex: "*.txt", lua: replace }, { name: command2, regex: "*.go", lua: delete } ]`) yamlData := []byte(`commands: [ { name: command1, regex: "*.txt", lua: replace }, { name: command2, regex: "*.go", lua: delete } ]`)
// Act // Act
commands, err := LoadCommandsFromCookFile(yamlData) commands, _, err := LoadCommandsFromCookFile(yamlData)
// Assert // Assert
assert.NoError(t, err) assert.NoError(t, err)
@@ -357,8 +359,8 @@ func TestLoadCommandsFromCookFileNilOrEmptyData(t *testing.T) {
emptyData := []byte{} emptyData := []byte{}
// Act // Act
commandsNil, errNil := LoadCommandsFromCookFile(nilData) commandsNil, _, errNil := LoadCommandsFromCookFile(nilData)
commandsEmpty, errEmpty := LoadCommandsFromCookFile(emptyData) commandsEmpty, _, errEmpty := LoadCommandsFromCookFile(emptyData)
// Assert // Assert
assert.Nil(t, errNil) assert.Nil(t, errNil)
@@ -373,7 +375,7 @@ func TestLoadCommandsFromCookFileEmptyData(t *testing.T) {
yamlData := []byte(``) yamlData := []byte(``)
// Act // Act
commands, err := LoadCommandsFromCookFile(yamlData) commands, _, err := LoadCommandsFromCookFile(yamlData)
// Assert // Assert
assert.NoError(t, err) assert.NoError(t, err)
@@ -384,6 +386,7 @@ func TestLoadCommandsFromCookFileEmptyData(t *testing.T) {
func TestLoadCommandsFromCookFileWithMultipleEntries(t *testing.T) { func TestLoadCommandsFromCookFileWithMultipleEntries(t *testing.T) {
// Arrange // Arrange
yamlData := []byte(` yamlData := []byte(`
commands:
- name: command1 - name: command1
regex: "*.txt" regex: "*.txt"
lua: replace lua: replace
@@ -396,7 +399,7 @@ func TestLoadCommandsFromCookFileWithMultipleEntries(t *testing.T) {
`) `)
// Act // Act
commands, err := LoadCommandsFromCookFile(yamlData) commands, _, err := LoadCommandsFromCookFile(yamlData)
// Assert // Assert
assert.NoError(t, err) assert.NoError(t, err)
@@ -415,6 +418,7 @@ func TestLoadCommandsFromCookFileWithMultipleEntries(t *testing.T) {
func TestLoadCommandsFromCookFileLegitExample(t *testing.T) { func TestLoadCommandsFromCookFileLegitExample(t *testing.T) {
// Arrange // Arrange
yamlData := []byte(` yamlData := []byte(`
commands:
- name: crewlayabout - name: crewlayabout
pattern: '<Talent identifier="crewlayabout">!anyvalue="(?<repairspeedpenalty>!num)"!anyvalue="(?<skillpenalty>!num)"!anyvalue="(?<repairspeedbonus>!num)"!anyvalue="(?<skillbonus>!num)"!anydistance="(?<distance>!num)"!anySkillBonus!anyvalue="(?<skillpenaltyv>!num)"!anyvalue="(?<skillpenaltyv1>!num)"!anyvalue="(?<skillpenaltyv2>!num)"!anyvalue="(?<skillpenaltyv3>!num)"!anyvalue="(?<skillpenaltyv4>!num)"!anyvalue="(?<repairspeedpenaltyv>!num)' pattern: '<Talent identifier="crewlayabout">!anyvalue="(?<repairspeedpenalty>!num)"!anyvalue="(?<skillpenalty>!num)"!anyvalue="(?<repairspeedbonus>!num)"!anyvalue="(?<skillbonus>!num)"!anydistance="(?<distance>!num)"!anySkillBonus!anyvalue="(?<skillpenaltyv>!num)"!anyvalue="(?<skillpenaltyv1>!num)"!anyvalue="(?<skillpenaltyv2>!num)"!anyvalue="(?<skillpenaltyv3>!num)"!anyvalue="(?<skillpenaltyv4>!num)"!anyvalue="(?<repairspeedpenaltyv>!num)'
lua: | lua: |
@@ -434,7 +438,7 @@ func TestLoadCommandsFromCookFileLegitExample(t *testing.T) {
`) `)
// Act // Act
commands, err := LoadCommandsFromCookFile(yamlData) commands, _, err := LoadCommandsFromCookFile(yamlData)
// Assert // Assert
assert.NoError(t, err) assert.NoError(t, err)
@@ -543,7 +547,7 @@ func TestLoadCommandsFromCookFilesNoYamlFiles(t *testing.T) {
} }
// Execute function // Execute function
commands, err := LoadCommandsFromCookFiles("") commands, _, err := LoadCommandsFromCookFiles("")
// Assertions // Assertions
if err != nil { if err != nil {
@@ -609,7 +613,7 @@ func TestLoadCommandsFromCookFilesNoYamlFiles(t *testing.T) {
// } // }
// //
// // Execute function // // Execute function
// commands, err := LoadCommandsFromCookFiles("") // commands, _, err := LoadCommandsFromCookFiles("")
// //
// // Assertions // // Assertions
// if err != nil { // if err != nil {
@@ -693,7 +697,7 @@ func TestLoadCommandsFromCookFilesNoYamlFiles(t *testing.T) {
// } // }
// //
// // Execute function // // Execute function
// commands, err := LoadCommandsFromCookFiles("") // commands, _, err := LoadCommandsFromCookFiles("")
// //
// // Assertions // // Assertions
// if err != nil { // if err != nil {
@@ -852,7 +856,7 @@ func TestExpandGlobsMemoization(t *testing.T) {
// } // }
// //
// // Execute function // // Execute function
// commands, err := LoadCommandsFromCookFiles("") // commands, _, err := LoadCommandsFromCookFiles("")
// //
// // Assertions // // Assertions
// if err == nil { // if err == nil {
@@ -919,7 +923,7 @@ func TestExpandGlobsMemoization(t *testing.T) {
// } // }
// //
// // Execute function // // Execute function
// commands, err := LoadCommandsFromCookFiles("") // commands, _, err := LoadCommandsFromCookFiles("")
// //
// // Assertions // // Assertions
// if err != nil { // if err != nil {
@@ -989,7 +993,7 @@ func TestExpandGlobsMemoization(t *testing.T) {
// } // }
// //
// // Execute function // // Execute function
// commands, err := LoadCommandsFromCookFiles("") // commands, _, err := LoadCommandsFromCookFiles("")
// //
// // Assertions // // Assertions
// if err != nil { // if err != nil {
@@ -1047,7 +1051,7 @@ func TestExpandGlobsMemoization(t *testing.T) {
// } // }
// //
// // Execute function // // Execute function
// commands, err := LoadCommandsFromCookFiles("") // commands, _, err := LoadCommandsFromCookFiles("")
// //
// // Assertions // // Assertions
// if err != nil { // if err != nil {