github.com/dahs81/otto@v0.2.1-0.20160126165905-6400716cf085/builtin/app/go/gopath.go (about)

     1  package goapp
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  
     9  	"github.com/hashicorp/otto/app"
    10  )
    11  
    12  // DetectImportPath will try to automatically determine the import path
    13  // for the Go application under development.
    14  //
    15  // This is necessary to setup proper GOPATH directories for development
    16  // and builds.
    17  func DetectImportPath(ctx *app.Context) (string, error) {
    18  	gopath := os.Getenv("GOPATH")
    19  	if gopath == "" {
    20  		ctx.Ui.Message(
    21  			"Warning! GOPATH not set. Otto will be unable to automatically\n" +
    22  				"setup your application GOPATH for development and builds. While Otto\n" +
    23  				"sets up a development for you, your folder structure outside of Otto\n" +
    24  				"should still represent a proper Go environment. If you do this, then\n" +
    25  				"the development and build process function a lot smoother.\n\n" +
    26  				"For simple Go applications, this may not be necessary.\n\n" +
    27  				"This is just an informational message. This is not a bug.")
    28  		return "", nil
    29  	}
    30  
    31  	// Gopath should be absolute
    32  	gopath, err := filepath.Abs(gopath)
    33  	if err != nil {
    34  		return "", fmt.Errorf(
    35  			"Error expanding GOPATH to an absolute path: %s", err)
    36  	}
    37  
    38  	dir := filepath.Dir(ctx.Appfile.Path)
    39  	dir, err = filepath.Abs(dir)
    40  	if err != nil {
    41  		return "", fmt.Errorf(
    42  			"Error expanding Appfile path to an absolute path: %s", err)
    43  	}
    44  
    45  	// If the directory to our Appfile is a symlink, resolve that symlink
    46  	// through. This makes this heuristic work for local dependencies.
    47  	if fi, err := os.Lstat(dir); err == nil {
    48  		if fi.Mode()&os.ModeSymlink != 0 {
    49  			newDir, err := os.Readlink(dir)
    50  			if err != nil {
    51  				return "", fmt.Errorf(
    52  					"Error reading symlink %s: %s", dir, err)
    53  			}
    54  
    55  			dir = newDir
    56  		}
    57  	}
    58  
    59  	// The directory has to be prefixed with the gopath
    60  	gopath = filepath.Join(gopath, "src")
    61  	if !strings.HasPrefix(dir, gopath) {
    62  		ctx.Ui.Message(
    63  			"Warning! It looks like your application is not within your set\n" +
    64  				"GOPATH. Otto will be unable to automatically setup the proper\n" +
    65  				"GOPATH structure within your development and build environments.\n\n" +
    66  				"To fix this, please put your application into the proper GOPATH\n" +
    67  				"location as according to standard Go development practices.")
    68  		return "", nil
    69  	}
    70  
    71  	detected := dir[len(gopath)+1:]
    72  	ctx.Ui.Message(fmt.Sprintf(
    73  		"Detected import path: %s\n\n"+
    74  			"Otto will use this import path to automatically setup your dev\n"+
    75  			"and build environments in the proper directories.",
    76  		detected))
    77  	return detected, nil
    78  }