Rework rounding and building lua script
To allow user script to specify what was modified where
This commit is contained in:
@@ -7,7 +7,6 @@ import (
|
|||||||
"modify/processor/jsonpath"
|
"modify/processor/jsonpath"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
|
|
||||||
lua "github.com/yuin/gopher-lua"
|
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
|
return content, 0, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
modCount := 0
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
log.Printf("Processing node at path: %s with value: %v", node.Path, node.Value)
|
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)
|
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
|
// Execute Lua script
|
||||||
log.Printf("Executing Lua script: %s", luaExpr)
|
log.Printf("Executing Lua script: %q", fullScript)
|
||||||
if err := L.DoString(luaExpr); err != nil {
|
if err := L.DoString(fullScript); err != nil {
|
||||||
return content, len(nodes), 0, fmt.Errorf("error executing Lua %s: %v", luaExpr, err)
|
return content, len(nodes), 0, fmt.Errorf("error executing Lua %q: %v", fullScript, err)
|
||||||
}
|
}
|
||||||
log.Println("Lua script executed successfully.")
|
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)
|
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
|
// Apply the modification to the JSON data
|
||||||
err = p.updateJSONValue(jsonData, node.Path, result)
|
err = p.updateJSONValue(jsonData, node.Path, result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return content, len(nodes), 0, fmt.Errorf("error updating JSON: %v", err)
|
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)
|
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
|
// Convert the modified JSON back to a string with same formatting
|
||||||
var jsonBytes []byte
|
var jsonBytes []byte
|
||||||
if indent, err := detectJsonIndentation(content); err == nil && indent != "" {
|
jsonBytes, err = json.MarshalIndent(jsonData, "", " ")
|
||||||
// Use detected indentation for output formatting
|
if err != nil {
|
||||||
jsonBytes, err = json.MarshalIndent(jsonData, "", indent)
|
return content, len(nodes), 0, fmt.Errorf("error marshalling JSON: %v", err)
|
||||||
} else {
|
|
||||||
// Fall back to standard 2-space indent
|
|
||||||
jsonBytes, err = json.MarshalIndent(jsonData, "", " ")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We changed all the nodes trust me bro
|
// We changed all the nodes trust me bro
|
||||||
return string(jsonBytes), len(nodes), len(nodes), nil
|
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 from the root node
|
||||||
// // Selects nodes in the document from the current node that match the selection no matter where they are
|
// // Selects nodes in the document from the current node that match the selection no matter where they are
|
||||||
// . Selects the current node
|
// . Selects the current node
|
||||||
|
@@ -129,7 +129,10 @@ func InitLuaHelpers(L *lua.LState) error {
|
|||||||
-- Custom Lua helpers for math operations
|
-- Custom Lua helpers for math operations
|
||||||
function min(a, b) return math.min(a, b) end
|
function min(a, b) return math.min(a, b) end
|
||||||
function max(a, b) return math.max(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 floor(x) return math.floor(x) end
|
||||||
function ceil(x) return math.ceil(x) end
|
function ceil(x) return math.ceil(x) end
|
||||||
function upper(s) return string.upper(s) end
|
function upper(s) return string.upper(s) end
|
||||||
@@ -149,6 +152,8 @@ end
|
|||||||
function is_number(str)
|
function is_number(str)
|
||||||
return tonumber(str) ~= nil
|
return tonumber(str) ~= nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
modified = false
|
||||||
`
|
`
|
||||||
if err := L.DoString(helperScript); err != nil {
|
if err := L.DoString(helperScript); err != nil {
|
||||||
return fmt.Errorf("error loading helper functions: %v", err)
|
return fmt.Errorf("error loading helper functions: %v", err)
|
||||||
@@ -187,7 +192,21 @@ func BuildLuaScript(luaExpr string) string {
|
|||||||
luaExpr = "v1 = " + luaExpr
|
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
|
// Max returns the maximum of two integers
|
||||||
|
Reference in New Issue
Block a user