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

     1  package phpapp
     2  
     3  import (
     4  	"fmt"
     5  	"path/filepath"
     6  	"strings"
     7  
     8  	"github.com/hashicorp/otto/app"
     9  	"github.com/hashicorp/otto/appfile"
    10  	phpSP "github.com/hashicorp/otto/builtin/scriptpack/php"
    11  	stdSP "github.com/hashicorp/otto/builtin/scriptpack/stdlib"
    12  	"github.com/hashicorp/otto/helper/bindata"
    13  	"github.com/hashicorp/otto/helper/compile"
    14  	"github.com/hashicorp/otto/helper/oneline"
    15  	"github.com/hashicorp/otto/helper/packer"
    16  	"github.com/hashicorp/otto/helper/schema"
    17  	"github.com/hashicorp/otto/helper/terraform"
    18  	"github.com/hashicorp/otto/helper/vagrant"
    19  	"github.com/hashicorp/otto/scriptpack"
    20  )
    21  
    22  //go:generate go-bindata -pkg=phpapp -nomemcopy -nometadata ./data/...
    23  
    24  // App is an implementation of app.App
    25  type App struct{}
    26  
    27  func (a *App) Meta() (*app.Meta, error) {
    28  	return Meta, nil
    29  }
    30  
    31  func (a *App) Implicit(ctx *app.Context) (*appfile.File, error) {
    32  	// For Wordpress we implicitly depend on MySQL
    33  	var result appfile.File
    34  	if ctx.Tuple.App == "wordpress" {
    35  		result.Application = &appfile.Application{
    36  			Dependencies: []*appfile.Dependency{
    37  				&appfile.Dependency{
    38  					Source: "github.com/hashicorp/otto/examples/mysql",
    39  				},
    40  			},
    41  		}
    42  	}
    43  
    44  	return &result, nil
    45  }
    46  
    47  func (a *App) Compile(ctx *app.Context) (*app.CompileResult, error) {
    48  	var opts compile.AppOptions
    49  	custom := &customizations{Opts: &opts}
    50  	opts = compile.AppOptions{
    51  		Ctx: ctx,
    52  		Result: &app.CompileResult{
    53  			Version: 1,
    54  		},
    55  		Bindata: &bindata.Data{
    56  			Asset:    Asset,
    57  			AssetDir: AssetDir,
    58  			Context:  map[string]interface{}{},
    59  		},
    60  		ScriptPacks: []*scriptpack.ScriptPack{
    61  			&stdSP.ScriptPack,
    62  			&phpSP.ScriptPack,
    63  		},
    64  		Customization: (&compile.Customization{
    65  			Callback: custom.process,
    66  			Schema: map[string]*schema.FieldSchema{
    67  				"php_version": &schema.FieldSchema{
    68  					Type:        schema.TypeString,
    69  					Default:     "5.6",
    70  					Description: "PHP version to install",
    71  				},
    72  			},
    73  		}).Merge(compile.VagrantCustomizations(&opts)),
    74  	}
    75  
    76  	return compile.App(&opts)
    77  }
    78  
    79  func (a *App) Build(ctx *app.Context) error {
    80  	return packer.Build(ctx, &packer.BuildOptions{
    81  		InfraOutputMap: map[string]string{
    82  			"region": "aws_region",
    83  			"vpc_id": "aws_vpc_id",
    84  			"subnet_public":  "aws_subnet_id",
    85  		},
    86  	})
    87  }
    88  
    89  func (a *App) Deploy(ctx *app.Context) error {
    90  	return terraform.Deploy(&terraform.DeployOptions{
    91  		InfraOutputMap: map[string]string{
    92  			"region":         "aws_region",
    93  			"subnet-private": "private_subnet_id",
    94  			"subnet-public":  "public_subnet_id",
    95  		},
    96  	}).Route(ctx)
    97  }
    98  
    99  func (a *App) Dev(ctx *app.Context) error {
   100  	var layered *vagrant.Layered
   101  
   102  	// We only setup a layered environment if we've recompiled since
   103  	// version 0. If we're still at version 0 then we have to use the
   104  	// non-layered dev environment.
   105  	if ctx.CompileResult.Version > 0 {
   106  		// Read the go version, since we use that for our layer
   107  		version, err := oneline.Read(filepath.Join(ctx.Dir, "dev", "php_version"))
   108  		if err != nil {
   109  			return err
   110  		}
   111  
   112  		// Setup layers
   113  		layered, err = vagrant.DevLayered(ctx, []*vagrant.Layer{
   114  			&vagrant.Layer{
   115  				ID:          fmt.Sprintf("php%s", version),
   116  				Vagrantfile: filepath.Join(ctx.Dir, "dev", "layer-base", "Vagrantfile"),
   117  			},
   118  		})
   119  		if err != nil {
   120  			return err
   121  		}
   122  	}
   123  
   124  	instructions := devInstructions
   125  	if ctx.Tuple.App == "wordpress" {
   126  		instructions = devInstructionsWordpress
   127  	}
   128  
   129  	// Build the actual development environment
   130  	return vagrant.Dev(&vagrant.DevOptions{
   131  		Instructions: strings.TrimSpace(instructions),
   132  		Layer:        layered,
   133  	}).Route(ctx)
   134  }
   135  
   136  func (a *App) DevDep(dst, src *app.Context) (*app.DevDep, error) {
   137  	return vagrant.DevDep(dst, src, &vagrant.DevDepOptions{})
   138  }
   139  
   140  const devInstructions = `
   141  A development environment has been created for writing a PHP app.
   142  
   143  Edit files locally on your machine, the file changes will be synced
   144  to the development environment automatically.
   145  
   146  To run and view your application, run 'otto dev ssh' to enter the
   147  development environment. You'll be placed directly into the working
   148  directory where you can run "composer", "php", etc.
   149  
   150  You can access the environment from this machine using the IP address above.
   151  For example, if you start your app with 'php -S 0.0.0.0:5000', then you can
   152  access it using the above IP at port 5000.
   153  `
   154  
   155  const devInstructionsWordpress = `
   156  A development environment has been created for working on Wordpress.
   157  
   158  To start the web server, SSH into the development environment using
   159  "otto dev ssh" and run "php -S 0.0.0.0:3000". You can then visit Wordpress
   160  using the IP above on port 3000.
   161  
   162  MySQL has also automatically been setup. The address for MySQL is
   163  "mysql.service.consul", the username and password is "root".
   164  `
   165  
   166  const buildErr = `
   167  Build isn't supported yet for PHP!
   168  
   169  Early versions of Otto are focusing on creating a fantastic development
   170  experience. Because of this, build/deploy are still lacking for many
   171  application types. These will be fixed very soon in upcoming versions of
   172  Otto. Sorry!
   173  `