Repository: sacloud/usacloud
Pull request #545 (2020-11-05 06:38:42)

 Generate code to convert CLI parameters to service requests
from: #534 
closes: #542 
related: #543 

CLIパラメータからlibsacloud serviceを呼び出す際のパラメータ(xxxRequest)への変換処理をコード生成する。

### 現在の仕様

DSLで定義したResource-Commandのうち、`Parameters`が指定されている場合に変換コードを生成する。
対象のlibsacloud servicesはデフォルトだと`github.com/sacloud/libsacloud/v2/helper/service/{{ .Resource.Nameを小文字にしたもの}}`パッケージの`{{ .Command.Name }}Request`structとなる。

Commandの`ServiceFuncAltName`が指定されていた場合は`{{ .Command.ServiceFuncAltName }}Request`となる。
(Command名とservicesのfunc名が異なる例: `List`など)


Patch:
diff --git a/go.mod b/go.mod
index b6c01402..59b062b2 100644
--- a/go.mod
+++ b/go.mod
@@ -17,7 +17,7 @@ require (
 	github.com/olekukonko/tablewriter v0.0.0-20180506121414-d4647c9c7a84
 	github.com/sacloud/ftps v1.1.0
 	github.com/sacloud/go-jmespath v0.0.0-20190125082617-862639817e08
-	github.com/sacloud/libsacloud/v2 v2.8.9-0.20201104084812-02587fb2e64c
+	github.com/sacloud/libsacloud/v2 v2.8.9-0.20201105050622-3b40f109ba37
 	github.com/spf13/cobra v1.0.0
 	github.com/spf13/pflag v1.0.5
 	github.com/stretchr/testify v1.6.1
diff --git a/go.sum b/go.sum
index f4bda0c1..1743aee7 100644
--- a/go.sum
+++ b/go.sum
@@ -129,8 +129,8 @@ github.com/sacloud/ftps v1.1.0 h1:cYv+b6qhrIT8msfx64XXRJzbv5S+Dqwb/rXa5Y641XA=
 github.com/sacloud/ftps v1.1.0/go.mod h1:h4awhOi3PEyhKLj1FpXjoVV5yVkmRUU+d5L95EwX2JU=
 github.com/sacloud/go-jmespath v0.0.0-20190125082617-862639817e08 h1:hGFzyq3AgiEHgI9xYPrtbK466gP7AimFCjrn3nZktc8=
 github.com/sacloud/go-jmespath v0.0.0-20190125082617-862639817e08/go.mod h1:PLy4tK2PN6G8fxd/cCWH6db2mJGmUlflYs4ASdfNulg=
-github.com/sacloud/libsacloud/v2 v2.8.9-0.20201104084812-02587fb2e64c h1:E1wBQhJsPw1VfzmrLHXr77BDQSxqFvHRPWzTtEGkOeM=
-github.com/sacloud/libsacloud/v2 v2.8.9-0.20201104084812-02587fb2e64c/go.mod h1:gRNUdloSQqgQfTEMpot80TK7REly0TSME6dn5aZl3GY=
+github.com/sacloud/libsacloud/v2 v2.8.9-0.20201105050622-3b40f109ba37 h1:NyBVXBJvHIyc7xoubDsdyad3wja7+ywCoULeaZqh/4c=
+github.com/sacloud/libsacloud/v2 v2.8.9-0.20201105050622-3b40f109ba37/go.mod h1:gRNUdloSQqgQfTEMpot80TK7REly0TSME6dn5aZl3GY=
 github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
diff --git a/pkg/cmd/conv/converter.go b/pkg/cmd/conv/converter.go
new file mode 100644
index 00000000..a3abb2dc
--- /dev/null
+++ b/pkg/cmd/conv/converter.go
@@ -0,0 +1,69 @@
+// Copyright 2017-2020 The Usacloud Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package conv
+
+import (
+	"fmt"
+
+	"github.com/sacloud/libsacloud/v2/sacloud/ostype"
+
+	"github.com/sacloud/libsacloud/v2/pkg/mapconv"
+	"github.com/sacloud/libsacloud/v2/sacloud/types"
+)
+
+var converter = &mapconv.Decoder{
+	Config: &mapconv.DecoderConfig{
+		TagName: mapconv.DefaultMapConvTag,
+		FilterFuncs: map[string]mapconv.FilterFunc{
+			"disk_plan_to_id": diskPlanToID,
+			"os_type":         strToOSType,
+		},
+	},
+}
+
+// ConvertTo mapconvでの変換
+func ConvertTo(src, dest interface{}) error {
+	return converter.ConvertTo(src, dest)
+}
+
+// ConvertFrom mapconvでの変換
+func ConvertFrom(src, dest interface{}) error {
+	return converter.ConvertFrom(src, dest)
+}
+
+func diskPlanToID(v interface{}) (interface{}, error) {
+	s, ok := v.(string)
+	if !ok {
+		return nil, fmt.Errorf("invalid disk plan: %v", v)
+	}
+	for diskPlanName, id := range types.DiskPlanIDMap {
+		if diskPlanName == s {
+			return id, nil
+		}
+	}
+	return nil, fmt.Errorf("disk plan %s not found", s)
+}
+
+func strToOSType(v interface{}) (interface{}, error) {
+	s, ok := v.(string)
+	if !ok {
+		return nil, fmt.Errorf("invalid os type: %v", v)
+	}
+	ot := ostype.StrToOSType(s)
+	if ot == ostype.Custom {
+		return nil, fmt.Errorf("os type %s not found", s)
+	}
+	return ot, nil
+}
diff --git a/pkg/cmd/disk/create.go b/pkg/cmd/disk/create.go
index 4866bab3..453e108c 100644
--- a/pkg/cmd/disk/create.go
+++ b/pkg/cmd/disk/create.go
@@ -29,14 +29,14 @@ type CreateParameter struct {
 	Description     string     `cli:",category=disk"`
 	Tags            []string   `cli:",category=disk"`
 	IconID          types.ID   `cli:",category=disk"`
-	DiskPlanID      string     `cli:",category=disk" validate:"oneof=ssd hdd"` // TODO パラメータ変換ロジック(string -> types.ID)をコード生成と組み合わせる
+	DiskPlan        string     `cli:",category=disk" mapconv:"DiskPlanID,filters=disk_plan_to_id" validate:"oneof=ssd hdd"`
 	Connection      string     `cli:",category=disk" validate:"oneof=virtio ide"`
 	SourceDiskID    types.ID   `cli:",category=disk"`
 	SourceArchiveID types.ID   `cli:",category=disk"`
 	ServerID        types.ID   `cli:",category=disk"`
 	SizeGB          int        `cli:"size,category=disk"`
 	DistantFrom     []types.ID `cli:",category=disk"`
-	OSType          string     `cli:",category=disk"` // TODO 設定できる値の例示をどうするか
+	OSType          string     `cli:",category=disk" mapconv:",filters=os_type"` // TODO 設定できる値の例示をどうするか
 
 	*base.OutputParameter `cli:",squash" mapconv:"-"`
 }
diff --git a/pkg/cmd/disk/create_gen.go b/pkg/cmd/disk/create_gen.go
index b42dc446..76013ecb 100644
--- a/pkg/cmd/disk/create_gen.go
+++ b/pkg/cmd/disk/create_gen.go
@@ -17,7 +17,9 @@
 package disk
 
 import (
+	service "github.com/sacloud/libsacloud/v2/helper/service/disk"
 	"github.com/sacloud/usacloud/pkg/cmd/base"
+	"github.com/sacloud/usacloud/pkg/cmd/conv"
 	"github.com/spf13/cobra"
 	"github.com/spf13/pflag"
 )
@@ -27,7 +29,7 @@ func (p *CreateParameter) BuildFlags(fs *pflag.FlagSet) {
 	fs.StringVarP(&p.Description, "description", "", p.Description, "")
 	fs.StringSliceVarP(&p.Tags, "tags", "", p.Tags, "")
 	fs.VarP(base.NewIDFlag(&p.IconID, &p.IconID), "icon-id", "", "")
-	fs.StringVarP(&p.DiskPlanID, "disk-plan-id", "", p.DiskPlanID, "")
+	fs.StringVarP(&p.DiskPlan, "disk-plan", "", p.DiskPlan, "")
 	fs.StringVarP(&p.Connection, "connection", "", p.Connection, "")
 	fs.VarP(base.NewIDFlag(&p.SourceDiskID, &p.SourceDiskID), "source-disk-id", "", "")
 	fs.VarP(base.NewIDFlag(&p.SourceArchiveID, &p.SourceArchiveID), "source-archive-id", "", "")
@@ -63,7 +65,7 @@ func (p *CreateParameter) CategorizedFlagSets(cmd *cobra.Command) []*base.FlagSe
 		fs.AddFlag(cmd.LocalFlags().Lookup("description"))
 		fs.AddFlag(cmd.LocalFlags().Lookup("tags"))
 		fs.AddFlag(cmd.LocalFlags().Lookup("icon-id"))
-		fs.AddFlag(cmd.LocalFlags().Lookup("disk-plan-id"))
+		fs.AddFlag(cmd.LocalFlags().Lookup("disk-plan"))
 		fs.AddFlag(cmd.LocalFlags().Lookup("connection"))
 		fs.AddFlag(cmd.LocalFlags().Lookup("source-disk-id"))
 		fs.AddFlag(cmd.LocalFlags().Lookup("source-archive-id"))
@@ -93,3 +95,8 @@ func (p *CreateParameter) CategorizedFlagSets(cmd *cobra.Command) []*base.FlagSe
 
 	return sets
 }
+
+func (p *CreateParameter) ServiceRequest() (*service.CreateRequest, error) {
+	req := &service.CreateRequest{}
+	return req, conv.ConvertTo(p, req)
+}
diff --git a/pkg/cmd/disk/list_gen.go b/pkg/cmd/disk/list_gen.go
index d355aaaf..a779ef08 100644
--- a/pkg/cmd/disk/list_gen.go
+++ b/pkg/cmd/disk/list_gen.go
@@ -17,7 +17,9 @@
 package disk
 
 import (
+	service "github.com/sacloud/libsacloud/v2/helper/service/disk"
 	"github.com/sacloud/usacloud/pkg/cmd/base"
+	"github.com/sacloud/usacloud/pkg/cmd/conv"
 	"github.com/spf13/cobra"
 	"github.com/spf13/pflag"
 )
@@ -83,3 +85,8 @@ func (p *ListParameter) CategorizedFlagSets(cmd *cobra.Command) []*base.FlagSet
 
 	return sets
 }
