github.com/jlowellwofford/u-root@v1.0.0/xcmds/run/run.go (about) 1 // Copyright 2012-2017 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Run executes its arguments as a Go program. 6 // 7 // Synopsis: 8 // run [-v] GO_CODE.. 9 // 10 // Examples: 11 // run {fmt.Println("hello")} 12 // 13 // Options: 14 // -v: verbose display of processing 15 package main 16 17 import ( 18 "flag" 19 "log" 20 "os" 21 "os/exec" 22 23 "golang.org/x/tools/imports" 24 ) 25 26 var verbose = flag.Bool("v", false, "Verbose display of processing") 27 28 func main() { 29 opts := imports.Options{ 30 Fragment: true, 31 AllErrors: true, 32 Comments: true, 33 TabIndent: true, 34 TabWidth: 8, 35 } 36 flag.Parse() 37 // Interesting problem: 38 // We want a combination of args and arbitrary Go code. 39 // Possibly, we should take the entire Go code as the one arg, 40 // i.e. in a 'string', and then take the args following. 41 a := "func main()" 42 for _, v := range flag.Args() { 43 a = a + v 44 } 45 if *verbose { 46 log.Printf("Pre-import version: '%v'", a) 47 } 48 goCode, err := imports.Process("commandline", []byte(a), &opts) 49 if err != nil { 50 log.Fatalf("bad parse: '%v': %v", a, err) 51 } 52 if *verbose { 53 log.Printf("Post-import version: '%v'", string(goCode)) 54 } 55 56 // of course we have to deal with the Unix issue that /tmp is not private. 57 f, err := TempFile("", "run%s.go") 58 if err != nil { 59 log.Fatalf("Script: opening TempFile: %v", err) 60 } 61 62 if _, err := f.Write([]byte(goCode)); err != nil { 63 log.Fatalf("Script: Writing %v: %v", f, err) 64 } 65 if err := f.Close(); err != nil { 66 log.Fatalf("Script: Closing %v: %v", f, err) 67 } 68 69 os.Setenv("GOBIN", "/tmp") 70 cmd := exec.Command("go", "install", "-x", f.Name()) 71 cmd.Dir = "/" 72 73 cmd.Stdin = os.Stdin 74 cmd.Stderr = os.Stderr 75 cmd.Stdout = os.Stdout 76 log.Printf("Install %v", f.Name()) 77 if err = cmd.Run(); err != nil { 78 log.Printf("%v\n", err) 79 } 80 81 // stupid, but hey ... 82 execName := f.Name() 83 // strip .go from the name. 84 execName = execName[:len(execName)-3] 85 cmd = exec.Command(execName) 86 cmd.Dir = "/tmp" 87 88 cmd.Stdin = os.Stdin 89 cmd.Stderr = os.Stderr 90 cmd.Stdout = os.Stdout 91 log.Printf("Run %v", f.Name()) 92 if err := cmd.Run(); err != nil { 93 log.Printf("%v\n", err) 94 } 95 96 }