diff --git a/go.mod b/go.mod index e562aa7..3770cf5 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module scanoss.com/dependencies go 1.24.0 require ( - github.com/Masterminds/semver/v3 v3.3.1 github.com/golobby/config/v3 v3.4.2 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/guseggert/pkggodev-client v0.0.0-20240318140526-cdb0034504cf @@ -11,6 +10,7 @@ require ( github.com/lib/pq v1.10.9 github.com/package-url/packageurl-go v0.1.3 github.com/scanoss/go-grpc-helper v0.9.0 + github.com/scanoss/go-models-helper v0.0.0-unpublished github.com/scanoss/go-purl-helper v0.2.1 github.com/scanoss/papi v0.7.2 github.com/scanoss/zap-logging-helper v0.4.0 @@ -25,9 +25,11 @@ require ( //replace github.com/scanoss/papi => ../papi //replace github.com/scanoss/go-grpc-helper => ../go-grpc-helper //replace github.com/scanoss/zap-logging-helper => ../zap-logging-helper +replace github.com/scanoss/go-models-helper => ../go-models-helper require ( github.com/BurntSushi/toml v1.5.0 // indirect + github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/PuerkitoBio/goquery v1.10.3 // indirect github.com/andybalholm/cascadia v1.3.3 // indirect github.com/antchfx/htmlquery v1.2.4 // indirect diff --git a/go.sum b/go.sum index f0f1ad0..9292949 100644 --- a/go.sum +++ b/go.sum @@ -392,8 +392,8 @@ github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= -github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/PuerkitoBio/goquery v1.10.3 h1:pFYcNSqHxBD06Fpj/KsbStFRsgRATgnf3LeXiUkhzPo= @@ -464,8 +464,6 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -659,8 +657,6 @@ github.com/scanoss/go-purl-helper v0.2.1 h1:jp960a585ycyJSlqZky1NatMJBIQi/JGITDf github.com/scanoss/go-purl-helper v0.2.1/go.mod h1:v20/bKD8G+vGrILdiq6r0hyRD2bO8frCJlu9drEcQ38= github.com/scanoss/ipfilter/v2 v2.0.2 h1:GaB9i8kVJg9JQZm5XGStYkEpiaCVdsrj7ezI2wV/oh8= github.com/scanoss/ipfilter/v2 v2.0.2/go.mod h1:AwrpX4XGbZ7EKISMi1d6E5csBk1nWB8+ugpvXHFcTpA= -github.com/scanoss/papi v0.6.0 h1:hSDYFVtRuoZGJcCEYwyWkTSg3U3gNwDbufhK0NgeQ+o= -github.com/scanoss/papi v0.6.0/go.mod h1:pqi3lfS79CwrNvYUKpiVVKc0BR+CFwrgksf4mVmVbRs= github.com/scanoss/papi v0.7.2 h1:RdILfOVelqANeM05OC/rXKrOQqzSfaUfj68eHWvVzVc= github.com/scanoss/papi v0.7.2/go.mod h1:pqi3lfS79CwrNvYUKpiVVKc0BR+CFwrgksf4mVmVbRs= github.com/scanoss/zap-logging-helper v0.4.0 h1:2qTYoaFa9+MlD2/1wmPtiDHfh+42NIEwgKVU3rPpl0Y= @@ -709,8 +705,6 @@ go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJyS go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= -go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= -go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0 h1:QcFwRrZLc82r8wODjvyCbP7Ifp3UANaBSmhDSFjnqSc= @@ -719,16 +713,12 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0f go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo= -go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= -go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= -go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= -go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= @@ -768,8 +758,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw= -golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM= golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM= golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -914,8 +902,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= +golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -992,8 +980,6 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= -golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= @@ -1092,8 +1078,8 @@ golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU= -golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ= +golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= +golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1275,12 +1261,8 @@ google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZV google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= -google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 h1:hE3bRWtU6uceqlh4fhrSnUyjKHMKB9KrTLLG+bc0ddM= google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463/go.mod h1:U90ffi8eUL9MwPcrJylN5+Mk2v3vuPDptd5yyNUiRR8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 h1:e0AIkUUhxyBKh6ssZNrAMeqhA7RKUj42346d1y02i2g= google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1321,8 +1303,6 @@ google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCD google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= -google.golang.org/grpc v1.72.0 h1:S7UkcVa60b5AAQTaO6ZKamFp1zMZSU0fGDK2WZLbBnM= -google.golang.org/grpc v1.72.0/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= @@ -1362,33 +1342,24 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -modernc.org/cc/v4 v4.25.2 h1:T2oH7sZdGvTaie0BRNFbIYsabzCxUQg8nLqCdQ2i0ic= -modernc.org/cc/v4 v4.25.2/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= modernc.org/cc/v4 v4.26.1 h1:+X5NtzVBn0KgsBCBe+xkDC7twLb/jNVj9FPgiwSQO3s= -modernc.org/ccgo/v4 v4.25.1 h1:TFSzPrAGmDsdnhT9X2UrcPMI3N/mJ9/X9ykKXwLhDsU= -modernc.org/ccgo/v4 v4.25.1/go.mod h1:njjuAYiPflywOOrm3B7kCB444ONP5pAVr8PIEoE0uDw= +modernc.org/cc/v4 v4.26.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU= -modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= -modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= +modernc.org/ccgo/v4 v4.28.0/go.mod h1:JygV3+9AV6SmPhDasu4JgquwU81XAKLd3OKTUDNOiKE= modernc.org/fileutil v1.3.3 h1:3qaU+7f7xxTUmvU1pJTZiDLAIoJVdUSSauJNHg9yXoA= +modernc.org/fileutil v1.3.3/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc= modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= -modernc.org/libc v1.62.1 h1:s0+fv5E3FymN8eJVmnk0llBe6rOxCu/DEU+XygRbS8s= -modernc.org/libc v1.62.1/go.mod h1:iXhATfJQLjG3NWy56a6WVU73lWOcdYVxsvwCgoPljuo= modernc.org/libc v1.65.10 h1:ZwEk8+jhW7qBjHIT+wd0d9VjitRyQef9BnzlzGwMODc= modernc.org/libc v1.65.10/go.mod h1:StFvYpx7i/mXtBAfVOjaU0PWZOvIRoZSgXhrwXzr8Po= modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= -modernc.org/memory v1.9.1 h1:V/Z1solwAVmMW1yttq3nDdZPJqV1rM05Ccq6KMSZ34g= -modernc.org/memory v1.9.1/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= -modernc.org/sqlite v1.37.0 h1:s1TMe7T3Q3ovQiK2Ouz4Jwh7dw4ZDqbebSDTlSJdfjI= -modernc.org/sqlite v1.37.0/go.mod h1:5YiWv+YviqGMuGw4V+PNplcyaJ5v+vQd7TQOgkACoJM= modernc.org/sqlite v1.38.0 h1:+4OrfPQ8pxHKuWG4md1JpR/EYAh3Md7TdejuuzE7EUI= modernc.org/sqlite v1.38.0/go.mod h1:1Bj+yES4SVvBZ4cBOpVZ6QgesMCKpJZDq0nxYzOpmNE= modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= diff --git a/pkg/models/all_urls.go b/pkg/models/all_urls.go deleted file mode 100644 index bfb5c3b..0000000 --- a/pkg/models/all_urls.go +++ /dev/null @@ -1,257 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018-2023 SCANOSS.COM - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package models - -import ( - "context" - "errors" - "fmt" - "sort" - "strings" - - "github.com/scanoss/go-grpc-helper/pkg/grpc/database" - - "github.com/Masterminds/semver/v3" - "github.com/jmoiron/sqlx" - purlutils "github.com/scanoss/go-purl-helper/pkg" - "go.uber.org/zap" -) - -type AllUrlsModel struct { - ctx context.Context - s *zap.SugaredLogger - conn *sqlx.Conn - project *ProjectModel - golangProj *GolangProjects - q *database.DBQueryContext -} - -type AllURL struct { - Component string `db:"component"` - Version string `db:"version"` - SemVer string `db:"semver"` - License string `db:"license"` - LicenseID string `db:"license_id"` - IsSpdx bool `db:"is_spdx"` - PurlName string `db:"purl_name"` - MineID int32 `db:"mine_id"` - URL string `db:"-"` -} - -// SQL Query constants. -const ( - purlSQLQuerySelect = "SELECT component, v.version_name AS version, v.semver AS semver," - licSpdxSQLQuery = " l.license_name AS license, l.spdx_id AS license_id, l.is_spdx AS is_spdx," - verLeftJoinSQL = " LEFT JOIN versions v ON u.version_id = v.id" - licLeftJoinSQL = " LEFT JOIN licenses l ON u.license_id = l.id" - mineLeftJoinSQL = " LEFT JOIN mines m ON u.mine_id = m.id" -) - -// NewAllURLModel creates a new instance of the 'All URL' Model. -func NewAllURLModel(ctx context.Context, s *zap.SugaredLogger, conn *sqlx.Conn, project *ProjectModel, golangProj *GolangProjects, q *database.DBQueryContext) *AllUrlsModel { - return &AllUrlsModel{ctx: ctx, s: s, conn: conn, project: project, golangProj: golangProj, q: q} -} - -// GetURLsByPurlString searches for component details of the specified Purl string (and optional requirement). -func (m *AllUrlsModel) GetURLsByPurlString(purlString, purlReq string) (AllURL, error) { - if len(purlString) == 0 { - m.s.Error("Please specify a valid Purl String to query") - return AllURL{}, errors.New("please specify a valid Purl String to query") - } - purl, err := purlutils.PurlFromString(purlString) - if err != nil { - return AllURL{}, err - } - purlName, err := purlutils.PurlNameFromString(purlString) // Make sure we just have the bare minimum for a Purl Name - if err != nil { - return AllURL{}, err - } - // TODO check what to do if we get a "file" requirement - if len(purlReq) > 0 && strings.HasPrefix(purlReq, "file:") { // internal dependency requirement. Assume latest - m.s.Debugf("Removing 'local' requirement for purl: %v (req: %v)", purlString, purlReq) - purlReq = "" - } - if len(purl.Version) == 0 && len(purlReq) > 0 { // No version specified, but we might have a specific version in the Requirement - ver := purlutils.GetVersionFromReq(purlReq) - if len(ver) > 0 { - purl.Version = ver // Switch to exact version search (faster) - purlReq = "" - } - } - if purl.Type == "golang" { - allURL, err := m.golangProj.GetGoLangURLByPurl(purl, purlName, purlReq) // Search a separate table for golang dependencies - // If no golang package/license is found, but it's a GitHub component, search GitHub for it - if err == nil && (len(allURL.Component) == 0 || len(allURL.License) == 0) && strings.HasPrefix(purlString, "pkg:golang/github.com/") { - if len(allURL.Component) == 0 { - m.s.Debugf("Didn't find component in golang projects table for %v. Checking all urls...", purlString) - } else if len(allURL.License) == 0 { - m.s.Debugf("Didn't find license in golang projects table for %v. Checking all urls...", purlString) - } - purlString = purlutils.ConvertGoPurlStringToGithub(purlString) // Convert to GitHub purl - purl, err = purlutils.PurlFromString(purlString) - if err != nil { - return AllURL{}, err - } - purlName, err = purlutils.PurlNameFromString(purlString) // Make sure we just have the bare minimum for a Purl Name - if err != nil { - return AllURL{}, err - } - m.s.Debugf("Now searching All Urls for Purl: %#v, PurlName: %v", purl, purlName) - } else { - return allURL, err - } - } - if len(purl.Version) > 0 { - return m.GetURLsByPurlNameTypeVersion(purlName, purl.Type, purl.Version) - } - return m.GetURLsByPurlNameType(purlName, purl.Type, purlReq) -} - -// GetURLsByPurlNameType searches for component details of the specified Purl Name/Type (and optional requirement). -func (m *AllUrlsModel) GetURLsByPurlNameType(purlName, purlType, purlReq string) (AllURL, error) { - if len(purlName) == 0 { - m.s.Error("Please specify a valid Purl Name to query") - return AllURL{}, errors.New("please specify a valid Purl Name to query") - } - if len(purlType) == 0 { - m.s.Errorf("Please specify a valid Purl Type to query: %v", purlName) - return AllURL{}, errors.New("please specify a valid Purl Type to query") - } - query := purlSQLQuerySelect + licSpdxSQLQuery + " purl_name, mine_id FROM all_urls u" + - mineLeftJoinSQL + licLeftJoinSQL + verLeftJoinSQL + - " WHERE m.purl_type = $1 AND u.purl_name = $2 ORDER BY date DESC" - var allUrls []AllURL - err := m.q.SelectContext(m.ctx, &allUrls, query, purlType, purlName) - if err != nil { - m.s.Errorf("Failed to query all urls table for %v - %v: %v", purlType, purlName, err) - return AllURL{}, fmt.Errorf("failed to query the all urls table: %v", err) - } - m.s.Debugf("Found %v results for %v, %v.", len(allUrls), purlType, purlName) - // Pick one URL to return (checking for license details also) - return pickOneUrl(m.s, m.project, allUrls, purlName, purlType, purlReq) -} - -// GetURLsByPurlNameTypeVersion searches for component details of the specified Purl Name/Type and version. -func (m *AllUrlsModel) GetURLsByPurlNameTypeVersion(purlName, purlType, purlVersion string) (AllURL, error) { - if len(purlName) == 0 { - m.s.Error("Please specify a valid Purl Name to query") - return AllURL{}, errors.New("please specify a valid Purl Name to query") - } - if len(purlType) == 0 { - m.s.Error("Please specify a valid Purl Type to query") - return AllURL{}, errors.New("please specify a valid Purl Type to query") - } - if len(purlVersion) == 0 { - m.s.Error("Please specify a valid Purl Version to query") - return AllURL{}, errors.New("please specify a valid Purl Version to query") - } - query := purlSQLQuerySelect + licSpdxSQLQuery + " purl_name, mine_id FROM all_urls u" + - mineLeftJoinSQL + licLeftJoinSQL + verLeftJoinSQL + - " WHERE m.purl_type = $1 AND u.purl_name = $2 AND v.version_name = $3 ORDER BY date DESC" - var allUrls []AllURL - err := m.q.SelectContext(m.ctx, &allUrls, query, purlType, purlName, purlVersion) - if err != nil { - m.s.Errorf("Failed to query all urls table for %v - %v: %v", purlType, purlName, err) - return AllURL{}, fmt.Errorf("failed to query the all urls table: %v", err) - } - m.s.Debugf("Found %v results for %v, %v.", len(allUrls), purlType, purlName) - // Pick one URL to return (checking for license details also) - return pickOneUrl(m.s, m.project, allUrls, purlName, purlType, "") -} - -// pickOneUrl takes the potential matching component/versions and selects the most appropriate one. -func pickOneUrl(s *zap.SugaredLogger, projModel *ProjectModel, allUrls []AllURL, purlName, purlType, purlReq string) (AllURL, error) { - if len(allUrls) == 0 { - s.Infof("No component match (in urls) found for %v, %v", purlName, purlType) - return AllURL{}, nil - } - // s.Debugf("Potential Matches: %v", allUrls) - var c *semver.Constraints - var urlMap = make(map[*semver.Version]AllURL) - if len(purlReq) > 0 { - s.Debugf("Building version constraint for %v: %v", purlName, purlReq) - var err error - c, err = semver.NewConstraint(purlReq) - if err != nil { - s.Warnf("Encountered an issue parsing version constraint string '%v' (%v,%v): %v", purlReq, purlName, purlType, err) - } - } - s.Debugf("Checking versions...") - for _, url := range allUrls { - if len(url.SemVer) > 0 || len(url.Version) > 0 { - v, err := semver.NewVersion(url.Version) - if err != nil && len(url.SemVer) > 0 { - s.Debugf("Failed to parse SemVer: '%v'. Trying Version instead: %v (%v)", url.Version, url.SemVer, err) - v, err = semver.NewVersion(url.SemVer) // Semver failed, try the normal version - } - if err != nil { - s.Warnf("Encountered an issue parsing version string '%v' (%v) for %v: %v. Using v0.0.0", url.Version, url.SemVer, url, err) - v, err = semver.NewVersion("v0.0.0") // Semver failed, just use a standard version zero (for now) - } - if err == nil { - if c == nil || c.Check(v) { - _, ok := urlMap[v] - if !ok { - urlMap[v] = url // fits inside the constraint and hasn't already been stored - } - } - } - } else { - s.Infof("Skipping match as it doesn't have a version: %#v", url) - } - } - if len(urlMap) == 0 { // TODO should we return the latest version anyway? - s.Warnf("No component match found for %v, %v after filter %v", purlName, purlType, purlReq) - return AllURL{}, nil - } - var versions = make([]*semver.Version, len(urlMap)) - var vi = 0 - for version := range urlMap { // Save the list of versions so they can be sorted - versions[vi] = version - vi++ - } - sort.Sort(semver.Collection(versions)) - version := versions[len(versions)-1] // Get the latest (acceptable) URL version - s.Debugf("Sorted versions: %v. Highest: %v", versions, version) - - url, ok := urlMap[version] // Retrieve the latest accepted URL version - if !ok { - s.Errorf("Problem retrieving URL data for %v (%v, %v)", version, purlName, purlType) - return AllURL{}, fmt.Errorf("failed to retrieve specific URL version: %v", version) - } - url.URL, _ = purlutils.ProjectUrl(purlName, purlType) - - s.Debugf("Selected version: %#v", url) - if len(url.License) == 0 && projModel != nil { // Check for a project license if we don't have a component one - project, err := projModel.GetProjectByPurlName(purlName, url.MineID) - switch { - case err != nil: - s.Warnf("Problem searching projects table for %v, %v", purlName, purlType) - case len(project.License) > 0: - s.Debugf("Adding project license data to %v from %v", url, project) - url.License = project.License - url.IsSpdx = project.IsSpdx - url.LicenseID = project.LicenseID - case len(project.GitLicense) > 0: - s.Debugf("Adding project git license data to %v from %v", url, project) - url.License = project.GitLicense - url.IsSpdx = project.GitIsSpdx - url.LicenseID = project.GitLicenseID - } - } - return url, nil // Return the best component match -} diff --git a/pkg/models/all_urls_test.go b/pkg/models/all_urls_test.go deleted file mode 100644 index 7d0cc02..0000000 --- a/pkg/models/all_urls_test.go +++ /dev/null @@ -1,353 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018-2023 SCANOSS.COM - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package models - -import ( - "context" - "fmt" - "testing" - - "github.com/scanoss/go-grpc-helper/pkg/grpc/database" - - "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" - zlog "github.com/scanoss/zap-logging-helper/pkg/logger" - myconfig "scanoss.com/dependencies/pkg/config" -) - -func TestAllUrlsSearch(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - err = LoadTestSQLData(db, ctx, conn) - if err != nil { - t.Fatalf("failed to load SQL test data: %v", err) - } - myConfig, err := myconfig.NewServerConfig(nil) - if err != nil { - t.Fatalf("failed to load Config: %v", err) - } - myConfig.Components.CommitMissing = true - myConfig.Database.Trace = true - allUrlsModel := NewAllURLModel(ctx, s, conn, NewProjectModel(ctx, s, conn), - NewGolangProjectModel(ctx, s, db, conn, myConfig), database.NewDBSelectContext(s, db, conn, myConfig.Database.Trace)) - - allUrls, err := allUrlsModel.GetURLsByPurlNameType("tablestyle", "gem", "") - if err != nil { - t.Errorf("all_urls.GetUrlsByPurlName() error = %v", err) - } - if len(allUrls.PurlName) == 0 { - t.Errorf("all_urls.GetUrlsByPurlName() No URLs returned from query") - } - fmt.Printf("All Urls: %#v\n", allUrls) - - allUrls, err = allUrlsModel.GetURLsByPurlNameType("NONEXISTENT", "none", "") - if err != nil { - t.Errorf("all_urls.GetUrlsByPurlName() error = %v", err) - } - if len(allUrls.PurlName) > 0 { - t.Errorf("all_urls.GetURLsByPurlNameType() URLs found when none should be: %v", allUrlsModel) - } - fmt.Printf("No Urls: %v\n", allUrls) - - _, err = allUrlsModel.GetURLsByPurlNameType("NONEXISTENT", "", "") - if err == nil { - t.Errorf("all_urls.GetURLsByPurlString() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = allUrlsModel.GetURLsByPurlNameType("", "", "") - if err == nil { - t.Errorf("all_urls.GetURLsByPurlString() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = allUrlsModel.GetURLsByPurlString("", "") - if err == nil { - t.Errorf("all_urls.GetURLsByPurlString() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = allUrlsModel.GetURLsByPurlString("rubbish-purl", "") - if err == nil { - t.Errorf("all_urls.GetURLsByPurlString() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - allUrls, err = allUrlsModel.GetURLsByPurlString("pkg:gem/tablestyle", "") - if err != nil { - t.Errorf("all_urls.GetURLsByPurlString() error = %v", err) - } - if len(allUrls.PurlName) == 0 { - t.Errorf("all_urls.GetURLsByPurlString() No URLs returned from query") - } - fmt.Printf("All Urls: %v\n", allUrls) - - allUrls, err = allUrlsModel.GetURLsByPurlString("pkg:golang/google.golang.org/grpc", "") - if err != nil { - t.Errorf("all_urls.GetURLsByPurlString() error = %v", err) - } - if len(allUrls.PurlName) == 0 { - t.Errorf("all_urls.GetURLsByPurlString() No URLs returned from query") - } - fmt.Printf("Golang URL: %v\n", allUrls) - - fmt.Printf("Searching for pkg:golang/github.com/scanoss/dependencies") - allUrls, err = allUrlsModel.GetURLsByPurlString("pkg:golang/github.com/scanoss/dependencies", "") - if err != nil { - t.Errorf("all_urls.GetURLsByPurlString() error = %v", err) - } - if len(allUrls.PurlName) == 0 { - t.Errorf("all_urls.GetURLsByPurlString() No URLs returned from query") - } - fmt.Printf("Golang URL: %v\n", allUrls) -} - -func TestAllUrlsSearchVersion(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - err = LoadTestSQLData(db, ctx, conn) - if err != nil { - t.Fatalf("failed to load SQL test data: %v", err) - } - myConfig, err := myconfig.NewServerConfig(nil) - if err != nil { - t.Fatalf("failed to load Config: %v", err) - } - myConfig.Components.CommitMissing = true - myConfig.Database.Trace = true - allUrlsModel := NewAllURLModel(ctx, s, conn, NewProjectModel(ctx, s, conn), - NewGolangProjectModel(ctx, s, db, conn, myConfig), database.NewDBSelectContext(s, db, conn, myConfig.Database.Trace)) - - allUrls, err := allUrlsModel.GetURLsByPurlNameTypeVersion("tablestyle", "gem", "0.0.12") - if err != nil { - t.Errorf("all_urls.GetUrlsByPurlName() error = %v", err) - } - if len(allUrls.PurlName) == 0 { - t.Errorf("all_urls.GetURLsByPurlNameTypeVersion() No URLs returned from query") - } - fmt.Printf("All Urls Version: %#v\n", allUrls) - - allUrls, err = allUrlsModel.GetURLsByPurlString("pkg:gem/tablestyle@0.0.7", "") - if err != nil { - t.Errorf("all_urls.GetURLsByPurlString() error = failed to find purl by version string") - } - fmt.Printf("All Urls Version String: %#v\n", allUrls) - - _, err = allUrlsModel.GetURLsByPurlNameTypeVersion("", "", "") - if err == nil { - t.Errorf("all_urls.GetURLsByPurlNameTypeVersion() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = allUrlsModel.GetURLsByPurlNameTypeVersion("NONEXISTENT", "", "") - if err == nil { - t.Errorf("all_urls.GetURLsByPurlNameTypeVersion() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = allUrlsModel.GetURLsByPurlNameTypeVersion("NONEXISTENT", "NONEXISTENT", "") - if err == nil { - t.Errorf("all_urls.GetURLsByPurlNameTypeVersion() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - - allUrls, err = allUrlsModel.GetURLsByPurlString("pkg:gem/tablestyle", "22.22.22") // Shouldn't exist - if err != nil { - t.Errorf("all_urls.GetURLsByPurlString() error = failed to find purl by version string") - } - if len(allUrls.PurlName) > 0 { - t.Errorf("all_urls.GetURLsByPurlString() error = Found match, when we shouldn't: %v", allUrls) - } -} - -func TestAllUrlsSearchVersionRequirement(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - err = LoadTestSQLData(db, ctx, conn) - if err != nil { - t.Fatalf("failed to load SQL test data: %v", err) - } - myConfig, err := myconfig.NewServerConfig(nil) - if err != nil { - t.Fatalf("failed to load Config: %v", err) - } - myConfig.Components.CommitMissing = true - myConfig.Database.Trace = true - allUrlsModel := NewAllURLModel(ctx, s, conn, NewProjectModel(ctx, s, conn), - NewGolangProjectModel(ctx, s, db, conn, myConfig), database.NewDBSelectContext(s, db, conn, myConfig.Database.Trace)) - - allUrls, err := allUrlsModel.GetURLsByPurlString("pkg:gem/tablestyle", ">0.0.4") - if err != nil { - t.Errorf("all_urls.GetUrlsByPurlName() error = %v", err) - } - if len(allUrls.PurlName) == 0 { - t.Errorf("all_urls.GetURLsByPurlString() No URLs returned from query") - } - fmt.Printf("All Urls Version: %#v\n", allUrls) - - allUrls, err = allUrlsModel.GetURLsByPurlString("pkg:gem/tablestyle", "<0.0.4>") - if err != nil { - t.Errorf("all_urls.GetUrlsByPurlName() error = %v", err) - } - if len(allUrls.PurlName) == 0 { - t.Errorf("all_urls.GetURLsByPurlString() No URLs returned from query") - } -} - -func TestAllUrlsSearchNoProject(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - err = LoadTestSQLData(db, ctx, conn) - if err != nil { - t.Fatalf("failed to load SQL test data: %v", err) - } - myConfig, err := myconfig.NewServerConfig(nil) - if err != nil { - t.Fatalf("failed to load Config: %v", err) - } - myConfig.Components.CommitMissing = true - myConfig.App.Trace = true - allUrlsModel := NewAllURLModel(ctx, s, conn, nil, NewGolangProjectModel(ctx, s, db, conn, myConfig), database.NewDBSelectContext(s, db, conn, myConfig.Database.Trace)) - - allUrls, err := allUrlsModel.GetURLsByPurlNameType("tablestyle", "gem", "0.0.8") - if err != nil { - t.Errorf("all_urls.GetUrlsByPurlName() error = %v", err) - } - if len(allUrls.PurlName) == 0 { - t.Errorf("all_urls.GetURLsByPurlNameType() No URLs returned from query") - } - fmt.Printf("All Urls: %#v\n", allUrls) -} - -func TestAllUrlsSearchNoLicense(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - err = LoadTestSQLData(db, ctx, conn) - if err != nil { - t.Fatalf("failed to load SQL test data: %v", err) - } - myConfig, err := myconfig.NewServerConfig(nil) - if err != nil { - t.Fatalf("failed to load Config: %v", err) - } - myConfig.Components.CommitMissing = true - myConfig.App.Trace = true - allUrlsModel := NewAllURLModel(ctx, s, conn, NewProjectModel(ctx, s, conn), - NewGolangProjectModel(ctx, s, db, conn, myConfig), database.NewDBSelectContext(s, db, conn, myConfig.Database.Trace)) - - allUrls, err := allUrlsModel.GetURLsByPurlString("pkg:gem/tablestyle@0.0.8", "") - if err != nil { - t.Errorf("all_urls.GetURLsByPurlString() error = %v", err) - } - if len(allUrls.PurlName) == 0 { - t.Errorf("all_urls.GetURLsByPurlString() No URLs returned from query") - } - fmt.Printf("All (with project) Urls: %#v\n", allUrls) -} - -func TestAllUrlsSearchBadSql(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - myConfig, err := myconfig.NewServerConfig(nil) - if err != nil { - t.Fatalf("failed to load Config: %v", err) - } - myConfig.Components.CommitMissing = true - myConfig.App.Trace = true - allUrlsModel := NewAllURLModel(ctx, s, conn, NewProjectModel(ctx, s, conn), - NewGolangProjectModel(ctx, s, db, conn, myConfig), database.NewDBSelectContext(s, db, conn, myConfig.Database.Trace)) - _, err = allUrlsModel.GetURLsByPurlString("pkg:gem/tablestyle", "") - if err == nil { - t.Errorf("all_urls.GetURLsByPurlString() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = allUrlsModel.GetURLsByPurlString("pkg:gem/tablestyle@0.0.8", "") - if err == nil { - t.Errorf("all_urls.GetURLsByPurlString() error = did not get an error: %v", err) - } else { - fmt.Printf("Got expected error = %v\n", err) - } - // Load some tables (leaving out projects) - err = loadTestSQLDataFiles(db, ctx, conn, []string{"./tests/mines.sql", "./tests/all_urls.sql", "./tests/licenses.sql", "./tests/versions.sql"}) - if err != nil { - t.Fatalf("failed to load SQL test data: %v", err) - } - // allUrls, err := allUrlsModel.GetURLsByPurlNameType("tablestyle", "gem", "") - allUrls, err := allUrlsModel.GetURLsByPurlString("pkg:gem/tablestyle@0.0.8", "") - if err != nil { - t.Errorf("all_urls.GetUrlsByPurlName() error = %v", err) - } - if len(allUrls.PurlName) == 0 { - t.Errorf("all_urls.GetURLsByPurlNameType() No URLs returned from query") - } - fmt.Printf("All Urls: %v\n", allUrls) -} diff --git a/pkg/models/golang_projects.go b/pkg/models/golang_projects.go deleted file mode 100644 index 29f80e6..0000000 --- a/pkg/models/golang_projects.go +++ /dev/null @@ -1,330 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018-2023 SCANOSS.COM - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package models - -import ( - "context" - "database/sql" - "errors" - "fmt" - - "github.com/scanoss/go-grpc-helper/pkg/grpc/database" - - pkggodevclient "github.com/guseggert/pkggodev-client" - "github.com/jmoiron/sqlx" - "github.com/package-url/packageurl-go" - purlutils "github.com/scanoss/go-purl-helper/pkg" - "go.uber.org/zap" - myconfig "scanoss.com/dependencies/pkg/config" -) - -type GolangProjects struct { - ctx context.Context - s *zap.SugaredLogger - conn *sqlx.Conn - config *myconfig.ServerConfig - q *database.DBQueryContext - ver *VersionModel - lic *LicenseModel - mine *MineModel - project *ProjectModel // TODO Do we add golang component to the projects table? -} - -// NewGolangProjectModel creates a new instance of Golang Project Model. -func NewGolangProjectModel(ctx context.Context, s *zap.SugaredLogger, db *sqlx.DB, conn *sqlx.Conn, config *myconfig.ServerConfig) *GolangProjects { - return &GolangProjects{ctx: ctx, s: s, conn: conn, config: config, - q: database.NewDBSelectContext(s, db, conn, config.Database.Trace), - ver: NewVersionModel(ctx, s, conn), lic: NewLicenseModel(ctx, s, conn), mine: NewMineModel(ctx, s, conn), - project: NewProjectModel(ctx, s, conn), - } -} - -// GetGoLangURLByPurlString searches the Golang Projects for the specified Purl (and requirement). -func (m *GolangProjects) GetGoLangURLByPurlString(purlString, purlReq string) (AllURL, error) { - if len(purlString) == 0 { - m.s.Error("Please specify a valid Purl String to query") - return AllURL{}, errors.New("please specify a valid Purl String to query") - } - purl, err := purlutils.PurlFromString(purlString) - if err != nil { - return AllURL{}, err - } - purlName, err := purlutils.PurlNameFromString(purlString) - if err != nil { - return AllURL{}, err - } - if len(purl.Version) == 0 && len(purlReq) > 0 { // No version specified, but we might have a specific version in the Requirement - ver := purlutils.GetVersionFromReq(purlReq) - if len(ver) > 0 { - purl.Version = ver - purlReq = "" - } - } - return m.GetGoLangURLByPurl(purl, purlName, purlReq) -} - -// GetGoLangURLByPurl searches the Golang Projects for the specified Purl Package (and optional requirement). -func (m *GolangProjects) GetGoLangURLByPurl(purl packageurl.PackageURL, purlName, purlReq string) (AllURL, error) { - if len(purl.Version) > 0 { - return m.GetGolangUrlsByPurlNameTypeVersion(purlName, purl.Type, purl.Version) - } - return m.GetGolangUrlsByPurlNameType(purlName, purl.Type, purlReq) -} - -// GetGolangUrlsByPurlNameType searches Golang Project for the specified Purl by Purl Type (and optional requirement). -func (m *GolangProjects) GetGolangUrlsByPurlNameType(purlName, purlType, purlReq string) (AllURL, error) { - if len(purlName) == 0 { - m.s.Error("Please specify a valid Purl Name to query") - return AllURL{}, errors.New("please specify a valid Purl Name to query") - } - if len(purlType) == 0 { - m.s.Errorf("Please specify a valid Purl Type to query: %v", purlName) - return AllURL{}, errors.New("please specify a valid Purl Type to query") - } - query := "SELECT component, v.version_name AS version, v.semver AS semver," + - " l.license_name AS license, l.spdx_id AS license_id, l.is_spdx AS is_spdx," + - " purl_name, mine_id FROM golang_projects u" + - " LEFT JOIN mines m ON u.mine_id = m.id" + - " LEFT JOIN licenses l ON u.license_id = l.id" + - " LEFT JOIN versions v ON u.version_id = v.id" + - " WHERE m.purl_type = $1 AND u.purl_name = $2 AND is_indexed = True" + - " ORDER BY version_date DESC" - var allURLs []AllURL - err := m.q.SelectContext(m.ctx, &allURLs, query, purlType, purlName) - if err != nil { - m.s.Errorf("Failed to query golang projects table for %v - %v: %v", purlType, purlName, err) - return AllURL{}, fmt.Errorf("failed to query the golang projects table: %v", err) - } - m.s.Debugf("Found %v results for %v, %v.", len(allURLs), purlType, purlName) - if len(allURLs) == 0 { // Check pkg.go.dev for the latest data - m.s.Debugf("Checking PkgGoDev for live info...") - allURL, err := m.getLatestPkgGoDev(purlName, purlType, "") - if err == nil { - m.s.Debugf("Retrieved golang data from pkg.go.dev: %#v", allURL) - allURLs = append(allURLs, allURL) - } else { - m.s.Infof("Ran into an issue looking up pkg.go.dev for: %v. Ignoring", purlName) - } - } - - // Pick the most appropriate version to return - return pickOneUrl(m.s, m.project, allURLs, purlName, purlType, purlReq) -} - -// GetGolangUrlsByPurlNameTypeVersion searches Golang Projects for specified Purl, Type and Version. -func (m *GolangProjects) GetGolangUrlsByPurlNameTypeVersion(purlName, purlType, purlVersion string) (AllURL, error) { - if len(purlName) == 0 { - m.s.Error("Please specify a valid Purl Name to query") - return AllURL{}, errors.New("please specify a valid Purl Name to query") - } - if len(purlType) == 0 { - m.s.Error("Please specify a valid Purl Type to query") - return AllURL{}, errors.New("please specify a valid Purl Type to query") - } - if len(purlVersion) == 0 { - m.s.Error("Please specify a valid Purl Version to query") - return AllURL{}, errors.New("please specify a valid Purl Version to query") - } - query := "SELECT component, v.version_name AS version, v.semver AS semver," + - " l.license_name AS license, l.spdx_id AS license_id, l.is_spdx AS is_spdx," + - " purl_name, mine_id FROM golang_projects u" + - " LEFT JOIN mines m ON u.mine_id = m.id" + - " LEFT JOIN licenses l ON u.license_id = l.id" + - " LEFT JOIN versions v ON u.version_id = v.id" + - " WHERE m.purl_type = $1 AND u.purl_name = $2 AND v.version_name = $3 AND is_indexed = True" + - " ORDER BY version_date DESC" - var allURLs []AllURL - err := m.q.SelectContext(m.ctx, &allURLs, query, purlType, purlName, purlVersion) - if err != nil { - m.s.Errorf("Failed to query golang projects table for %v - %v: %v", purlType, purlName, err) - return AllURL{}, fmt.Errorf("failed to query the golang projects table: %v", err) - } - m.s.Debugf("Found %v results for %v, %v.", len(allURLs), purlType, purlName) - if len(allURLs) > 0 { // We found an entry. Let's check if it has license data - allURL, err2 := pickOneUrl(m.s, m.project, allURLs, purlName, purlType, "") - if len(allURL.License) == 0 { // No license data found. Need to search for live info - m.s.Debugf("Couldn't find license data for component. Need to search live data") - allURLs = allURLs[:0] - } else { - return allURL, err2 // Return the component details - } - } - if len(allURLs) == 0 { // Check pkg.go.dev for the latest data - m.s.Debugf("Checking PkgGoDev for live info...") - allURL, err := m.getLatestPkgGoDev(purlName, purlType, purlVersion) - if err == nil { - m.s.Debugf("Retrieved golang data from pkg.go.dev: %#v", allURL) - allURLs = append(allURLs, allURL) - } else { - m.s.Infof("Ran into an issue looking up pkg.go.dev for: %v - %v. Ignoring", purlName, purlVersion) - } - } - // Pick the most appropriate version to return - return pickOneUrl(m.s, m.project, allURLs, purlName, purlType, "") -} - -// savePkg writes the given package details to the Golang Projects table. -// -//goland:noinspection ALL -func (m *GolangProjects) savePkg(allURL AllURL, version Version, license License, comp *pkggodevclient.Package) error { - if len(allURL.PurlName) == 0 { - m.s.Error("Please specify a valid Purl to save") - return errors.New("please specify a valid Purl to save") - } - if allURL.MineID <= 0 { - m.s.Error("Please specify a valid mine id to save") - return errors.New("please specify a valid mine id to save") - } - if version.ID <= 0 || len(version.VersionName) == 0 { - m.s.Error("Please specify a valid version to save") - return errors.New("please specify a valid version to save") - } - if license.ID <= 0 || len(license.LicenseName) == 0 { - m.s.Error("Please specify a valid license to save") - return errors.New("please specify a valid license to save") - } - if comp == nil { - m.s.Error("Please specify a valid component package to save") - return errors.New("please specify a valid component package to save") - } - m.s.Debugf("Attempting to save '%#v' - %#v to the golang_projects table...", allURL, version) - // Search for an existing entry first - var existingPurl string - err := m.conn.QueryRowxContext(m.ctx, - "SELECT purl_name FROM golang_projects"+ - " WHERE purl_name = $1 AND version = $2", - allURL.PurlName, allURL.Version, - ).Scan(&existingPurl) - if err != nil && err != sql.ErrNoRows { - m.s.Warnf("Error: Problem encountered searching golang_projects table for %v: %v", allURL, err) - } - var purlName string - sqlQueryType := "insert" - if len(existingPurl) > 0 { - // update entry - sqlQueryType = "update" - m.s.Debugf("Updating new Golang project: %#v", comp) - //goland:noinspection ALL - err = m.conn.QueryRowxContext(m.ctx, - "UPDATE golang_projects SET component = $1, version = $2, version_id = $3, version_date = $4,"+ - " is_module = $5, is_package = $6, license = $7, license_id = $8, has_valid_go_mod_file = $9,"+ - " has_redistributable_license = $10, has_tagged_version = $11, has_stable_version = $12,"+ - " repository = $13, is_indexed = $14, purl_name = $15, mine_id = $16"+ - " WHERE purl_name = $17 AND version = $18"+ - " RETURNING purl_name", - allURL.Component, allURL.Version, version.ID, comp.Published, - comp.IsModule, comp.IsPackage, license.LicenseName, license.ID, comp.HasValidGoModFile, - comp.HasRedistributableLicense, comp.HasTaggedVersion, comp.HasStableVersion, - comp.Repository, true, allURL.PurlName, allURL.MineID, - allURL.PurlName, allURL.Version, - ).Scan(&purlName) - } else { - m.s.Debugf("Inserting new Golang project: %#v", comp) - // insert new entry - err = m.conn.QueryRowxContext(m.ctx, - "INSERT INTO golang_projects (component, version, version_id, version_date, is_module, is_package,"+ - " license, license_id, has_valid_go_mod_file, has_redistributable_license, has_tagged_version,"+ - " has_stable_version, repository, is_indexed, purl_name, mine_id, index_timestamp)"+ - " VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)"+ - " RETURNING purl_name", - allURL.Component, allURL.Version, version.ID, comp.Published, - comp.IsModule, comp.IsPackage, license.LicenseName, license.ID, comp.HasValidGoModFile, - comp.HasRedistributableLicense, comp.HasTaggedVersion, comp.HasStableVersion, - comp.Repository, true, allURL.PurlName, allURL.MineID, "", - ).Scan(&purlName) - } - if err != nil { - m.s.Errorf("Error: Failed to %v new component into golang_projects table for %v - %#v: %v", sqlQueryType, allURL, comp, err) - return fmt.Errorf("failed to %v new component into golang projects: %v", sqlQueryType, err) - } - m.s.Debugf("Completed %v of %v", sqlQueryType, purlName) - return nil -} - -// getLatestPkgGoDev retrieves the latest information about a Golang Package from https://pkg.go.dev -// If requested (via config), it will commit that data to the Golang Projects table. -func (m *GolangProjects) getLatestPkgGoDev(purlName, purlType, purlVersion string) (AllURL, error) { - allURL, pkg, latest, err := m.queryPkgGoDev(purlName, purlVersion) - if err != nil { - return allURL, err - } - cleansedLicense, err := CleanseLicenseName(allURL.License) - if err != nil { - return allURL, err - } - license, _ := m.lic.GetLicenseByName(cleansedLicense, m.config.Components.CommitMissing) - if len(license.LicenseName) == 0 { - m.s.Warnf("No license details in DB for: %v", cleansedLicense) - } else { - allURL.License = license.LicenseName - allURL.LicenseID = license.LicenseID - allURL.IsSpdx = license.IsSpdx - } - version, _ := m.ver.GetVersionByName(allURL.Version, m.config.Components.CommitMissing) - if len(version.VersionName) == 0 { - m.s.Warnf("No version details in DB for: %v", allURL.Version) - } - mineIDs, _ := m.mine.GetMineIdsByPurlType(purlType) - if len(mineIDs) > 0 { - allURL.MineID = mineIDs[0] // Assign the first mine id - } else { - m.s.Warnf("No mine details in DB for purl type: %v", purlType) - } - // Package is not the "latest" version (i.e. queried with a version) and we've been requested to save it - if !latest && m.config.Components.CommitMissing { - _ = m.savePkg(allURL, version, license, pkg) - } - return allURL, nil -} - -// queryPkgGoDev retrieves the latest information about a Golang Package from https://pkg.go.dev -func (m *GolangProjects) queryPkgGoDev(purlName, purlVersion string) (AllURL, *pkggodevclient.Package, bool, error) { - if len(purlName) == 0 { - m.s.Errorf("Please specify a valid Purl Name to query") - return AllURL{}, nil, false, errors.New("please specify a valid Purl Name to query") - } - client := pkggodevclient.New() - pkg := purlName - if len(purlVersion) > 0 { - pkg = fmt.Sprintf("%s@%s", purlName, purlVersion) - } - latest := false - m.s.Debugf("Checking pkg.go.dev for the latest info: %v", pkg) - comp, err := client.DescribePackage(pkggodevclient.DescribePackageRequest{Package: pkg}) - if err != nil && len(purlVersion) > 0 { - // We have a version zero search, so look for the latest one - m.s.Debugf("Failed to query pkg.go.dev for %v: %v. Trying without version...", pkg, err) - comp, err = client.DescribePackage(pkggodevclient.DescribePackageRequest{Package: purlName}) - latest = true // Mark that this information is from the latest package and not a specific version - } - if err != nil { - m.s.Warnf("Failed to query pkg.go.dev for %v: %v", pkg, err) - return AllURL{}, nil, latest, fmt.Errorf("failed to query pkg.go.dev: %v", err) - } - var version = comp.Version - if len(purlVersion) > 0 { - version = purlVersion // Force the requested version if specified (the returned value can be concatenated) - } - allURL := AllURL{ - Component: purlName, - Version: version, - License: comp.License, - PurlName: purlName, - URL: fmt.Sprintf("https://%v", comp.Repository), - } - return allURL, comp, latest, nil -} diff --git a/pkg/models/golang_projects_test.go b/pkg/models/golang_projects_test.go deleted file mode 100644 index de8ffdf..0000000 --- a/pkg/models/golang_projects_test.go +++ /dev/null @@ -1,375 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018-2023 SCANOSS.COM - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package models - -import ( - "context" - "fmt" - "testing" - - "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" - pkggodevclient "github.com/guseggert/pkggodev-client" - zlog "github.com/scanoss/zap-logging-helper/pkg/logger" - myconfig "scanoss.com/dependencies/pkg/config" -) - -func TestGolangProjectUrlsSearch(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - err = LoadTestSQLData(db, ctx, conn) - if err != nil { - t.Fatalf("failed to load SQL test data: %v", err) - } - myConfig, err := myconfig.NewServerConfig(nil) - if err != nil { - t.Fatalf("failed to load Config: %v", err) - } - myConfig.Components.CommitMissing = true - myConfig.Database.Trace = true - golangProjModel := NewGolangProjectModel(ctx, s, db, conn, myConfig) - - url, err := golangProjModel.GetGolangUrlsByPurlNameType("google.golang.org/grpc", "golang", "") - if err != nil { - t.Errorf("FAILED: golang_projects.GetUrlsByPurlName() error = %v", err) - } - if len(url.PurlName) == 0 { - t.Errorf("FAILED: golang_projects.GetGoLangURLByPurlString() No URLs returned from query") - } - fmt.Printf("Golang URL: %#v\n", url) - - url, err = golangProjModel.GetGolangUrlsByPurlNameType("NONEXISTENT", "none", "") - if err != nil { - t.Errorf("FAILED: golang_projects.GetGolangUrlsByPurlNameType() error = %v", err) - } - if len(url.PurlName) > 0 { - t.Errorf("FAILED: golang_projects.GetGolangUrlsByPurlNameType() URLs found when none should be: %v", golangProjModel) - } - fmt.Printf("No Urls: %v\n", url) - - _, err = golangProjModel.GetGolangUrlsByPurlNameType("NONEXISTENT", "", "") - if err == nil { - t.Errorf("FAILED: golang_projects.GetGolangUrlsByPurlNameType() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = golangProjModel.GetGolangUrlsByPurlNameType("", "", "") - if err == nil { - t.Errorf("FAILED: golang_projects.GetURLsByPurlString() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = golangProjModel.GetGoLangURLByPurlString("", "") - if err == nil { - t.Errorf("FAILED: golang_projects.GetURLsByPurlString() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = golangProjModel.GetGoLangURLByPurlString("rubbish-purl", "") - if err == nil { - t.Errorf("FAILED: golang_projects.GetGoLangURLByPurlString() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - url, err = golangProjModel.GetGoLangURLByPurlString("pkg:golang/google.golang.org/grpc", "") - if err != nil { - t.Errorf("FAILED: golang_projects.GetGoLangURLByPurlString() error = %v", err) - } - if len(url.PurlName) == 0 { - t.Errorf("FAILED: golang_projects.GetGoLangURLByPurlString() No URLs returned from query") - } - fmt.Printf("Golang URL: %v\n", url) -} - -func TestGolangProjectsSearchVersion(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - err = LoadTestSQLData(db, ctx, conn) - if err != nil { - t.Fatalf("FAILED: failed to load SQL test data: %v", err) - } - myConfig, err := myconfig.NewServerConfig(nil) - if err != nil { - t.Fatalf("FAILED: failed to load Config: %v", err) - } - myConfig.Components.CommitMissing = true - myConfig.Database.Trace = true - golangProjModel := NewGolangProjectModel(ctx, s, db, conn, myConfig) - - url, err := golangProjModel.GetGolangUrlsByPurlNameTypeVersion("google.golang.org/grpc", "golang", "1.19.0") - if err != nil { - t.Errorf("FAILED: golang_projects.GetGolangUrlsByPurlNameTypeVersion() error = %v", err) - } - if len(url.PurlName) == 0 { - t.Errorf("FAILED: golang_projects.GetGolangUrlsByPurlNameTypeVersion() No URLs returned from query") - } - fmt.Printf("Golang URL Version: %#v\n", url) - - url, err = golangProjModel.GetGoLangURLByPurlString("pkg:golang/google.golang.org/grpc@v1.19.0", "") - if err != nil { - t.Errorf("FAILED: golang_projects.GetGoLangURLByPurlString() error = failed to find purl by version string") - } - fmt.Printf("Golang URL Version: %#v\n", url) - - _, err = golangProjModel.GetGolangUrlsByPurlNameTypeVersion("", "", "") - if err == nil { - t.Errorf("FAILED: golang_projects.GetGolangUrlsByPurlNameTypeVersion() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = golangProjModel.GetGolangUrlsByPurlNameTypeVersion("NONEXISTENT", "", "") - if err == nil { - t.Errorf("FAILED: golang_projects.GetGolangUrlsByPurlNameTypeVersion() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = golangProjModel.GetGolangUrlsByPurlNameTypeVersion("NONEXISTENT", "NONEXISTENT", "") - if err == nil { - t.Errorf("FAILED: golang_projects.GetGolangUrlsByPurlNameTypeVersion() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - - url, err = golangProjModel.GetGoLangURLByPurlString("pkg:golang/google.golang.org/grpc", "22.22.22") // Shouldn't exist - if err != nil { - t.Errorf("FAILED: golang_projects.GetGoLangURLByPurlString() error = failed to find purl by version string") - } - url, err = golangProjModel.GetGoLangURLByPurlString("pkg:golang/google.golang.org/grpc", "=v1.19.0") - if err != nil { - t.Errorf("FAILED: golang_projects.GetGoLangURLByPurlString() error = %v", err) - } - if len(url.PurlName) == 0 { - t.Errorf("FAILED: golang_projects.GetGoLangURLByPurlString() No URLs returned from query") - } - fmt.Printf("Golang URL: %v\n", url) - url, err = golangProjModel.GetGoLangURLByPurlString("pkg:golang/google.golang.org/grpc", "==v1.19.0") - if err != nil { - t.Errorf("FAILED: golang_projects.GetGoLangURLByPurlString() error = %v", err) - } - if len(url.PurlName) == 0 { - t.Errorf("FAILED: golang_projects.GetGoLangURLByPurlString() No URLs returned from query") - } - fmt.Printf("Golang URL: %v\n", url) - - url, err = golangProjModel.GetGoLangURLByPurlString("pkg:golang/google.golang.org/grpc@1.7.0", "") // Should be missing license - if err != nil { - t.Errorf("FAILED: golang_projects.GetGoLangURLByPurlString() error = %v", err) - } - if len(url.License) == 0 { - t.Errorf("FAILED: golang_projects.GetGoLangURLByPurlString() No URL License returned from query") - } - fmt.Printf("Golang URL: %v\n", url) -} - -func TestGolangProjectsSearchVersionRequirement(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - err = LoadTestSQLData(db, ctx, conn) - if err != nil { - t.Fatalf("failed to load SQL test data: %v", err) - } - myConfig, err := myconfig.NewServerConfig(nil) - if err != nil { - t.Fatalf("failed to load Config: %v", err) - } - myConfig.Components.CommitMissing = true - golangProjModel := NewGolangProjectModel(ctx, s, db, conn, myConfig) - - url, err := golangProjModel.GetGoLangURLByPurlString("pkg:golang/google.golang.org/grpc", ">0.0.4") - if err != nil { - t.Errorf("FAILED: golang_projects.GetUrlsByPurlName() error = %v", err) - } - if len(url.PurlName) == 0 { - t.Errorf("FAILED: golang_projects.GetUrlsByPurlName() No URLs returned from query") - } - fmt.Printf("Golang URL Version: %#v\n", url) - - url, err = golangProjModel.GetGoLangURLByPurlString("pkg:golang/google.golang.org/grpc", "v0.0.0-201910101010-s3333") - if err != nil { - t.Errorf("FAILED: golang_projects.GetUrlsByPurlName() error = %v", err) - } - if len(url.PurlName) == 0 { - t.Errorf("FAILED: golang_projects.GetUrlsByPurlName() No URLs returned from query") - } - fmt.Printf("Golang URL Version: %#v\n", url) -} - -func TestGolangPkgGoDev(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - err = LoadTestSQLData(db, ctx, conn) - if err != nil { - t.Fatalf("failed to load SQL test data: %v", err) - } - myConfig, err := myconfig.NewServerConfig(nil) - if err != nil { - t.Fatalf("failed to load Config: %v", err) - } - myConfig.Components.CommitMissing = true - golangProjModel := NewGolangProjectModel(ctx, s, db, conn, myConfig) - - _, _, _, err = golangProjModel.queryPkgGoDev("", "") - if err == nil { - t.Errorf("FAILED: golang_projects.queryPkgGoDev() error = did not get an error") - } - - url, err := golangProjModel.getLatestPkgGoDev("google.golang.org/grpc", "golang", "v0.0.0-201910101010-s3333") - if err != nil { - t.Errorf("FAILED: golang_projects.getLatestPkgGoDev() error = %v", err) - } - if len(url.PurlName) == 0 { - t.Errorf("FAILED: golang_projects.getLatestPkgGoDev() No URLs returned from query") - } - fmt.Printf("Golang URL Version: %#v\n", url) - - url, err = golangProjModel.getLatestPkgGoDev("github.com/scanoss/papi", "golang", "v0.0.3") - if err != nil { - t.Errorf("FAILED: golang_projects.getLatestPkgGoDev() error = %v", err) - } - if len(url.PurlName) == 0 { - t.Errorf("FAILED: golang_projects.getLatestPkgGoDev() No URLs returned from query") - } - fmt.Printf("Golang URL Version: %#v\n", url) - - var allUrl AllURL - var license License - var version Version - fmt.Printf("SavePkg: %#v - %#v - %#v", allUrl, license, version) - err = golangProjModel.savePkg(allUrl, version, license, nil) - if err == nil { - t.Errorf("FAILED: golangProjModel.savePkg() error = did not get an error") - } - allUrl.PurlName = "github.com/scanoss/papi" - err = golangProjModel.savePkg(allUrl, version, license, nil) - if err == nil { - t.Errorf("FAILED: golangProjModel.savePkg() error = did not get an error") - } - allUrl.MineID = 45 - err = golangProjModel.savePkg(allUrl, version, license, nil) - if err == nil { - t.Errorf("FAILED: golangProjModel.savePkg() error = did not get an error") - } - allUrl.Version = "v0.0.1" - version.VersionName = "v0.0.1" - version.ID = 5958021 - err = golangProjModel.savePkg(allUrl, version, license, nil) - if err == nil { - t.Errorf("FAILED: golangProjModel.savePkg() error = did not get an error") - } - license.LicenseName = "MIT" - license.ID = 5614 - err = golangProjModel.savePkg(allUrl, version, license, nil) - if err == nil { - t.Errorf("FAILED: golangProjModel.savePkg() error = did not get an error") - } - var comp pkggodevclient.Package - comp.Package = "github.com/scanoss/papi" - comp.IsPackage = true - comp.IsModule = true - comp.Version = "v0.0.1" - comp.License = "MIT" - comp.HasRedistributableLicense = true - comp.HasStableVersion = true - comp.HasTaggedVersion = true - comp.HasValidGoModFile = true - comp.Repository = "github.com/scanoss/papi" - err = golangProjModel.savePkg(allUrl, version, license, &comp) - if err != nil { - t.Errorf("FAILED: golangProjModel.savePkg() error = %v", err) - } - allUrl.Version = "v0.0.2" - version.VersionName = "v0.0.2" - comp.Version = "v0.0.2" - err = golangProjModel.savePkg(allUrl, version, license, &comp) - if err != nil { - t.Errorf("FAILED: golangProjModel.savePkg() error = %v", err) - } -} - -func TestGolangProjectsSearchBadSql(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - myConfig, err := myconfig.NewServerConfig(nil) - if err != nil { - t.Fatalf("failed to load Config: %v", err) - } - myConfig.Components.CommitMissing = true - golangProjModel := NewGolangProjectModel(ctx, s, db, conn, myConfig) - - _, err = golangProjModel.GetGoLangURLByPurlString("pkg:golang/google.golang.org/grpc", "") - if err == nil { - t.Errorf("FAILED: golang_projects.GetGoLangURLByPurlString() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = golangProjModel.GetGoLangURLByPurlString("pkg:golang/google.golang.org/grpc@1.19.0", "") - if err == nil { - t.Errorf("FAILED: golang_projects.GetGoLangURLByPurlString() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = golangProjModel.getLatestPkgGoDev("github.com/scanoss/does-not-exist", "golang", "v0.0.99") - if err == nil { - t.Errorf("FAILED: golang_projects.getLatestPkgGoDev() error = did not get an error: %v", err) - } else { - fmt.Printf("Got expected error = %v\n", err) - } -} diff --git a/pkg/models/licenses.go b/pkg/models/licenses.go deleted file mode 100644 index a18c7d6..0000000 --- a/pkg/models/licenses.go +++ /dev/null @@ -1,140 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018-2022 SCANOSS.COM - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -// Handle all interaction with the licenses table - -package models - -import ( - "context" - "database/sql" - "errors" - "fmt" - "regexp" - "strings" - - "github.com/jmoiron/sqlx" - "go.uber.org/zap" -) - -type LicenseModel struct { - ctx context.Context - s *zap.SugaredLogger - conn *sqlx.Conn -} - -type License struct { - ID int32 `db:"id"` - LicenseName string `db:"license_name"` - LicenseID string `db:"spdx_id"` - IsSpdx bool `db:"is_spdx"` -} - -var bannedLicPrefixes = []string{"see ", "\"", "'", "-", "*", ".", "/", "?", "@", "\\", ";", ",", "`", "$"} // unwanted license prefixes -var bannedLicSuffixes = []string{".md", ".txt", ".html"} // unwanted license suffixes -var whiteSpaceRegex = regexp.MustCompile(`\s+`) // generic whitespace regex - -// TODO add cache for licenses already searched for? - -// NewLicenseModel create a new instance of the License Model. -func NewLicenseModel(ctx context.Context, s *zap.SugaredLogger, conn *sqlx.Conn) *LicenseModel { - return &LicenseModel{ctx: ctx, s: s, conn: conn} -} - -// GetLicenseByID retrieves license data by the given row ID. -func (m *LicenseModel) GetLicenseByID(id int32) (License, error) { - if id < 0 { - m.s.Error("Please specify a valid License ID to query") - return License{}, errors.New("please specify a valid License Name to query") - } - var license License - err := m.conn.QueryRowxContext(m.ctx, - "SELECT id, license_name, spdx_id, is_spdx FROM licenses"+ - " WHERE id = $1", - id).StructScan(&license) - if err != nil && !errors.Is(err, sql.ErrNoRows) { - m.s.Errorf("Error: Failed to query license table for %v: %#v", id, err) - return License{}, fmt.Errorf("failed to query the license table: %v", err) - } - return license, nil -} - -// GetLicenseByName retrieves the license details for the given license name. -func (m *LicenseModel) GetLicenseByName(name string, create bool) (License, error) { - if len(name) == 0 { - m.s.Warn("No License Name specified to query") - return License{}, nil - } - var license License - err := m.conn.QueryRowxContext(m.ctx, - "SELECT id, license_name, spdx_id, is_spdx FROM licenses"+ - " WHERE license_name = $1", - name, - ).StructScan(&license) - if err != nil && !errors.Is(err, sql.ErrNoRows) { - m.s.Errorf("Failed to query license table for %v: %v", name, err) - return License{}, fmt.Errorf("failed to query the license table: %v", err) - } - if create && len(license.LicenseName) == 0 { // No license found and requested to create an entry - return m.saveLicense(name) - } - return license, nil -} - -// saveLicense writes the given license name to the licenses table. -func (m *LicenseModel) saveLicense(name string) (License, error) { - if len(name) == 0 { - m.s.Error("Please specify a valid License Name to save") - return License{}, errors.New("please specify a valid License Name to save") - } - m.s.Debugf("Attempting to save '%v' to the licenses table...", name) - // TODO should we populate the spdx_id before inserting the license? - var license License - err := m.conn.QueryRowxContext(m.ctx, - "INSERT INTO licenses (license_name, spdx_id, is_spdx, is_sanitized) VALUES($1, $2, $3, $4)"+ - " RETURNING id, license_name, spdx_id, is_spdx", - name, "", false, false, - ).StructScan(&license) - if err != nil { - m.s.Warnf("Failed to insert new license name into licenses table for %v: %v", name, err) - return m.GetLicenseByName(name, false) // Search one more time for it, just in case someone else added it - } - return license, nil -} - -// CleanseLicenseName cleans up a license name to make it searchable in the licenses table. -func CleanseLicenseName(name string) (string, error) { - if len(name) > 0 { - name = strings.TrimSpace(name) // remove leading/trailing spaces before even starting - nameLower := strings.ToLower(name) // check banned strings against lowercase - for _, prefix := range bannedLicPrefixes { - if strings.HasPrefix(nameLower, prefix) { - return "", fmt.Errorf("license name has banned prefix: %v", prefix) - } - } - for _, suffix := range bannedLicSuffixes { - if strings.HasSuffix(nameLower, suffix) { - return "", fmt.Errorf("license name has banned suffix: %v", suffix) - } - } - clean := whiteSpaceRegex.ReplaceAllString(name, " ") // gets rid of new lines, tabs, etc. - cleaner := whiteSpaceRegex.ReplaceAllString(clean, " ") // reduces it down to a single space - cleanest := strings.ReplaceAll(cleaner, ",", ";") // swap commas with semicolons - // zlog.S.Debugf("in: %v clean: %v cleaner: %v cleanest: %v", name, clean, cleaner, cleanest) - return strings.TrimSpace(cleanest), nil // return the cleansed license name - } - return "", nil // empty string, so just return it. -} diff --git a/pkg/models/licenses_test.go b/pkg/models/licenses_test.go deleted file mode 100644 index d6fe38d..0000000 --- a/pkg/models/licenses_test.go +++ /dev/null @@ -1,268 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018-2023 SCANOSS.COM - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package models - -import ( - "context" - "fmt" - "reflect" - "testing" - - "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" - zlog "github.com/scanoss/zap-logging-helper/pkg/logger" -) - -func TestLicensesSearch(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - err = loadTestSQLDataFiles(db, ctx, conn, []string{"../models/tests/licenses.sql"}) - if err != nil { - t.Fatalf("failed to load SQL test data: %v", err) - } - licenseModel := NewLicenseModel(ctx, s, conn) - var name = "MIT" - fmt.Printf("Searching for license: %v\n", name) - license, err := licenseModel.GetLicenseByName(name, false) - if err != nil { - t.Errorf("licenses.GetLicenseByName() error = %v", err) - } - if len(license.LicenseName) == 0 { - t.Errorf("licenses.GetLicenseByName() No license returned from query") - } - fmt.Printf("License: %#v\n", license) - - name = "" - fmt.Printf("Searching for license: %v\n", name) - license, err = licenseModel.GetLicenseByName(name, false) - if err != nil { - t.Errorf("licenses.GetLicenseByName() error = %v", err) - } - if len(license.LicenseName) > 0 { - t.Errorf("licenses.GetLicenseByName() License returned when one shouldn't") - } - fmt.Printf("License: %#v\n", license) - - name = "" - fmt.Printf("Searching for license: %v\n", name) - license, err = licenseModel.saveLicense(name) - if err == nil { - t.Errorf("licenses.saveLicense() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - - name = "Unknown License" - fmt.Printf("Searching for license: %v\n", name) - license, err = licenseModel.GetLicenseByName(name, true) - if err != nil { - t.Errorf("licenses.GetLicenseByName() error = %v", err) - } - if len(license.LicenseName) == 0 { - t.Errorf("licenses.GetLicenseByName() No license returned from query") - } - fmt.Printf("Created License: %#v\n", license) - - name = "MIT" - fmt.Printf("Searching for license: %v\n", name) - license, err = licenseModel.saveLicense(name) - if err != nil { - t.Errorf("licenses.saveLicense() error = %v", err) - } - if len(license.LicenseName) == 0 { - t.Errorf("licenses.saveLicense() No license returned from query") - } - fmt.Printf("Found License: %#v\n", license) - - name = "Apache 2.0; MIT; BSD" - fmt.Printf("Searching for license: %v\n", name) - license, err = licenseModel.GetLicenseByName(name, true) - if err != nil { - t.Errorf("licenses.GetLicenseByName() error = %v", err) - } - if len(license.LicenseName) == 0 { - t.Errorf("licenses.GetLicenseByName() No license returned from query") - } - fmt.Printf("Created License: %#v\n", license) -} - -func TestLicensesSearchId(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - err = loadTestSQLDataFiles(db, ctx, conn, []string{"../models/tests/licenses.sql"}) - if err != nil { - t.Fatalf("failed to load SQL test data: %v", err) - } - licenseModel := NewLicenseModel(ctx, s, conn) - - name := "MIT" - fmt.Printf("Searching for license: %v\n", name) - license, err := licenseModel.GetLicenseByName(name, false) - if err != nil { - t.Errorf("licenses.saveLicense() error = %v", err) - } - if len(license.LicenseName) == 0 { - t.Errorf("licenses.saveLicense() No license returned from query") - } - fmt.Printf("Found License: %#v\n", license) - - id := license.ID - fmt.Printf("Searching for license by id: %v\n", id) - license, err = licenseModel.GetLicenseByID(id) - if err != nil { - t.Errorf("licenses.GetLicenseByID() error = %v", err) - } - if len(license.LicenseName) == 0 { - t.Errorf("licenses.GetLicenseByID() No license returned from query") - } - fmt.Printf("License: %#v\n", license) - - id = 109 - fmt.Printf("Searching for license by id: %v\n", id) - license, err = licenseModel.GetLicenseByID(id) - if err != nil { - t.Errorf("licenses.GetLicenseByID() error = %v", err) - } - if len(license.LicenseName) == 0 { - t.Errorf("licenses.GetLicenseByID() No license returned from query") - } - fmt.Printf("License: %#v\n", license) - - id = -1 - fmt.Printf("Searching for license by id: %v\n", id) - _, err = licenseModel.GetLicenseByID(id) - if err == nil { - t.Errorf("licenses.GetLicenseByID() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } -} - -func TestLicensesSearchBadSql(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - licenseModel := NewLicenseModel(ctx, s, conn) - _, err = licenseModel.GetLicenseByName("rubbish", false) - if err == nil { - t.Errorf("licenses.GetLicenseByName() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = licenseModel.GetLicenseByName("rubbish", true) - if err == nil { - t.Errorf("licenses.GetLicenseByName() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = licenseModel.saveLicense("rubbish") - if err == nil { - t.Errorf("licenses.saveLicense() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = licenseModel.GetLicenseByID(100) - if err == nil { - t.Errorf("licenses.GetLicenseByID() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } -} - -func TestCleanseLicenseName(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - tests := []struct { - name string - input string - want string - wantErr bool - }{ - { - name: "MIT", - input: "MIT", - want: "MIT", - }, - { - name: "Apache 2", - input: " Apache 2.0 ", - want: "Apache 2.0", - }, - { - name: "Apache/MIT", - input: " Apache 2.0, MIT ", - want: "Apache 2.0; MIT", - }, - { - name: "Empty String", - input: "", - want: "", - }, - { - name: "Banned prefixes", - input: "see something else", - want: "", - wantErr: true, - }, - { - name: "Banned suffixes", - input: "license name.html", - want: "", - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := CleanseLicenseName(tt.input) - if (err != nil) != tt.wantErr { - t.Errorf("licenses.CleanseLicenseName() error = %v, wantErr %v", err, tt.wantErr) - return - } - if err == nil && !reflect.DeepEqual(got, tt.want) { - t.Errorf("licenses.CleanseLicenseName() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/pkg/models/mines.go b/pkg/models/mines.go deleted file mode 100644 index 1d279cd..0000000 --- a/pkg/models/mines.go +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018-2022 SCANOSS.COM - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -// Handle all interaction with the mines table - -package models - -import ( - "context" - "errors" - "fmt" - - "github.com/jmoiron/sqlx" - "go.uber.org/zap" -) - -type MineModel struct { - ctx context.Context - s *zap.SugaredLogger - conn *sqlx.Conn -} - -type Mine struct { - ID int32 `db:"id"` - Name string `db:"mine_name"` - PurlType string `db:"purl_type"` -} - -// NewMineModel creates a new instance of the 'Mine' Model. -func NewMineModel(ctx context.Context, s *zap.SugaredLogger, conn *sqlx.Conn) *MineModel { - return &MineModel{ctx: ctx, s: s, conn: conn} -} - -// GetMineIdsByPurlType retrieves a list of the Purl Type IDs associated with the given Purl Type (string). -func (m *MineModel) GetMineIdsByPurlType(purlType string) ([]int32, error) { - if len(purlType) == 0 { - m.s.Error("Please specify a Purl Type to query") - return nil, errors.New("please specify a Purl Type to query") - } - var mines []Mine - err := m.conn.SelectContext(m.ctx, &mines, - "SELECT id,mine_name,purl_type FROM mines WHERE purl_type = $1", purlType, - ) - if err != nil { - m.s.Errorf("Error: Failed to query mines table for %v: %v", purlType, err) - return nil, fmt.Errorf("failed to query the mines table: %v", err) - } - if len(mines) > 0 { - var mineIds []int32 - for _, mine := range mines { - mineIds = append(mineIds, mine.ID) - } - return mineIds, nil - } - m.s.Error("No entries found in the mines table.") - return nil, errors.New("no entry in mines table") -} diff --git a/pkg/models/mines_test.go b/pkg/models/mines_test.go deleted file mode 100644 index 4640c08..0000000 --- a/pkg/models/mines_test.go +++ /dev/null @@ -1,104 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018-2023 SCANOSS.COM - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package models - -import ( - "context" - "fmt" - "testing" - - "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" - zlog "github.com/scanoss/zap-logging-helper/pkg/logger" - _ "modernc.org/sqlite" -) - -func TestMines(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - err = loadSQLData(db, ctx, conn, "./tests/mines.sql") - if err != nil { - t.Fatalf("failed to load SQL test data: %v", err) - } - mine := NewMineModel(ctx, s, conn) - var purlType = "maven" - mineIds, err := mine.GetMineIdsByPurlType(purlType) - if err != nil { - t.Errorf("mines.GetMineIdByPurlType() error = %v", err) - } - fmt.Printf("Mine ID for %v: %v\n", purlType, mineIds) - - purlType = "gem" - mineIds, err = mine.GetMineIdsByPurlType(purlType) - if err != nil { - t.Errorf("mines.GetMineIdByPurlType() error = %v", err) - } - fmt.Printf("Mine ID for %v: %v\n", purlType, mineIds) - - purlType = "" - mineIds, err = mine.GetMineIdsByPurlType(purlType) - if err != nil { - fmt.Printf("Mine ID not found: %v\n", err) - } else { - t.Errorf("mines.GetMineIdByPurlType() found for %v = %v", purlType, mineIds) - } - - purlType = "NONEXISTENT" - mineIds, err = mine.GetMineIdsByPurlType(purlType) - if err != nil { - fmt.Printf("Mine ID not found: %v\n", err) - } else { - t.Errorf("mines.GetMineIdByPurlType() found for %v = %v", purlType, mineIds) - } - purlType = "npm" - mineIds, err = mine.GetMineIdsByPurlType(purlType) - if err != nil { - t.Errorf("mines.GetMineIdsByPurlType() error = %v", err) - } - fmt.Printf("Mine IDs for %v: %v\n", purlType, mineIds) -} - -// TestMinesBadSql test bad queries without creating/loading the mines table. -func TestMinesBadSql(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - mine := NewMineModel(ctx, s, conn) - purlType := "NONEXISTENT" - mineIds, err := mine.GetMineIdsByPurlType(purlType) - if err != nil { - fmt.Printf("Mine ID not found: %v\n", err) - } else { - t.Errorf("mines.GetMineIdByPurlType() found for %v = %v", purlType, mineIds) - } -} diff --git a/pkg/models/projects.go b/pkg/models/projects.go deleted file mode 100644 index cc77659..0000000 --- a/pkg/models/projects.go +++ /dev/null @@ -1,114 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018-2022 SCANOSS.COM - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -// Handle all interaction with the projects table - -package models - -import ( - "context" - "errors" - "fmt" - - "github.com/jmoiron/sqlx" - "go.uber.org/zap" -) - -type ProjectModel struct { - ctx context.Context - s *zap.SugaredLogger - conn *sqlx.Conn -} - -type Project struct { - PurlName string `db:"purl_name"` - Component string `db:"component"` - License string `db:"license"` - LicenseID string `db:"license_id"` - IsSpdx bool `db:"is_spdx"` - GitLicense string `db:"g_license"` - GitLicenseID string `db:"g_license_id"` - GitIsSpdx bool `db:"g_is_spdx"` -} - -// NewProjectModel creates a new instance of the Project Model. -func NewProjectModel(ctx context.Context, s *zap.SugaredLogger, conn *sqlx.Conn) *ProjectModel { - return &ProjectModel{ctx: ctx, s: s, conn: conn} -} - -// GetProjectsByPurlName searches the projects' table for details about Purl Name and Type. -func (m *ProjectModel) GetProjectsByPurlName(purlName string, purlType string) ([]Project, error) { - if len(purlName) == 0 { - m.s.Error("Please specify a valid Purl Name to query") - return nil, errors.New("please specify a valid Purl Name to query") - } - if len(purlType) == 0 { - m.s.Error("Please specify a valid Purl Type to query") - return nil, errors.New("please specify a valid Purl Type to query") - } - var allProjects []Project - err := m.conn.SelectContext(m.ctx, &allProjects, - "SELECT purl_name, component,"+ - " l.license_name AS license, l.spdx_id AS license_id, l.is_spdx AS is_spdx,"+ - " g.license_name AS g_license, g.spdx_id AS g_license_id, g.is_spdx AS g_is_spdx"+ - " FROM projects p"+ - " LEFT JOIN mines m ON p.mine_id = m.id"+ - " LEFT JOIN licenses l ON p.license_id = l.id"+ - " LEFT JOIN licenses g ON p.git_license_id = g.id"+ - " WHERE m.purl_type = $1 AND p.purl_name = $2", - purlType, purlName) - if err != nil { - m.s.Errorf("Failed to query projects table for %v, %v: %v", purlName, purlType, err) - return nil, fmt.Errorf("failed to query the projects table: %v", err) - } - return allProjects, nil -} - -// GetProjectByPurlName searches the projects' table for details about a Purl Name and Mine ID. -func (m *ProjectModel) GetProjectByPurlName(purlName string, mineID int32) (Project, error) { - if len(purlName) == 0 { - m.s.Error("Please specify a valid Purl Name to query") - return Project{}, errors.New("please specify a valid Purl Name to query") - } - if mineID < 0 { - m.s.Error("Please specify a valid Mine ID to query") - return Project{}, errors.New("please specify a valid Mine ID to query") - } - rows, err := m.conn.QueryxContext(m.ctx, - "SELECT purl_name, component,"+ - " l.license_name AS license, l.spdx_id AS license_id, l.is_spdx AS is_spdx,"+ - " g.license_name AS g_license, g.spdx_id AS g_license_id, g.is_spdx AS g_is_spdx"+ - " FROM projects p"+ - " LEFT JOIN licenses l ON p.license_id = l.id"+ - " LEFT JOIN licenses g ON p.git_license_id = g.id"+ - " WHERE purl_name = $1 AND mine_id = $2", - purlName, mineID) - defer CloseRows(rows) - if err != nil { - m.s.Errorf("Error: Failed to query projects table for %v, %v: %v", purlName, mineID, err) - return Project{}, fmt.Errorf("failed to query the projects table: %v", err) - } - var project Project - if rows.Next() { - err = rows.StructScan(&project) - if err != nil { - m.s.Errorf("Failed to parse projects table results for %#v: %v", rows, err) - m.s.Errorf("Query failed for purl_name = %v, mine_id = %v", purlName, mineID) - return Project{}, fmt.Errorf("failed to query the projects table: %v", err) - } - } - return project, nil -} diff --git a/pkg/models/projects_test.go b/pkg/models/projects_test.go deleted file mode 100644 index 837ba7a..0000000 --- a/pkg/models/projects_test.go +++ /dev/null @@ -1,132 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018-2023 SCANOSS.COM - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package models - -import ( - "context" - "fmt" - "testing" - - "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" - zlog "github.com/scanoss/zap-logging-helper/pkg/logger" -) - -func TestProjectsSearch(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - err = loadTestSQLDataFiles(db, ctx, conn, []string{"../models/tests/projects.sql", "../models/tests/mines.sql", "../models/tests/licenses.sql"}) - if err != nil { - t.Fatalf("failed to load SQL test data: %v", err) - } - projectsModel := NewProjectModel(ctx, s, conn) - var purlName = "tablestyle" - var purlType = "gem" - fmt.Printf("Searching for project list: %v - %v\n", purlName, purlType) - projects, err := projectsModel.GetProjectsByPurlName(purlName, purlType) - if err != nil { - t.Errorf("projects.GetProjectsByPurlName() error = %v", err) - } - if len(projects) < 1 { - t.Errorf("projects.GetProjectsByPurlName() No projects returned from query") - } - fmt.Printf("Projects: %#v\n", projects) - - purlName = "" - purlType = "npm" - fmt.Printf("Searching for project list: %v - %v\n", purlName, purlType) - _, err = projectsModel.GetProjectsByPurlName(purlName, purlType) - if err == nil { - t.Errorf("projects.GetProjectsByPurlName() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - purlName = "tablestyle" - purlType = "" - fmt.Printf("Searching for project list: %v - %v\n", purlName, purlType) - _, err = projectsModel.GetProjectsByPurlName(purlName, purlType) - if err == nil { - t.Errorf("projects.GetProjectsByPurlName() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - purlName = "tablestyle" - var mineId int32 = 1 - fmt.Printf("Searching for project: %v - %v\n", purlName, mineId) - project, err := projectsModel.GetProjectByPurlName("tablestyle", mineId) - if err != nil { - t.Errorf("projects.GetProjectByPurlName() error = %+v", err) - } - if len(project.PurlName) == 0 { - t.Errorf("projects.GetProjectByPurlName() No project returned from query") - } else { - fmt.Printf("Project: %v\n", project) - } - purlName = "" - mineId = -1 - fmt.Printf("Searching for project list: %v - %v\n", purlName, purlType) - _, err = projectsModel.GetProjectByPurlName(purlName, mineId) - if err == nil { - t.Errorf("projects.GetProjectByPurlName() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - purlName = "NONEXISTENT" - mineId = -1 - fmt.Printf("Searching for project list: %v - %v\n", purlName, purlType) - _, err = projectsModel.GetProjectByPurlName(purlName, mineId) - if err == nil { - t.Errorf("projects.GetProjectByPurlName() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } -} - -func TestProjectsSearchBadSql(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - projectsModel := NewProjectModel(ctx, s, conn) - _, err = projectsModel.GetProjectsByPurlName("rubbish", "rubbish") - if err == nil { - t.Errorf("projects.GetProjectsByPurlName() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = projectsModel.GetProjectByPurlName("rubbish", 2) - if err == nil { - t.Errorf("projects.GetProjectByPurlName() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } -} diff --git a/pkg/models/versions.go b/pkg/models/versions.go deleted file mode 100644 index 389cf2e..0000000 --- a/pkg/models/versions.go +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018-2022 SCANOSS.COM - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -// Handle all interaction with the versions table - -package models - -import ( - "context" - "database/sql" - "errors" - "fmt" - - "github.com/jmoiron/sqlx" - "go.uber.org/zap" -) - -type VersionModel struct { - ctx context.Context - s *zap.SugaredLogger - conn *sqlx.Conn -} - -type Version struct { - ID int32 `db:"id"` - VersionName string `db:"version_name"` - SemVer string `db:"semver"` -} - -// TODO add cache for versions already searched for? - -// NewVersionModel creates a new instance of the Version Model. -func NewVersionModel(ctx context.Context, s *zap.SugaredLogger, conn *sqlx.Conn) *VersionModel { - return &VersionModel{ctx: ctx, s: s, conn: conn} -} - -// GetVersionByName gets the given version from the versions table. -func (m *VersionModel) GetVersionByName(name string, create bool) (Version, error) { - if len(name) == 0 { - m.s.Error("Please specify a valid Version Name to query") - return Version{}, errors.New("please specify a valid Version Name to query") - } - var version Version - err := m.conn.QueryRowxContext(m.ctx, - "SELECT id, version_name, semver FROM versions"+ - " WHERE version_name = $1", - name).StructScan(&version) - if err != nil && !errors.Is(err, sql.ErrNoRows) { - m.s.Errorf("Error: Failed to query versions table for %v: %v", name, err) - return Version{}, fmt.Errorf("failed to query the versions table: %v", err) - } - if create && len(version.VersionName) == 0 { // No version found and requested to create an entry - return m.saveVersion(name) - } - - return version, nil -} - -// saveVersion writes the given version name to the versions table. -func (m *VersionModel) saveVersion(name string) (Version, error) { - if len(name) == 0 { - m.s.Error("Please specify a valid version Name to save") - return Version{}, errors.New("please specify a valid Version Name to save") - } - m.s.Debugf("Attempting to save '%v' to the versions table...", name) - var version Version - err := m.conn.QueryRowxContext(m.ctx, - "INSERT INTO versions (version_name, semver) VALUES($1, $2)"+ - " RETURNING id, version_name, semver", - name, "", false, false, - ).StructScan(&version) - if err != nil { - m.s.Errorf("Error: Failed to insert new version name into versions table for %v: %v", name, err) - return m.GetVersionByName(name, false) // Search one more time for it, just in case someone else added it - } - return version, nil -} diff --git a/pkg/models/versions_test.go b/pkg/models/versions_test.go deleted file mode 100644 index b154f20..0000000 --- a/pkg/models/versions_test.go +++ /dev/null @@ -1,121 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2018-2023 SCANOSS.COM - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package models - -import ( - "context" - "fmt" - "testing" - - "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" - zlog "github.com/scanoss/zap-logging-helper/pkg/logger" -) - -func TestVersionsSearch(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - err = loadTestSQLDataFiles(db, ctx, conn, []string{"../models/tests/versions.sql"}) - if err != nil { - t.Fatalf("failed to load SQL test data: %v", err) - } - versionModel := NewVersionModel(ctx, s, conn) - var name = "1.0.0" - fmt.Printf("Searching for version: %v\n", name) - version, err := versionModel.GetVersionByName(name, false) - if err != nil { - t.Errorf("versions.GetVersionByName() error = %v", err) - } - if len(version.VersionName) == 0 { - t.Errorf("versions.GetVersionByName() No version returned from query") - } - fmt.Printf("Version: %#v\n", version) - - name = "" - fmt.Printf("Searching for license: %v\n", name) - _, err = versionModel.GetVersionByName(name, false) - if err == nil { - t.Errorf("versions.GetVersionByName() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - name = "" - fmt.Printf("Saving for license: %v\n", name) - _, err = versionModel.saveVersion(name) - if err == nil { - t.Errorf("versions.saveVersion() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - - name = "22.22.22" - fmt.Printf("Searching for version: %v\n", name) - version, err = versionModel.GetVersionByName(name, true) - if err != nil { - t.Errorf("versions.GetVersionByName() error = %v", err) - } - if len(version.VersionName) == 0 { - t.Errorf("versions.GetVersionByName() No version returned from query") - } - fmt.Printf("Version: %#v\n", version) - - name = "22.22.22" - fmt.Printf("Searching for version: %v\n", name) - version, err = versionModel.saveVersion(name) - if err != nil { - t.Errorf("versions.GetVersionByName() error = %v", err) - } - if len(version.VersionName) == 0 { - t.Errorf("versions.GetVersionByName() No version returned from query") - } - fmt.Printf("Version: %#v\n", version) -} - -func TestVersionsSearchBadSql(t *testing.T) { - err := zlog.NewSugaredDevLogger() - if err != nil { - t.Fatalf("an error '%s' was not expected when opening a sugared logger", err) - } - defer zlog.SyncZap() - ctx := ctxzap.ToContext(context.Background(), zlog.L) - s := ctxzap.Extract(ctx).Sugar() - db := sqliteSetup(t) // Setup SQL Lite DB - defer CloseDB(db) - conn := sqliteConn(t, ctx, db) // Get a connection from the pool - defer CloseConn(conn) - versionModel := NewVersionModel(ctx, s, conn) - _, err = versionModel.GetVersionByName("rubbish", false) - if err == nil { - t.Errorf("versions.GetVersionByName() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } - _, err = versionModel.saveVersion("rubbish") - if err == nil { - t.Errorf("versions.saveVersion() error = did not get an error") - } else { - fmt.Printf("Got expected error = %v\n", err) - } -} diff --git a/pkg/service/dependency_service.go b/pkg/service/dependency_service.go index deca4e9..5a8dec3 100644 --- a/pkg/service/dependency_service.go +++ b/pkg/service/dependency_service.go @@ -25,6 +25,7 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" "github.com/jmoiron/sqlx" gd "github.com/scanoss/go-grpc-helper/pkg/grpc/database" + "github.com/scanoss/go-models-helper/pkg/models" common "github.com/scanoss/papi/api/commonv2" pb "github.com/scanoss/papi/api/dependenciesv2" "google.golang.org/grpc" @@ -78,8 +79,14 @@ func (d dependencyServer) GetDependencies(ctx context.Context, request *pb.Depen return &pb.DependencyResponse{Status: &statusResp}, errors.New("problem getting database pool connection") } defer gd.CloseSQLConnection(conn) + // Create request-scoped models with request logger and connection + modelConfig := models.ModelConfig{ + CommitMissing: d.config.Components.CommitMissing, + Trace: d.config.Database.Trace, + } + scanossModels := models.NewScanossModels(ctx, s, conn, modelConfig) // Search the KB for information about each dependency - depUc := usecase.NewDependencies(ctx, s, d.db, conn, d.config) + depUc := usecase.NewDependencies(ctx, scanossModels) dtoDependencies, warn, err := depUc.GetDependencies(dtoRequest) statusResp := common.StatusResponse{Status: common.StatusCode_SUCCESS, Message: "Success"} // Assume success :-) if err != nil { diff --git a/pkg/usecase/dependency.go b/pkg/usecase/dependency.go index cbfe77a..2a992a1 100644 --- a/pkg/usecase/dependency.go +++ b/pkg/usecase/dependency.go @@ -21,31 +21,20 @@ import ( "errors" "strings" - "github.com/scanoss/go-grpc-helper/pkg/grpc/database" - - "github.com/jmoiron/sqlx" - "go.uber.org/zap" - myconfig "scanoss.com/dependencies/pkg/config" + "github.com/scanoss/go-models-helper/pkg/models" "scanoss.com/dependencies/pkg/dtos" - "scanoss.com/dependencies/pkg/models" ) type DependencyUseCase struct { - ctx context.Context - s *zap.SugaredLogger - conn *sqlx.Conn - allUrls *models.AllUrlsModel - lic *models.LicenseModel + ctx context.Context + models *models.ScanossModels } // NewDependencies creates a new instance of the Dependency Use Case. -func NewDependencies(ctx context.Context, s *zap.SugaredLogger, db *sqlx.DB, conn *sqlx.Conn, config *myconfig.ServerConfig) *DependencyUseCase { - return &DependencyUseCase{ctx: ctx, s: s, conn: conn, - allUrls: models.NewAllURLModel(ctx, s, conn, models.NewProjectModel(ctx, s, conn), - models.NewGolangProjectModel(ctx, s, db, conn, config), - database.NewDBSelectContext(s, db, conn, config.Database.Trace), - ), - lic: models.NewLicenseModel(ctx, s, conn), +func NewDependencies(ctx context.Context, models *models.ScanossModels) *DependencyUseCase { + return &DependencyUseCase{ + ctx: ctx, + models: models, } } @@ -53,24 +42,24 @@ func NewDependencies(ctx context.Context, s *zap.SugaredLogger, db *sqlx.DB, con func (d DependencyUseCase) GetDependencies(request dtos.DependencyInput) (dtos.DependencyOutput, bool, error) { var depFileOutputs []dtos.DependencyFileOutput var problems = false - d.s.Infof("Processing %v dependency files...", len(request.Files)) + d.models.Logger().Infof("Processing %v dependency files...", len(request.Files)) for _, file := range request.Files { var fileOutput dtos.DependencyFileOutput fileOutput.File = file.File fileOutput.ID = "dependency" fileOutput.Status = "pending" var depOutputs []dtos.DependenciesOutput - d.s.Infof("Processing %v purls for %v...", len(file.Purls), file.File) + d.models.Logger().Infof("Processing %v purls for %v...", len(file.Purls), file.File) for _, purl := range file.Purls { if len(purl.Purl) == 0 { - d.s.Infof("Empty Purl string supplied for: %v. Skipping", file.File) + d.models.Logger().Infof("Empty Purl string supplied for: %v. Skipping", file.File) continue } var depOutput dtos.DependenciesOutput depOutput.Purl = strings.Split(purl.Purl, "@")[0] // Remove any version specific info from the PURL - url, err := d.allUrls.GetURLsByPurlString(purl.Purl, purl.Requirement) + url, err := d.models.AllUrls.GetURLsByPurlString(purl.Purl, purl.Requirement) if err != nil { - d.s.Warnf("Problem encountered extracting URLs for: %v, %v - %v.", file.File, purl, err) + d.models.Logger().Warnf("Problem encountered extracting URLs for: %v, %v - %v.", file.File, purl, err) problems = true // Record this as a warning continue } @@ -96,11 +85,11 @@ func (d DependencyUseCase) GetDependencies(request dtos.DependencyInput) (dtos.D if len(splitLicenses) > 1 { for _, splitLicense := range splitLicenses { spl := strings.TrimSpace(splitLicense) - d.s.Debugf("Searching for split license: %v", spl) - lic, err := d.lic.GetLicenseByName(spl, false) + d.models.Logger().Debugf("Searching for split license: %v", spl) + lic, err := d.models.Licenses.GetLicenseByName(spl, false) if err != nil || len(lic.LicenseName) == 0 { if err != nil { - d.s.Warnf("Problem encountered searching for license %v (%v): %v", spl, splitLicense, err) + d.models.Logger().Warnf("Problem encountered searching for license %v (%v): %v", spl, splitLicense, err) } var license dtos.DependencyLicense license.Name = spl @@ -128,9 +117,9 @@ func (d DependencyUseCase) GetDependencies(request dtos.DependencyInput) (dtos.D fileOutput.Dependencies = depOutputs depFileOutputs = append(depFileOutputs, fileOutput) } - d.s.Debugf("Output dependencies: %v", depFileOutputs) + d.models.Logger().Debugf("Output dependencies: %v", depFileOutputs) if problems { - d.s.Warnf("Encountered issues while processing dependencies: %v", request) + d.models.Logger().Warnf("Encountered issues while processing dependencies: %v", request) return dtos.DependencyOutput{Files: depFileOutputs}, true, errors.New("encountered issues while processing dependencies") } diff --git a/pkg/usecase/dependency_test.go b/pkg/usecase/dependency_test.go index ca43ec1..9cb6b82 100644 --- a/pkg/usecase/dependency_test.go +++ b/pkg/usecase/dependency_test.go @@ -23,11 +23,10 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" "github.com/jmoiron/sqlx" + "github.com/scanoss/go-models-helper/pkg/models" zlog "github.com/scanoss/zap-logging-helper/pkg/logger" _ "modernc.org/sqlite" - myconfig "scanoss.com/dependencies/pkg/config" "scanoss.com/dependencies/pkg/dtos" - "scanoss.com/dependencies/pkg/models" ) func TestDependencyUseCase(t *testing.T) { @@ -53,6 +52,12 @@ func TestDependencyUseCase(t *testing.T) { if err != nil { t.Fatalf("an error '%s' was not expected when loading test data", err) } + // Create models for testing + modelConfig := models.ModelConfig{ + CommitMissing: false, + Trace: false, + } + scanossModels := models.NewScanossModels(ctx, s, conn, modelConfig) var depRequestData = `{ "depth": 1, "files": [ @@ -80,11 +85,7 @@ func TestDependencyUseCase(t *testing.T) { ] } ` - myConfig, err := myconfig.NewServerConfig(nil) - if err != nil { - t.Fatalf("failed to load Config: %v", err) - } - depUc := NewDependencies(ctx, s, db, conn, myConfig) + depUc := NewDependencies(ctx, scanossModels) requestDto, err := dtos.ParseDependencyInput(s, []byte(depRequestData)) if err != nil { t.Fatalf("an error '%s' was not expected when parsing input json", err)