Files
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

64 lines
1.8 KiB
Go

package main
import (
"encoding/json"
"fmt"
"io"
"os"
"strings"
)
// readStructuredArg resolves a JSON argument from, in precedence order:
//
// 1. the inline value, when non-empty and not "-"
// 2. the file path, when non-empty
// 3. stdin, when the inline value is exactly "-"
//
// It is the shared lowering primitive for the edit verb's JSON-shaped
// parameters (verify_change's changes, preview_edit's workspace_edit,
// simulate_chain's steps, batch_edit's edits, change_contract's ranges).
// The returned value is the verbatim JSON bytes (validated as syntactically
// well-formed JSON); the caller decides whether to forward it as a string or
// a parsed value. An empty result (no source provided) returns (nil, nil) so
// the caller can decide whether the argument is required.
//
// stdinReader is injected so tests can drive the "-" path without touching
// the process's real stdin; nil falls back to os.Stdin.
func readStructuredArg(inline, file string, stdinReader io.Reader) (json.RawMessage, error) {
var (
data []byte
source string
)
switch {
case inline == "-":
r := stdinReader
if r == nil {
r = os.Stdin
}
b, err := io.ReadAll(r)
if err != nil {
return nil, fmt.Errorf("reading JSON from stdin: %w", err)
}
data, source = b, "stdin"
case inline != "":
data, source = []byte(inline), "inline JSON"
case file != "":
b, err := os.ReadFile(file)
if err != nil {
return nil, fmt.Errorf("reading JSON file %s: %w", file, err)
}
data, source = b, fmt.Sprintf("file %s", file)
default:
return nil, nil
}
trimmed := strings.TrimSpace(string(data))
if trimmed == "" {
return nil, fmt.Errorf("%s is empty", source)
}
if !json.Valid([]byte(trimmed)) {
return nil, fmt.Errorf("%s is not valid JSON", source)
}
return json.RawMessage(trimmed), nil
}