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