diff options
Diffstat (limited to 'vendor/google.golang.org/appengine/cmd/aedeploy/aedeploy.go')
-rw-r--r-- | vendor/google.golang.org/appengine/cmd/aedeploy/aedeploy.go | 242 |
1 files changed, 23 insertions, 219 deletions
diff --git a/vendor/google.golang.org/appengine/cmd/aedeploy/aedeploy.go b/vendor/google.golang.org/appengine/cmd/aedeploy/aedeploy.go index 155fc1c..8093c93 100644 --- a/vendor/google.golang.org/appengine/cmd/aedeploy/aedeploy.go +++ b/vendor/google.golang.org/appengine/cmd/aedeploy/aedeploy.go @@ -16,32 +16,29 @@ package main import ( "flag" "fmt" - "go/build" - "io" - "io/ioutil" + "log" "os" "os/exec" - "path/filepath" "strings" ) -var ( - skipFiles = map[string]bool{ - ".git": true, - ".gitconfig": true, - ".hg": true, - ".travis.yml": true, - } - - gopathCache = map[string]string{} -) - func usage() { fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) - fmt.Fprintf(os.Stderr, "\t%s gcloud --verbosity debug preview app deploy --version myversion ./app.yaml\tDeploy app to production\n", os.Args[0]) + fmt.Fprintf(os.Stderr, "\t%s gcloud --verbosity debug app deploy --version myversion ./app.yaml\tDeploy app to production\n", os.Args[0]) +} + +var verbose bool + +// vlogf logs to stderr if the "-v" flag is provided. +func vlogf(f string, v ...interface{}) { + if !verbose { + return + } + log.Printf("[aedeploy] "+f, v...) } func main() { + flag.BoolVar(&verbose, "v", false, "Verbose logging.") flag.Usage = usage flag.Parse() if flag.NArg() < 1 { @@ -49,35 +46,23 @@ func main() { os.Exit(1) } - if err := aedeploy(); err != nil { - fmt.Fprintf(os.Stderr, os.Args[0]+": Error: %v\n", err) - os.Exit(1) - } -} - -func aedeploy() error { - tags := []string{"appenginevm"} - app, err := analyze(tags) - if err != nil { - return err - } - - tmpDir, err := app.bundle() - if tmpDir != "" { - defer os.RemoveAll(tmpDir) - } - if err != nil { - return err + notice := func() { + fmt.Fprintln(os.Stderr, `NOTICE: aedeploy is deprecated. Just use "gcloud app deploy".`) } - if err := os.Chdir(tmpDir); err != nil { - return fmt.Errorf("unable to chdir to %v: %v", tmpDir, err) + notice() + if err := deploy(); err != nil { + fmt.Fprintf(os.Stderr, os.Args[0]+": Error: %v\n", err) + notice() + fmt.Fprintln(os.Stderr, `You might need to update gcloud. Run "gcloud components update".`) + os.Exit(1) } - return deploy() + notice() // Make sure they see it at the end. } // deploy calls the provided command to deploy the app from the temporary directory. func deploy() error { + vlogf("Running command %v", flag.Args()) cmd := exec.Command(flag.Arg(0), flag.Args()[1:]...) cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr if err := cmd.Run(); err != nil { @@ -85,184 +70,3 @@ func deploy() error { } return nil } - -type app struct { - appFiles []string - imports map[string]string -} - -// analyze checks the app for building with the given build tags and returns -// app files, and a map of full directory import names to original import names. -func analyze(tags []string) (*app, error) { - ctxt := buildContext(tags) - appFiles, err := appFiles(ctxt) - if err != nil { - return nil, err - } - gopath := filepath.SplitList(ctxt.GOPATH) - im, err := imports(ctxt, ".", gopath) - return &app{ - appFiles: appFiles, - imports: im, - }, err -} - -// buildContext returns the context for building the source. -func buildContext(tags []string) *build.Context { - return &build.Context{ - GOARCH: "amd64", - GOOS: "linux", - GOROOT: build.Default.GOROOT, - GOPATH: build.Default.GOPATH, - Compiler: build.Default.Compiler, - BuildTags: append(defaultBuildTags, tags...), - } -} - -// All build tags except go1.7, since Go 1.6 is the runtime version. -var defaultBuildTags = []string{ - "go1.1", "go1.2", "go1.3", "go1.4", "go1.5", "go1.6"} - -// bundle bundles the app into a temporary directory. -func (s *app) bundle() (tmpdir string, err error) { - workDir, err := ioutil.TempDir("", "aedeploy") - if err != nil { - return "", fmt.Errorf("unable to create tmpdir: %v", err) - } - - for srcDir, importName := range s.imports { - dstDir := "_gopath/src/" + importName - if err := copyTree(workDir, dstDir, srcDir); err != nil { - return workDir, fmt.Errorf("unable to copy directory %v to %v: %v", srcDir, dstDir, err) - } - } - if err := copyTree(workDir, ".", "."); err != nil { - return workDir, fmt.Errorf("unable to copy root directory to /app: %v", err) - } - return workDir, nil -} - -// imports returns a map of all import directories (recursively) used by the app. -// The return value maps full directory names to original import names. -func imports(ctxt *build.Context, srcDir string, gopath []string) (map[string]string, error) { - pkg, err := ctxt.ImportDir(srcDir, 0) - if err != nil { - return nil, err - } - - // Resolve all non-standard-library imports - result := make(map[string]string) - for _, v := range pkg.Imports { - if !strings.Contains(v, ".") { - continue - } - src, err := findInGopath(v, gopath) - if err != nil { - return nil, fmt.Errorf("unable to find import %v in gopath %v: %v", v, gopath, err) - } - if _, ok := result[src]; ok { // Already processed - continue - } - result[src] = v - im, err := imports(ctxt, src, gopath) - if err != nil { - return nil, fmt.Errorf("unable to parse package %v: %v", src, err) - } - for k, v := range im { - result[k] = v - } - } - return result, nil -} - -// findInGopath searches the gopath for the named import directory. -func findInGopath(dir string, gopath []string) (string, error) { - if v, ok := gopathCache[dir]; ok { - return v, nil - } - for _, v := range gopath { - dst := filepath.Join(v, "src", dir) - if _, err := os.Stat(dst); err == nil { - gopathCache[dir] = dst - return dst, nil - } - } - return "", fmt.Errorf("unable to find package %v in gopath %v", dir, gopath) -} - -// copyTree copies srcDir to dstDir relative to dstRoot, ignoring skipFiles. -func copyTree(dstRoot, dstDir, srcDir string) error { - d := filepath.Join(dstRoot, dstDir) - if err := os.MkdirAll(d, 0755); err != nil { - return fmt.Errorf("unable to create directory %q: %v", d, err) - } - - entries, err := ioutil.ReadDir(srcDir) - if err != nil { - return fmt.Errorf("unable to read dir %q: %v", srcDir, err) - } - for _, entry := range entries { - n := entry.Name() - if skipFiles[n] { - continue - } - s := filepath.Join(srcDir, n) - if entry.Mode()&os.ModeSymlink == os.ModeSymlink { - if entry, err = os.Stat(s); err != nil { - return fmt.Errorf("unable to stat %v: %v", s, err) - } - } - d := filepath.Join(dstDir, n) - if entry.IsDir() { - if err := copyTree(dstRoot, d, s); err != nil { - return fmt.Errorf("unable to copy dir %q to %q: %v", s, d, err) - } - continue - } - if err := copyFile(dstRoot, d, s); err != nil { - return fmt.Errorf("unable to copy dir %q to %q: %v", s, d, err) - } - } - return nil -} - -// copyFile copies src to dst relative to dstRoot. -func copyFile(dstRoot, dst, src string) error { - s, err := os.Open(src) - if err != nil { - return fmt.Errorf("unable to open %q: %v", src, err) - } - defer s.Close() - - dst = filepath.Join(dstRoot, dst) - d, err := os.Create(dst) - if err != nil { - return fmt.Errorf("unable to create %q: %v", dst, err) - } - _, err = io.Copy(d, s) - if err != nil { - d.Close() // ignore error, copy already failed. - return fmt.Errorf("unable to copy %q to %q: %v", src, dst, err) - } - if err := d.Close(); err != nil { - return fmt.Errorf("unable to close %q: %v", dst, err) - } - return nil -} - -// appFiles returns a list of all Go source files in the app. -func appFiles(ctxt *build.Context) ([]string, error) { - pkg, err := ctxt.ImportDir(".", 0) - if err != nil { - return nil, err - } - if !pkg.IsCommand() { - return nil, fmt.Errorf(`the root of your app needs to be package "main" (currently %q). Please see https://cloud.google.com/appengine/docs/flexible/go/ for more details on structuring your app.`, pkg.Name) - } - var appFiles []string - for _, f := range pkg.GoFiles { - n := filepath.Join(".", f) - appFiles = append(appFiles, n) - } - return appFiles, nil -} |