qingstor/snips

qingcloud-sdk-go 升级遇到问题

chai2010 opened this issue · 8 comments

snips version 0.2.3

之前的 qingcloud-sdk-go 是基于 snips 0.0.9 版本生成.

snips 0.2 之后模板的结构有发生变化.

针对生成代码时产生的问题, 对 qingcloud-sdk-go 的模板文件做了更新.

qingcloud-sdk-go/template/shared.tmpl 的更新 (137-248行):

type {{$opID}}Output struct {
	Message *string `json:"message" name:"message"`
-		{{- if $operation.Response.Elements.Properties | len -}}
-			{{$data := $operation.Response.Elements}}
-			{{template "RenderProperties" passThrough $data `location:"elements"`}}
+		{{- range $keyStatus, $valueStatus := $operation.Responses -}}
+			{{- if $valueStatus.Elements.Properties | len -}}
+				{{$data := $valueStatus.Elements}}
+				{{template "RenderProperties" passThrough $data `location:"elements"`}}
+			{{- end -}}
+
	{{- end -}}
}
{{end}}

上面的修改修复了 snips 生成代码时的错误提升.

导致输出的文件发生变化. 下面是 service/cache.go 发生的变化的片段(74-82行):

type AddCacheNodesInput struct {
-	Cache      *string           `json:"cache" name:"cache" location:"params"`           // Required
-	NodeCount  *int              `json:"node_count" name:"node_count" location:"params"` // Required
-	PrivateIPs []*CachePrivateIP `json:"private_ips" name:"private_ips" location:"params"`
+	Cache      *string       `json:"cache" name:"cache" location:"params"`           // Required
+	NodeCount  *int          `json:"node_count" name:"node_count" location:"params"` // Required
+	PrivateIPs []interface{} `json:"private_ips" name:"private_ips" location:"params"`
}

其中 PrivateIPs 的类型退化为 []interface{}

命令参数:

snips -f /Users/chai/go/src/github.com/yunify/qingcloud-api-specs/2013-08-30/swagger/api_v2.0.json -t /Users/chai/go/src/github.com/yunify/qingcloud-sdk-go/template -o ./qingcloud-sdk-go
Loaded templates from /Users/chai/go/src/github.com/yunify/qingcloud-sdk-go/template
4 template(s) detected.
Loaded specification file /Users/chai/go/src/github.com/yunify/qingcloud-api-specs/2013-08-30/swagger/api_v2.0.json (Swagger-v2.0)

Snips 不会修改这个,看一下 qingcloud-api-specs 的变更吧

那暂时先维护基于 0.0.9 的sdk了

建议你再检查一下。如你 issues 所说,你修改的是 type {{$opID}}Output ,但是你指出的有变化的地方是一个 AddCacheNodesInput

修改模板的目的只是为了修复snips-0.2升级导致的snips错误。
代码生成的逻辑和之前是一样的,输出应该也是一样的.

input和output的变化是一个类型:都是自定义的类型被当作 inteface{} 处理了。

下面是output的一个变化(672-682行):

 type DescribeCacheNodesOutput struct {
-	Message      *string      `json:"message" name:"message"`
-	Action       *string      `json:"action" name:"action" location:"elements"`
-	CacheNodeSet []*CacheNode `json:"cache_node_set" name:"cache_node_set" location:"elements"`
-	RetCode      *int         `json:"ret_code" name:"ret_code" location:"elements"`
-	TotalCount   *int         `json:"total_count" name:"total_count" location:"elements"`
+	Message      *string       `json:"message" name:"message"`
+	Action       *string       `json:"action" name:"action" location:"elements"`
+	CacheNodeSet []interface{} `json:"cache_node_set" name:"cache_node_set" location:"elements"`
+	RetCode      *int          `json:"ret_code" name:"ret_code" location:"elements"`
+	TotalCount   *int          `json:"total_count" name:"total_count" location:"elements"`
 }

在这个 commit bfe433f 中我们加入了对 array 的支持,会将 array 的 item 类型填充到 array 的 ExtraType 属性中。
而在模板的类型推导中: https://github.com/yunify/qingcloud-sdk-go/blob/master/template/shared.tmpl#L17-L27object 会先于 ”“ 被推导为 interface{}
因此这个地方需要修改模板的判断逻辑。

Closed for wonfix.

shared.tmpl 针对 array 添加了调试信息:

{{define "PropertyType"}}
	{{- $property := index . 0 -}}
	{{- $disablePointer := index . 1 -}}

	{{- if eq $property.Type "object" -}}
		{{template "Type" passThrough $property.ExtraType $disablePointer}}
	{{- else if eq $property.Type "array" -}}
-		[]{{template "Type" passThrough $property.ExtraType $disablePointer}}
+		/*{{printf "%q,%q,%q" $property.Name $property.Type $property.ExtraType}}*/[]{{template "Type" passThrough $property.ExtraType $disablePointer}}
	{{- else if eq $property.Type "map" -}}
		map[string]{{template "Type" passThrough $property.ExtraType $disablePointer}}
	{{- else if eq $property.Type "any" -}}
		{{template "Type" passThrough $property.Type $disablePointer}}
	{{- else -}}
		{{template "Type" passThrough $property.Type $disablePointer}}
	{{- end -}}
{{end}}

在 types.go 的输出到结果中,Tags 字段的 ExtraType 类型是 “object”:

 	RDBName             *string    `json:"rdb_name" name:"rdb_name"`
 	RDBType             *int       `json:"rdb_type" name:"rdb_type"`
 	// Status's available values: pending, active, stopped, deleted, suspended, ceased
-	Status      *string `json:"status" name:"status"`
-	StatusTime  *string `json:"status_time" name:"status_time"`
-	StorageSize *int    `json:"storage_size" name:"storage_size"`
-	Tags        []*Tag  `json:"tags" name:"tags"`
+	Status                                        *string `json:"status" name:"status"`
+	StatusTime                                    *string `json:"status_time" name:"status_time"`
+	StorageSize                                   *int    `json:"storage_size" name:"storage_size"`
+	Tags/*"tags","array","object"*/ []interface{}         `json:"tags" name:"tags"`
 	// TransitionStatus's available values: creating, stopping, starting, deleting, backup-creating, temp-creating, configuring, switching, invalid-tackling, resizing, suspending, ceasing, instance-ceasing, vxnet-leaving, vxnet-joining
 	TransitionStatus *string `json:"transition_status" name:"transition_status"`
 	VxNet            *VxNet  `json:"vxnet" name:"vxnet"`

那么如何根据 ExtraType 的值 "object" 解析出 tags 数组元素的真正类型 Tag 呢?

Moved to yunify/qingcloud-sdk-go#55 for not related with snips.