Rework rounding and building lua script

To allow user script to specify what was modified where
This commit is contained in:
2025-03-25 18:28:28 +01:00
parent 1b0b198297
commit db92033642
2 changed files with 40 additions and 37 deletions

View File

@@ -7,7 +7,6 @@ import (
"modify/processor/jsonpath"
"os"
"path/filepath"
"strings"
lua "github.com/yuin/gopher-lua"
)
@@ -68,6 +67,7 @@ func (p *JSONProcessor) ProcessContent(content string, pattern string, luaExpr s
return content, 0, 0, nil
}
modCount := 0
for _, node := range nodes {
log.Printf("Processing node at path: %s with value: %v", node.Path, node.Value)
@@ -85,10 +85,14 @@ func (p *JSONProcessor) ProcessContent(content string, pattern string, luaExpr s
}
log.Printf("Converted node value to Lua: %v", node.Value)
originalScript := luaExpr
fullScript := BuildLuaScript(luaExpr)
log.Printf("Original script: %q, Full script: %q", originalScript, fullScript)
// Execute Lua script
log.Printf("Executing Lua script: %s", luaExpr)
if err := L.DoString(luaExpr); err != nil {
return content, len(nodes), 0, fmt.Errorf("error executing Lua %s: %v", luaExpr, err)
log.Printf("Executing Lua script: %q", fullScript)
if err := L.DoString(fullScript); err != nil {
return content, len(nodes), 0, fmt.Errorf("error executing Lua %q: %v", fullScript, err)
}
log.Println("Lua script executed successfully.")
@@ -99,53 +103,33 @@ func (p *JSONProcessor) ProcessContent(content string, pattern string, luaExpr s
}
log.Printf("Retrieved modified value from Lua: %v", result)
modified := false
modified = L.GetGlobal("modified").String() == "true"
if !modified {
log.Printf("No changes made to node at path: %s", node.Path)
continue
}
// Apply the modification to the JSON data
err = p.updateJSONValue(jsonData, node.Path, result)
if err != nil {
return content, len(nodes), 0, fmt.Errorf("error updating JSON: %v", err)
}
log.Printf("Updated JSON at path: %s with new value: %v", node.Path, result)
modCount++
}
// Convert the modified JSON back to a string with same formatting
var jsonBytes []byte
if indent, err := detectJsonIndentation(content); err == nil && indent != "" {
// Use detected indentation for output formatting
jsonBytes, err = json.MarshalIndent(jsonData, "", indent)
} else {
// Fall back to standard 2-space indent
jsonBytes, err = json.MarshalIndent(jsonData, "", " ")
jsonBytes, err = json.MarshalIndent(jsonData, "", " ")
if err != nil {
return content, len(nodes), 0, fmt.Errorf("error marshalling JSON: %v", err)
}
// We changed all the nodes trust me bro
return string(jsonBytes), len(nodes), len(nodes), nil
}
// detectJsonIndentation tries to determine the indentation used in the original JSON
func detectJsonIndentation(content string) (string, error) {
lines := strings.Split(content, "\n")
if len(lines) < 2 {
return "", fmt.Errorf("not enough lines to detect indentation")
}
// Look for the first indented line
for i := 1; i < len(lines); i++ {
line := lines[i]
trimmed := strings.TrimSpace(line)
if trimmed == "" {
continue
}
// Calculate leading whitespace
indent := line[:len(line)-len(trimmed)]
if len(indent) > 0 {
return indent, nil
}
}
return "", fmt.Errorf("no indentation detected")
}
// / Selects from the root node
// // Selects nodes in the document from the current node that match the selection no matter where they are
// . Selects the current node

View File

@@ -129,7 +129,10 @@ func InitLuaHelpers(L *lua.LState) error {
-- Custom Lua helpers for math operations
function min(a, b) return math.min(a, b) end
function max(a, b) return math.max(a, b) end
function round(x) return math.floor(x + 0.5) end
function round(x, n)
if n == nil then n = 0 end
return math.floor(x * 10^n + 0.5) / 10^n
end
function floor(x) return math.floor(x) end
function ceil(x) return math.ceil(x) end
function upper(s) return string.upper(s) end
@@ -149,6 +152,8 @@ end
function is_number(str)
return tonumber(str) ~= nil
end
modified = false
`
if err := L.DoString(helperScript); err != nil {
return fmt.Errorf("error loading helper functions: %v", err)
@@ -187,7 +192,21 @@ func BuildLuaScript(luaExpr string) string {
luaExpr = "v1 = " + luaExpr
}
return luaExpr
// This allows the user to specify whether or not they modified a value
// If they do nothing we assume they did modify (no return at all)
// If they return before our return then they themselves specify what they did
// If nothing is returned lua assumes nil
// So we can say our value was modified if the return value is either nil or true
// If the return value is false then the user wants to keep the original
fullScript := fmt.Sprintf(`
function run()
%s
end
local res = run()
modified = res == nil or res
`, luaExpr)
return fullScript
}
// Max returns the maximum of two integers