github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/cmd/getgo/main.go (about) 1 // Copyright 2017 The Go 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 //go:build !plan9 6 // +build !plan9 7 8 // The getgo command installs Go to the user's system. 9 package main 10 11 import ( 12 "bufio" 13 "context" 14 "errors" 15 "flag" 16 "fmt" 17 exec "golang.org/x/sys/execabs" 18 "os" 19 "strings" 20 ) 21 22 var ( 23 interactive = flag.Bool("i", false, "Interactive mode, prompt for inputs.") 24 verbose = flag.Bool("v", false, "Verbose.") 25 setupOnly = flag.Bool("skip-dl", false, "Don't download - only set up environment variables") 26 goVersion = flag.String("version", "", `Version of Go to install (e.g. "1.8.3"). If empty, uses the latest version.`) 27 28 version = "devel" 29 ) 30 31 var errExitCleanly error = errors.New("exit cleanly sentinel value") 32 33 func main() { 34 flag.Parse() 35 if *goVersion != "" && !strings.HasPrefix(*goVersion, "go") { 36 *goVersion = "go" + *goVersion 37 } 38 39 ctx := context.Background() 40 41 verbosef("version " + version) 42 43 runStep := func(s step) { 44 err := s(ctx) 45 if err == errExitCleanly { 46 os.Exit(0) 47 } 48 if err != nil { 49 fmt.Fprintln(os.Stderr, err) 50 os.Exit(2) 51 } 52 } 53 54 if !*setupOnly { 55 runStep(welcome) 56 runStep(checkOthers) 57 runStep(chooseVersion) 58 runStep(downloadGo) 59 } 60 61 runStep(setupGOPATH) 62 } 63 64 func verbosef(format string, v ...interface{}) { 65 if !*verbose { 66 return 67 } 68 69 fmt.Printf(format+"\n", v...) 70 } 71 72 func prompt(ctx context.Context, query, defaultAnswer string) (string, error) { 73 if !*interactive { 74 return defaultAnswer, nil 75 } 76 77 fmt.Printf("%s [%s]: ", query, defaultAnswer) 78 79 type result struct { 80 answer string 81 err error 82 } 83 ch := make(chan result, 1) 84 go func() { 85 s := bufio.NewScanner(os.Stdin) 86 if !s.Scan() { 87 ch <- result{"", s.Err()} 88 return 89 } 90 answer := s.Text() 91 if answer == "" { 92 answer = defaultAnswer 93 } 94 ch <- result{answer, nil} 95 }() 96 97 select { 98 case r := <-ch: 99 return r.answer, r.err 100 case <-ctx.Done(): 101 return "", ctx.Err() 102 } 103 } 104 105 func runCommand(ctx context.Context, prog string, args ...string) ([]byte, error) { 106 verbosef("Running command: %s %v", prog, args) 107 108 cmd := exec.CommandContext(ctx, prog, args...) 109 out, err := cmd.CombinedOutput() 110 if err != nil { 111 return nil, fmt.Errorf("running cmd '%s %s' failed: %s err: %v", prog, strings.Join(args, " "), string(out), err) 112 } 113 if out != nil && err == nil && len(out) != 0 { 114 verbosef("%s", out) 115 } 116 117 return out, nil 118 }