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