github.com/devcamcar/cli@v0.0.0-20181107134215-706a05759d18/langs/base.go (about)

     1  package langs
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os"
     7  )
     8  
     9  // not a map because some helpers can handle multiple keys
    10  var helpers = []LangHelper{}
    11  
    12  func init() {
    13  	registerHelper(&GoLangHelper{})
    14  	registerHelper(&JavaLangHelper{version: "1.8"})
    15  	registerHelper(&JavaLangHelper{version: "9"})
    16  	registerHelper(&NodeLangHelper{})
    17  	registerHelper(&PythonLangHelper{Version: "3.6"})
    18  	registerHelper(&PythonLangHelper{Version: "3.7"})
    19  	registerHelper(&RubyLangHelper{})
    20  	registerHelper(&KotlinLangHelper{})
    21  
    22  }
    23  
    24  func registerHelper(h LangHelper) {
    25  	helpers = append(helpers, h)
    26  }
    27  
    28  func Helpers() []LangHelper {
    29  	return helpers
    30  }
    31  
    32  var (
    33  	ErrBoilerplateExists = errors.New("Function boilerplate already exists")
    34  )
    35  
    36  // GetLangHelper returns a LangHelper for the passed in language
    37  func GetLangHelper(lang string) LangHelper {
    38  	for _, h := range helpers {
    39  		if h.Handles(lang) {
    40  			return h
    41  		}
    42  	}
    43  	return nil
    44  }
    45  
    46  // LangHelper is the interface that language helpers must implement.
    47  type LangHelper interface {
    48  	// Handles return whether it can handle the passed in lang string or not
    49  	Handles(string) bool
    50  	// LangStrings returns list of supported language strings user can use for runtime
    51  	LangStrings() []string
    52  	// Extension is the file extension this helper supports. Eg: .java, .go, .js
    53  	Extensions() []string
    54  	// Runtime that will be used for the build (includes version)
    55  	Runtime() string
    56  	// BuildFromImage is the base image to build off, typically fnproject/LANG:dev
    57  	BuildFromImage() (string, error)
    58  	// RunFromImage is the base image to use for deployment (usually smaller than the build images)
    59  	RunFromImage() (string, error)
    60  	// If set to false, it will use a single Docker build step, rather than multi-stage
    61  	IsMultiStage() bool
    62  	// Dockerfile build lines for building dependencies or anything else language specific
    63  	DockerfileBuildCmds() []string
    64  	// DockerfileCopyCmds will run in second/final stage of multi-stage build to copy artifacts form the build stage
    65  	DockerfileCopyCmds() []string
    66  	// Entrypoint sets the Docker Entrypoint. One of Entrypoint or Cmd is required.
    67  	Entrypoint() (string, error)
    68  	// Cmd sets the Docker command. One of Entrypoint or Cmd is required.
    69  	Cmd() (string, error)
    70  	// DefaultFormat provides the default fn format to set in func.yaml fn init, return "" for an empty format.
    71  	DefaultFormat() string
    72  	HasPreBuild() bool
    73  	PreBuild() error
    74  	AfterBuild() error
    75  	// HasBoilerplate indicates whether a language has support for generating function boilerplate.
    76  	HasBoilerplate() bool
    77  	// GenerateBoilerplate generates basic function boilerplate. Returns ErrBoilerplateExists if the function file
    78  	// already exists.
    79  	GenerateBoilerplate(string) error
    80  	// FixImagesOnInit determines if images should be fixed on initialization - BuildFromImage and RunFromImage will be written to func.yaml
    81  	FixImagesOnInit() bool
    82  }
    83  
    84  func defaultHandles(h LangHelper, lang string) bool {
    85  	for _, s := range h.LangStrings() {
    86  		if lang == s {
    87  			return true
    88  		}
    89  	}
    90  	return false
    91  }
    92  
    93  // BaseHelper is empty implementation of LangHelper for embedding in implementations.
    94  type BaseHelper struct {
    95  }
    96  
    97  func (h *BaseHelper) IsMultiStage() bool               { return true }
    98  func (h *BaseHelper) DockerfileBuildCmds() []string    { return []string{} }
    99  func (h *BaseHelper) DockerfileCopyCmds() []string     { return []string{} }
   100  func (h *BaseHelper) Entrypoint() (string, error)      { return "", nil }
   101  func (h *BaseHelper) Cmd() (string, error)             { return "", nil }
   102  func (h *BaseHelper) HasPreBuild() bool                { return false }
   103  func (h *BaseHelper) PreBuild() error                  { return nil }
   104  func (h *BaseHelper) AfterBuild() error                { return nil }
   105  func (h *BaseHelper) HasBoilerplate() bool             { return false }
   106  func (h *BaseHelper) GenerateBoilerplate(string) error { return nil }
   107  func (h *BaseHelper) DefaultFormat() string            { return "" }
   108  func (h *BaseHelper) FixImagesOnInit() bool            { return false }
   109  
   110  // exists checks if a file exists
   111  func exists(name string) bool {
   112  	if _, err := os.Stat(name); err != nil {
   113  		if os.IsNotExist(err) {
   114  			return false
   115  		}
   116  	}
   117  	return true
   118  }
   119  
   120  func dockerBuildError(err error) error {
   121  	return fmt.Errorf("error running docker build: %v", err)
   122  }