diff --git a/acceptance_tests/basic.sh b/acceptance_tests/basic.sh index 9e7e9c4a..f81f01c5 100755 --- a/acceptance_tests/basic.sh +++ b/acceptance_tests/basic.sh @@ -3,6 +3,7 @@ setUp() { rm test*.yml 2>/dev/null || true rm .xyz 2>/dev/null || true + rm instructions.txt 2>/dev/null || true } testBasicEvalRoundTrip() { @@ -26,7 +27,17 @@ testBasicExpressionMatchesFileName() { X=$(./yq ea --expression '.xyz' test.yml) assertEquals "123" "$X" +} +testBasicExpressionFromFile() { + ./yq -n ".xyz = 123" > test.yml + echo '.xyz = "meow" | .cool = "frog"' > instructions.txt + + X=$(./yq --from-file instructions.txt test.yml -o=j -I=0) + assertEquals '{"xyz":"meow","cool":"frog"}' "$X" + + X=$(./yq ea --from-file instructions.txt test.yml -o=j -I=0) + assertEquals '{"xyz":"meow","cool":"frog"}' "$X" } testBasicGitHubAction() { diff --git a/cmd/constant.go b/cmd/constant.go index 31e1c66b..818c1974 100644 --- a/cmd/constant.go +++ b/cmd/constant.go @@ -30,3 +30,5 @@ var splitFileExp = "" var completedSuccessfully = false var forceExpression = "" + +var expressionFile = "" diff --git a/cmd/evaluate_all_command.go b/cmd/evaluate_all_command.go index ae55b92b..b0b71ea1 100644 --- a/cmd/evaluate_all_command.go +++ b/cmd/evaluate_all_command.go @@ -126,7 +126,10 @@ func evaluateAll(cmd *cobra.Command, args []string) (cmdError error) { allAtOnceEvaluator := yqlib.NewAllAtOnceEvaluator() - expression, args := processArgs(pipingStdIn, args) + expression, args, err := processArgs(pipingStdIn, args) + if err != nil { + return err + } yqlib.GetLogger().Debugf("processed args: %v", args) switch len(args) { diff --git a/cmd/evalute_sequence_command.go b/cmd/evalute_sequence_command.go index 5c19c256..1a7b7013 100644 --- a/cmd/evalute_sequence_command.go +++ b/cmd/evalute_sequence_command.go @@ -143,7 +143,10 @@ func evaluateSequence(cmd *cobra.Command, args []string) (cmdError error) { } defer frontMatterHandler.CleanUp() } - expression, args := processArgs(pipingStdIn, args) + expression, args, err := processArgs(pipingStdIn, args) + if err != nil { + return err + } switch len(args) { case 0: diff --git a/cmd/root.go b/cmd/root.go index d53ed809..d4ea034c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -86,6 +86,8 @@ yq -i '.stuff = "foo"' myfile.yml # update myfile.yml inplace rootCmd.PersistentFlags().StringVarP(&splitFileExp, "split-exp", "s", "", "print each result (or doc) into a file named (exp). [exp] argument must return a string. You can use $index in the expression as the result counter.") + rootCmd.PersistentFlags().StringVarP(&expressionFile, "from-file", "", "", "Load expression from specified file.") + rootCmd.AddCommand( createEvaluateSequenceCommand(), createEvaluateAllCommand(), diff --git a/cmd/utils.go b/cmd/utils.go index feff0b8e..d2da6825 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -137,14 +137,22 @@ func processStdInArgs(pipingStdin bool, args []string) []string { return append(args, "-") } -func processArgs(pipingStdin bool, originalArgs []string) (string, []string) { +func processArgs(pipingStdin bool, originalArgs []string) (string, []string, error) { + expression := forceExpression + if expressionFile != "" { + expressionBytes, err := os.ReadFile(expressionFile) + if err != nil { + return "", nil, err + } + expression = string(expressionBytes) + } + args := processStdInArgs(pipingStdin, originalArgs) yqlib.GetLogger().Debugf("processed args: %v", args) - expression := forceExpression if expression == "" && len(args) > 0 && args[0] != "-" && !maybeFile(args[0]) { yqlib.GetLogger().Debug("assuming expression is '%v'", args[0]) expression = args[0] args = args[1:] } - return expression, args + return expression, args, nil }