diff --git a/cmd/analyzer/main.go b/cmd/analyzer/main.go index 374f1d04..f96fcfe9 100644 --- a/cmd/analyzer/main.go +++ b/cmd/analyzer/main.go @@ -2,6 +2,7 @@ package main import ( "context" + "encoding/json" "fmt" "os" "sort" @@ -18,6 +19,7 @@ import ( "github.com/konveyor/analyzer-lsp/tracing" "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "github.com/swaggest/openapi-go/openapi3" "gopkg.in/yaml.v2" ) @@ -41,6 +43,7 @@ var ( analysisMode string noDependencyRules bool contextLines int + getOpenAPISpec string ) func AnalysisCmd() *cobra.Command { @@ -155,6 +158,21 @@ func AnalysisCmd() *cobra.Command { } } } + if getOpenAPISpec != "" { + sc := createOpenAPISchema(providers, log) + b, err := json.Marshal(sc) + if err != nil { + log.Error(err, "unable to create inital schema") + os.Exit(1) + } + + err = os.WriteFile(getOpenAPISpec, b, 0644) + if err != nil { + log.Error(err, "error writing output file", "file", getOpenAPISpec) + os.Exit(1) // Treat the error as a fatal error + } + os.Exit(0) + } parser := parser.RuleParser{ ProviderNameToClient: providers, @@ -224,6 +242,7 @@ func AnalysisCmd() *cobra.Command { rootCmd.Flags().StringVar(&analysisMode, "analysis-mode", "", "select one of full or source-only to tell the providers what to analyize. This can be given on a per provider setting, but this flag will override") rootCmd.Flags().BoolVar(&noDependencyRules, "no-dependency-rules", false, "Disable dependency analysis rules") rootCmd.Flags().IntVar(&contextLines, "context-lines", 10, "When violation occurs, A part of source code is added to the output, So this flag configures the number of source code lines to be printed to the output.") + rootCmd.Flags().StringVar(&getOpenAPISpec, "get-openapi-spec", "", "Get the openAPI spec for the rulesets, rules and provider capabilities and put in file passed in.") return rootCmd } @@ -242,10 +261,12 @@ func validateFlags() error { return fmt.Errorf("unable to find provider settings file") } - for _, f := range rulesFile { - _, err = os.Stat(f) - if err != nil { - return fmt.Errorf("unable to find rule path or file") + if getOpenAPISpec == "" { + for _, f := range rulesFile { + _, err = os.Stat(f) + if err != nil { + return fmt.Errorf("unable to find rule path or file") + } } } m := provider.AnalysisMode(strings.ToLower(analysisMode)) @@ -255,3 +276,121 @@ func validateFlags() error { return nil } + +func createOpenAPISchema(providers map[string]provider.InternalProviderClient, log logr.Logger) openapi3.Spec { + + // in the future loop and build the openapi spec here: + spec, err := parser.CreateSchema() + if err != nil { + log.Error(err, "unable to create inital schema") + os.Exit(1) + } + + AndOrRefRuleRef := []openapi3.SchemaOrRef{} + for provName, prov := range providers { + cap := prov.Capabilities() + for _, c := range cap { + spec.MapOfSchemaOrRefValues[fmt.Sprintf("%s.%s", provName, c.Name)] = openapi3.SchemaOrRef{ + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeObject, + Properties: map[string]openapi3.SchemaOrRef{ + fmt.Sprintf("%s.%s", provName, c.Name): { + Schema: c.Input.Schema, + }, + "from": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeString, + }, + }, + "as": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeString, + }, + }, + "ignore": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeBool, + }, + }, + "not": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeBool, + }, + }, + }, + }, + } + AndOrRefRuleRef = append(AndOrRefRuleRef, openapi3.SchemaOrRef{ + SchemaReference: &openapi3.SchemaReference{ + Ref: fmt.Sprintf("#/components/schemas/%s.%s", provName, c.Name), + }, + }) + } + } + + AndOrRefRuleRef = append(AndOrRefRuleRef, openapi3.SchemaOrRef{ + SchemaReference: &openapi3.SchemaReference{ + Ref: "#/components/schemas/and", + }, + }) + AndOrRefRuleRef = append(AndOrRefRuleRef, openapi3.SchemaOrRef{ + SchemaReference: &openapi3.SchemaReference{ + Ref: "#/components/schemas/or", + }, + }) + spec.MapOfSchemaOrRefValues["and"] = openapi3.SchemaOrRef{ + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeObject, + Properties: map[string]openapi3.SchemaOrRef{ + "and": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeArray, + Items: &openapi3.SchemaOrRef{ + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeObject, + OneOf: AndOrRefRuleRef, + }, + }, + }, + }, + }, + }, + } + spec.MapOfSchemaOrRefValues["or"] = openapi3.SchemaOrRef{ + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeObject, + Properties: map[string]openapi3.SchemaOrRef{ + "or": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeArray, + Items: &openapi3.SchemaOrRef{ + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeObject, + OneOf: AndOrRefRuleRef, + }, + }, + }, + }, + }, + }, + } + + spec.MapOfSchemaOrRefValues["rule"].Schema.Properties["when"] = openapi3.SchemaOrRef{ + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeObject, + OneOf: AndOrRefRuleRef, + }, + } + sc := openapi3.Spec{ + Components: &openapi3.Components{ + Schemas: &spec, + }, + Openapi: "3.0.0", + Info: openapi3.Info{ + Title: "Konveyor API", + Version: "1.0.0", + }, + } + + return sc +} diff --git a/examples/golang/go.sum b/examples/golang/go.sum index b5a4d86b..16ccc8cf 100644 --- a/examples/golang/go.sum +++ b/examples/golang/go.sum @@ -125,7 +125,6 @@ github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoD github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= diff --git a/external-providers/generic-external-provider/go.mod b/external-providers/generic-external-provider/go.mod index 9f1e2468..b073f48c 100644 --- a/external-providers/generic-external-provider/go.mod +++ b/external-providers/generic-external-provider/go.mod @@ -4,12 +4,10 @@ go 1.19 require ( github.com/bombsimon/logrusr/v3 v3.1.0 - github.com/getkin/kin-openapi v0.118.0 github.com/go-logr/logr v1.2.4 github.com/konveyor/analyzer-lsp v0.3.0-beta.2 github.com/sirupsen/logrus v1.9.3 go.lsp.dev/uri v0.3.0 - golang.org/x/tools v0.6.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -17,16 +15,14 @@ require ( github.com/PaesslerAG/gval v1.2.2 // indirect github.com/cbroglie/mustache v1.4.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/swag v0.19.5 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/invopop/yaml v0.1.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/perimeterx/marshmallow v1.1.4 // indirect + github.com/kr/pretty v0.3.1 // indirect github.com/shopspring/decimal v1.3.1 // indirect + github.com/stretchr/testify v1.8.4 // indirect + github.com/swaggest/jsonschema-go v0.3.64 // indirect + github.com/swaggest/openapi-go v0.2.45 // indirect + github.com/swaggest/refl v1.3.0 // indirect go.opentelemetry.io/otel v1.11.2 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.11.2 // indirect go.opentelemetry.io/otel/sdk v1.11.2 // indirect @@ -37,7 +33,7 @@ require ( google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect google.golang.org/grpc v1.54.0 // indirect google.golang.org/protobuf v1.30.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) -// replace github.com/konveyor/analyzer-lsp => ../../ +replace github.com/konveyor/analyzer-lsp => ../../ diff --git a/external-providers/generic-external-provider/go.sum b/external-providers/generic-external-provider/go.sum index 841accb9..cd8efe9b 100644 --- a/external-providers/generic-external-provider/go.sum +++ b/external-providers/generic-external-provider/go.sum @@ -4,72 +4,59 @@ github.com/PaesslerAG/jsonpath v0.1.0 h1:gADYeifvlqK3R3i2cR5B4DGgxLXIPb3TRTH1mGi github.com/PaesslerAG/jsonpath v0.1.0/go.mod h1:4BzmtoM/PI8fPO4aQGIusjGxGir2BzcV0grWtFzq1Y8= github.com/bombsimon/logrusr/v3 v3.1.0 h1:zORbLM943D+hDMGgyjMhSAz/iDz86ZV72qaak/CA0zQ= github.com/bombsimon/logrusr/v3 v3.1.0/go.mod h1:PksPPgSFEL2I52pla2glgCyyd2OqOHAnFF5E+g8Ixco= +github.com/bool64/dev v0.2.32 h1:DRZtloaoH1Igky3zphaUHV9+SLIV2H3lsf78JsJHFg0= +github.com/bool64/shared v0.1.5 h1:fp3eUhBsrSjNCQPcSdQqZxxh9bBwrYiZ+zOKFkM0/2E= github.com/cbroglie/mustache v1.4.0 h1:Azg0dVhxTml5me+7PsZ7WPrQq1Gkf3WApcHMjMprYoU= github.com/cbroglie/mustache v1.4.0/go.mod h1:SS1FTIghy0sjse4DUVGV1k/40B1qE1XkD9DtDsHo9iM= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/getkin/kin-openapi v0.118.0 h1:z43njxPmJ7TaPpMSCQb7PN0dEYno4tyBPQcrFdHoLuM= -github.com/getkin/kin-openapi v0.118.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -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/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc= -github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/konveyor/analyzer-lsp v0.3.0-beta.2 h1:Cg9rJfoWYrl/Kkx+sY1WLF5HOESt/aZ2se1xo80HFGI= -github.com/konveyor/analyzer-lsp v0.3.0-beta.2/go.mod h1:zJCmIq08X0kPvtU8ZSmz+mZmQfBt4hdy9enoEy1AQw4= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/perimeterx/marshmallow v1.1.4 h1:pZLDH9RjlLGGorbXhcaQLhfuV0pFMNfPO55FuFkxqLw= -github.com/perimeterx/marshmallow v1.1.4/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= -github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= -github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= -github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/swaggest/assertjson v1.9.0 h1:dKu0BfJkIxv/xe//mkCrK5yZbs79jL7OVf9Ija7o2xQ= +github.com/swaggest/jsonschema-go v0.3.64 h1:HyB41fkA4XP0BZkqWfGap5i2JtRHQGXG/21dGDPbyLM= +github.com/swaggest/jsonschema-go v0.3.64/go.mod h1:DYuKqdpms/edvywsX6p1zHXCZkdwB28wRaBdFCe3Duw= +github.com/swaggest/openapi-go v0.2.45 h1:LOMAEleKVLg4E86lSCyioJK7ltjWRx50AaP4LZIbJ+Q= +github.com/swaggest/openapi-go v0.2.45/go.mod h1:/ykzNtS1ZO7X43OnEtyisMktxCiawQLyGd08rkjV68U= +github.com/swaggest/refl v1.3.0 h1:PEUWIku+ZznYfsoyheF97ypSduvMApYyGkYF3nabS0I= +github.com/swaggest/refl v1.3.0/go.mod h1:3Ujvbmh1pfSbDYjC6JGG7nMgPvpG0ehQL4iNonnLNbg= +github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= go.lsp.dev/uri v0.3.0 h1:KcZJmh6nFIBeJzTugn5JTU6OOyG0lDOo3R9KwTxTYbo= go.lsp.dev/uri v0.3.0/go.mod h1:P5sbO1IQR+qySTWOCnhnK7phBx+W3zbLqSMDJNTw88I= go.opentelemetry.io/otel v1.11.2 h1:YBZcQlsVekzFsFbjygXMOXSs6pialIZxcjfO/mBDmR0= @@ -97,12 +84,9 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/external-providers/generic-external-provider/main.go b/external-providers/generic-external-provider/main.go index 550e5e51..dc8a2907 100644 --- a/external-providers/generic-external-provider/main.go +++ b/external-providers/generic-external-provider/main.go @@ -47,7 +47,7 @@ func main() { // panic(fmt.Errorf("must pass in the name of the lsp server")) } - client := generic_external_provider.NewGenericProvider(*lspServerName) + client := generic_external_provider.NewGenericProvider(*lspServerName, log) if port == nil || *port == 0 { panic(fmt.Errorf("must pass in the port for the external provider")) diff --git a/external-providers/generic-external-provider/pkg/generic_external_provider/provider.go b/external-providers/generic-external-provider/pkg/generic_external_provider/provider.go index 7e9290d0..50e591a1 100644 --- a/external-providers/generic-external-provider/pkg/generic_external_provider/provider.go +++ b/external-providers/generic-external-provider/pkg/generic_external_provider/provider.go @@ -7,7 +7,7 @@ import ( "github.com/go-logr/logr" "github.com/konveyor/analyzer-lsp/provider" - "github.com/konveyor/generic-external-provider/pkg/server_configurations" + serverconf "github.com/konveyor/generic-external-provider/pkg/server_configurations" ) // TODO(shawn-hurley): Pipe the logger through Determine how and where external @@ -19,41 +19,33 @@ type genericProvider struct { capabilities []provider.Capability // Limit this instance of the generic provider to one lsp server type - lspServerName string - ctor server_configurations.ServiceClientConstructor + lspServerName string + serviceClientBuilder serverconf.ServiceClientBuilder } // Create a generic provider locked to a specific service client found in the // server_configuration maps. If the lspServerName is not found, then it // defaults to "generic" -func NewGenericProvider(lspServerName string) *genericProvider { +func NewGenericProvider(lspServerName string, log logr.Logger) *genericProvider { // Get the constructor associated with the server - ctor, ok := server_configurations.SupportedLanguages[lspServerName] + ctor, ok := serverconf.SupportedLanguages[lspServerName] if !ok { lspServerName = "generic" - ctor = server_configurations.SupportedLanguages["generic"] - } - - // Get the capabilities associated with the server - caps, ok := server_configurations.SupportedCapabilities[lspServerName] - if !ok || len(caps) == 0 { - fmt.Printf("%s has no capabilities", lspServerName) - lspServerName = "generic" - ctor = server_configurations.SupportedLanguages["generic"] - caps = server_configurations.SupportedCapabilities["generic"] + ctor = serverconf.SupportedLanguages["generic"] } p := genericProvider{ - ctx: context.TODO(), - lspServerName: lspServerName, - ctor: ctor, + ctx: context.TODO(), + lspServerName: lspServerName, + serviceClientBuilder: ctor, } // Load up the capabilities for this lsp server into the provider - for _, cap := range caps { + for _, cap := range ctor.GetGenericServiceClientCapabilities(log) { p.capabilities = append(p.capabilities, provider.Capability{ - Name: cap.Name, - TemplateContext: cap.TemplateContext, + Name: cap.Name, + Input: cap.Input, + Output: cap.Output, }) } @@ -91,7 +83,7 @@ func (p *genericProvider) Init(ctx context.Context, log logr.Logger, c provider. // Simple matter of calling the constructor that we set earlier to get the // service client - sc, err := p.ctor(ctx, log, c) + sc, err := p.serviceClientBuilder.Init(ctx, log, c) if err != nil { log.Error(err, "ctor error") fmt.Fprintf(os.Stderr, "ctor blah") diff --git a/external-providers/generic-external-provider/pkg/server_configurations/constants.go b/external-providers/generic-external-provider/pkg/server_configurations/constants.go index c071b419..3417000e 100644 --- a/external-providers/generic-external-provider/pkg/server_configurations/constants.go +++ b/external-providers/generic-external-provider/pkg/server_configurations/constants.go @@ -9,23 +9,18 @@ import ( "github.com/konveyor/generic-external-provider/pkg/server_configurations/generic" "github.com/konveyor/generic-external-provider/pkg/server_configurations/nodejs" "github.com/konveyor/generic-external-provider/pkg/server_configurations/pylsp" - "github.com/konveyor/generic-external-provider/pkg/server_configurations/yaml_language_server" + yaml "github.com/konveyor/generic-external-provider/pkg/server_configurations/yaml_language_server" ) -type ServiceClientConstructor func(context.Context, logr.Logger, provider.InitConfig) (provider.ServiceClient, error) - -var SupportedLanguages = map[string]ServiceClientConstructor{ - // "": generic.NewGenericServiceClient, - "generic": generic.NewGenericServiceClient, - "pylsp": pylsp.NewPythonServiceClient, - "yaml_language_server": yaml_language_server.NewYamlServiceClient, - "nodejs": nodejs.NewNodeServiceClient, +type ServiceClientBuilder interface { + Init(context.Context, logr.Logger, provider.InitConfig) (provider.ServiceClient, error) + GetGenericServiceClientCapabilities(log logr.Logger) []base.LSPServiceClientCapability } -var SupportedCapabilities = map[string][]base.LSPServiceClientCapability{ - // "": generic.GenericServiceClientCapabilities, - "generic": generic.GenericServiceClientCapabilities, - "pylsp": pylsp.PythonServiceClientCapabilities, - "yaml_language_server": yaml_language_server.YamlServiceClientCapabilities, - "nodejs": nodejs.NodeServiceClientCapabilities, +var SupportedLanguages = map[string]ServiceClientBuilder{ + // "": generic.NewGenericServiceClient, + "generic": &generic.GenericServiceClientBuilder{}, + "pylsp": &pylsp.PythonServiceClientBuilder{}, + "yaml_language_server": &yaml.YamlServiceClientBuilder{}, + "nodejs": &nodejs.NodeServiceClientBuilder{}, } diff --git a/external-providers/generic-external-provider/pkg/server_configurations/generic/service_client.go b/external-providers/generic-external-provider/pkg/server_configurations/generic/service_client.go index 0f6da99d..b6038eb5 100644 --- a/external-providers/generic-external-provider/pkg/server_configurations/generic/service_client.go +++ b/external-providers/generic-external-provider/pkg/server_configurations/generic/service_client.go @@ -5,12 +5,11 @@ import ( "encoding/json" "fmt" - "github.com/getkin/kin-openapi/openapi3" - "github.com/getkin/kin-openapi/openapi3gen" "github.com/go-logr/logr" base "github.com/konveyor/analyzer-lsp/lsp/base_service_client" "github.com/konveyor/analyzer-lsp/lsp/protocol" "github.com/konveyor/analyzer-lsp/provider" + "github.com/swaggest/openapi-go/openapi3" "gopkg.in/yaml.v2" ) @@ -42,6 +41,9 @@ type GenericServiceClientConfig struct { base.LSPServiceClientConfig `yaml:",inline"` } +// Tidy aliases +type serviceClientFn = base.LSPServiceClientFunc[*GenericServiceClient] + type GenericServiceClient struct { *base.LSPServiceClientBase *base.LSPServiceClientEvaluator[*GenericServiceClient] @@ -49,7 +51,9 @@ type GenericServiceClient struct { Config GenericServiceClientConfig } -func NewGenericServiceClient(ctx context.Context, log logr.Logger, c provider.InitConfig) (provider.ServiceClient, error) { +type GenericServiceClientBuilder struct{} + +func (g *GenericServiceClientBuilder) Init(ctx context.Context, log logr.Logger, c provider.InitConfig) (provider.ServiceClient, error) { sc := &GenericServiceClient{} // Unmarshal the config @@ -98,7 +102,7 @@ func NewGenericServiceClient(ctx context.Context, log logr.Logger, c provider.In sc.LSPServiceClientBase = scBase // Initialize the fancy evaluator (dynamic dispatch ftw) - eval, err := base.NewLspServiceClientEvaluator[*GenericServiceClient](sc, GenericServiceClientCapabilities) + eval, err := base.NewLspServiceClientEvaluator[*GenericServiceClient](sc, g.GetGenericServiceClientCapabilities(log)) if err != nil { return nil, fmt.Errorf("lsp service client evaluator error: %w", err) } @@ -107,31 +111,38 @@ func NewGenericServiceClient(ctx context.Context, log logr.Logger, c provider.In return sc, nil } -// Tidy aliases - -type serviceClientFn = base.LSPServiceClientFunc[*GenericServiceClient] - -func serviceClientTemplateContext(v any) openapi3.SchemaRef { - r, _ := openapi3gen.NewSchemaRefForValue(v, nil) - return *r -} +func (g *GenericServiceClientBuilder) GetGenericServiceClientCapabilities(log logr.Logger) []base.LSPServiceClientCapability { + caps := []base.LSPServiceClientCapability{} + r := openapi3.NewReflector() + refCap, err := provider.ToProviderCap(r, log, base.ReferencedCondition{}, "referenced") + if err != nil { + log.Error(err, "unable to get referenced cap") + } else { + caps = append(caps, base.LSPServiceClientCapability{ + Capability: refCap, + Fn: serviceClientFn(base.EvaluateReferenced[*GenericServiceClient]), + }) + } + depCap, err := provider.ToProviderCap(r, log, base.NoOpCondition{}, "dependency") + if err != nil { + log.Error(err, "unable to get referenced cap") + } else { + caps = append(caps, base.LSPServiceClientCapability{ + Capability: depCap, + Fn: serviceClientFn(base.EvaluateNoOp[*GenericServiceClient]), + }) + } + echoCap, err := provider.ToProviderCap(r, log, echoCondition{}, "echo") + if err != nil { + log.Error(err, "unable to get referenced cap") + } else { + caps = append(caps, base.LSPServiceClientCapability{ + Capability: echoCap, + Fn: serviceClientFn((*GenericServiceClient).EvaluateEcho), + }) + } + return caps -var GenericServiceClientCapabilities = []base.LSPServiceClientCapability{ - { - Name: "referenced", - TemplateContext: serviceClientTemplateContext(base.ReferencedCondition{}), - Fn: serviceClientFn(base.EvaluateReferenced[*GenericServiceClient]), - }, - { - Name: "dependency", - TemplateContext: serviceClientTemplateContext(base.NoOpCondition{}), - Fn: serviceClientFn(base.EvaluateNoOp[*GenericServiceClient]), - }, - { - Name: "echo", - TemplateContext: serviceClientTemplateContext(echoCondition{}), - Fn: serviceClientFn((*GenericServiceClient).EvaluateEcho), - }, } // Example condition diff --git a/external-providers/generic-external-provider/pkg/server_configurations/generic/service_client_test.go b/external-providers/generic-external-provider/pkg/server_configurations/generic/service_client_test.go index 0565cce0..f3770f53 100644 --- a/external-providers/generic-external-provider/pkg/server_configurations/generic/service_client_test.go +++ b/external-providers/generic-external-provider/pkg/server_configurations/generic/service_client_test.go @@ -11,7 +11,6 @@ import ( "time" "github.com/bombsimon/logrusr/v3" - "github.com/getkin/kin-openapi/openapi3gen" "github.com/go-logr/logr" "github.com/konveyor/analyzer-lsp/lsp/protocol" "github.com/konveyor/analyzer-lsp/provider" @@ -58,7 +57,13 @@ func TestMain(m *testing.M) { } func TestHopefullyNothingBroke(t *testing.T) { - prov := generic_external_provider.NewGenericProvider("generic") + logrusLog := logrus.New() + logrusLog.SetOutput(os.Stdout) + logrusLog.SetFormatter(&logrus.TextFormatter{}) + logrusLog.SetLevel(logrus.Level(5)) + + log = logrusr.New(logrusLog) + prov := generic_external_provider.NewGenericProvider("generic", log) goplsExamples := "file://" + filepath.Join(examplesDir, "/golang") @@ -146,39 +151,3 @@ type echoCondition struct { } type someOtherType string - -func TestSchemaGen(t *testing.T) { - r0, _ := openapi3gen.NewSchemaRefForValue(someStruct{}, nil) - b0, _ := json.Marshal(*r0) - - r1, _ := openapi3gen.NewSchemaRefForValue(&someStruct{}, nil) - b1, _ := json.Marshal(r1) - - fmt.Printf("%s\n", string(b0)) - fmt.Printf("%s\n", string(b1)) - - if string(b0) != string(b1) { - panic(1) - } - - e2_before := echoCondition{ - Echo: struct { - Input string `json:"input"` - }{ - Input: "hello!", - }, - } - r2, _ := openapi3gen.NewSchemaRefForValue(e2_before, nil) - b2, _ := json.Marshal(*r2) - fmt.Printf("%s\n", string(b2)) - - b2_yaml, _ := yaml.Marshal(e2_before) - fmt.Printf("%s\n", string(b2_yaml)) - e2_after := echoCondition{} - yaml.Unmarshal(b2_yaml, &e2_after) - fmt.Printf("%v\n", e2_after) - - r3, _ := openapi3gen.NewSchemaRefForValue(struct{}{}, nil) - b3, _ := json.Marshal(*r3) - fmt.Printf("%s\n", string(b3)) -} diff --git a/external-providers/generic-external-provider/pkg/server_configurations/nodejs/service_client.go b/external-providers/generic-external-provider/pkg/server_configurations/nodejs/service_client.go index 9a5e51bc..3accf6d5 100644 --- a/external-providers/generic-external-provider/pkg/server_configurations/nodejs/service_client.go +++ b/external-providers/generic-external-provider/pkg/server_configurations/nodejs/service_client.go @@ -6,12 +6,11 @@ import ( "fmt" "strings" - "github.com/getkin/kin-openapi/openapi3" - "github.com/getkin/kin-openapi/openapi3gen" "github.com/go-logr/logr" base "github.com/konveyor/analyzer-lsp/lsp/base_service_client" "github.com/konveyor/analyzer-lsp/lsp/protocol" "github.com/konveyor/analyzer-lsp/provider" + "github.com/swaggest/openapi-go/openapi3" "go.lsp.dev/uri" "gopkg.in/yaml.v2" ) @@ -22,6 +21,9 @@ type NodeServiceClientConfig struct { blah int `yaml:",inline"` } +// Tidy aliases +type serviceClientFn = base.LSPServiceClientFunc[*NodeServiceClient] + type NodeServiceClient struct { *base.LSPServiceClientBase *base.LSPServiceClientEvaluator[*NodeServiceClient] @@ -29,7 +31,9 @@ type NodeServiceClient struct { Config NodeServiceClientConfig } -func NewNodeServiceClient(ctx context.Context, log logr.Logger, c provider.InitConfig) (provider.ServiceClient, error) { +type NodeServiceClientBuilder struct{} + +func (n *NodeServiceClientBuilder) Init(ctx context.Context, log logr.Logger, c provider.InitConfig) (provider.ServiceClient, error) { sc := &NodeServiceClient{} // Unmarshal the config @@ -86,7 +90,7 @@ func NewNodeServiceClient(ctx context.Context, log logr.Logger, c provider.InitC sc.LSPServiceClientBase = scBase // Initialize the fancy evaluator (dynamic dispatch ftw) - eval, err := base.NewLspServiceClientEvaluator[*NodeServiceClient](sc, NodeServiceClientCapabilities) + eval, err := base.NewLspServiceClientEvaluator[*NodeServiceClient](sc, n.GetGenericServiceClientCapabilities(log)) if err != nil { return nil, err } @@ -95,26 +99,19 @@ func NewNodeServiceClient(ctx context.Context, log logr.Logger, c provider.InitC return sc, nil } -// Tidy aliases - -type serviceClientFn = base.LSPServiceClientFunc[*NodeServiceClient] - -func serviceClientTemplateContext(v any) openapi3.SchemaRef { - r, _ := openapi3gen.NewSchemaRefForValue(v, nil) - return *r -} - -var NodeServiceClientCapabilities = []base.LSPServiceClientCapability{ - { - Name: "referenced", - TemplateContext: serviceClientTemplateContext(referencedCondition{}), - Fn: serviceClientFn((*NodeServiceClient).EvaluateReferenced), - }, - { - Name: "dependency", - TemplateContext: serviceClientTemplateContext(base.NoOpCondition{}), - Fn: serviceClientFn(base.EvaluateNoOp[*NodeServiceClient]), - }, +func (n *NodeServiceClientBuilder) GetGenericServiceClientCapabilities(log logr.Logger) []base.LSPServiceClientCapability { + caps := []base.LSPServiceClientCapability{} + r := openapi3.NewReflector() + refCap, err := provider.ToProviderCap(r, log, referencedCondition{}, "referenced") + if err != nil { + log.Error(err, "unable to get referenced cap") + } else { + caps = append(caps, base.LSPServiceClientCapability{ + Capability: refCap, + Fn: serviceClientFn((*NodeServiceClient).EvaluateReferenced), + }) + } + return caps } type resp = provider.ProviderEvaluateResponse diff --git a/external-providers/generic-external-provider/pkg/server_configurations/pylsp/service_client.go b/external-providers/generic-external-provider/pkg/server_configurations/pylsp/service_client.go index e0bc5b8a..063cf1c5 100644 --- a/external-providers/generic-external-provider/pkg/server_configurations/pylsp/service_client.go +++ b/external-providers/generic-external-provider/pkg/server_configurations/pylsp/service_client.go @@ -4,12 +4,11 @@ import ( "context" "encoding/json" - "github.com/getkin/kin-openapi/openapi3" - "github.com/getkin/kin-openapi/openapi3gen" "github.com/go-logr/logr" base "github.com/konveyor/analyzer-lsp/lsp/base_service_client" "github.com/konveyor/analyzer-lsp/lsp/protocol" "github.com/konveyor/analyzer-lsp/provider" + "github.com/swaggest/openapi-go/openapi3" "gopkg.in/yaml.v2" ) @@ -19,6 +18,10 @@ type PythonServiceClientConfig struct { blah int `yaml:",inline"` } +// Tidy aliases + +type serviceClientFn = base.LSPServiceClientFunc[*PythonServiceClient] + type PythonServiceClient struct { *base.LSPServiceClientBase *base.LSPServiceClientEvaluator[*PythonServiceClient] @@ -26,7 +29,9 @@ type PythonServiceClient struct { Config PythonServiceClientConfig } -func NewPythonServiceClient(ctx context.Context, log logr.Logger, c provider.InitConfig) (provider.ServiceClient, error) { +type PythonServiceClientBuilder struct{} + +func (p *PythonServiceClientBuilder) Init(ctx context.Context, log logr.Logger, c provider.InitConfig) (provider.ServiceClient, error) { sc := &PythonServiceClient{} // Unmarshal the config @@ -75,7 +80,7 @@ func NewPythonServiceClient(ctx context.Context, log logr.Logger, c provider.Ini sc.LSPServiceClientBase = scBase // Initialize the fancy evaluator (dynamic dispatch ftw) - eval, err := base.NewLspServiceClientEvaluator[*PythonServiceClient](sc, PythonServiceClientCapabilities) + eval, err := base.NewLspServiceClientEvaluator[*PythonServiceClient](sc, p.GetGenericServiceClientCapabilities(log)) if err != nil { return nil, err } @@ -84,24 +89,18 @@ func NewPythonServiceClient(ctx context.Context, log logr.Logger, c provider.Ini return sc, nil } -// Tidy aliases +func (p *PythonServiceClientBuilder) GetGenericServiceClientCapabilities(log logr.Logger) []base.LSPServiceClientCapability { -type serviceClientFn = base.LSPServiceClientFunc[*PythonServiceClient] - -func serviceClientTemplateContext(v any) openapi3.SchemaRef { - r, _ := openapi3gen.NewSchemaRefForValue(v, nil) - return *r -} - -var PythonServiceClientCapabilities = []base.LSPServiceClientCapability{ - { - Name: "referenced", - TemplateContext: serviceClientTemplateContext(base.ReferencedCondition{}), - Fn: serviceClientFn(base.EvaluateReferenced[*PythonServiceClient]), - }, - { - Name: "dependency", - TemplateContext: serviceClientTemplateContext(base.NoOpCondition{}), - Fn: serviceClientFn(base.EvaluateNoOp[*PythonServiceClient]), - }, + caps := []base.LSPServiceClientCapability{} + r := openapi3.NewReflector() + refCap, err := provider.ToProviderCap(r, log, base.ReferencedCondition{}, "referenced") + if err != nil { + log.Error(err, "unable to get referenced cap") + } else { + caps = append(caps, base.LSPServiceClientCapability{ + Capability: refCap, + Fn: serviceClientFn(base.EvaluateReferenced[*PythonServiceClient]), + }) + } + return caps } diff --git a/external-providers/generic-external-provider/pkg/server_configurations/pylsp/service_client_test.go b/external-providers/generic-external-provider/pkg/server_configurations/pylsp/service_client_test.go index 388ea6b9..1f4542cb 100644 --- a/external-providers/generic-external-provider/pkg/server_configurations/pylsp/service_client_test.go +++ b/external-providers/generic-external-provider/pkg/server_configurations/pylsp/service_client_test.go @@ -10,7 +10,6 @@ import ( "time" "github.com/bombsimon/logrusr/v3" - "github.com/getkin/kin-openapi/openapi3gen" "github.com/konveyor/analyzer-lsp/lsp/protocol" "github.com/konveyor/analyzer-lsp/provider" "github.com/konveyor/generic-external-provider/pkg/generic_external_provider" @@ -36,7 +35,7 @@ func TestHopefullyNothingBroke(t *testing.T) { log := logrusr.New(logrusLog) ctx := context.TODO() - prov := generic_external_provider.NewGenericProvider("generic") + prov := generic_external_provider.NewGenericProvider("generic", log) pylspSC, err := prov.Init(ctx, log, provider.InitConfig{ ProviderSpecificConfig: map[string]interface{}{ @@ -139,39 +138,3 @@ type echoCondition struct { } type someOtherType string - -func XTestSchemaGen(t *testing.T) { - r0, _ := openapi3gen.NewSchemaRefForValue(someStruct{}, nil) - b0, _ := json.Marshal(*r0) - - r1, _ := openapi3gen.NewSchemaRefForValue(&someStruct{}, nil) - b1, _ := json.Marshal(r1) - - fmt.Printf("%s\n", string(b0)) - fmt.Printf("%s\n", string(b1)) - - if string(b0) != string(b1) { - panic(1) - } - - e2_before := echoCondition{ - Echo: struct { - Input string `json:"input"` - }{ - Input: "hello!", - }, - } - r2, _ := openapi3gen.NewSchemaRefForValue(e2_before, nil) - b2, _ := json.Marshal(*r2) - fmt.Printf("%s\n", string(b2)) - - b2_yaml, _ := yaml.Marshal(e2_before) - fmt.Printf("%s\n", string(b2_yaml)) - e2_after := echoCondition{} - yaml.Unmarshal(b2_yaml, &e2_after) - fmt.Printf("%v\n", e2_after) - - r3, _ := openapi3gen.NewSchemaRefForValue(struct{}{}, nil) - b3, _ := json.Marshal(*r3) - fmt.Printf("%s\n", string(b3)) -} diff --git a/external-providers/generic-external-provider/pkg/server_configurations/yaml_language_server/service_client.go b/external-providers/generic-external-provider/pkg/server_configurations/yaml_language_server/service_client.go index 9a22c05c..96d066a7 100644 --- a/external-providers/generic-external-provider/pkg/server_configurations/yaml_language_server/service_client.go +++ b/external-providers/generic-external-provider/pkg/server_configurations/yaml_language_server/service_client.go @@ -9,13 +9,12 @@ import ( "strings" "time" - "github.com/getkin/kin-openapi/openapi3" - "github.com/getkin/kin-openapi/openapi3gen" "github.com/go-logr/logr" jsonrpc2 "github.com/konveyor/analyzer-lsp/jsonrpc2_v2" base "github.com/konveyor/analyzer-lsp/lsp/base_service_client" "github.com/konveyor/analyzer-lsp/lsp/protocol" "github.com/konveyor/analyzer-lsp/provider" + "github.com/swaggest/openapi-go/openapi3" "go.lsp.dev/uri" "gopkg.in/yaml.v2" ) @@ -49,7 +48,12 @@ type YamlServiceClient struct { configParams []map[string]any } -func NewYamlServiceClient(ctx context.Context, log logr.Logger, c provider.InitConfig) (provider.ServiceClient, error) { +// Tidy alias +type serviceClientFn = base.LSPServiceClientFunc[*YamlServiceClient] + +type YamlServiceClientBuilder struct{} + +func (y *YamlServiceClientBuilder) Init(ctx context.Context, log logr.Logger, c provider.InitConfig) (provider.ServiceClient, error) { sc := &YamlServiceClient{} // Unmarshal the config @@ -111,7 +115,7 @@ func NewYamlServiceClient(ctx context.Context, log logr.Logger, c provider.InitC sc.LSPServiceClientBase = scBase // Initialize the fancy evaluator - eval, err := base.NewLspServiceClientEvaluator[*YamlServiceClient](sc, YamlServiceClientCapabilities) + eval, err := base.NewLspServiceClientEvaluator[*YamlServiceClient](sc, y.GetGenericServiceClientCapabilities(log)) if err != nil { return nil, err } @@ -120,25 +124,19 @@ func NewYamlServiceClient(ctx context.Context, log logr.Logger, c provider.InitC return sc, nil } -// Tidy alias -type serviceClientFn = base.LSPServiceClientFunc[*YamlServiceClient] - -func serviceClientTemplateContext(v any) openapi3.SchemaRef { - r, _ := openapi3gen.NewSchemaRefForValue(v, nil) - return *r -} - -var YamlServiceClientCapabilities = []base.LSPServiceClientCapability{ - { - Name: "referenced", - TemplateContext: serviceClientTemplateContext(referencedCondition{}), - Fn: serviceClientFn((*YamlServiceClient).EvaluateReferenced), - }, - { - Name: "dependency", - TemplateContext: serviceClientTemplateContext(base.NoOpCondition{}), - Fn: serviceClientFn(base.EvaluateNoOp[*YamlServiceClient]), - }, +func (y *YamlServiceClientBuilder) GetGenericServiceClientCapabilities(log logr.Logger) []base.LSPServiceClientCapability { + caps := []base.LSPServiceClientCapability{} + r := openapi3.NewReflector() + refCap, err := provider.ToProviderCap(r, log, referencedCondition{}, "referenced") + if err != nil { + log.Error(err, "unable to get referenced cap") + } else { + caps = append(caps, base.LSPServiceClientCapability{ + Capability: refCap, + Fn: serviceClientFn((*YamlServiceClient).EvaluateReferenced), + }) + } + return caps } type referencedCondition struct { diff --git a/external-providers/generic-external-provider/pkg/server_configurations/yaml_language_server/service_client_test.go b/external-providers/generic-external-provider/pkg/server_configurations/yaml_language_server/service_client_test.go index 27b75eb6..08ece087 100644 --- a/external-providers/generic-external-provider/pkg/server_configurations/yaml_language_server/service_client_test.go +++ b/external-providers/generic-external-provider/pkg/server_configurations/yaml_language_server/service_client_test.go @@ -31,7 +31,7 @@ func TestHopefullyNothingBroke(t *testing.T) { log := logrusr.New(logrusLog) ctx := context.TODO() - prov := generic_external_provider.NewGenericProvider("yaml_language_server") + prov := generic_external_provider.NewGenericProvider("yaml_language_server", log) yamlSC, err := prov.Init(ctx, log, provider.InitConfig{ ProviderSpecificConfig: map[string]interface{}{ diff --git a/external-providers/golang-dependency-provider/go.mod b/external-providers/golang-dependency-provider/go.mod index bcca5c28..1864f614 100644 --- a/external-providers/golang-dependency-provider/go.mod +++ b/external-providers/golang-dependency-provider/go.mod @@ -10,7 +10,6 @@ require ( require ( github.com/PaesslerAG/gval v1.2.2 // indirect github.com/cbroglie/mustache v1.4.0 // indirect - github.com/getkin/kin-openapi v0.108.0 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.20.0 // indirect diff --git a/external-providers/golang-dependency-provider/go.sum b/external-providers/golang-dependency-provider/go.sum index 91f8c97e..b13cde76 100644 --- a/external-providers/golang-dependency-provider/go.sum +++ b/external-providers/golang-dependency-provider/go.sum @@ -8,8 +8,6 @@ github.com/cbroglie/mustache v1.4.0/go.mod h1:SS1FTIghy0sjse4DUVGV1k/40B1qE1XkD9 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/getkin/kin-openapi v0.108.0 h1:EYf0GtsKa4hQNIlplGS+Au7NEfGQ1F7MoHD2kcVevPQ= -github.com/getkin/kin-openapi v0.108.0/go.mod h1:QtwUNt0PAAgIIBEvFWYfB7dfngxtAaqCX1zYHMZDeK8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= diff --git a/external-providers/yq-external-provider/go.mod b/external-providers/yq-external-provider/go.mod index ef1d9967..0e03547a 100644 --- a/external-providers/yq-external-provider/go.mod +++ b/external-providers/yq-external-provider/go.mod @@ -4,8 +4,8 @@ go 1.19 require ( github.com/bombsimon/logrusr/v3 v3.1.0 - github.com/getkin/kin-openapi v0.118.0 github.com/go-logr/logr v1.2.4 + github.com/swaggest/openapi-go v0.2.45 github.com/konveyor/analyzer-lsp v0.3.0-alpha.3.0.20230915135621-94f04595688b github.com/sirupsen/logrus v1.9.3 go.lsp.dev/uri v0.3.0 diff --git a/external-providers/yq-external-provider/go.sum b/external-providers/yq-external-provider/go.sum index e1d43772..2aef7066 100644 --- a/external-providers/yq-external-provider/go.sum +++ b/external-providers/yq-external-provider/go.sum @@ -9,8 +9,6 @@ github.com/cbroglie/mustache v1.4.0/go.mod h1:SS1FTIghy0sjse4DUVGV1k/40B1qE1XkD9 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/getkin/kin-openapi v0.118.0 h1:z43njxPmJ7TaPpMSCQb7PN0dEYno4tyBPQcrFdHoLuM= -github.com/getkin/kin-openapi v0.118.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= diff --git a/external-providers/yq-external-provider/pkg/yq_provider/provider.go b/external-providers/yq-external-provider/pkg/yq_provider/provider.go index 311265cf..e73d14c2 100644 --- a/external-providers/yq-external-provider/pkg/yq_provider/provider.go +++ b/external-providers/yq-external-provider/pkg/yq_provider/provider.go @@ -6,15 +6,17 @@ import ( "os" "os/exec" - "github.com/getkin/kin-openapi/openapi3" "github.com/go-logr/logr" "github.com/konveyor/analyzer-lsp/provider" + "github.com/swaggest/openapi-go/openapi3" ) // TODO(shawn-hurley): Pipe the logger through // Determine how and where external providers will add the logs to make the logs viewable in a single location. type yqProvider struct { ctx context.Context + + log logr.Logger } var _ provider.BaseClient = &yqProvider{} @@ -24,12 +26,14 @@ func NewYqProvider() *yqProvider { } func (p *yqProvider) Capabilities() []provider.Capability { - return []provider.Capability{ - { - Name: "k8sResourceMatched", - TemplateContext: openapi3.SchemaRef{}, - }, + caps := []provider.Capability{} + r := openapi3.NewReflector() + k8sResourceMatched, err := provider.ToProviderCap(r, p.log, k8sResourceCondition{}, "k8sResourceMatched") + if err != nil { + fmt.Printf("not working") } + caps = append(caps, k8sResourceMatched) + return caps } type yqCondition struct { diff --git a/go.mod b/go.mod index 88f01137..fff2d208 100644 --- a/go.mod +++ b/go.mod @@ -7,11 +7,12 @@ require ( github.com/antchfx/jsonquery v1.3.0 github.com/antchfx/xmlquery v1.3.12 github.com/bombsimon/logrusr/v3 v3.0.0 - github.com/getkin/kin-openapi v0.108.0 github.com/go-logr/logr v1.2.3 github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 github.com/sirupsen/logrus v1.9.0 github.com/spf13/cobra v1.7.0 + github.com/swaggest/jsonschema-go v0.3.64 + github.com/swaggest/openapi-go v0.2.45 github.com/vifraa/gopom v1.0.0 go.lsp.dev/uri v0.3.0 go.opentelemetry.io/otel/trace v1.11.2 @@ -22,29 +23,25 @@ require ( require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/kr/pretty v0.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/swaggest/refl v1.3.0 // indirect + gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect ) require ( github.com/antchfx/xpath v1.2.4 github.com/cbroglie/mustache v1.3.0 github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/swag v0.19.5 // indirect github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/hashicorp/go-version v1.6.0 - github.com/invopop/yaml v0.1.0 // indirect - github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e // indirect - github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/shopspring/decimal v1.3.1 // indirect go.opentelemetry.io/otel v1.11.2 go.opentelemetry.io/otel/exporters/jaeger v1.11.2 go.opentelemetry.io/otel/sdk v1.11.2 - golang.org/x/mod v0.14.0 golang.org/x/net v0.17.0 golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index ee5c7e09..78977368 100644 --- a/go.sum +++ b/go.sum @@ -11,23 +11,19 @@ github.com/antchfx/xpath v1.2.4 h1:dW1HB/JxKvGtJ9WyVGJ0sIoEcqftV3SqIstujI+B9XY= github.com/antchfx/xpath v1.2.4/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= github.com/bombsimon/logrusr/v3 v3.0.0 h1:tcAoLfuAhKP9npBxWzSdpsvKPQt1XV02nSf2lZA82TQ= github.com/bombsimon/logrusr/v3 v3.0.0/go.mod h1:PksPPgSFEL2I52pla2glgCyyd2OqOHAnFF5E+g8Ixco= +github.com/bool64/dev v0.2.32 h1:DRZtloaoH1Igky3zphaUHV9+SLIV2H3lsf78JsJHFg0= +github.com/bool64/shared v0.1.5 h1:fp3eUhBsrSjNCQPcSdQqZxxh9bBwrYiZ+zOKFkM0/2E= github.com/cbroglie/mustache v1.3.0 h1:sj24GVYl8G7MH4b3zaROGsZnF8X79JqtjMx8/6H/nXM= github.com/cbroglie/mustache v1.3.0/go.mod h1:w58RIHjw/L7DPyRX2CcCTduNmcP1dvztaHP72ciSfh0= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/getkin/kin-openapi v0.108.0 h1:EYf0GtsKa4hQNIlplGS+Au7NEfGQ1F7MoHD2kcVevPQ= -github.com/getkin/kin-openapi v0.108.0/go.mod h1:QtwUNt0PAAgIIBEvFWYfB7dfngxtAaqCX1zYHMZDeK8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= @@ -36,28 +32,22 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc= -github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= @@ -67,18 +57,21 @@ github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRM github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/swaggest/assertjson v1.9.0 h1:dKu0BfJkIxv/xe//mkCrK5yZbs79jL7OVf9Ija7o2xQ= +github.com/swaggest/jsonschema-go v0.3.64 h1:HyB41fkA4XP0BZkqWfGap5i2JtRHQGXG/21dGDPbyLM= +github.com/swaggest/jsonschema-go v0.3.64/go.mod h1:DYuKqdpms/edvywsX6p1zHXCZkdwB28wRaBdFCe3Duw= +github.com/swaggest/openapi-go v0.2.45 h1:LOMAEleKVLg4E86lSCyioJK7ltjWRx50AaP4LZIbJ+Q= +github.com/swaggest/openapi-go v0.2.45/go.mod h1:/ykzNtS1ZO7X43OnEtyisMktxCiawQLyGd08rkjV68U= +github.com/swaggest/refl v1.3.0 h1:PEUWIku+ZznYfsoyheF97ypSduvMApYyGkYF3nabS0I= +github.com/swaggest/refl v1.3.0/go.mod h1:3Ujvbmh1pfSbDYjC6JGG7nMgPvpG0ehQL4iNonnLNbg= github.com/vifraa/gopom v1.0.0 h1:L9XlKbyvid8PAIK8nr0lihMApJQg/12OBvMA28BcWh0= github.com/vifraa/gopom v1.0.0/go.mod h1:oPa1dcrGrtlO37WPDBm5SqHAT+wTgF8An1Q71Z6Vv4o= +github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= go.lsp.dev/uri v0.3.0 h1:KcZJmh6nFIBeJzTugn5JTU6OOyG0lDOo3R9KwTxTYbo= go.lsp.dev/uri v0.3.0/go.mod h1:P5sbO1IQR+qySTWOCnhnK7phBx+W3zbLqSMDJNTw88I= go.opentelemetry.io/otel v1.11.2 h1:YBZcQlsVekzFsFbjygXMOXSs6pialIZxcjfO/mBDmR0= @@ -89,8 +82,6 @@ go.opentelemetry.io/otel/sdk v1.11.2 h1:GF4JoaEx7iihdMFu30sOyRx52HDHOkl9xQ8SMqNX go.opentelemetry.io/otel/sdk v1.11.2/go.mod h1:wZ1WxImwpq+lVRo4vsmSOxdd+xwoUJ6rqyLc3SyX9aU= go.opentelemetry.io/otel/trace v1.11.2 h1:Xf7hWSF2Glv0DE3MH7fBHvtpSBsjcBUe5MYAmZM/+y0= go.opentelemetry.io/otel/trace v1.11.2/go.mod h1:4N+yC7QEz7TTsG9BSRLNAa63eg5E06ObSbKPmxQ/pKA= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= @@ -116,10 +107,8 @@ google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/lsp/base_service_client/base_service_client.go b/lsp/base_service_client/base_service_client.go index fd72a570..05283b97 100644 --- a/lsp/base_service_client/base_service_client.go +++ b/lsp/base_service_client/base_service_client.go @@ -13,7 +13,6 @@ import ( "sync" "time" - "github.com/getkin/kin-openapi/openapi3" "github.com/go-logr/logr" jsonrpc2 "github.com/konveyor/analyzer-lsp/jsonrpc2_v2" "github.com/konveyor/analyzer-lsp/lsp/protocol" @@ -30,9 +29,8 @@ type LSPServiceClientFunc[T HasLSPServiceClientBase] func(T, context.Context, st // `Fn` field to reduce code duplication. We can use this struct for the // Evaluator struct to call the appropriate method when queried. type LSPServiceClientCapability struct { - Name string - TemplateContext openapi3.SchemaRef - Fn interface{} + provider.Capability + Fn interface{} } // The base service client configs that all subsequent configs must embed @@ -356,20 +354,6 @@ func (sc *LSPServiceClientBase) GetAllDeclarations(ctx context.Context, workspac return symbols } - // if p.capabilities.Supports("workspace/symbol") && len(symbols) == 0 { - // // Run empty string query and manually search using the query as a regex - // var allSymbols []protocol.WorkspaceSymbol - // err = p.rpc.Call(ctx, "workspace/symbol", &protocol.WorkspaceSymbolParams{Query: ""}, &allSymbols) - // if err != nil { - // fmt.Printf("error: %v\n", err) - // } - // for _, s := range allSymbols { - // if regex.MatchString(s.Name) { - // symbols = append(symbols, s) - // } - // } - // } - if sc.ServerCapabilities.Supports("textDocument/definition") && len(symbols) == 0 { // if p.capabilities.Supports("textDocument/declaration") && len(symbols) == 0 { var positions []protocol.TextDocumentPositionParams diff --git a/parser/open_api.go b/parser/open_api.go new file mode 100644 index 00000000..b531fbaa --- /dev/null +++ b/parser/open_api.go @@ -0,0 +1,151 @@ +package parser + +import ( + "github.com/konveyor/analyzer-lsp/provider" + "github.com/swaggest/openapi-go/openapi3" +) + +func CreateSchema() (openapi3.ComponentsSchemas, error) { + schema := openapi3.ComponentsSchemas{ + MapOfSchemaOrRefValues: map[string]openapi3.SchemaOrRef{}, + } + + schema.MapOfSchemaOrRefValues["rule"] = openapi3.SchemaOrRef{ + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeObject, + Properties: map[string]openapi3.SchemaOrRef{ + "ruleID": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeString, + }, + }, + "description": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeString, + }, + }, + "labels": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeArray, + Items: &openapi3.SchemaOrRef{ + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeString, + }, + }, + }, + }, + "effort": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeNumber, + }, + }, + "category": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeString, + OneOf: []openapi3.SchemaOrRef{ + { + Schema: &openapi3.Schema{ + Enum: []interface{}{ + "potential", + "optional", + "mandatory", + }, + }, + }, + }, + }, + }, + "customVariable": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeArray, + Properties: map[string]openapi3.SchemaOrRef{ + "name": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeString, + }, + }, + "defaultValue": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeString, + }, + }, + "nameOfCaptureGroup": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeString, + }, + }, + }, + }, + }, + "message": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeString, + }, + }, + "tag": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeArray, + Items: &openapi3.SchemaOrRef{ + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeString, + }, + }, + }, + }, + // We will override this, with the capabilties from the providers + "when": {}, + }, + }, + } + + schema.MapOfSchemaOrRefValues["rulesets"] = openapi3.SchemaOrRef{ + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeObject, + Properties: map[string]openapi3.SchemaOrRef{ + "name": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeString, + }, + }, + "description": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeString, + }, + }, + "labels": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeArray, + Items: &openapi3.SchemaOrRef{ + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeString, + }, + }, + }, + }, + "tags": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeArray, + Items: &openapi3.SchemaOrRef{ + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeString, + }, + }, + }, + }, + "rules": { + Schema: &openapi3.Schema{ + Type: &provider.SchemaTypeArray, + Items: &openapi3.SchemaOrRef{ + SchemaReference: &openapi3.SchemaReference{ + Ref: "#/components/schemas/rule", + }, + }, + }, + }, + }, + }, + } + + return schema, nil + +} diff --git a/provider/internal/builtin/provider.go b/provider/internal/builtin/provider.go index 3bb03814..d67a5255 100644 --- a/provider/internal/builtin/provider.go +++ b/provider/internal/builtin/provider.go @@ -4,55 +4,19 @@ import ( "context" "os" - "github.com/getkin/kin-openapi/openapi3" "github.com/go-logr/logr" "github.com/konveyor/analyzer-lsp/provider" + "github.com/swaggest/openapi-go/openapi3" "gopkg.in/yaml.v2" ) const TAGS_FILE_INIT_OPTION = "tagsFile" -var capabilities = []provider.Capability{ - { - Name: "filecontent", - TemplateContext: openapi3.SchemaRef{}, - }, - { - Name: "file", - TemplateContext: openapi3.SchemaRef{ - Value: &openapi3.Schema{ - Properties: openapi3.Schemas{ - "filepaths": &openapi3.SchemaRef{ - Value: &openapi3.Schema{ - Description: "List of filepaths matching pattern", - Items: &openapi3.SchemaRef{ - Value: &openapi3.Schema{ - Type: "string", - }, - }, - }, - }, - }, - }, - }, - }, - { - Name: "xml", - TemplateContext: openapi3.SchemaRef{}, - }, - { - Name: "xmlPublicID", - TemplateContext: openapi3.SchemaRef{}, - }, - { - Name: "json", - TemplateContext: openapi3.SchemaRef{}, - }, - { - Name: "hasTags", - TemplateContext: openapi3.SchemaRef{}, - }, -} +var ( + filePathsDescription = "file pattern to search" +) + +var capabilities = []provider.Capability{} type builtinCondition struct { Filecontent fileContentCondition `yaml:"filecontent"` @@ -65,31 +29,31 @@ type builtinCondition struct { } type fileContentCondition struct { - FilePattern string `yaml:"filePattern"` - Pattern string `yaml:"pattern` + FilePattern string `yaml:"filePattern" json:"filePattern,omitempty"` + Pattern string `yaml:"pattern" json:"pattern"` } type fileCondition struct { - Pattern string `yaml:"pattern"` + Pattern string `yaml:"pattern" json:"pattern"` } var _ provider.InternalProviderClient = &builtinProvider{} type xmlCondition struct { - XPath string `yaml:"xpath"` - Namespaces map[string]string `yaml:"namespaces"` - Filepaths []string `yaml:"filepaths"` + XPath string `yaml:"xpath" json:"xpath"` + Namespaces map[string]string `yaml:"namespaces" json:"namespace,omitempty"` + Filepaths []string `yaml:"filepaths" json:"filepaths,omitempty"` } type xmlPublicIDCondition struct { - Regex string `yaml:"regex"` - Namespaces map[string]string `yaml:"namespaces"` - Filepaths []string `yaml:"filepaths"` + Regex string `yaml:"regex" json:"regex"` + Namespaces map[string]string `yaml:"namespaces" json:"namespaces"` + Filepaths []string `yaml:"filepaths" json:"filepaths"` } type jsonCondition struct { - XPath string `yaml:'xpath'` - Filepaths []string `yaml:"filepaths"` + XPath string `yaml:"xpath" json:"xpath"` + Filepaths []string `yaml:"filepaths" json:"filepaths,omitempty"` } type builtinProvider struct { @@ -111,7 +75,52 @@ func NewBuiltinProvider(config provider.Config, log logr.Logger) *builtinProvide } func (p *builtinProvider) Capabilities() []provider.Capability { - return capabilities + r := openapi3.NewReflector() + + caps := []provider.Capability{} + jsonCap, err := provider.ToProviderCap(r, p.log, jsonCondition{}, "json") + if err != nil { + p.log.Error(err, "unable to get json capability") + } else { + caps = append(caps, jsonCap) + } + + xmlCap, err := provider.ToProviderCap(r, p.log, xmlCondition{}, "xml") + if err != nil { + p.log.Error(err, "unable to get xml capability") + } else { + caps = append(caps, xmlCap) + } + + filecontentCap, err := provider.ToProviderCap(r, p.log, fileContentCondition{}, "filecontent") + if err != nil { + p.log.Error(err, "unable to get filecontent capability") + } else { + caps = append(caps, filecontentCap) + } + + fileCap, err := provider.ToProviderCap(r, p.log, fileCondition{}, "file") + if err != nil { + p.log.Error(err, "unable to get file capability") + } else { + caps = append(caps, fileCap) + } + + xmlPublicIDCap, err := provider.ToProviderCap(r, p.log, xmlPublicIDCondition{}, "xmlPublicID") + if err != nil { + p.log.Error(err, "unable to get xmlPublicID capability") + } else { + caps = append(caps, xmlPublicIDCap) + } + + hasTags, err := provider.ToProviderCap(r, p.log, []string{}, "hasTags") + if err != nil { + p.log.Error(err, "unable to get hasTags capability") + } else { + caps = append(caps, hasTags) + } + + return caps } func (p *builtinProvider) ProviderInit(ctx context.Context) error { diff --git a/provider/internal/java/dependency.go b/provider/internal/java/dependency.go index b264f2df..86026db6 100644 --- a/provider/internal/java/dependency.go +++ b/provider/internal/java/dependency.go @@ -134,9 +134,7 @@ func (p *javaServiceClient) GetDependenciesFallback(ctx context.Context, locatio p.log.V(10).Info("Analyzing POM", "POM", fmt.Sprintf("%s:%s:%s", pomCoordinate(pom.GroupID), pomCoordinate(pom.ArtifactID), pomCoordinate(pom.Version)), "error", err) - if err != nil { - return nil, err - } + // If the pom object is empty then parse failed silently. if reflect.DeepEqual(*pom, gopom.Project{}) { return nil, nil @@ -464,13 +462,13 @@ func addDepLabels(depToLabels map[string]*depLabelItem, depName string) []string m := map[string]interface{}{} for _, d := range depToLabels { if d.r.Match([]byte(depName)) { - for label, _ := range d.labels { + for label := range d.labels { m[label] = nil } } } s := []string{} - for k, _ := range m { + for k := range m { s = append(s, k) } // if open source label is not found, qualify the dep as being internal by default diff --git a/provider/internal/java/provider.go b/provider/internal/java/provider.go index f2381540..2b2535eb 100644 --- a/provider/internal/java/provider.go +++ b/provider/internal/java/provider.go @@ -14,13 +14,13 @@ import ( "strings" "sync" - "github.com/getkin/kin-openapi/openapi3" "github.com/go-logr/logr" "github.com/konveyor/analyzer-lsp/engine" "github.com/konveyor/analyzer-lsp/jsonrpc2" "github.com/konveyor/analyzer-lsp/lsp/protocol" "github.com/konveyor/analyzer-lsp/output/v1/konveyor" "github.com/konveyor/analyzer-lsp/provider" + "github.com/swaggest/openapi-go/openapi3" "go.lsp.dev/uri" ) @@ -103,17 +103,21 @@ func (p *javaProvider) Stop() { } func (p *javaProvider) Capabilities() []provider.Capability { - caps := []provider.Capability{ - { - Name: "referenced", - TemplateContext: openapi3.SchemaRef{}, - }, + r := openapi3.NewReflector() + caps := []provider.Capability{} + refCap, err := provider.ToProviderCap(r, p.Log, javaCondition{}, "referenced") + if err != nil { + p.Log.Error(err, "this is not going to be cool if it fails") + } else { + caps = append(caps, refCap) } if p.hasMaven { - caps = append(caps, provider.Capability{ - Name: "dependency", - TemplateContext: openapi3.SchemaRef{}, - }) + depCap, err := provider.ToProviderCap(r, p.Log, provider.DependencyConditionCap{}, "dependency") + if err != nil { + p.Log.Error(err, "this is not goinag to be cool if it fails") + } else { + caps = append(caps, depCap) + } } return caps } diff --git a/provider/lib.go b/provider/lib.go index b7a028bb..e908ba39 100644 --- a/provider/lib.go +++ b/provider/lib.go @@ -89,7 +89,7 @@ func GetFiles(configLocation string, filepaths []string, patterns ...string) ([] for _, pattern := range filepaths { files, err := FindFilesMatchingPattern(configLocation, pattern) if err != nil { - fmt.Errorf("Unable to find files using pattern `%s`: %v", pattern, err) + fmt.Printf("Unable to find files using pattern `%s`: %v", pattern, err) continue } else { xmlFiles = append(xmlFiles, files...) diff --git a/provider/provider.go b/provider/provider.go index 51333168..0f9b7bac 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -9,13 +9,14 @@ import ( "time" "github.com/cbroglie/mustache" - "github.com/getkin/kin-openapi/openapi3" "github.com/go-logr/logr" "github.com/hashicorp/go-version" "github.com/konveyor/analyzer-lsp/engine" "github.com/konveyor/analyzer-lsp/engine/labels" "github.com/konveyor/analyzer-lsp/output/v1/konveyor" "github.com/konveyor/analyzer-lsp/tracing" + jsonschema "github.com/swaggest/jsonschema-go" + "github.com/swaggest/openapi-go/openapi3" "go.lsp.dev/uri" "go.opentelemetry.io/otel/attribute" "golang.org/x/net/http/httpproxy" @@ -33,6 +34,15 @@ const ( LspServerPathConfigKey = "lspServerPath" ) +// We need to make these Vars, because you can not take a pointer of the constant. +var ( + SchemaTypeString openapi3.SchemaType = openapi3.SchemaTypeString + SchemaTypeArray openapi3.SchemaType = openapi3.SchemaTypeArray + SchemaTypeObject openapi3.SchemaType = openapi3.SchemaTypeObject + SchemaTypeNumber openapi3.SchemaType = openapi3.SchemaTypeInteger + SchemaTypeBool openapi3.SchemaType = openapi3.SchemaTypeBoolean +) + // This will need a better name, may we want to move it to top level // Will be used by providers for common interface way of passing in configuration values. var builtinConfig = Config{ @@ -64,8 +74,9 @@ func (p *UnimplementedDependenciesComponent) GetDependenciesDAG(ctx context.Cont } type Capability struct { - Name string - TemplateContext openapi3.SchemaRef + Name string + Input openapi3.SchemaOrRef + Output openapi3.SchemaOrRef } type Config struct { @@ -519,15 +530,19 @@ func templateCondition(condition []byte, ctx map[string]engine.ChainTemplate) ([ return []byte(s), nil } -// TODO where should this go -type DependencyCondition struct { - Upperbound string - Lowerbound string - Name string +type DependencyConditionCap struct { + Upperbound string `json:"upperbound,omitempty"` + Lowerbound string `json:"lowerbound,omitempty"` + Name string `json:"name"` // NameRegex will be a valid go regex that will be used to // search the name of a given dependency. // Examples include kubernetes* or jakarta-.*-2.2. - NameRegex string + NameRegex string `json:"name_regex,omitempty"` +} + +// TODO where should this go +type DependencyCondition struct { + DependencyConditionCap Client Client } @@ -672,7 +687,7 @@ func getVersion(depVersion string) (*version.Version, error) { return v, nil } // Parsing failed so we'll try to extract a version and parse that - re := regexp.MustCompile("v?([0-9]+(?:\\.[0-9]+)*)") + re := regexp.MustCompile(`v?([0-9]+(?:.[0-9]+)*)`) matches := re.FindStringSubmatch(depVersion) // The group is matching twice for some reason, double-check it's just a dup match @@ -736,3 +751,20 @@ func deduplicateDependencies(dependencies map[uri.URI][]*Dep) map[uri.URI][]*Dep } return deduped } + +func ToProviderCap(r *openapi3.Reflector, log logr.Logger, cond interface{}, name string) (Capability, error) { + jsonCondition, err := r.Reflector.Reflect(cond) + if err != nil { + log.Error(err, "fix it") + return Capability{}, err + } + s := &openapi3.SchemaOrRef{} + s.FromJSONSchema(jsonschema.SchemaOrBool{ + TypeObject: &jsonCondition, + }) + return Capability{ + Name: name, + Input: *s, + }, nil + +} diff --git a/provider/provider_test.go b/provider/provider_test.go index 2a2045e1..9fe847fd 100644 --- a/provider/provider_test.go +++ b/provider/provider_test.go @@ -120,10 +120,12 @@ func Test_dependencyConditionEvaluation(t *testing.T) { for _, tt := range tests { t.Run(tt.title, func(t *testing.T) { depCondition := DependencyCondition{ - Name: tt.name, - Upperbound: tt.upperbound, - Lowerbound: tt.lowerbound, - Client: &fakeClient{dependencies: tt.dependencies}, + DependencyConditionCap: DependencyConditionCap{ + Name: tt.name, + Upperbound: tt.upperbound, + Lowerbound: tt.lowerbound, + }, + Client: &fakeClient{dependencies: tt.dependencies}, } resp, err := depCondition.Evaluate(context.TODO(), logr.Logger{}, engine.ConditionContext{}) @@ -252,21 +254,21 @@ func Test_deduplication(t *testing.T) { { title: "no duplicates within a file should result in an unchanged list", dependencies: map[uri.URI][]*Dep{ - uri.URI("file1"): []*Dep{ + uri.URI("file1"): { {Name: "dep1", Version: "v1.0.0", ResolvedIdentifier: "abcd"}, {Name: "dep2", Version: "v1.0.0", ResolvedIdentifier: "abcd"}, }, - uri.URI("file2"): []*Dep{ + uri.URI("file2"): { {Name: "dep1", Version: "v1.0.0", ResolvedIdentifier: "abcd"}, {Name: "dep2", Version: "v1.0.0", ResolvedIdentifier: "abcd"}, }, }, expected: map[uri.URI][]*Dep{ - uri.URI("file1"): []*Dep{ + uri.URI("file1"): { {Name: "dep1", Version: "v1.0.0", ResolvedIdentifier: "abcd"}, {Name: "dep2", Version: "v1.0.0", ResolvedIdentifier: "abcd"}, }, - uri.URI("file2"): []*Dep{ + uri.URI("file2"): { {Name: "dep1", Version: "v1.0.0", ResolvedIdentifier: "abcd"}, {Name: "dep2", Version: "v1.0.0", ResolvedIdentifier: "abcd"}, }, @@ -275,7 +277,7 @@ func Test_deduplication(t *testing.T) { { title: "different versions or shas of the same dependency should not be deduped", dependencies: map[uri.URI][]*Dep{ - uri.URI("file1"): []*Dep{ + uri.URI("file1"): { {Name: "dep1", Version: "v1.0.0", ResolvedIdentifier: "abcd"}, {Name: "dep1", Version: "v2.0.0", ResolvedIdentifier: "abcd"}, {Name: "dep2", Version: "v1.0.0", ResolvedIdentifier: "abcde"}, @@ -283,7 +285,7 @@ func Test_deduplication(t *testing.T) { }, }, expected: map[uri.URI][]*Dep{ - uri.URI("file1"): []*Dep{ + uri.URI("file1"): { {Name: "dep1", Version: "v1.0.0", ResolvedIdentifier: "abcd"}, {Name: "dep1", Version: "v2.0.0", ResolvedIdentifier: "abcd"}, {Name: "dep2", Version: "v1.0.0", ResolvedIdentifier: "abcde"}, @@ -294,13 +296,13 @@ func Test_deduplication(t *testing.T) { { title: "duplicates within a file should be removed", dependencies: map[uri.URI][]*Dep{ - uri.URI("file1"): []*Dep{ + uri.URI("file1"): { {Name: "dep1", Version: "v1.0.0", ResolvedIdentifier: "abcd"}, {Name: "dep1", Version: "v1.0.0", ResolvedIdentifier: "abcd"}, }, }, expected: map[uri.URI][]*Dep{ - uri.URI("file1"): []*Dep{ + uri.URI("file1"): { {Name: "dep1", Version: "v1.0.0", ResolvedIdentifier: "abcd"}, }, }, @@ -308,13 +310,13 @@ func Test_deduplication(t *testing.T) { { title: "direct dependencies should be preferred over indirect", dependencies: map[uri.URI][]*Dep{ - uri.URI("file1"): []*Dep{ + uri.URI("file1"): { {Name: "dep1", Version: "v1.0.0", ResolvedIdentifier: "abcd", Indirect: true}, {Name: "dep1", Version: "v1.0.0", ResolvedIdentifier: "abcd"}, }, }, expected: map[uri.URI][]*Dep{ - uri.URI("file1"): []*Dep{ + uri.URI("file1"): { {Name: "dep1", Version: "v1.0.0", ResolvedIdentifier: "abcd"}, }, },