diff --git a/cmd/utils.go b/cmd/utils.go index 553fc994..e354faa5 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -246,6 +246,20 @@ func maybeFile(str string) bool { return result } +func expressionLikeArg(str string) bool { + return strings.HasPrefix(str, ".") && !strings.HasPrefix(str, "./") && !strings.HasPrefix(str, "../") +} + +func firstArgIsExpression(args []string, firstArgIsFile bool) bool { + if len(args) == 0 || args[0] == "-" { + return false + } + if !firstArgIsFile { + return true + } + return len(args) > 1 && expressionLikeArg(args[0]) +} + func processStdInArgs(args []string) []string { stat, err := os.Stdin.Stat() if err != nil { @@ -295,7 +309,7 @@ func processArgs(originalArgs []string) (string, []string, error) { } yqlib.GetLogger().Debugf("processed args: %v", args) - if expression == "" && len(args) > 0 && args[0] != "-" && !maybeFile(args[0]) { + if expression == "" && firstArgIsExpression(args, maybeFirstArgIsAFile) { yqlib.GetLogger().Debugf("assuming expression is '%v'", args[0]) expression = args[0] args = args[1:] diff --git a/cmd/utils_test.go b/cmd/utils_test.go index c87af958..44d3bf56 100644 --- a/cmd/utils_test.go +++ b/cmd/utils_test.go @@ -77,6 +77,9 @@ func TestMaybeFile(t *testing.T) { } func TestProcessArgs(t *testing.T) { + workDir := t.TempDir() + t.Chdir(workDir) + // Create a temporary file for testing tempFile, err := os.CreateTemp("", "test") if err != nil { @@ -96,6 +99,13 @@ func TestProcessArgs(t *testing.T) { } tempYqFile.Close() + if err := os.WriteFile(".version", []byte("boom"), 0o600); err != nil { + t.Fatalf("Failed to write .version file: %v", err) + } + if err := os.WriteFile("data.yml", []byte("version: 1.1.1"), 0o600); err != nil { + t.Fatalf("Failed to write data.yml file: %v", err) + } + tests := []struct { name string args []string @@ -132,6 +142,33 @@ func TestProcessArgs(t *testing.T) { expectedArgs: []string{"file1"}, expectError: false, }, + { + name: "expression-looking file as first arg before file", + args: []string{".version", "data.yml"}, + forceExpression: "", + expressionFile: "", + expectedExpr: ".version", + expectedArgs: []string{"data.yml"}, + expectError: false, + }, + { + name: "expression-looking file as first arg before stdin", + args: []string{".version", "-"}, + forceExpression: "", + expressionFile: "", + expectedExpr: ".version", + expectedArgs: []string{"-"}, + expectError: false, + }, + { + name: "path-qualified expression-looking file stays file arg", + args: []string{"./.version", "data.yml"}, + forceExpression: "", + expressionFile: "", + expectedExpr: "", + expectedArgs: []string{"./.version", "data.yml"}, + expectError: false, + }, { name: "file as first arg", args: []string{tempFile.Name()},