github.com/franciscocpg/glide@v0.0.0-20160823235512-96aa2921b647/action/ensure.go (about)

     1  package action
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"os/exec"
     7  	"path"
     8  	"path/filepath"
     9  	"strings"
    10  
    11  	"github.com/Masterminds/glide/cfg"
    12  	"github.com/Masterminds/glide/mirrors"
    13  	"github.com/Masterminds/glide/msg"
    14  	gpath "github.com/Masterminds/glide/path"
    15  	"github.com/Masterminds/glide/util"
    16  )
    17  
    18  // EnsureConfig loads and returns a config file.
    19  //
    20  // Any error will cause an immediate exit, with an error printed to Stderr.
    21  func EnsureConfig() *cfg.Config {
    22  	yamlpath, err := gpath.Glide()
    23  	if err != nil {
    24  		msg.ExitCode(2)
    25  		msg.Die("Failed to find %s file in directory tree: %s", gpath.GlideFile, err)
    26  	}
    27  
    28  	yml, err := ioutil.ReadFile(yamlpath)
    29  	if err != nil {
    30  		msg.ExitCode(2)
    31  		msg.Die("Failed to load %s: %s", yamlpath, err)
    32  	}
    33  	conf, err := cfg.ConfigFromYaml(yml)
    34  	if err != nil {
    35  		msg.ExitCode(3)
    36  		msg.Die("Failed to parse %s: %s", yamlpath, err)
    37  	}
    38  
    39  	b := filepath.Dir(yamlpath)
    40  	buildContext, err := util.GetBuildContext()
    41  	if err != nil {
    42  		msg.Die("Failed to build an import context while ensuring config: %s", err)
    43  	}
    44  	cwd, err := os.Getwd()
    45  	if err != nil {
    46  		msg.Err("Unable to get the current working directory")
    47  	} else {
    48  		// Determining a package name requires a relative path
    49  		b, err = filepath.Rel(b, cwd)
    50  		if err == nil {
    51  			name := buildContext.PackageName(b)
    52  			if name != conf.Name {
    53  				msg.Warn("The name listed in the config file (%s) does not match the current location (%s)", conf.Name, name)
    54  			}
    55  		} else {
    56  			msg.Warn("Problem finding the config file path (%s) relative to the current directory (%s): %s", b, cwd, err)
    57  		}
    58  	}
    59  
    60  	err = mirrors.Load()
    61  	if err != nil {
    62  		msg.Err("Unable to load mirrors: %s", err)
    63  	}
    64  
    65  	return conf
    66  }
    67  
    68  // EnsureGoVendor ensures that the Go version is correct.
    69  func EnsureGoVendor() {
    70  	// 6l was removed in 1.5, when vendoring was introduced.
    71  	cmd := exec.Command(goExecutable(), "tool", "6l")
    72  	if _, err := cmd.CombinedOutput(); err == nil {
    73  		msg.Warn("You must install the Go 1.5 or greater toolchain to work with Glide.\n")
    74  		os.Exit(1)
    75  	}
    76  
    77  	// Check if this is go15, which requires GO15VENDOREXPERIMENT
    78  	// Any release after go15 does not require that env var.
    79  	cmd = exec.Command(goExecutable(), "version")
    80  	if out, err := cmd.CombinedOutput(); err != nil {
    81  		msg.Err("Error getting version: %s.\n", err)
    82  		os.Exit(1)
    83  	} else if strings.HasPrefix(string(out), "go version 1.5") {
    84  		// This works with 1.5 and 1.6.
    85  		cmd = exec.Command(goExecutable(), "env", "GO15VENDOREXPERIMENT")
    86  		if out, err := cmd.CombinedOutput(); err != nil {
    87  			msg.Err("Error looking for $GOVENDOREXPERIMENT: %s.\n", err)
    88  			os.Exit(1)
    89  		} else if strings.TrimSpace(string(out)) != "1" {
    90  			msg.Err("To use Glide, you must set GO15VENDOREXPERIMENT=1")
    91  			os.Exit(1)
    92  		}
    93  	}
    94  
    95  	// In the case where vendoring is explicitly disabled, balk.
    96  	if os.Getenv("GO15VENDOREXPERIMENT") == "0" {
    97  		msg.Err("To use Glide, you must set GO15VENDOREXPERIMENT=1")
    98  		os.Exit(1)
    99  	}
   100  
   101  	// Verify the setup isn't for the old version of glide. That is, this is
   102  	// no longer assuming the _vendor directory as the GOPATH. Inform of
   103  	// the change.
   104  	if _, err := os.Stat("_vendor/"); err == nil {
   105  		msg.Warn(`Your setup appears to be for the previous version of Glide.
   106  Previously, vendor packages were stored in _vendor/src/ and
   107  _vendor was set as your GOPATH. As of Go 1.5 the go tools
   108  recognize the vendor directory as a location for these
   109  files. Glide has embraced this. Please remove the _vendor
   110  directory or move the _vendor/src/ directory to vendor/.` + "\n")
   111  		os.Exit(1)
   112  	}
   113  }
   114  
   115  // EnsureVendorDir ensures that a vendor/ directory is present in the cwd.
   116  func EnsureVendorDir() {
   117  	fi, err := os.Stat(gpath.VendorDir)
   118  	if err != nil {
   119  		msg.Debug("Creating %s", gpath.VendorDir)
   120  		if err := os.MkdirAll(gpath.VendorDir, os.ModeDir|0755); err != nil {
   121  			msg.Die("Could not create %s: %s", gpath.VendorDir, err)
   122  		}
   123  	} else if !fi.IsDir() {
   124  		msg.Die("Vendor is not a directory")
   125  	}
   126  }
   127  
   128  // EnsureGopath fails if GOPATH is not set, or if $GOPATH/src is missing.
   129  //
   130  // Otherwise it returns the value of GOPATH.
   131  func EnsureGopath() string {
   132  	gps := gpath.Gopaths()
   133  	if len(gps) == 0 {
   134  		msg.Die("$GOPATH is not set.")
   135  	}
   136  
   137  	for _, gp := range gps {
   138  		_, err := os.Stat(path.Join(gp, "src"))
   139  		if err != nil {
   140  			msg.Warn("%s", err)
   141  			continue
   142  		}
   143  		return gp
   144  	}
   145  
   146  	msg.Err("Could not find any of %s/src.\n", strings.Join(gps, "/src, "))
   147  	msg.Info("As of Glide 0.5/Go 1.5, this is required.\n")
   148  	msg.Die("Without src, cannot continue.")
   149  	return ""
   150  }
   151  
   152  // goExecutable checks for a set environment variable of GLIDE_GO_EXECUTABLE
   153  // for the go executable name. The Google App Engine SDK ships with a python
   154  // wrapper called goapp
   155  //
   156  // Example usage: GLIDE_GO_EXECUTABLE=goapp glide install
   157  func goExecutable() string {
   158  	goExecutable := os.Getenv("GLIDE_GO_EXECUTABLE")
   159  	if len(goExecutable) <= 0 {
   160  		goExecutable = "go"
   161  	}
   162  
   163  	return goExecutable
   164  }