+
+func (p *ListParameter) ServiceRequest() (*service.FindRequest, error) {
+	req := &service.FindRequest{}
+	return req, conv.ConvertTo(p, req)
+}
diff --git a/pkg/cmd/disk/update_gen.go b/pkg/cmd/disk/update_gen.go
index 2fb5f114..cbc3312e 100644
--- a/pkg/cmd/disk/update_gen.go
+++ b/pkg/cmd/disk/update_gen.go
@@ -17,7 +17,9 @@
 package disk
 
 import (
+	service "github.com/sacloud/libsacloud/v2/helper/service/disk"
 	"github.com/sacloud/usacloud/pkg/cmd/base"
+	"github.com/sacloud/usacloud/pkg/cmd/conv"
 	"github.com/spf13/cobra"
 	"github.com/spf13/pflag"
 )
@@ -79,3 +81,8 @@ func (p *UpdateParameter) CategorizedFlagSets(cmd *cobra.Command) []*base.FlagSe
 
 	return sets
 }
+
+func (p *UpdateParameter) ServiceRequest() (*service.UpdateRequest, error) {
+	req := &service.UpdateRequest{}
+	return req, conv.ConvertTo(p, req)
+}
diff --git a/pkg/define/disk.go b/pkg/define/disk.go
index 3d9a07ff..99e43b2b 100644
--- a/pkg/define/disk.go
+++ b/pkg/define/disk.go
@@ -30,6 +30,7 @@ func DiskResource() *schema.Resource {
 			Type:               schema.CommandList,
 			Aliases:            []string{"ls", "find", "select"},
 			Parameters:         &disk.ListParameter{}, // TODO v1向け試験実装
+			ServiceFuncAltName: "Find",                // TODO v1向け試験実装
 			Params:             diskListParam(),
 			TableType:          output.TableSimple,
 			TableColumnDefines: diskListColumns(),
diff --git a/pkg/schema/command.go b/pkg/schema/command.go
index 586bd2c6..6a2912af 100644
--- a/pkg/schema/command.go
+++ b/pkg/schema/command.go
@@ -32,11 +32,12 @@ type Command struct {
 	Order    int
 
 	// TODO v0向け、あとで消す
-	Params          map[string]*Schema
-	ParamCategories []Category
+	Params map[string]*Schema
+	// TODO v1向け
+	Parameters         interface{} // cmd/xxx配下の各コマンドパラメータstruct
+	ServiceFuncAltName string
 
-	// v1向け
-	Parameters interface{} // cmd/xxx配下の各コマンドパラメータstruct
+	ParamCategories []Category
 
 	AltResource         string // 空の場合はResourceのキーをCamelizeしてsacloud.XXXを対象とする。
 	ListResultFieldName string
diff --git a/tools/command.go b/tools/command.go
index 8070649f..d4189067 100644
--- a/tools/command.go
+++ b/tools/command.go
@@ -289,6 +289,14 @@ func (c *Command) CLICommandParameterTypeName() string {
 	return structs.Name(c.Command.Parameters)
 }
 
+func (c *Command) ServiceRequestTypeName() string {
+	name := c.Name
+	if c.ServiceFuncAltName != "" {
+		name = c.ServiceFuncAltName
+	}
+	return fmt.Sprintf("%sRequest", utils.ToCamelCaseName(name))
+}
+
 func (c *Command) CategorizedParameterFields() []*CategorizedParameterFields {
 	if c.Parameters == nil {
 		return nil
diff --git a/tools/gen-cli-params-v1/main.go b/tools/gen-cli-params-v1/main.go
index e2719e93..22dd0a25 100644
--- a/tools/gen-cli-params-v1/main.go
+++ b/tools/gen-cli-params-v1/main.go
@@ -74,9 +74,11 @@ var srcTemplate = `// Code generated by 'github.com/sacloud/usacloud/tools/gen-c
 package {{ .PackageDirName }}
 
 import (
+	service "github.com/sacloud/libsacloud/v2/helper/service/{{ .PackageDirName }}"
 	"github.com/sacloud/libsacloud/v2/sacloud/pointer"
 	"github.com/sacloud/libsacloud/v2/sacloud/types"
 	"github.com/sacloud/usacloud/pkg/cmd/base"
+	"github.com/sacloud/usacloud/pkg/cmd/conv"
 	"github.com/spf13/pflag"
 )
 
@@ -114,4 +116,9 @@ func (p *{{.CLICommandParameterTypeName}}) CategorizedFlagSets(cmd *cobra.Comman
 	{{ end }}
 	return sets	
 }
+
+func (p *{{.CLICommandParameterTypeName}}) ServiceRequest() (*service.{{.ServiceRequestTypeName}}, error) {
+	req := &service.{{.ServiceRequestTypeName}}{}
+	return req, conv.ConvertTo(p, req)
+}
 `
diff --git a/vendor/github.com/sacloud/libsacloud/v2/pkg/mapconv/mapconv.go b/vendor/github.com/sacloud/libsacloud/v2/pkg/mapconv/mapconv.go
index b20fe489..71777f40 100644
--- a/vendor/github.com/sacloud/libsacloud/v2/pkg/mapconv/mapconv.go
+++ b/vendor/github.com/sacloud/libsacloud/v2/pkg/mapconv/mapconv.go
@@ -16,6 +16,7 @@ package mapconv
 
 import (
 	"errors"
+	"fmt"
 	"reflect"
 	"strings"
 
@@ -23,17 +24,23 @@ import (
 	"github.com/mitchellh/mapstructure"
 )
 
-const defaultMapConvTag = "mapconv"
+// DefaultMapConvTag デフォルトのmapconvタグ名
+const DefaultMapConvTag = "mapconv"
 
 // DecoderConfig mapconvでの変換の設定
 type DecoderConfig struct {
-	TagName string
+	TagName     string
+	FilterFuncs map[string]FilterFunc
 }
 
+// FilterFunc mapconvでの変換時に適用するフィルタ
+type FilterFunc func(v interface{}) (interface{}, error)
+
 // TagInfo mapconvタグの情報
 type TagInfo struct {
 	Ignore       bool
 	SourceFields []string
+	Filters      []string
 	DefaultValue interface{}
 	OmitEmpty    bool
 	Recursive    bool
@@ -76,6 +83,18 @@ func (d *Decoder) ConvertTo(source interface{}, dest interface{}) error {
 				}
 			}
 
+			for _, filter := range tags.Filters {
+				filterFunc, ok := d.Config.FilterFuncs[filter]
+				if !ok {
+					return fmt.Errorf("filter %s not exists", filter)
+				}
+				filtered, err := filterFunc(value)
+				if err != nil {
+					return fmt.Errorf("failed to apply the filter: %s", err)
+				}
+				value = filtered
+			}
+
 			if tags.Squash {
 				d := Map(make(map[string]interface{}))
 				err := ConvertTo(value, &d)
@@ -162,6 +181,18 @@ func (d *Decoder) ConvertFrom(source interface{}, dest interface{}) error {
 				continue
 			}
 
+			for _, filter := range tags.Filters {
+				filterFunc, ok := d.Config.FilterFuncs[filter]
+				if !ok {
+					return fmt.Errorf("filter %s not exists", filter)
+				}
+				filtered, err := filterFunc(value)
+				if err != nil {
+					return fmt.Errorf("failed to apply the filter: %s", err)
+				}
+				value = filtered
+			}
+
 			if tags.Recursive {
 				t := reflect.TypeOf(f.Value())
 				if t.Kind() == reflect.Slice {
@@ -210,23 +241,24 @@ func (d *Decoder) ConvertFrom(source interface{}, dest interface{}) error {
 
 // ConvertTo converts struct which input by mapconv to plain models
 func ConvertTo(source interface{}, dest interface{}) error {
-	decoder := &Decoder{Config: &DecoderConfig{TagName: defaultMapConvTag}}
+	decoder := &Decoder{Config: &DecoderConfig{TagName: DefaultMapConvTag}}
 	return decoder.ConvertTo(source, dest)
 }
 
 // ConvertFrom converts struct which input by mapconv from plain models
 func ConvertFrom(source interface{}, dest interface{}) error {
-	decoder := &Decoder{Config: &DecoderConfig{TagName: defaultMapConvTag}}
+	decoder := &Decoder{Config: &DecoderConfig{TagName: DefaultMapConvTag}}
 	return decoder.ConvertFrom(source, dest)
 }
 
 // ParseMapConvTag mapconvタグを文字列で受け取りパースしてTagInfoを返す
 func (d *Decoder) ParseMapConvTag(tagBody string) TagInfo {
 	tokens := strings.Split(tagBody, ",")
-	key := tokens[0]
+	key := strings.TrimSpace(tokens[0])
 
 	keys := strings.Split(key, "/")
 	var defaultValue interface{}
+	var filters []string
 	var ignore, omitEmpty, recursive, squash, isSlice bool
 
 	for _, k := range keys {
@@ -244,6 +276,8 @@ func (d *Decoder) ParseMapConvTag(tagBody string) TagInfo {
 			continue
 		}
 
+		token = strings.TrimSpace(token)
+
 		switch {
 		case strings.HasPrefix(token, "omitempty"):
 			omitEmpty = true
@@ -251,6 +285,11 @@ func (d *Decoder) ParseMapConvTag(tagBody string) TagInfo {
 			recursive = true
 		case strings.HasPrefix(token, "squash"):
 			squash = true
+		case strings.HasPrefix(token, "filters"):
+			keyValue := strings.Split(token, "=")
+			if len(keyValue) > 1 {
+				filters = strings.Split(strings.Join(keyValue[1:], ""), " ")
+			}
 		case strings.HasPrefix(token, "default"):
 			keyValue := strings.Split(token, "=")
 			if len(keyValue) > 1 {
@@ -266,5 +305,6 @@ func (d *Decoder) ParseMapConvTag(tagBody string) TagInfo {
 		Recursive:    recursive,
 		Squash:       squash,
 		IsSlice:      isSlice,
+		Filters:      filters,
 	}
 }
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 7f66a455..fbb23f95 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -47,7 +47,7 @@ github.com/pmezard/go-difflib/difflib
 github.com/sacloud/ftps
 # github.com/sacloud/go-jmespath v0.0.0-20190125082617-862639817e08
 github.com/sacloud/go-jmespath
-# github.com/sacloud/libsacloud/v2 v2.8.9-0.20201104084812-02587fb2e64c
+# github.com/sacloud/libsacloud/v2 v2.8.9-0.20201105050622-3b40f109ba37
 github.com/sacloud/libsacloud/v2
 github.com/sacloud/libsacloud/v2/helper/api
 github.com/sacloud/libsacloud/v2/helper/builder


Test patch:
diff --git a/pkg/cmd/disk/create_test.go b/pkg/cmd/disk/create_test.go
new file mode 100644
index 00000000..57a814c6
--- /dev/null
+++ b/pkg/cmd/disk/create_test.go
@@ -0,0 +1,61 @@
+// Copyright 2017-2020 The Usacloud Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package disk
+
+import (
+	"testing"
+
+	"github.com/sacloud/libsacloud/v2/sacloud/ostype"
+
+	"github.com/sacloud/usacloud/pkg/cmd/conv"
+
+	"github.com/sacloud/libsacloud/v2/sacloud/types"
+
+	"github.com/sacloud/libsacloud/v2/helper/service/disk"
+	"github.com/stretchr/testify/require"
+)
+
+func TestCreate_ConvertToServiceRequest(t *testing.T) {
+	t.Run("full", func(t *testing.T) {
+		in := &CreateParameter{
+			Zone:        "is1a",
+			Name:        "name",
+			Description: "desc",
+			Tags:        []string{"tag1", "tag2"},
+			IconID:      types.ID(1),
+			DiskPlan:    "ssd",
+			Connection:  types.DiskConnections.VirtIO.String(),
+			SizeGB:      20,
+			OSType:      "ubuntu",
+		}
+
+		out := &disk.CreateRequest{}
+		if err := conv.ConvertTo(in, out); err != nil {
+			t.Fatal(err)
+		}
+
+		require.EqualValues(t, &disk.CreateRequest{
+			Zone:        "is1a",
+			Name:        "name",
+			Description: "desc",
+			Tags:        types.Tags{"tag1", "tag2"},
+			IconID:      types.ID(1),
+			DiskPlanID:  types.DiskPlans.SSD,
+			Connection:  types.DiskConnections.VirtIO,
+			SizeGB:      20,
+			OSType:      ostype.Ubuntu,
+		}, out)
+	})
+}
diff --git a/pkg/cmd/disk/update_test.go b/pkg/cmd/disk/update_test.go
index 2952910b..533132e5 100644
--- a/pkg/cmd/disk/update_test.go
+++ b/pkg/cmd/disk/update_test.go
@@ -17,11 +17,12 @@ package disk
 import (
 	"testing"
 
+	"github.com/sacloud/usacloud/pkg/cmd/conv"
+
 	"github.com/sacloud/libsacloud/v2/sacloud/pointer"
 	"github.com/sacloud/libsacloud/v2/sacloud/types"
 
 	"github.com/sacloud/libsacloud/v2/helper/service/disk"
-	"github.com/sacloud/libsacloud/v2/pkg/mapconv"
 	"github.com/stretchr/testify/require"
 )
 
@@ -40,7 +41,7 @@ func TestUpdate_ConvertToServiceRequest(t *testing.T) {
 		}
 
 		out := &disk.UpdateRequest{}
-		if err := mapconv.ConvertTo(in, out); err != nil {
+		if err := conv.ConvertTo(in, out); err != nil {
 			t.Fatal(err)
 		}
 
@@ -65,7 +66,7 @@ func TestUpdate_ConvertToServiceRequest(t *testing.T) {
 		}
 
 		out := &disk.UpdateRequest{}
-		if err := mapconv.ConvertTo(in, out); err != nil {
+		if err := conv.ConvertTo(in, out); err != nil {
 			t.Fatal(err)
 		}
 
@@ -92,7 +93,7 @@ func TestUpdate_ConvertToServiceRequest(t *testing.T) {
 		}
 
 		out := &disk.UpdateRequest{}
-		if err := mapconv.ConvertTo(in, out); err != nil {
+		if err := conv.ConvertTo(in, out); err != nil {
 			t.Fatal(err)
 		}