Implement loading lua from separate files via @
This commit is contained in:
@@ -60,7 +60,7 @@ func ProcessJSON(content string, command utils.ModifyCommand, filename string) (
|
||||
processJSONLogger.Debug("Set JSON data as Lua global 'data'")
|
||||
|
||||
// Build and execute Lua script for JSON mode
|
||||
luaExpr := BuildJSONLuaScript(command.Lua)
|
||||
luaExpr := BuildJSONLuaScript(command.Lua, command.SourceDir)
|
||||
processJSONLogger.Debug("Built Lua script from expression: %q", command.Lua)
|
||||
processJSONLogger.Trace("Full Lua script: %q", utils.LimitString(luaExpr, 200))
|
||||
|
||||
|
||||
191
processor/lua_external_integration_test.go
Normal file
191
processor/lua_external_integration_test.go
Normal file
@@ -0,0 +1,191 @@
|
||||
package processor
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"cook/utils"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestProcessRegexWithExternalLuaFile(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp("", "lua-external-integration-test-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Create a test Lua file with replacement variable
|
||||
luaFile := filepath.Join(tmpDir, "multiply.lua")
|
||||
luaContent := `v1 = v1 * 2
|
||||
replacement = format("<value>%s</value>", v1)
|
||||
return true`
|
||||
err = os.WriteFile(luaFile, []byte(luaContent), 0644)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Create test content
|
||||
content := `<value>10</value>`
|
||||
|
||||
// Create command with external Lua reference
|
||||
command := utils.ModifyCommand{
|
||||
Name: "test",
|
||||
Regex: `<value>(\d+)</value>`,
|
||||
Lua: "@" + filepath.Base(luaFile),
|
||||
SourceDir: tmpDir,
|
||||
}
|
||||
|
||||
// Process
|
||||
modifications, err := ProcessRegex(content, command, "test.xml")
|
||||
assert.NoError(t, err)
|
||||
assert.Greater(t, len(modifications), 0)
|
||||
|
||||
// Apply modifications
|
||||
result := content
|
||||
for _, mod := range modifications {
|
||||
result = result[:mod.From] + mod.With + result[mod.To:]
|
||||
}
|
||||
assert.Contains(t, result, "<value>20</value>")
|
||||
}
|
||||
|
||||
func TestProcessJSONWithExternalLuaFile(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp("", "lua-external-json-integration-test-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Create a test Lua file
|
||||
luaFile := filepath.Join(tmpDir, "json_modify.lua")
|
||||
luaContent := `data.value = 84
|
||||
modified = true`
|
||||
err = os.WriteFile(luaFile, []byte(luaContent), 0644)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Create test JSON content
|
||||
content := `{"value": 42}`
|
||||
|
||||
// Create command with external Lua reference
|
||||
command := utils.ModifyCommand{
|
||||
Name: "test",
|
||||
JSON: true,
|
||||
Lua: "@" + filepath.Base(luaFile),
|
||||
SourceDir: tmpDir,
|
||||
}
|
||||
|
||||
// Process
|
||||
modifications, err := ProcessJSON(content, command, "test.json")
|
||||
assert.NoError(t, err)
|
||||
assert.Greater(t, len(modifications), 0)
|
||||
|
||||
// Apply modifications to verify
|
||||
result := content
|
||||
for _, mod := range modifications {
|
||||
result = result[:mod.From] + mod.With + result[mod.To:]
|
||||
}
|
||||
// Check that value was changed to 84 (formatting may vary)
|
||||
assert.Contains(t, result, `"value"`)
|
||||
assert.Contains(t, result, `84`)
|
||||
assert.NotContains(t, result, `"value": 42`)
|
||||
assert.NotContains(t, result, `"value":42`)
|
||||
}
|
||||
|
||||
func TestProcessXMLWithExternalLuaFile(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp("", "lua-external-xml-integration-test-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Create a test Lua file (XML uses 'root' not 'data')
|
||||
luaFile := filepath.Join(tmpDir, "xml_modify.lua")
|
||||
luaContent := `visitElements(root, function(elem)
|
||||
if elem._tag == "Item" then
|
||||
modifyNumAttr(elem, "Weight", function(val) return val * 2 end)
|
||||
end
|
||||
end)
|
||||
modified = true`
|
||||
err = os.WriteFile(luaFile, []byte(luaContent), 0644)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Create test XML content
|
||||
content := `<Items><Item Weight="10" /></Items>`
|
||||
|
||||
// Create command with external Lua reference
|
||||
command := utils.ModifyCommand{
|
||||
Name: "test",
|
||||
Lua: "@" + filepath.Base(luaFile),
|
||||
SourceDir: tmpDir,
|
||||
}
|
||||
|
||||
// Process
|
||||
modifications, err := ProcessXML(content, command, "test.xml")
|
||||
assert.NoError(t, err)
|
||||
assert.Greater(t, len(modifications), 0)
|
||||
|
||||
// Apply modifications to verify
|
||||
result := content
|
||||
for _, mod := range modifications {
|
||||
result = result[:mod.From] + mod.With + result[mod.To:]
|
||||
}
|
||||
assert.Contains(t, result, `Weight="20"`)
|
||||
}
|
||||
|
||||
func TestExternalLuaFileWithVariables(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp("", "lua-external-vars-integration-test-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Create a test Lua file with variable reference
|
||||
luaFile := filepath.Join(tmpDir, "with_vars.lua")
|
||||
luaContent := `v1 = v1 * $multiply
|
||||
replacement = format("<value>%s</value>", v1)
|
||||
return true`
|
||||
err = os.WriteFile(luaFile, []byte(luaContent), 0644)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Set global variable
|
||||
SetVariables(map[string]interface{}{"multiply": 1.5})
|
||||
defer SetVariables(map[string]interface{}{})
|
||||
|
||||
// Create test content
|
||||
content := `<value>10</value>`
|
||||
|
||||
// Create command with external Lua reference
|
||||
command := utils.ModifyCommand{
|
||||
Name: "test",
|
||||
Regex: `<value>(\d+)</value>`,
|
||||
Lua: "@" + filepath.Base(luaFile),
|
||||
SourceDir: tmpDir,
|
||||
}
|
||||
|
||||
// Process
|
||||
modifications, err := ProcessRegex(content, command, "test.xml")
|
||||
assert.NoError(t, err)
|
||||
assert.Greater(t, len(modifications), 0)
|
||||
|
||||
// Apply modifications
|
||||
result := content
|
||||
for _, mod := range modifications {
|
||||
result = result[:mod.From] + mod.With + result[mod.To:]
|
||||
}
|
||||
assert.Contains(t, result, "<value>15</value>")
|
||||
}
|
||||
|
||||
func TestExternalLuaFileErrorHandling(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp("", "lua-external-error-test-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Create command with non-existent external Lua file
|
||||
command := utils.ModifyCommand{
|
||||
Name: "test",
|
||||
Regex: `<value>(\d+)</value>`,
|
||||
Lua: "@nonexistent.lua",
|
||||
SourceDir: tmpDir,
|
||||
}
|
||||
|
||||
// Process - the error script will be generated but execution will fail
|
||||
// ProcessRegex continues on Lua errors, so no modifications will be made
|
||||
content := `<value>10</value>`
|
||||
modifications, err := ProcessRegex(content, command, "test.xml")
|
||||
|
||||
// No error returned (ProcessRegex continues on Lua errors), but no modifications made
|
||||
assert.NoError(t, err)
|
||||
assert.Empty(t, modifications)
|
||||
}
|
||||
224
processor/lua_external_test.go
Normal file
224
processor/lua_external_test.go
Normal file
@@ -0,0 +1,224 @@
|
||||
package processor
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestLoadExternalLuaFile(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp("", "lua-external-test-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Create a test Lua file
|
||||
luaFile := filepath.Join(tmpDir, "test.lua")
|
||||
luaContent := `data.value = 42
|
||||
modified = true`
|
||||
err = os.WriteFile(luaFile, []byte(luaContent), 0644)
|
||||
assert.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
luaPath string
|
||||
sourceDir string
|
||||
expected string
|
||||
wantError bool
|
||||
}{
|
||||
{
|
||||
name: "Relative path with sourceDir",
|
||||
luaPath: "test.lua",
|
||||
sourceDir: tmpDir,
|
||||
expected: luaContent,
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "Absolute path",
|
||||
luaPath: luaFile,
|
||||
sourceDir: "",
|
||||
expected: luaContent,
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "Relative path without sourceDir (uses CWD)",
|
||||
luaPath: filepath.Base(luaFile),
|
||||
sourceDir: "",
|
||||
expected: luaContent,
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "Nested relative path",
|
||||
luaPath: "scripts/test.lua",
|
||||
sourceDir: tmpDir,
|
||||
expected: "",
|
||||
wantError: true,
|
||||
},
|
||||
{
|
||||
name: "Non-existent file",
|
||||
luaPath: "nonexistent.lua",
|
||||
sourceDir: tmpDir,
|
||||
expected: "",
|
||||
wantError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Change to tmpDir for CWD-based tests
|
||||
if tt.sourceDir == "" && !filepath.IsAbs(tt.luaPath) {
|
||||
origDir, _ := os.Getwd()
|
||||
defer os.Chdir(origDir)
|
||||
os.Chdir(tmpDir)
|
||||
}
|
||||
|
||||
result, err := LoadExternalLuaFile(tt.luaPath, tt.sourceDir)
|
||||
if tt.wantError {
|
||||
assert.Error(t, err)
|
||||
assert.Empty(t, result)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildLuaScriptWithExternalFile(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp("", "lua-external-build-test-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Create a test Lua file
|
||||
luaFile := filepath.Join(tmpDir, "multiply.lua")
|
||||
luaContent := `v1 = v1 * 2`
|
||||
err = os.WriteFile(luaFile, []byte(luaContent), 0644)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Test with relative path
|
||||
relativePath := filepath.Base(luaFile)
|
||||
result := BuildLuaScript("@"+relativePath, tmpDir)
|
||||
assert.Contains(t, result, "v1 = v1 * 2")
|
||||
assert.Contains(t, result, "function run()")
|
||||
|
||||
// Test with absolute path
|
||||
result = BuildLuaScript("@"+luaFile, "")
|
||||
assert.Contains(t, result, "v1 = v1 * 2")
|
||||
}
|
||||
|
||||
func TestBuildLuaScriptWithExternalFileError(t *testing.T) {
|
||||
// Test that missing file returns error script
|
||||
result := BuildLuaScript("@nonexistent.lua", "/tmp")
|
||||
assert.Contains(t, result, "error(")
|
||||
assert.Contains(t, result, "Failed to load external Lua file")
|
||||
}
|
||||
|
||||
func TestBuildJSONLuaScriptWithExternalFile(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp("", "lua-external-json-test-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Create a test Lua file
|
||||
luaFile := filepath.Join(tmpDir, "json_modify.lua")
|
||||
luaContent := `data.value = 84
|
||||
modified = true`
|
||||
err = os.WriteFile(luaFile, []byte(luaContent), 0644)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Test with relative path
|
||||
relativePath := filepath.Base(luaFile)
|
||||
result := BuildJSONLuaScript("@"+relativePath, tmpDir)
|
||||
assert.Contains(t, result, "data.value = 84")
|
||||
assert.Contains(t, result, "modified = true")
|
||||
assert.Contains(t, result, "function run()")
|
||||
}
|
||||
|
||||
func TestBuildLuaScriptWithInlineCode(t *testing.T) {
|
||||
// Test that inline code (without @) still works
|
||||
result := BuildLuaScript("v1 = v1 * 2", "")
|
||||
assert.Contains(t, result, "v1 = v1 * 2")
|
||||
assert.Contains(t, result, "function run()")
|
||||
assert.NotContains(t, result, "@")
|
||||
}
|
||||
|
||||
func TestBuildLuaScriptExternalFileWithVariables(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp("", "lua-external-vars-test-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Create a test Lua file with variable reference
|
||||
luaFile := filepath.Join(tmpDir, "with_vars.lua")
|
||||
luaContent := `v1 = v1 * $multiply`
|
||||
err = os.WriteFile(luaFile, []byte(luaContent), 0644)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Set a global variable
|
||||
SetVariables(map[string]interface{}{"multiply": 1.5})
|
||||
defer SetVariables(map[string]interface{}{})
|
||||
|
||||
// Test that variables are substituted in external files
|
||||
result := BuildLuaScript("@"+filepath.Base(luaFile), tmpDir)
|
||||
assert.Contains(t, result, "v1 = v1 * 1.5")
|
||||
assert.NotContains(t, result, "$multiply")
|
||||
}
|
||||
|
||||
func TestBuildLuaScriptExternalFileNestedPath(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp("", "lua-external-nested-test-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Create nested directory structure
|
||||
scriptsDir := filepath.Join(tmpDir, "scripts")
|
||||
err = os.MkdirAll(scriptsDir, 0755)
|
||||
assert.NoError(t, err)
|
||||
|
||||
luaFile := filepath.Join(scriptsDir, "test.lua")
|
||||
luaContent := `data.value = 100`
|
||||
err = os.WriteFile(luaFile, []byte(luaContent), 0644)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Test with nested relative path
|
||||
result := BuildLuaScript("@scripts/test.lua", tmpDir)
|
||||
assert.Contains(t, result, "data.value = 100")
|
||||
}
|
||||
|
||||
func TestBuildLuaScriptExternalFileWithPrependLuaAssignment(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp("", "lua-external-prepend-test-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Create a test Lua file with operator prefix (should trigger prepend)
|
||||
luaFile := filepath.Join(tmpDir, "multiply.lua")
|
||||
luaContent := `* 2`
|
||||
err = os.WriteFile(luaFile, []byte(luaContent), 0644)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Test that prepend still works with external files
|
||||
result := BuildLuaScript("@"+filepath.Base(luaFile), tmpDir)
|
||||
// PrependLuaAssignment adds "v1 = v1" + "* 2" = "v1 = v1* 2" (no space between v1 and *)
|
||||
assert.Contains(t, result, "v1 = v1* 2")
|
||||
}
|
||||
|
||||
func TestBuildLuaScriptExternalFilePreservesWhitespace(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp("", "lua-external-whitespace-test-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// Create a test Lua file with multiline content
|
||||
luaFile := filepath.Join(tmpDir, "multiline.lua")
|
||||
luaContent := `if data.items then
|
||||
for i, item in ipairs(data.items) do
|
||||
item.value = item.value * 2
|
||||
end
|
||||
modified = true
|
||||
end`
|
||||
err = os.WriteFile(luaFile, []byte(luaContent), 0644)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Test that whitespace and formatting is preserved
|
||||
result := BuildLuaScript("@"+filepath.Base(luaFile), tmpDir)
|
||||
assert.Contains(t, result, "if data.items then")
|
||||
assert.Contains(t, result, " for i, item in ipairs(data.items) do")
|
||||
assert.Contains(t, result, " item.value = item.value * 2")
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
@@ -205,11 +207,62 @@ func PrependLuaAssignment(luaExpr string) string {
|
||||
return luaExpr
|
||||
}
|
||||
|
||||
// LoadExternalLuaFile loads Lua code from an external file
|
||||
func LoadExternalLuaFile(luaPath string, sourceDir string) (string, error) {
|
||||
loadLuaLogger := processorLogger.WithPrefix("LoadExternalLuaFile").WithField("luaPath", luaPath).WithField("sourceDir", sourceDir)
|
||||
loadLuaLogger.Debug("Loading external Lua file")
|
||||
|
||||
// Resolve path: if relative, resolve relative to sourceDir; if absolute, use as-is
|
||||
var resolvedPath string
|
||||
if filepath.IsAbs(luaPath) {
|
||||
resolvedPath = luaPath
|
||||
} else {
|
||||
if sourceDir == "" {
|
||||
// No source directory, use current working directory
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
loadLuaLogger.Error("Failed to get current working directory: %v", err)
|
||||
return "", fmt.Errorf("failed to get current working directory: %w", err)
|
||||
}
|
||||
resolvedPath = filepath.Join(cwd, luaPath)
|
||||
} else {
|
||||
resolvedPath = filepath.Join(sourceDir, luaPath)
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize path
|
||||
resolvedPath = filepath.Clean(resolvedPath)
|
||||
loadLuaLogger.Debug("Resolved Lua file path: %q", resolvedPath)
|
||||
|
||||
// Read the file
|
||||
content, err := os.ReadFile(resolvedPath)
|
||||
if err != nil {
|
||||
loadLuaLogger.Error("Failed to read Lua file %q: %v", resolvedPath, err)
|
||||
return "", fmt.Errorf("failed to read Lua file %q: %w", luaPath, err)
|
||||
}
|
||||
|
||||
loadLuaLogger.Debug("Successfully loaded %d bytes from Lua file %q", len(content), resolvedPath)
|
||||
return string(content), nil
|
||||
}
|
||||
|
||||
// BuildLuaScript prepares a Lua expression from shorthand notation
|
||||
func BuildLuaScript(luaExpr string) string {
|
||||
func BuildLuaScript(luaExpr string, sourceDir string) string {
|
||||
buildLuaScriptLogger := processorLogger.WithPrefix("BuildLuaScript").WithField("inputLuaExpr", luaExpr)
|
||||
buildLuaScriptLogger.Debug("Building full Lua script from expression")
|
||||
|
||||
// Check if this is an external Lua file reference
|
||||
if strings.HasPrefix(luaExpr, "@") {
|
||||
luaPath := strings.TrimPrefix(luaExpr, "@")
|
||||
externalLua, err := LoadExternalLuaFile(luaPath, sourceDir)
|
||||
if err != nil {
|
||||
buildLuaScriptLogger.Error("Failed to load external Lua file: %v", err)
|
||||
// Return error script that will fail at runtime
|
||||
return fmt.Sprintf(`error("Failed to load external Lua file: %v")`, err)
|
||||
}
|
||||
luaExpr = externalLua
|
||||
buildLuaScriptLogger.Debug("Loaded external Lua file, %d characters", len(luaExpr))
|
||||
}
|
||||
|
||||
// Perform $var substitutions from globalVariables
|
||||
luaExpr = replaceVariables(luaExpr)
|
||||
|
||||
@@ -228,10 +281,23 @@ func BuildLuaScript(luaExpr string) string {
|
||||
}
|
||||
|
||||
// BuildJSONLuaScript prepares a Lua expression for JSON mode
|
||||
func BuildJSONLuaScript(luaExpr string) string {
|
||||
func BuildJSONLuaScript(luaExpr string, sourceDir string) string {
|
||||
buildJSONLuaScriptLogger := processorLogger.WithPrefix("BuildJSONLuaScript").WithField("inputLuaExpr", luaExpr)
|
||||
buildJSONLuaScriptLogger.Debug("Building full Lua script for JSON mode from expression")
|
||||
|
||||
// Check if this is an external Lua file reference
|
||||
if strings.HasPrefix(luaExpr, "@") {
|
||||
luaPath := strings.TrimPrefix(luaExpr, "@")
|
||||
externalLua, err := LoadExternalLuaFile(luaPath, sourceDir)
|
||||
if err != nil {
|
||||
buildJSONLuaScriptLogger.Error("Failed to load external Lua file: %v", err)
|
||||
// Return error script that will fail at runtime
|
||||
return fmt.Sprintf(`error("Failed to load external Lua file: %v")`, err)
|
||||
}
|
||||
luaExpr = externalLua
|
||||
buildJSONLuaScriptLogger.Debug("Loaded external Lua file, %d characters", len(luaExpr))
|
||||
}
|
||||
|
||||
// Perform $var substitutions from globalVariables
|
||||
luaExpr = replaceVariables(luaExpr)
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ func TestBuildJSONLuaScript(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := BuildJSONLuaScript(tt.input)
|
||||
result := BuildJSONLuaScript(tt.input, "")
|
||||
for _, substr := range tt.contains {
|
||||
assert.Contains(t, result, substr)
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ func ProcessRegex(content string, command utils.ModifyCommand, filename string)
|
||||
// More important is that we don't fuck up the command
|
||||
// But we shouldn't be able to since it's passed by value
|
||||
previousLuaExpr := command.Lua
|
||||
luaExpr := BuildLuaScript(command.Lua)
|
||||
luaExpr := BuildLuaScript(command.Lua, command.SourceDir)
|
||||
processRegexLogger.Debug("Transformed Lua expression: %q → %q", previousLuaExpr, luaExpr)
|
||||
processRegexLogger.Trace("Full Lua script: %q", utils.LimitString(luaExpr, 200))
|
||||
|
||||
|
||||
@@ -252,7 +252,7 @@ func TestDecimalValues(t *testing.T) {
|
||||
`
|
||||
|
||||
regex := regexp.MustCompile(`(?s)<value>([0-9.]+)</value>.*?<multiplier>([0-9.]+)</multiplier>`)
|
||||
luaExpr := BuildLuaScript("v1 = v1 * v2")
|
||||
luaExpr := BuildLuaScript("v1 = v1 * v2", "")
|
||||
|
||||
result, _, _, err := APIAdaptor(content, regex.String(), luaExpr)
|
||||
assert.NoError(t, err, "Error processing content: %v", err)
|
||||
@@ -280,7 +280,7 @@ func TestLuaMathFunctions(t *testing.T) {
|
||||
`
|
||||
|
||||
regex := regexp.MustCompile(`(?s)<value>(\d+)</value>`)
|
||||
luaExpr := BuildLuaScript("v1 = math.sqrt(v1)")
|
||||
luaExpr := BuildLuaScript("v1 = math.sqrt(v1)", "")
|
||||
|
||||
modifiedContent, _, _, err := APIAdaptor(content, regex.String(), luaExpr)
|
||||
assert.NoError(t, err, "Error processing content: %v", err)
|
||||
@@ -308,7 +308,7 @@ func TestDirectAssignment(t *testing.T) {
|
||||
`
|
||||
|
||||
regex := regexp.MustCompile(`(?s)<value>(\d+)</value>`)
|
||||
luaExpr := BuildLuaScript("=0")
|
||||
luaExpr := BuildLuaScript("=0", "")
|
||||
|
||||
modifiedContent, _, _, err := APIAdaptor(content, regex.String(), luaExpr)
|
||||
assert.NoError(t, err, "Error processing content: %v", err)
|
||||
@@ -366,7 +366,7 @@ func TestStringAndNumericOperations(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Compile the regex pattern with multiline support
|
||||
pattern := "(?s)" + tt.regexPattern
|
||||
luaExpr := BuildLuaScript(tt.luaExpression)
|
||||
luaExpr := BuildLuaScript(tt.luaExpression, "")
|
||||
|
||||
// Process with our function
|
||||
result, modCount, _, err := APIAdaptor(tt.input, pattern, luaExpr)
|
||||
@@ -427,7 +427,7 @@ func TestEdgeCases(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Make sure the regex can match across multiple lines
|
||||
pattern := "(?s)" + tt.regexPattern
|
||||
luaExpr := BuildLuaScript(tt.luaExpression)
|
||||
luaExpr := BuildLuaScript(tt.luaExpression, "")
|
||||
|
||||
// Process with our function
|
||||
result, modCount, _, err := APIAdaptor(tt.input, pattern, luaExpr)
|
||||
|
||||
@@ -428,7 +428,7 @@ func ProcessXML(content string, command utils.ModifyCommand, filename string) ([
|
||||
processXMLLogger.Debug("Set XML data as Lua global 'root'")
|
||||
|
||||
// Build and execute Lua script
|
||||
luaExpr := BuildJSONLuaScript(command.Lua) // Reuse JSON script builder
|
||||
luaExpr := BuildJSONLuaScript(command.Lua, command.SourceDir) // Reuse JSON script builder
|
||||
processXMLLogger.Debug("Built Lua script from expression: %q", command.Lua)
|
||||
|
||||
if err := L.DoString(luaExpr); err != nil {
|
||||
|
||||
@@ -16,17 +16,18 @@ import (
|
||||
var modifyCommandLogger = logger.Default.WithPrefix("utils/modifycommand")
|
||||
|
||||
type ModifyCommand struct {
|
||||
Name string `yaml:"name,omitempty" toml:"name,omitempty"`
|
||||
Regex string `yaml:"regex,omitempty" toml:"regex,omitempty"`
|
||||
Regexes []string `yaml:"regexes,omitempty" toml:"regexes,omitempty"`
|
||||
Lua string `yaml:"lua,omitempty" toml:"lua,omitempty"`
|
||||
Files []string `yaml:"files,omitempty" toml:"files,omitempty"`
|
||||
Reset bool `yaml:"reset,omitempty" toml:"reset,omitempty"`
|
||||
LogLevel string `yaml:"loglevel,omitempty" toml:"loglevel,omitempty"`
|
||||
Isolate bool `yaml:"isolate,omitempty" toml:"isolate,omitempty"`
|
||||
NoDedup bool `yaml:"nodedup,omitempty" toml:"nodedup,omitempty"`
|
||||
Disabled bool `yaml:"disable,omitempty" toml:"disable,omitempty"`
|
||||
JSON bool `yaml:"json,omitempty" toml:"json,omitempty"`
|
||||
Name string `yaml:"name,omitempty" toml:"name,omitempty"`
|
||||
Regex string `yaml:"regex,omitempty" toml:"regex,omitempty"`
|
||||
Regexes []string `yaml:"regexes,omitempty" toml:"regexes,omitempty"`
|
||||
Lua string `yaml:"lua,omitempty" toml:"lua,omitempty"`
|
||||
Files []string `yaml:"files,omitempty" toml:"files,omitempty"`
|
||||
Reset bool `yaml:"reset,omitempty" toml:"reset,omitempty"`
|
||||
LogLevel string `yaml:"loglevel,omitempty" toml:"loglevel,omitempty"`
|
||||
Isolate bool `yaml:"isolate,omitempty" toml:"isolate,omitempty"`
|
||||
NoDedup bool `yaml:"nodedup,omitempty" toml:"nodedup,omitempty"`
|
||||
Disabled bool `yaml:"disable,omitempty" toml:"disable,omitempty"`
|
||||
JSON bool `yaml:"json,omitempty" toml:"json,omitempty"`
|
||||
SourceDir string `yaml:"-" toml:"-"` // Directory of the config file that loaded this command
|
||||
}
|
||||
|
||||
type CookFile []ModifyCommand
|
||||
@@ -331,6 +332,11 @@ func LoadCommandsFromCookFiles(pattern string) ([]ModifyCommand, map[string]inte
|
||||
loadCookFilesLogger.Error("Failed to load commands from cook file data for %q: %v", cookFile, err)
|
||||
return nil, nil, fmt.Errorf("failed to load commands from cook file: %w", err)
|
||||
}
|
||||
// Set source directory for each command
|
||||
sourceDir := filepath.Dir(cookFile)
|
||||
for i := range newCommands {
|
||||
newCommands[i].SourceDir = sourceDir
|
||||
}
|
||||
commands = append(commands, newCommands...)
|
||||
for k, v := range newVariables {
|
||||
variables[k] = v
|
||||
@@ -429,6 +435,11 @@ func LoadCommandsFromTomlFiles(pattern string) ([]ModifyCommand, map[string]inte
|
||||
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)
|
||||
}
|
||||
// Set source directory for each command
|
||||
sourceDir := filepath.Dir(tomlFile)
|
||||
for i := range newCommands {
|
||||
newCommands[i].SourceDir = sourceDir
|
||||
}
|
||||
commands = append(commands, newCommands...)
|
||||
for k, v := range newVariables {
|
||||
variables[k] = v
|
||||
|
||||
Reference in New Issue
Block a user