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