Skip to content

Commit ce4c3b3

Browse files
committed
Add flag -o to just build a binary
Closes #15.
1 parent f2dbb25 commit ce4c3b3

File tree

2 files changed

+73
-16
lines changed

2 files changed

+73
-16
lines changed

main.go

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -137,19 +137,24 @@ func runTime(cmd *exec.Cmd) error {
137137
}
138138

139139
func gorun(srcFilename string, env []string, buildDir string, runDir string, args ...string) error {
140-
exeDir, err := os.MkdirTemp("", "goeval*")
141-
if err != nil {
142-
return err
143-
}
144-
defer func() {
145-
if err := os.RemoveAll(exeDir); err != nil {
146-
log.Printf("RemoveAll(%q): %v", exeDir, err)
140+
exePath := buildOutput
141+
if exePath == "" {
142+
143+
exeDir, err := os.MkdirTemp("", "goeval*")
144+
if err != nil {
145+
return err
147146
}
148-
}()
149147

150-
exePath := filepath.Join(exeDir, "goeval-run")
151-
if runtime.GOOS == "windows" {
152-
exePath += ".exe"
148+
defer func() {
149+
if err := os.RemoveAll(exeDir); err != nil {
150+
log.Printf("RemoveAll(%q): %v", exeDir, err)
151+
}
152+
}()
153+
154+
filepath.Join(exeDir, "goeval-run")
155+
if runtime.GOOS == "windows" {
156+
exePath += ".exe"
157+
}
153158
}
154159

155160
cmdBuild := exec.Command(goCmd, "build",
@@ -171,6 +176,11 @@ func gorun(srcFilename string, env []string, buildDir string, runDir string, arg
171176
return fmt.Errorf("failed to build: %w", err)
172177
}
173178

179+
// actionBuild: don't run
180+
if buildOutput != "" {
181+
return nil
182+
}
183+
174184
cmdRun := exec.Command(exePath, args...)
175185
cmdRun.Env = env
176186
cmdRun.Dir = runDir // In Go module mode we run from the temp module dir
@@ -212,6 +222,7 @@ type actionBits uint
212222

213223
const (
214224
actionRun actionBits = iota
225+
actionBuild // -o ...
215226
actionDump // -E
216227
actionDumpPlay // -Eplay
217228
actionPlay // -play
@@ -220,15 +231,20 @@ const (
220231
actionDefault = actionRun
221232
)
222233

223-
var action actionBits
234+
var (
235+
action actionBits
236+
buildOutput string // -o
237+
238+
errActionExclusive = errors.New("flags -o, -E, -Eplay, -play and -share are exclusive")
239+
)
224240

225241
func flagAction(name string, a actionBits, target *string, usage string) {
226242
flag.BoolFunc(name, usage, func(value string) error {
227243
if target == nil && value != "true" {
228244
return errors.New("no value expected")
229245
}
230246
if action != actionDefault {
231-
return errors.New("flags -E, -Eplay, -play and -share are exclusive")
247+
return errActionExclusive
232248
}
233249
action = a
234250
return nil
@@ -256,6 +272,18 @@ func _main() error {
256272

257273
// TODO allow to optionally set a different endpoint for the Go Playground
258274

275+
flag.Func("o", "just build a binary, don't execute.", func(value string) (err error) {
276+
if action != actionDefault {
277+
return errActionExclusive
278+
}
279+
if value == "" {
280+
return errors.New("invalid empty output file")
281+
}
282+
action = actionBuild
283+
buildOutput, err = filepath.Abs(value)
284+
return
285+
})
286+
259287
showCmds := flag.Bool("x", false, "print commands executed.")
260288

261289
flag.Usage = func() {
@@ -294,7 +322,7 @@ func _main() error {
294322
args := flag.Args()[1:]
295323
if len(args) > 0 {
296324
switch action {
297-
case actionDump:
325+
case actionBuild, actionDump:
298326
return errors.New("arguments not expected")
299327
}
300328
}
@@ -445,7 +473,7 @@ func _main() error {
445473
tail func() error
446474
)
447475
switch action {
448-
case actionRun:
476+
case actionRun, actionBuild:
449477
f, err := os.CreateTemp(dir, "*.go")
450478
if err != nil {
451479
log.Fatal(err)
@@ -521,7 +549,7 @@ func _main() error {
521549
*/
522550

523551
// dump go.mod, go.sum
524-
if moduleMode && action != actionRun {
552+
if moduleMode && action >= actionDump {
525553
gomod, err := os.Open(dir + "/go.mod")
526554
if err != nil {
527555
log.Fatal(err)

main_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"bytes"
2121
"os"
2222
"os/exec"
23+
"path/filepath"
24+
"runtime"
2325
"testing"
2426
)
2527

@@ -126,3 +128,30 @@ func TestPrintStack(t *testing.T) {
126128
// PrintStack sends output to stderr
127129
goevalPrint(t.Log, t.Log, `-i=runtime/debug`, `-goimports=`, `debug.PrintStack()`)
128130
}
131+
132+
// Test "goeval -o ..."
133+
func TestBuild(t *testing.T) {
134+
tempDir := t.TempDir()
135+
136+
exe := filepath.Join(tempDir, "x")
137+
if runtime.GOOS == "windows" {
138+
exe += ".exe"
139+
}
140+
t.Logf("Building %q...", exe)
141+
142+
goevalT(t, `-o`, exe, `fmt.Print(os.Args[1])`)
143+
144+
_, err := os.Stat(exe)
145+
if err != nil {
146+
t.Fatalf(`%q: %v`, exe, err)
147+
}
148+
149+
cmd := exec.Command(exe, `toto`)
150+
out, err := cmd.Output()
151+
if err != nil {
152+
t.Fatalf(`exec(%q): %v`, exe, err)
153+
}
154+
if string(out) != "toto" {
155+
t.Errorf(`output: got %q, expected "toto"`, out)
156+
}
157+
}

0 commit comments

Comments
 (0)