In the following directory structure,
.
├── foo.go
├── go.mod
└── main.go
I have a foo.go
with a simple type definition:
package main
type Foo struct {
Baz string
}
If I run gofmt -r
from the command line to replace a variable name, it works:
> gofmt -r 'Foo -> Bar' foo.go
package main
type Bar struct {
Baz string
}
However, if I try to do this from main.go
with the program
package main
import (
"fmt"
"log"
"os/exec"
)
func main() {
combinedOutput, err := exec.Command("gofmt", "-r", "'Foo -> Bar'", "foo.go").CombinedOutput()
if err != nil {
log.Fatalf("gofmt foo.go: %v. Combined output: %s", err, combinedOutput)
}
fmt.Println(string(combinedOutput))
}
I get an error:
> go run main.go
2023/01/14 23:42:07 gofmt foo.go: exit status 2. Combined output: parsing pattern 'Foo at 1:1: rune literal not terminated
exit status 1
Any idea what is causing this?
You don't need to quote arguments to exec.Command
; quoting is a feature of your shell, and doesn't apply when you make system calls. It's also not necessary, because quoting is done to delineate arguments in the shell, but in exec.Command
, the arguments are separated as arguments to the function call.
Concretely:
exec.Command("gofmt", "-r", "'Foo -> Bar'", "foo.go")
should be
exec.Command("gofmt", "-r", "Foo -> Bar", "foo.go")