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 }