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
 

Reply via email to