diff --git a/go.mod b/go.mod index 4b7d390b..450d20bd 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/mod v0.19.0 gopkg.in/yaml.v3 v3.0.1 gotest.tools/v3 v3.5.1 - kcl-lang.io/kcl-go v0.9.2 + kcl-lang.io/kcl-go v0.10.0-alpha.1.0.20240730084238-c647f95196d2 ) require ( @@ -68,7 +68,7 @@ require ( github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/goccy/go-yaml v1.11.3 // indirect + github.com/goccy/go-yaml v1.12.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect @@ -142,13 +142,13 @@ require ( google.golang.org/protobuf v1.34.2 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 // indirect - kcl-lang.io/lib v0.9.2 // indirect + kcl-lang.io/lib v0.10.0-alpha.1 // indirect ) require ( github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/go-git/go-git/v5 v5.12.0 - github.com/gofrs/flock v0.12.0 + github.com/gofrs/flock v0.12.1 github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-getter v1.7.5 diff --git a/go.sum b/go.sum index dd90f8d9..4443f033 100644 --- a/go.sum +++ b/go.sum @@ -374,10 +374,10 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/goccy/go-yaml v1.11.3 h1:B3W9IdWbvrUu2OYQGwvU1nZtvMQJPBKgBUuweJjLj6I= -github.com/goccy/go-yaml v1.11.3/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= -github.com/gofrs/flock v0.12.0 h1:xHW8t8GPAiGtqz7KxiSqfOEXwpOaqhpYZrTE2MQBgXY= -github.com/gofrs/flock v0.12.0/go.mod h1:FirDy1Ing0mI2+kB6wk+vyyAH+e6xiE+EYA0jnzV9jc= +github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM= +github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= +github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= +github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 h1:zN2lZNZRflqFyxVaTIU61KNKQ9C0055u9CAfpmqUvo4= github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3/go.mod h1:nPpo7qLxd6XL3hWJG/O60sR8ZKfMCiIoNap5GvD12KU= @@ -1300,10 +1300,10 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk= k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -kcl-lang.io/kcl-go v0.9.2 h1:Mgb/+ha3D+vkCO8ttEbIoZitb+cKsjDsX0zeONseTc0= -kcl-lang.io/kcl-go v0.9.2/go.mod h1:mTlLNhhk76+CLMRKkA//wROCs/XOVl+yv6qai/Nl3+A= -kcl-lang.io/lib v0.9.2 h1:fTYAQYBFQDqEUxpxcfG2Twrm4tYLBe4ZfecLWXeXe9I= -kcl-lang.io/lib v0.9.2/go.mod h1:tu+tzwGgHLzYZSIxUG/ntipStrxZd6OvutWYPTxS7cs= +kcl-lang.io/kcl-go v0.10.0-alpha.1.0.20240730084238-c647f95196d2 h1:GbX+J5OE+sPbFz2HPMD0oDHnvdJB055Il7brmY+5Wsg= +kcl-lang.io/kcl-go v0.10.0-alpha.1.0.20240730084238-c647f95196d2/go.mod h1:q1NZjPbx9XnR7gd1SEtPng82meJNx8sW/wRcRW8DGJs= +kcl-lang.io/lib v0.10.0-alpha.1 h1:GMVB75Pc1W29gcl1WlVgdgUscH6h+d9No0fzBH0rNYg= +kcl-lang.io/lib v0.10.0-alpha.1/go.mod h1:tu+tzwGgHLzYZSIxUG/ntipStrxZd6OvutWYPTxS7cs= oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo= oras.land/oras-go v1.2.5/go.mod h1:PuAwRShRZCsZb7g8Ar3jKKQR/2A/qN+pkYxIOd/FAoo= oras.land/oras-go/v2 v2.5.0 h1:o8Me9kLY74Vp5uw07QXPiitjsw7qNXi8Twd+19Zf02c= diff --git a/pkg/api/kpm_pkg.go b/pkg/api/kpm_pkg.go index 7d649b81..3860ad4c 100644 --- a/pkg/api/kpm_pkg.go +++ b/pkg/api/kpm_pkg.go @@ -7,6 +7,7 @@ import ( "kcl-lang.io/kcl-go/pkg/kcl" "kcl-lang.io/kcl-go/pkg/spec/gpyrpc" + "kcl-lang.io/kcl-go/pkg/tools/gen" "kcl-lang.io/kpm/pkg/client" "kcl-lang.io/kpm/pkg/constants" "kcl-lang.io/kpm/pkg/errors" @@ -248,6 +249,34 @@ func (pkg *KclPackage) GetSchemaTypeMappingWithFilters(filterFuncs []KclTypeFilt return schemaTypes, nil } +// ExportSwaggerV2Spec extracts the swagger v2 representation of a kcl package +// with external dependencies. +func (pkg *KclPackage) ExportSwaggerV2Spec() (*gen.SwaggerV2Spec, error) { + spec := &gen.SwaggerV2Spec{ + Swagger: "2.0", + Definitions: make(map[string]*gen.KclOpenAPIType), + Paths: map[string]interface{}{}, + Info: gen.SpecInfo{ + Title: pkg.GetPkgName(), + Version: pkg.GetVersion(), + }, + } + pkgMapping, err := pkg.GetAllSchemaTypeMapping() + if err != nil { + return spec, err + } + // package path -> package + for packagePath, p := range pkgMapping { + // schema name -> schema type + for _, t := range p { + id := gen.SchemaId(packagePath, t.KclType) + spec.Definitions[id] = gen.GetKclOpenAPIType(packagePath, t.KclType, false) + fmt.Printf("exporting openAPI spec from schema %s\n", id) + } + } + return spec, nil +} + type KclTypeFilterFunc func(kt *KclType) bool // IsSchema returns true if the type is schema. diff --git a/pkg/api/kpm_pkg_test.go b/pkg/api/kpm_pkg_test.go index 7d91fe71..d5c41c8f 100644 --- a/pkg/api/kpm_pkg_test.go +++ b/pkg/api/kpm_pkg_test.go @@ -208,3 +208,16 @@ func TestGetEntries(t *testing.T) { assert.Equal(t, res.GetRawYamlResult(), "sub: test in sub") assert.Equal(t, res.GetRawJsonResult(), "{\"sub\": \"test in sub\"}") } + +func TestExportSwaggerV2Spec(t *testing.T) { + pkg_path := filepath.Join(getTestDir("test_kpm_package"), "export_swagger", "aaa") + pkg, err := GetKclPackage(pkg_path) + assert.Equal(t, err, nil) + kpmcli, err := client.NewKpmClient() + assert.Equal(t, err, nil) + err = kpmcli.ResolvePkgDepsMetadata(pkg.pkg, true) + assert.Equal(t, err, nil) + spec, err := pkg.ExportSwaggerV2Spec() + assert.Equal(t, err, nil) + assert.Equal(t, len(spec.Definitions), 1) +} diff --git a/pkg/api/test_data/test_kpm_package/export_swagger/aaa/kcl.mod b/pkg/api/test_data/test_kpm_package/export_swagger/aaa/kcl.mod new file mode 100644 index 00000000..79bceba5 --- /dev/null +++ b/pkg/api/test_data/test_kpm_package/export_swagger/aaa/kcl.mod @@ -0,0 +1,7 @@ +[package] +name = "aaa" +edition = "0.0.1" +version = "0.0.1" + +[dependencies] +bbb = { path = "../bbb" } diff --git a/pkg/api/test_data/test_kpm_package/export_swagger/aaa/kcl.mod.lock b/pkg/api/test_data/test_kpm_package/export_swagger/aaa/kcl.mod.lock new file mode 100644 index 00000000..7ff35292 --- /dev/null +++ b/pkg/api/test_data/test_kpm_package/export_swagger/aaa/kcl.mod.lock @@ -0,0 +1,6 @@ +[dependencies] + [dependencies.bbb] + name = "bbb" + full_name = "bbb_0.0.1" + version = "0.0.1" + sum = "/PGJJE6Rp0lAsq3n9RUZ34jPGfwzYIZESs17L6kSG/Y=" diff --git a/pkg/api/test_data/test_kpm_package/export_swagger/aaa/main.k b/pkg/api/test_data/test_kpm_package/export_swagger/aaa/main.k new file mode 100644 index 00000000..677b8581 --- /dev/null +++ b/pkg/api/test_data/test_kpm_package/export_swagger/aaa/main.k @@ -0,0 +1,10 @@ +import bbb + +schema A: + b: bbb.B + +a = A { + b: bbb.B { + name = "name" + } +} diff --git a/pkg/api/test_data/test_kpm_package/export_swagger/bbb/kcl.mod b/pkg/api/test_data/test_kpm_package/export_swagger/bbb/kcl.mod new file mode 100644 index 00000000..e9ea10a5 --- /dev/null +++ b/pkg/api/test_data/test_kpm_package/export_swagger/bbb/kcl.mod @@ -0,0 +1,5 @@ +[package] +name = "bbb" +edition = "0.0.1" +version = "0.0.1" + diff --git a/pkg/api/test_data/test_kpm_package/export_swagger/bbb/kcl.mod.lock b/pkg/api/test_data/test_kpm_package/export_swagger/bbb/kcl.mod.lock new file mode 100644 index 00000000..e69de29b diff --git a/pkg/api/test_data/test_kpm_package/export_swagger/bbb/main.k b/pkg/api/test_data/test_kpm_package/export_swagger/bbb/main.k new file mode 100644 index 00000000..21dad4f9 --- /dev/null +++ b/pkg/api/test_data/test_kpm_package/export_swagger/bbb/main.k @@ -0,0 +1,2 @@ +schema B: + name: str \ No newline at end of file diff --git a/pkg/git/git.go b/pkg/git/git.go index b9697d32..ceca49b4 100644 --- a/pkg/git/git.go +++ b/pkg/git/git.go @@ -128,34 +128,34 @@ func (cloneOpts *CloneOptions) CloneBare() (*git.Repository, error) { // CheckoutFromBare checks out the specified reference from a bare repository func (cloneOpts *CloneOptions) CheckoutFromBare() error { - if !cloneOpts.Bare { - return errors.New("repository is not bare") - } - - repo, err := git.PlainOpen(cloneOpts.LocalPath) - if err != nil { - return err - } - - worktree, err := repo.Worktree() - if err != nil { - return err - } - - checkoutOpts := &git.CheckoutOptions{ - Force: true, - } - - if cloneOpts.Branch != "" { - checkoutOpts.Branch = plumbing.NewBranchReferenceName(cloneOpts.Branch) - } else if cloneOpts.Tag != "" { - checkoutOpts.Branch = plumbing.NewTagReferenceName(cloneOpts.Tag) - } else if cloneOpts.Commit != "" { - hash := plumbing.NewHash(cloneOpts.Commit) - checkoutOpts.Hash = hash - } - - return worktree.Checkout(checkoutOpts) + if !cloneOpts.Bare { + return errors.New("repository is not bare") + } + + repo, err := git.PlainOpen(cloneOpts.LocalPath) + if err != nil { + return err + } + + worktree, err := repo.Worktree() + if err != nil { + return err + } + + checkoutOpts := &git.CheckoutOptions{ + Force: true, + } + + if cloneOpts.Branch != "" { + checkoutOpts.Branch = plumbing.NewBranchReferenceName(cloneOpts.Branch) + } else if cloneOpts.Tag != "" { + checkoutOpts.Branch = plumbing.NewTagReferenceName(cloneOpts.Tag) + } else if cloneOpts.Commit != "" { + hash := plumbing.NewHash(cloneOpts.Commit) + checkoutOpts.Hash = hash + } + + return worktree.Checkout(checkoutOpts) } // Clone clones a git repository @@ -204,22 +204,22 @@ func CloneWithOpts(opts ...CloneOption) (*git.Repository, error) { var repo *git.Repository - if cloneOpts.Bare { - repo, err = cloneOpts.CloneBare() - if err != nil { - return nil, err - } - - err = cloneOpts.CheckoutFromBare() - if err != nil { - return nil, err - } - } else { - repo, err = cloneOpts.Clone() - if err != nil { - return nil, err - } - } + if cloneOpts.Bare { + repo, err = cloneOpts.CloneBare() + if err != nil { + return nil, err + } + + err = cloneOpts.CheckoutFromBare() + if err != nil { + return nil, err + } + } else { + repo, err = cloneOpts.Clone() + if err != nil { + return nil, err + } + } return repo, nil }