github.com/devcamcar/cli@v0.0.0-20181107134215-706a05759d18/langs/go.go (about) 1 package langs 2 3 import ( 4 "errors" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 ) 9 10 type GoLangHelper struct { 11 BaseHelper 12 } 13 14 func (h *GoLangHelper) Handles(lang string) bool { 15 return defaultHandles(h, lang) 16 } 17 func (h *GoLangHelper) Runtime() string { 18 return h.LangStrings()[0] 19 } 20 21 func (h *GoLangHelper) DefaultFormat() string { 22 return "http-stream" 23 } 24 25 func (lh *GoLangHelper) LangStrings() []string { 26 return []string{"go"} 27 } 28 func (lh *GoLangHelper) Extensions() []string { 29 return []string{".go"} 30 } 31 32 func (lh *GoLangHelper) BuildFromImage() (string, error) { 33 return "fnproject/go:dev", nil 34 } 35 36 func (lh *GoLangHelper) RunFromImage() (string, error) { 37 return "fnproject/go", nil 38 } 39 40 func (h *GoLangHelper) DockerfileBuildCmds() []string { 41 r := []string{} 42 // more info on Go multi-stage builds: https://medium.com/travis-on-docker/multi-stage-docker-builds-for-creating-tiny-go-images-e0e1867efe5a 43 // TODO: if we keep the Gopkg.lock on user's drive, we can put this after the dep commands and then the dep layers will be cached. 44 vendor := exists("vendor/") 45 // skip dep tool install if vendor is there 46 if !vendor && exists("Gopkg.toml") { 47 r = append(r, "RUN go get -u github.com/golang/dep/cmd/dep") 48 if exists("Gopkg.lock") { 49 r = append(r, "ADD Gopkg.* /go/src/func/") 50 r = append(r, "RUN cd /go/src/func/ && dep ensure --vendor-only") 51 r = append(r, "ADD . /go/src/func/") 52 } else { 53 r = append(r, "ADD . /go/src/func/") 54 r = append(r, "RUN cd /go/src/func/ && dep ensure") 55 } 56 } else { 57 r = append(r, "ADD . /go/src/func/") 58 } 59 60 r = append(r, "RUN cd /go/src/func/ && go build -o func") 61 62 return r 63 } 64 65 func (h *GoLangHelper) DockerfileCopyCmds() []string { 66 return []string{ 67 "COPY --from=build-stage /go/src/func/func /function/", 68 } 69 } 70 71 func (lh *GoLangHelper) Entrypoint() (string, error) { 72 return "./func", nil 73 } 74 75 func (lh *GoLangHelper) HasBoilerplate() bool { return true } 76 77 func (lh *GoLangHelper) GenerateBoilerplate(path string) error { 78 codeFile := filepath.Join(path, "func.go") 79 if exists(codeFile) { 80 return errors.New("func.go already exists, canceling init") 81 } 82 if err := ioutil.WriteFile(codeFile, []byte(helloGoSrcBoilerplate), os.FileMode(0644)); err != nil { 83 return err 84 } 85 depFile := "Gopkg.toml" 86 if err := ioutil.WriteFile(depFile, []byte(depBoilerplate), os.FileMode(0644)); err != nil { 87 return err 88 } 89 90 return nil 91 } 92 93 const ( 94 helloGoSrcBoilerplate = `package main 95 96 import ( 97 "context" 98 "encoding/json" 99 "fmt" 100 "io" 101 102 fdk "github.com/fnproject/fdk-go" 103 ) 104 105 func main() { 106 fdk.Handle(fdk.HandlerFunc(myHandler)) 107 } 108 109 type Person struct { 110 Name string ` + "`json:\"name\"`" + ` 111 } 112 113 func myHandler(ctx context.Context, in io.Reader, out io.Writer) { 114 p := &Person{Name: "World"} 115 json.NewDecoder(in).Decode(p) 116 msg := struct { 117 Msg string ` + "`json:\"message\"`" + ` 118 }{ 119 Msg: fmt.Sprintf("Hello %s", p.Name), 120 } 121 json.NewEncoder(out).Encode(&msg) 122 } 123 ` 124 125 depBoilerplate = ` 126 [[constraint]] 127 branch = "master" 128 name = "github.com/fnproject/fdk-go" 129 130 [prune] 131 go-tests = true 132 unused-packages = true 133 ` 134 )