github.com/bhameyie/otto@v0.2.1-0.20160406174117-16052efa52ec/helper/compile/foundation.go (about)

     1  package compile
     2  
     3  import (
     4  	"fmt"
     5  	"path/filepath"
     6  	"strings"
     7  
     8  	"github.com/hashicorp/otto/foundation"
     9  	"github.com/hashicorp/otto/helper/bindata"
    10  )
    11  
    12  // FoundationOptions are the options for compiling a foundation.
    13  //
    14  // These options may be modified during customization processing, and
    15  // in fact that is an intended use case and common pattern. To do this,
    16  // use the FoundationCustomizationFunc method. See some of the builtin types for
    17  // examples.
    18  type FoundationOptions struct {
    19  	// Ctx is the foundation context of this compilation.
    20  	Ctx *foundation.Context
    21  
    22  	// Bindata is the data that is used for templating. This must be set.
    23  	// Template data should also be set on this. This will be modified with
    24  	// default template data if those keys are not set.
    25  	Bindata *bindata.Data
    26  
    27  	// Customization is used to configure the customizations for this
    28  	// application. See the Customization type docs for more info.
    29  	Customization *Customization
    30  
    31  	// Callbacks are called just prior to compilation completing.
    32  	Callbacks []CompileCallback
    33  }
    34  
    35  // Foundation is an opinionated compilation function to help implement
    36  // foundation.Foundation.Compile.
    37  //
    38  // FoundationOptions may be modified by this function during this call.
    39  func Foundation(opts *FoundationOptions) (*foundation.CompileResult, error) {
    40  	ctx := opts.Ctx
    41  
    42  	// Setup the basic templating data. We put this into the "data" local
    43  	// var just so that it is easier to reference.
    44  	//
    45  	// The exact default data put into the context is documented above.
    46  	data := opts.Bindata
    47  	if data.Context == nil {
    48  		data.Context = make(map[string]interface{})
    49  		opts.Bindata = data
    50  	}
    51  	data.Context["name"] = ctx.Appfile.Application.Name
    52  	data.Context["path"] = map[string]string{
    53  		"compiled": ctx.Dir,
    54  		"working":  filepath.Dir(ctx.Appfile.Path),
    55  	}
    56  	data.Context["app_config"] = ctx.AppConfig
    57  	if ctx.AppConfig == nil {
    58  		data.Context["app_config"] = &foundation.Config{}
    59  	}
    60  
    61  	// Process the customizations!
    62  	err := processCustomizations(
    63  		ctx.Appfile.Customization,
    64  		opts.Customization)
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  
    69  	// Create the directory list that we'll copy from, and copy those
    70  	// directly into the compilation directory.
    71  	bindirs := []string{
    72  		"data/common",
    73  		fmt.Sprintf("data/%s-%s", ctx.Tuple.Infra, ctx.Tuple.InfraFlavor),
    74  	}
    75  	for _, dir := range bindirs {
    76  		// Copy all the common files that exist
    77  		if err := data.CopyDir(ctx.Dir, dir); err != nil {
    78  			// Ignore any directories that don't exist
    79  			if strings.Contains(err.Error(), "not found") {
    80  				continue
    81  			}
    82  
    83  			return nil, err
    84  		}
    85  	}
    86  
    87  	// Callbacks
    88  	for _, cb := range opts.Callbacks {
    89  		if err := cb(); err != nil {
    90  			return nil, err
    91  		}
    92  	}
    93  
    94  	return nil, nil
    95  }