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

     1  package goapp
     2  
     3  import (
     4  	"fmt"
     5  	"path/filepath"
     6  	"strings"
     7  
     8  	"github.com/hashicorp/otto/app"
     9  	"github.com/hashicorp/otto/appfile"
    10  	"github.com/hashicorp/otto/foundation"
    11  	"github.com/hashicorp/otto/helper/bindata"
    12  	"github.com/hashicorp/otto/helper/compile"
    13  	"github.com/hashicorp/otto/helper/oneline"
    14  	"github.com/hashicorp/otto/helper/schema"
    15  	"github.com/hashicorp/otto/helper/vagrant"
    16  )
    17  
    18  //go:generate go-bindata -pkg=goapp -nomemcopy -nometadata ./data/...
    19  
    20  // App is an implementation of app.App
    21  type App struct{}
    22  
    23  func (a *App) Meta() (*app.Meta, error) {
    24  	return Meta, nil
    25  }
    26  
    27  func (a *App) Implicit(ctx *app.Context) (*appfile.File, error) {
    28  	return nil, nil
    29  }
    30  
    31  func (a *App) Compile(ctx *app.Context) (*app.CompileResult, error) {
    32  	var opts compile.AppOptions
    33  	custom := &customizations{Opts: &opts}
    34  	opts = compile.AppOptions{
    35  		Ctx: ctx,
    36  		Result: &app.CompileResult{
    37  			Version: 1,
    38  		},
    39  		FoundationConfig: foundation.Config{
    40  			ServiceName: ctx.Application.Name,
    41  		},
    42  		Bindata: &bindata.Data{
    43  			Asset:    Asset,
    44  			AssetDir: AssetDir,
    45  			Context: map[string]interface{}{
    46  				"dep_binary_path": fmt.Sprintf("/usr/local/bin/%s", ctx.Application.Name),
    47  				"path": map[string]string{
    48  					"guest_working": fmt.Sprintf(
    49  						"/otto-deps/%s-%s",
    50  						ctx.Application.Name,
    51  						ctx.Appfile.ID),
    52  				},
    53  			},
    54  		},
    55  		Customization: (&compile.Customization{
    56  			Callback: custom.process,
    57  			Schema: map[string]*schema.FieldSchema{
    58  				"go_version": &schema.FieldSchema{
    59  					Type:        schema.TypeString,
    60  					Default:     "1.5",
    61  					Description: "Go version to install",
    62  				},
    63  
    64  				"go_import_path": &schema.FieldSchema{
    65  					Type:        schema.TypeString,
    66  					Default:     "",
    67  					Description: "Go import path for where to put this in the GOPATH",
    68  				},
    69  
    70  				"run_command": &schema.FieldSchema{
    71  					Type:        schema.TypeString,
    72  					Default:     "{{ dep_binary_path }}",
    73  					Description: "Command to run this app as a dep",
    74  				},
    75  			},
    76  		}).Merge(compile.VagrantCustomizations(&opts)),
    77  	}
    78  
    79  	return compile.App(&opts)
    80  }
    81  
    82  func (a *App) Build(ctx *app.Context) error {
    83  	return fmt.Errorf(strings.TrimSpace(buildErr))
    84  }
    85  
    86  func (a *App) Deploy(ctx *app.Context) error {
    87  	return fmt.Errorf(strings.TrimSpace(buildErr))
    88  }
    89  
    90  func (a *App) Dev(ctx *app.Context) error {
    91  	var layered *vagrant.Layered
    92  
    93  	// We only setup a layered environment if we've recompiled since
    94  	// version 0. If we're still at version 0 then we have to use the
    95  	// non-layered dev environment.
    96  	if ctx.CompileResult.Version > 0 {
    97  		// Read the go version, since we use that for our layer
    98  		goVersion, err := oneline.Read(filepath.Join(ctx.Dir, "dev", "go_version"))
    99  		if err != nil {
   100  			return err
   101  		}
   102  
   103  		// Setup layers
   104  		layered, err = vagrant.DevLayered(ctx, []*vagrant.Layer{
   105  			&vagrant.Layer{
   106  				ID:          fmt.Sprintf("go%s", goVersion),
   107  				Vagrantfile: filepath.Join(ctx.Dir, "dev", "layer-base", "Vagrantfile"),
   108  			},
   109  		})
   110  		if err != nil {
   111  			return err
   112  		}
   113  	}
   114  
   115  	// Build the actual development environment
   116  	return vagrant.Dev(&vagrant.DevOptions{
   117  		Instructions: strings.TrimSpace(devInstructions),
   118  		Layer:        layered,
   119  	}).Route(ctx)
   120  }
   121  
   122  func (a *App) DevDep(dst, src *app.Context) (*app.DevDep, error) {
   123  	return vagrant.DevDep(dst, src, &vagrant.DevDepOptions{
   124  		Dir:    filepath.Join(src.Dir, "dev-dep"),
   125  		Script: "/otto/build.sh",
   126  		Files:  []string{"dev-dep-output"},
   127  	})
   128  }
   129  
   130  const devInstructions = `
   131  A development environment has been created for writing a generic Go-based
   132  application. For this development environment, Go is pre-installed. To
   133  work on your project, edit files locally on your own machine. The file changes
   134  will be synced to the development environment.
   135  
   136  When you're ready to build your project, run 'otto dev ssh' to enter
   137  the development environment. You'll be placed directly into the working
   138  directory where you can run 'go get' and 'go build' as you normally would.
   139  The GOPATH is already completely setup.
   140  `
   141  
   142  const buildErr = `
   143  Build isn't supported yet for Go!
   144  
   145  Early versions of Otto are focusing on creating a fantastic development
   146  experience. Because of this, build/deploy are still lacking for many
   147  application types. These will be fixed very soon in upcoming versions of
   148  Otto. Sorry!
   149  `