This is an automated email from the ASF dual-hosted git repository. davidjumani pushed a commit to branch add-iface in repository https://gitbox.apache.org/repos/asf/cloudstack-go.git
commit 70d6409d24de5cbb2505ed5d4fdf04765cf0519b Author: davidjumani <[email protected]> AuthorDate: Wed Oct 20 12:29:56 2021 +0530 Adding interfaces for better operability and mock / testing --- generate/Makefile | 25 ++++++++++++ generate/generate.go | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 133 insertions(+), 2 deletions(-) diff --git a/generate/Makefile b/generate/Makefile new file mode 100644 index 0000000..020c0a4 --- /dev/null +++ b/generate/Makefile @@ -0,0 +1,25 @@ +# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) +ifeq (,$(shell go env GOBIN)) +GOBIN=$(shell go env GOPATH)/bin +else +GOBIN=$(shell go env GOBIN) +endif + +# Setting SHELL to bash allows bash commands to be executed by recipes. +# This is a requirement for 'setup-envtest.sh' in the test target. +# Options are set to exit when a recipe line exits non-zero or a piped command fails. +SHELL = /usr/bin/env bash -o pipefail +.SHELLFLAGS = -ec + +all: generate + +generate: + go run generate.go layout.go + +mock-gen: + $(MOCKGEN) -destination=../cloudstack/mock.go -package=mock -source=../cloudstack/*.go + +MOCKGEN := $(shell pwd)/bin/mockgen +mockgen: ## Download conversion-gen locally if necessary. + $(call go-get-tool,$(MOCKGEN),github.com/golang/mock/mockgen) + diff --git a/generate/generate.go b/generate/generate.go index 429df5a..1a7542b 100644 --- a/generate/generate.go +++ b/generate/generate.go @@ -305,7 +305,7 @@ func (as *allServices) GeneralCode() ([]byte, error) { pn(" timeout int64 // Max waiting timeout in seconds for async jobs to finish; defaults to 300 seconds") pn("") for _, s := range as.services { - pn(" %s *%s", strings.TrimSuffix(s.name, "Service"), s.name) + pn(" %s %sIface", strings.TrimSuffix(s.name, "Service"), s.name) } pn("}") pn("") @@ -685,7 +685,7 @@ func (as *allServices) GeneralCode() ([]byte, error) { pn(" cs *CloudStackClient") pn("}") pn("") - pn("func New%s(cs *CloudStackClient) *%s {", s.name, s.name) + pn("func New%s(cs *CloudStackClient) %sIface {", s.name, s.name) pn(" return &%s{cs: cs}", s.name) pn("}") pn("") @@ -887,6 +887,8 @@ func (s *service) GenerateCode() ([]byte, error) { pn("}") } + s.generateInterfaceType() + for _, a := range s.apis { s.generateParamType(a) s.generateToURLValuesFunc(a) @@ -913,6 +915,110 @@ func (s *service) generateParamType(a *API) { pn("}\n") } +func (s *service) generateInterfaceType() { + // var buf bytes.Buffer + // p := func(format string, args ...interface{}) { + // _, err := fmt.Fprintf(&buf, format, args...) + // if err != nil { + // panic(err) + // } + // } + // pn := func(format string, args ...interface{}) { + // p(format+"\n", args...) + // } + p, pn := s.p, s.pn + + pn("type %sIface interface {", capitalize(s.name)) + for _, api := range s.apis { + n := capitalize(api.Name) + tn := capitalize(api.Name + "Params") + // API Calls + pn(" %s(p *%s) (*%s, error)", n, n+"Params", strings.TrimPrefix(n, "Configure")+"Response") + + // NewParam funcs + p("New%s(", tn) + for _, ap := range api.Params { + if ap.Required { + // rp = append(rp, ap) + p("%s %s, ", s.parseParamName(ap.Name), mapType(api.Name, ap.Name, ap.Type)) + } + } + pn(") *%s", tn) + + // Helper funcs + if strings.HasPrefix(api.Name, "list") { + v, found := hasNameOrKeywordParamField(api.Name, api.Params) + if found && hasIDAndNameResponseField(api.Name, api.Response) { + ln := strings.TrimPrefix(api.Name, "list") + + // Check if ID is a required parameters and bail if so + for _, ap := range api.Params { + if ap.Required && ap.Name == "id" { + return + } + } + + // Generate the function signature + p("Get%sID(%s string, ", parseSingular(ln), v) + for _, ap := range api.Params { + if ap.Required { + p("%s %s, ", s.parseParamName(ap.Name), mapType(api.Name, ap.Name, ap.Type)) + } + } + if parseSingular(ln) == "Iso" { + p("isofilter string, ") + } + if parseSingular(ln) == "Template" || parseSingular(ln) == "Iso" { + p("zoneid string, ") + } + pn("opts ...OptionFunc) (string, int, error)") + + if hasIDParamField(api.Name, api.Params) { + p("Get%sByName(name string, ", parseSingular(ln)) + for _, ap := range api.Params { + if ap.Required { + p("%s %s, ", s.parseParamName(ap.Name), mapType(api.Name, ap.Name, ap.Type)) + } + } + if parseSingular(ln) == "Iso" { + p("isofilter string, ") + } + if parseSingular(ln) == "Template" || parseSingular(ln) == "Iso" { + p("zoneid string, ") + } + pn("opts ...OptionFunc) (*%s, int, error)", parseSingular(ln)) + } + } + + if hasIDParamField(api.Name, api.Params) { + ln := strings.TrimPrefix(api.Name, "list") + + // Generate the function signature + p("Get%sByID(id string, ", parseSingular(ln)) + for _, ap := range api.Params { + if ap.Required && s.parseParamName(ap.Name) != "id" { + p("%s %s, ", ap.Name, mapType(api.Name, ap.Name, ap.Type)) + } + } + if ln == "LoadBalancerRuleInstances" { + pn("opts ...OptionFunc) (*VirtualMachine, int, error)") + } else { + pn("opts ...OptionFunc) (*%s, int, error)", parseSingular(ln)) + } + } + } + } + pn("}\n") + + // outdir, err := sourceDir() + // if err != nil { + // log.Fatalf("Failed to get source dir: %s", err) + // } + // code, _ := format.Source(buf.Bytes()) + // file := path.Join(outdir, "interfaces.go") + // ioutil.WriteFile(file, code, 0644) +} + func (s *service) generateToURLValuesFunc(a *API) { pn := s.pn
