github.com/sacloud/iaas-api-go@v1.12.0/internal/tools/gen-api-fake-op/main.go (about)

     1  // Copyright 2022-2023 The sacloud/iaas-api-go Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package main
    16  
    17  import (
    18  	"fmt"
    19  	"log"
    20  	"path/filepath"
    21  
    22  	"github.com/sacloud/iaas-api-go/internal/define"
    23  	"github.com/sacloud/iaas-api-go/internal/dsl"
    24  	"github.com/sacloud/iaas-api-go/internal/tools"
    25  )
    26  
    27  const (
    28  	apisDestination = "fake/zz_api_ops.go"
    29  	opsDestination  = "fake/ops_%s.go"
    30  	testDestination = "fake/zz_api_ops_test.go"
    31  )
    32  
    33  func init() {
    34  	log.SetFlags(0)
    35  	log.SetPrefix("gen-api-fake-op: ")
    36  }
    37  
    38  func main() {
    39  	// generate xxxOp
    40  	outputPath := apisDestination
    41  	tools.WriteFileWithTemplate(&tools.TemplateConfig{
    42  		OutputPath: filepath.Join(tools.ProjectRootPath(), outputPath),
    43  		Template:   apisTmpl,
    44  		Parameter:  define.APIs,
    45  	})
    46  	log.Printf("generated: %s\n", outputPath)
    47  
    48  	// generate funcs
    49  	dsl.IsOutOfSacloudPackage = true
    50  	for _, resource := range define.APIs {
    51  		dest := fmt.Sprintf(opsDestination, resource.FileSafeName())
    52  		wrote := tools.WriteFileWithTemplate(&tools.TemplateConfig{
    53  			OutputPath:         filepath.Join(tools.ProjectRootPath(), dest),
    54  			Template:           opsTmpl,
    55  			Parameter:          resource,
    56  			PreventOverwriting: true,
    57  		})
    58  		if wrote {
    59  			log.Printf("generated: %s\n", filepath.Join(tools.ProjectRootPath(), dest))
    60  		}
    61  	}
    62  
    63  	// generate xxxOp
    64  	outputPath = testDestination
    65  	tools.WriteFileWithTemplate(&tools.TemplateConfig{
    66  		OutputPath: filepath.Join(tools.ProjectRootPath(), outputPath),
    67  		Template:   testTmpl,
    68  		Parameter:  define.APIs,
    69  	})
    70  	log.Printf("generated: %s\n", outputPath)
    71  }
    72  
    73  const apisTmpl = `// generated by 'github.com/sacloud/iaas-api-go/internal/tools/gen-api-fake-op'; DO NOT EDIT
    74  
    75  package fake
    76  
    77  import (
    78  {{- range .ImportStatements "sync" "github.com/sacloud/iaas-api-go" "github.com/sacloud/iaas-api-go/types"}}
    79  	{{ . }}
    80  {{- end }}
    81  )
    82  
    83  var switchOnce sync.Once
    84  
    85  // SwitchFactoryFuncToFake switches iaas.xxxAPI's factory methods to use fake client
    86  func SwitchFactoryFuncToFake() {
    87  	switchOnce.Do(func(){
    88  		switchFactoryFuncToFake()
    89  	})
    90  }
    91  
    92  func switchFactoryFuncToFake() {
    93  {{ range . -}}
    94  	iaas.SetClientFactoryFunc(Resource{{.TypeName}}, func(caller iaas.APICaller) interface{} {
    95  		return New{{ .TypeName }}Op()
    96  	})
    97  {{ end -}}
    98  }
    99  
   100  
   101  {{ range . }}{{ $typeName := .TypeName}} 
   102  
   103  /************************************************* 
   104  * {{$typeName}}Op
   105  *************************************************/
   106  
   107  // {{ .TypeName }}Op is fake implementation of {{ .TypeName }}API interface
   108  type {{ .TypeName }}Op struct{
   109  	key string
   110  }
   111  
   112  // New{{ $typeName}}Op creates new {{ $typeName}}Op instance
   113  func New{{ $typeName}}Op() iaas.{{ $typeName}}API {
   114  	return &{{$typeName}}Op {
   115  		key: Resource{{$typeName}},
   116  	}
   117  }
   118  {{ end -}}
   119  `
   120  
   121  const opsTmpl = `package fake
   122  
   123  import (
   124  {{- range .ImportStatements "context" "github.com/sacloud/iaas-api-go" "github.com/sacloud/iaas-api-go/types"}}
   125  	{{ . }}
   126  {{- end }}
   127  )
   128  
   129  {{ range .Operations }}
   130  // {{ .MethodName }} is fake implementation
   131  func (o *{{ $.TypeName }}Op) {{ .MethodName }}(ctx context.Context{{if not $.IsGlobal}}, zone string{{end}}{{ range .Arguments }}, {{ .ArgName }} {{ .TypeName }}{{ end }}) {{.ResultsStatement}} {
   132  {{ if eq .MethodName "Find" -}}
   133  	results, _ := find(o.key, {{if $.IsGlobal}}iaas.APIDefaultZone{{else}}zone{{end}}, conditions)
   134  	var values []*iaas.{{$.TypeName}}
   135  	for _, res := range results {
   136  		dest := &iaas.{{$.TypeName}}{}
   137  		copySameNameField(res, dest)
   138  		values = append(values, dest)
   139  	}
   140  	return &iaas.{{.ResultTypeName}}{
   141  		Total:    len(results),
   142  		Count:    len(results),
   143  		From:     0,
   144  		{{$.TypeName}}: values,
   145  	}, nil
   146  {{ else if eq .MethodName "List" -}}
   147  	results, _ := find(o.key, {{if $.IsGlobal}}iaas.APIDefaultZone{{else}}zone{{end}}, nil)
   148  	var values []*iaas.{{$.TypeName}}
   149  	for _, res := range results {
   150  		dest := &iaas.{{$.TypeName}}{}
   151  		copySameNameField(res, dest)
   152  		values = append(values, dest)
   153  	}
   154  	return &iaas.{{.ResultTypeName}}{
   155  		Total:    len(results),
   156  		Count:    len(results),
   157  		From:     0,
   158  		{{$.TypeName}}: values,
   159  	}, nil
   160  {{ else if eq .MethodName "Create" -}}
   161  	result := &iaas.{{$.TypeName}}{}
   162  	copySameNameField(param, result)
   163  	fill(result, fillID, fillCreatedAt)
   164  
   165  	// TODO core logic is not implemented
   166  
   167  	s.set{{$.TypeName}}({{if $.IsGlobal}}iaas.APIDefaultZone{{else}}zone{{end}}, result)
   168  	return result, nil
   169  {{ else if eq .MethodName "Read" -}}
   170  	value := s.get{{$.TypeName}}ByID({{if $.IsGlobal}}iaas.APIDefaultZone{{else}}zone{{end}}, id)
   171  	if value == nil {
   172  		return nil, newErrorNotFound(o.key, id)
   173  	}
   174  	dest := &iaas.{{$.TypeName}}{}
   175  	copySameNameField(value, dest)
   176  	return dest, nil
   177  {{ else if eq .MethodName "Update" -}}
   178  	value, err := o.Read(ctx{{if not $.IsGlobal}}, zone{{end}}, id)
   179  	if err != nil {
   180  		return nil, err
   181  	}
   182  	copySameNameField(param, value)
   183  	fill(value, fillModifiedAt)
   184  
   185  	// TODO core logic is not implemented
   186  	return value, nil
   187  {{ else if eq .MethodName "Delete" -}}
   188  	_, err := o.Read(ctx{{if not $.IsGlobal}}, zone{{end}}, id)
   189  	if err != nil {
   190  		return err
   191  	}
   192  
   193  	// TODO core logic is not implemented
   194  
   195  	s.delete(o.key, {{if $.IsGlobal}}iaas.APIDefaultZone{{else}}zone{{end}}, id)
   196  	return nil
   197  {{ else -}}
   198  	// TODO not implemented
   199  	err := errors.New("not implements")
   200  	return {{.ReturnErrorStatement}}
   201  {{ end -}}
   202  }
   203  {{ end }}
   204  `
   205  
   206  const testTmpl = `// generated by 'github.com/sacloud/iaas-api-go/internal/tools/gen-api-fake-op'; DO NOT EDIT
   207  
   208  package fake
   209  
   210  import (
   211  {{- range .ImportStatements "testing" "github.com/sacloud/iaas-api-go" "github.com/sacloud/iaas-api-go/types"}}
   212          {{ . }}
   213  {{- end }}
   214  )
   215  
   216  func TestResourceOps(t *testing.T) {
   217  {{ range . }}
   218          if op, ok := New{{.TypeName}}Op().(iaas.{{.TypeName}}API); !ok {
   219                  t.Fatalf("%s is not iaas.{{.TypeName}}", op)
   220          }
   221  {{ end }}
   222  }`