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  )