diff --git a/go.mod b/go.mod index e4042050..f0d97a0f 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/devfile/registry-support/registry-library v0.0.0-20221018213054-47b3ffaeadba github.com/fatih/color v1.7.0 github.com/fsnotify/fsnotify v1.6.0 + github.com/go-git/go-git/v5 v5.4.2 github.com/gobwas/glob v0.2.3 github.com/golang/mock v1.6.0 github.com/google/go-cmp v0.5.9 @@ -33,6 +34,9 @@ require ( require ( github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/Microsoft/go-winio v0.5.1 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect + github.com/acomagu/bufpipe v1.0.3 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/containerd/containerd v1.5.9 // indirect @@ -46,7 +50,10 @@ require ( github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-units v0.4.0 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/emirpasic/gods v1.12.0 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/go-git/gcfg v1.5.0 // indirect + github.com/go-git/go-billy/v5 v5.3.1 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.20.0 // indirect @@ -59,14 +66,17 @@ require ( github.com/gorilla/mux v1.8.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect github.com/imdario/mergo v0.3.12 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/lucasjones/reggen v0.0.0-20200904144131-37ba4fa293bb // indirect github.com/mailru/easyjson v0.7.6 // indirect github.com/mattn/go-colorable v0.1.2 // indirect github.com/mattn/go-isatty v0.0.12 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/reflectwalk v1.0.1 // indirect github.com/moby/locker v1.0.1 // indirect github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect @@ -82,10 +92,13 @@ require ( github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect + github.com/sergi/go-diff v1.1.0 // indirect github.com/sirupsen/logrus v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/xanzy/ssh-agent v0.3.0 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + golang.org/x/crypto v0.1.0 // indirect golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 // indirect golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect @@ -98,6 +111,7 @@ require ( google.golang.org/grpc v1.49.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/component-base v0.26.1 // indirect k8s.io/klog/v2 v2.80.1 // indirect diff --git a/go.sum b/go.sum index f50e9c7c..7f14589e 100644 --- a/go.sum +++ b/go.sum @@ -87,6 +87,7 @@ github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:m github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -94,6 +95,7 @@ github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdko github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -101,12 +103,14 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= @@ -337,6 +341,7 @@ github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -368,11 +373,16 @@ github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXt github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8= github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= +github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -580,6 +590,7 @@ github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= @@ -602,6 +613,7 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= @@ -640,6 +652,7 @@ github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7 github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= +github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= @@ -662,6 +675,7 @@ github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WT github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= @@ -829,6 +843,7 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= @@ -906,6 +921,7 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17 github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= +github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -978,6 +994,7 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1444,6 +1461,7 @@ gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76 gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/pkg/devfile/parser/context/context.go b/pkg/devfile/parser/context/context.go index a9043cc6..8606a5dc 100644 --- a/pkg/devfile/parser/context/context.go +++ b/pkg/devfile/parser/context/context.go @@ -17,7 +17,6 @@ package parser import ( "fmt" - "github.com/devfile/library/v2/pkg/git" "net/url" "os" "path/filepath" @@ -52,9 +51,6 @@ type DevfileCtx struct { // token is a personal access token used with a private git repo URL token string - // Git is an interface used for git urls - git git.IGitUrl - // filesystem for devfile fs filesystem.Filesystem @@ -74,7 +70,6 @@ func NewDevfileCtx(path string) DevfileCtx { func NewURLDevfileCtx(url string) DevfileCtx { return DevfileCtx{ url: url, - git: &git.Url{}, } } @@ -83,7 +78,6 @@ func NewPrivateURLDevfileCtx(url string, token string) DevfileCtx { return DevfileCtx{ url: url, token: token, - git: &git.Url{}, } } @@ -172,11 +166,6 @@ func (d *DevfileCtx) GetToken() string { return d.token } -// GetGit func returns current git interface -func (d *DevfileCtx) GetGit() git.IGitUrl { - return d.git -} - // SetAbsPath sets absolute file path for devfile func (d *DevfileCtx) SetAbsPath() (err error) { // Set devfile absolute path @@ -198,8 +187,3 @@ func (d *DevfileCtx) GetConvertUriToInlined() bool { func (d *DevfileCtx) SetConvertUriToInlined(value bool) { d.convertUriToInlined = value } - -// SetGit sets the git interface -func (d *DevfileCtx) SetGit(git git.IGitUrl) { - d.git = git -} diff --git a/pkg/devfile/parser/context/context_test.go b/pkg/devfile/parser/context/context_test.go index 67d8c68f..32097edd 100644 --- a/pkg/devfile/parser/context/context_test.go +++ b/pkg/devfile/parser/context/context_test.go @@ -16,7 +16,6 @@ package parser import ( - "github.com/devfile/library/v2/pkg/git" "github.com/stretchr/testify/assert" "net/http" "net/http/httptest" @@ -94,13 +93,11 @@ func TestNewURLDevfileCtx(t *testing.T) { d := NewPrivateURLDevfileCtx(url, token) assert.Equal(t, "https://github.com/devfile/registry/blob/main/stacks/go/2.0.0/devfile.yaml", d.GetURL()) assert.Equal(t, "fake-token", d.GetToken()) - assert.Equal(t, &git.Url{}, d.GetGit()) } { d := NewURLDevfileCtx(url) assert.Equal(t, "https://github.com/devfile/registry/blob/main/stacks/go/2.0.0/devfile.yaml", d.GetURL()) assert.Equal(t, "", d.GetToken()) - assert.Equal(t, &git.Url{}, d.GetGit()) } } diff --git a/pkg/devfile/parser/parse.go b/pkg/devfile/parser/parse.go index 69c5dfae..a88e0e38 100644 --- a/pkg/devfile/parser/parse.go +++ b/pkg/devfile/parser/parse.go @@ -47,6 +47,42 @@ import ( "github.com/pkg/errors" ) +// downloadGitRepoResources is exposed as a global variable for the purpose of running mock tests +var downloadGitRepoResources = func(url string, destDir string, httpTimeout *int, token string) error { + gitUrl, err := git.NewGitUrlWithURL(url) + if err != nil { + return err + } + + if gitUrl.IsGitProviderRepo() && gitUrl.IsFile { + stackDir, err := ioutil.TempDir(os.TempDir(), fmt.Sprintf("git-resources")) + if err != nil { + return fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err) + } + defer os.RemoveAll(stackDir) + + if !gitUrl.IsPublic(httpTimeout) { + err = gitUrl.SetToken(token, httpTimeout) + if err != nil { + return err + } + } + + err = gitUrl.CloneGitRepo(stackDir) + if err != nil { + return err + } + + dir := path.Dir(path.Join(stackDir, gitUrl.Path)) + err = git.CopyAllDirFiles(dir, destDir) + if err != nil { + return err + } + } + + return nil +} + // ParseDevfile func validates the devfile integrity. // Creates devfile context and runtime objects func parseDevfile(d DevfileObj, resolveCtx *resolutionContextTree, tool resolverTools, flattenedDevfile bool) (DevfileObj, error) { @@ -142,7 +178,6 @@ func ParseDevfile(args ParserArgs) (d DevfileObj, err error) { context: args.Context, k8sClient: args.K8sClient, httpTimeout: args.HTTPTimeout, - git: d.Ctx.GetGit(), } flattenedDevfile := true @@ -196,8 +231,6 @@ type resolverTools struct { k8sClient client.Client // httpTimeout is the timeout value in seconds passed in from the client. httpTimeout *int - // git is the interface used for git urls - git git.IGitUrl } func populateAndParseDevfile(d DevfileObj, resolveCtx *resolutionContextTree, tool resolverTools, flattenedDevfile bool) (DevfileObj, error) { @@ -449,7 +482,7 @@ func parseFromURI(importReference v1.ImportReference, curDevfileCtx devfileCtx.D } destDir := path.Dir(curDevfileCtx.GetAbsPath()) - err = tool.git.DownloadGitRepoResources(newUri, destDir, tool.httpTimeout, token) + err = downloadGitRepoResources(newUri, destDir, tool.httpTimeout, token) if err != nil { return DevfileObj{}, err } diff --git a/pkg/devfile/parser/parse_test.go b/pkg/devfile/parser/parse_test.go index ee104a86..6412ea59 100644 --- a/pkg/devfile/parser/parse_test.go +++ b/pkg/devfile/parser/parse_test.go @@ -2859,7 +2859,8 @@ func Test_parseParentAndPluginFromURI(t *testing.T) { tt.args.devFileObj.Data.AddComponents(plugincomp) } - err := parseParentAndPlugin(tt.args.devFileObj, &resolutionContextTree{}, resolverTools{git: &git.MockGitUrl{}}) + downloadGitRepoResources = mockDownloadGitRepoResources(&git.Url{}) + err := parseParentAndPlugin(tt.args.devFileObj, &resolutionContextTree{}, resolverTools{}) // Unexpected error if (err != nil) != (tt.wantErr != nil) { @@ -3072,23 +3073,10 @@ func Test_parseParentAndPlugin_RecursivelyReference(t *testing.T) { httpTimeout := 0 - mockGitUrl := &git.MockGitUrl{ - Protocol: "https", - Host: "raw.githubusercontent.com", - Owner: "devfile", - Repo: "library", - Revision: "main", - Path: "devfile.yaml", - IsFile: true, - } - devFileObj.Ctx.SetGit(mockGitUrl) - devFileObj.Ctx.GetGit().SetToken("valid-token", &httpTimeout) - tool := resolverTools{ k8sClient: testK8sClient, context: context.Background(), httpTimeout: &httpTimeout, - git: devFileObj.Ctx.GetGit(), } err := parseParentAndPlugin(devFileObj, &resolutionContextTree{}, tool) @@ -4161,7 +4149,8 @@ func Test_parseFromURI(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := parseFromURI(tt.importReference, tt.curDevfileCtx, &resolutionContextTree{}, resolverTools{git: &git.MockGitUrl{}}) + downloadGitRepoResources = mockDownloadGitRepoResources(&git.Url{}) + got, err := parseFromURI(tt.importReference, tt.curDevfileCtx, &resolutionContextTree{}, resolverTools{}) if (err != nil) != (tt.wantErr != nil) { t.Errorf("Test_parseFromURI() unexpected error: %v, wantErr %v", err, tt.wantErr) } else if err == nil && !reflect.DeepEqual(got.Data, tt.wantDevFile.Data) { @@ -4173,15 +4162,16 @@ func Test_parseFromURI(t *testing.T) { } } -func Test_parseFromURI_GitResources(t *testing.T) { +func Test_parseFromURI_GitProviders(t *testing.T) { const ( invalidToken = "invalid-token" validToken = "valid-token" invalidRevision = "invalid-revision" ) + minimalDevfileContent := fmt.Sprintf("schemaVersion: 2.2.0") server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { - _, err := rw.Write([]byte("schemaVersion: 2.2.0")) + _, err := rw.Write([]byte(minimalDevfileContent)) if err != nil { t.Error(err) } @@ -4208,9 +4198,48 @@ func Test_parseFromURI_GitResources(t *testing.T) { defer parent.Close() defer nestedParent.Close() - httpTimeoutPrivate := 1 + httpTimeout := 0 + + minimalDevfile := DevfileObj{ + Ctx: devfileCtx.NewURLDevfileCtx(OutputDevfileYamlPath), + Data: &v2.DevfileV2{ + Devfile: v1.Devfile{ + DevfileHeader: devfilepkg.DevfileHeader{ + SchemaVersion: schemaVersion, + }, + }, + }, + } + + parentDevfile := DevfileObj{ + Ctx: devfileCtx.NewURLDevfileCtx(OutputDevfileYamlPath), + Data: &v2.DevfileV2{ + Devfile: v1.Devfile{ + DevfileHeader: devfilepkg.DevfileHeader{ + SchemaVersion: schemaVersion, + Metadata: devfilepkg.DevfileMetadata{ + Name: "parent-devfile", + }, + }, + }, + }, + } + + nestParentDevfile := DevfileObj{ + Ctx: devfileCtx.NewURLDevfileCtx(OutputDevfileYamlPath), + Data: &v2.DevfileV2{ + Devfile: v1.Devfile{ + DevfileHeader: devfilepkg.DevfileHeader{ + SchemaVersion: schemaVersion, + Metadata: devfilepkg.DevfileMetadata{ + Name: "nested-devfile", + }, + }, + }, + }, + } - publicGitUrl := &git.MockGitUrl{ + publicGitUrl := &git.Url{ Protocol: "https", Host: "raw.githubusercontent.com", Owner: "devfile", @@ -4220,7 +4249,7 @@ func Test_parseFromURI_GitResources(t *testing.T) { IsFile: true, } - privateGitUrlInvalidRevision := &git.MockGitUrl{ + privateGitUrlInvalidRevision := &git.Url{ Protocol: "https", Host: "raw.githubusercontent.com", Owner: "devfile", @@ -4229,9 +4258,9 @@ func Test_parseFromURI_GitResources(t *testing.T) { Path: "devfile.yaml", IsFile: true, } - privateGitUrlInvalidRevision.SetToken(validToken, &httpTimeoutPrivate) + privateGitUrlInvalidRevision.SetToken(validToken, &httpTimeout) - privateBitbucketGitUrl := &git.MockGitUrl{ + privateBitbucketGitUrl := &git.Url{ Protocol: "https", Host: "bitbucket.org", Owner: "devfile", @@ -4240,9 +4269,9 @@ func Test_parseFromURI_GitResources(t *testing.T) { Path: "stacks/go/1.0.2/devfile.yaml", IsFile: true, } - privateBitbucketGitUrl.SetToken(validToken, &httpTimeoutPrivate) + privateBitbucketGitUrl.SetToken(validToken, &httpTimeout) - privateGitUrl := &git.MockGitUrl{ + privateGitUrl := &git.Url{ Protocol: "https", Host: "github.com", Owner: "mock-owner", @@ -4251,7 +4280,7 @@ func Test_parseFromURI_GitResources(t *testing.T) { Path: "mock/stacks/go/1.0.2/devfile.yaml", IsFile: true, } - privateGitUrl.SetToken(validToken, &httpTimeoutPrivate) + privateGitUrl.SetToken(validToken, &httpTimeout) curDevfileContextWithValidToken := devfileCtx.NewPrivateURLDevfileCtx(OutputDevfileYamlPath, validToken) curDevfileContextWithInvalidToken := devfileCtx.NewPrivateURLDevfileCtx(OutputDevfileYamlPath, invalidToken) @@ -4263,64 +4292,59 @@ func Test_parseFromURI_GitResources(t *testing.T) { tests := []struct { name string curDevfileCtx *devfileCtx.DevfileCtx - gitUrl *git.MockGitUrl - timeout *int + gitUrl *git.Url importReference v1.ImportReference + wantDevFile DevfileObj wantError *string }{ { name: "private main devfile URL", curDevfileCtx: &curDevfileContextWithValidToken, gitUrl: privateGitUrl, - timeout: &httpTimeoutPrivate, importReference: v1.ImportReference{ ImportReferenceUnion: v1.ImportReferenceUnion{ Uri: server.URL, }, }, - wantError: nil, + wantDevFile: minimalDevfile, }, { name: "private main devfile Bitbucket URL", curDevfileCtx: &curDevfileContextWithValidToken, gitUrl: privateBitbucketGitUrl, - timeout: &httpTimeoutPrivate, importReference: v1.ImportReference{ ImportReferenceUnion: v1.ImportReferenceUnion{ Uri: server.URL, }, }, - wantError: nil, + wantDevFile: minimalDevfile, }, { name: "private main devfile with a private parent reference", curDevfileCtx: &curDevfileContextWithValidToken, gitUrl: privateGitUrl, - timeout: &httpTimeoutPrivate, importReference: v1.ImportReference{ ImportReferenceUnion: v1.ImportReferenceUnion{ Uri: parent.URL, }, }, - wantError: nil, + wantDevFile: parentDevfile, }, { name: "private main devfile with a private parent with a nested private parent reference", curDevfileCtx: &curDevfileContextWithValidToken, gitUrl: privateGitUrl, - timeout: &httpTimeoutPrivate, importReference: v1.ImportReference{ ImportReferenceUnion: v1.ImportReferenceUnion{ Uri: nestedParent.URL, }, }, - wantError: nil, + wantDevFile: nestParentDevfile, }, { name: "private main devfile without a valid token", curDevfileCtx: &curDevfileContextWithInvalidToken, gitUrl: privateGitUrl, - timeout: &httpTimeoutPrivate, importReference: v1.ImportReference{ ImportReferenceUnion: v1.ImportReferenceUnion{ Uri: server.URL, @@ -4332,19 +4356,17 @@ func Test_parseFromURI_GitResources(t *testing.T) { name: "public main devfile without a token", curDevfileCtx: &curDevfileContextWithoutToken, gitUrl: publicGitUrl, - timeout: &httpTimeoutPrivate, importReference: v1.ImportReference{ ImportReferenceUnion: v1.ImportReferenceUnion{ Uri: server.URL, }, }, - wantError: nil, + wantDevFile: minimalDevfile, }, { name: "private parent devfile with invalid revision", curDevfileCtx: &curDevfileContextWithoutToken, gitUrl: privateGitUrlInvalidRevision, - timeout: &httpTimeoutPrivate, importReference: v1.ImportReference{ ImportReferenceUnion: v1.ImportReferenceUnion{ Uri: parent.URL, @@ -4356,16 +4378,64 @@ func Test_parseFromURI_GitResources(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - _, err := parseFromURI(tt.importReference, *tt.curDevfileCtx, &resolutionContextTree{}, resolverTools{httpTimeout: tt.timeout, git: tt.gitUrl}) + downloadGitRepoResources = mockDownloadGitRepoResources(tt.gitUrl) + got, err := parseFromURI(tt.importReference, *tt.curDevfileCtx, &resolutionContextTree{}, resolverTools{}) if (err != nil) != (tt.wantError != nil) { t.Errorf("Unexpected error: %v, wantErr %v", err, tt.wantError) - } else if tt.wantError != nil { + } else if err == nil && !reflect.DeepEqual(got.Data, tt.wantDevFile.Data) { + t.Errorf("Wanted: %v, got: %v, difference at %v", tt.wantDevFile, got, pretty.Compare(tt.wantDevFile, got)) + } else if err != nil { assert.Regexp(t, *tt.wantError, err.Error(), "Error message should match") } }) } } +func mockDownloadGitRepoResources(gURL *git.Url) func(url string, destDir string, httpTimeout *int, token string) error { + return func(url string, destDir string, httpTimeout *int, token string) error { + // this converts the real git URL to a mock URL + mockGitUrl := git.MockGitUrl{ + Protocol: gURL.Protocol, + Host: gURL.Host, + Owner: gURL.Owner, + Repo: gURL.Repo, + Revision: gURL.Revision, + Path: gURL.Path, + IsFile: gURL.IsFile, + } + + if mockGitUrl.IsGitProviderRepo() && mockGitUrl.IsFile { + stackDir, err := ioutil.TempDir(os.TempDir(), fmt.Sprintf("git-resources")) + if err != nil { + return fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err) + } + defer os.RemoveAll(stackDir) + + err = mockGitUrl.SetToken(token) + if err != nil { + return err + } + + err = mockGitUrl.CloneGitRepo(stackDir) + if err != nil { + return err + } + + if mockGitUrl.GetToken() != "" { + _, err = os.Stat(stackDir + "/private-repo-resource.txt") + } else { + _, err = os.Stat(stackDir + "/public-repo-resource.txt") + } + + if err != nil { + return err + } + } + + return nil + } +} + func Test_parseFromRegistry(t *testing.T) { const ( registry = "127.0.0.1:8080" @@ -4701,47 +4771,66 @@ func Test_parseFromKubeCRD(t *testing.T) { } func Test_DownloadGitRepoResources(t *testing.T) { - destDir, err := ioutil.TempDir("", "") - if err != nil { - t.Errorf("Failed to create dest dir: %s, error: %v", destDir, err) + httpTimeout := 0 + + validGitUrl := git.Url{ + Protocol: "https", + Host: "raw.githubusercontent.com", + Owner: "devfile", + Repo: "registry", + Revision: "main", + Path: "stacks/python/3.0.0/devfile.yaml", + IsFile: true, } - defer os.RemoveAll(destDir) + validGitUrl.SetToken("valid-token", &httpTimeout) - httpTimeout := 0 - var g git.Url + invalidTokenErr := "failed to clone repo with token, ensure that the url and token is correct" tests := []struct { name string url string + gitUrl git.Url destDir string token string wantErr bool }{ { - name: "should fail with invalid git url", - url: "non-existent-url", - destDir: path.Join(os.TempDir(), "nonexistent"), - token: "", - wantErr: true, + name: "should be able to get resources with valid token", + url: "https://raw.githubusercontent.com/devfile/registry/main/stacks/python/3.0.0/devfile.yaml", + gitUrl: validGitUrl, + token: "valid-token", + wantErr: false, }, { - name: "should be able to get resources from valid git url", + name: "should be able to get resources from public repo (empty token)", url: "https://raw.githubusercontent.com/devfile/registry/main/stacks/python/3.0.0/devfile.yaml", - destDir: destDir, + gitUrl: validGitUrl, token: "", wantErr: false, }, + { + name: "should fail to get resources with invalid token", + url: "https://raw.githubusercontent.com/devfile/registry/main/stacks/python/3.0.0/devfile.yaml", + gitUrl: validGitUrl, + token: "invalid-token", + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - gotErr := false - err := g.DownloadGitRepoResources(tt.url, tt.destDir, &httpTimeout, tt.token) + destDir, err := ioutil.TempDir("", "") if err != nil { - gotErr = true + t.Errorf("Failed to create dest dir: %s, error: %v", destDir, err) } - if !reflect.DeepEqual(gotErr, tt.wantErr) { - t.Errorf("Got error: %t, want error: %t", gotErr, tt.wantErr) + defer os.RemoveAll(destDir) + + downloadGitRepoResources = mockDownloadGitRepoResources(&tt.gitUrl) + err = downloadGitRepoResources(tt.url, destDir, &httpTimeout, tt.token) + if (err != nil) && (tt.wantErr != true) { + t.Errorf("Unexpected error = %v", err) + } else if tt.wantErr == true { + assert.Containsf(t, err.Error(), invalidTokenErr, "expected error containing %q, got %s", invalidTokenErr, err) } }) } diff --git a/pkg/git/git.go b/pkg/git/git.go index 5c1a751e..44a7dc47 100644 --- a/pkg/git/git.go +++ b/pkg/git/git.go @@ -17,11 +17,8 @@ package git import ( "fmt" - "io/ioutil" "net/url" - "os" "os/exec" - "path" "path/filepath" "strings" ) @@ -33,13 +30,6 @@ const ( BitbucketHost string = "bitbucket.org" ) -type IGitUrl interface { - GitRawFileAPI() string - SetToken(token string, httpTimeout *int) error - IsPublic(httpTimeout *int) bool - DownloadGitRepoResources(url string, destDir string, httpTimeout *int, token string) error -} - type Url struct { Protocol string // URL scheme Host string // URL domain name @@ -52,12 +42,12 @@ type Url struct { } // NewGitUrlWithURL NewGitUrl creates a GitUrl from a string url -func NewGitUrlWithURL(url string) (*Url, error) { +func NewGitUrlWithURL(url string) (Url, error) { gitUrl, err := ParseGitUrl(url) if err != nil { - return &gitUrl, err + return gitUrl, err } - return &gitUrl, nil + return gitUrl, nil } // ParseGitUrl extracts information from a support git url @@ -157,40 +147,6 @@ func (g *Url) CloneGitRepo(destDir string) error { return nil } -func (g *Url) DownloadGitRepoResources(url string, destDir string, httpTimeout *int, token string) error { - gitUrl, err := NewGitUrlWithURL(url) - if err != nil { - return err - } - - if gitUrl.IsGitProviderRepo() && gitUrl.IsFile { - stackDir, err := ioutil.TempDir(os.TempDir(), fmt.Sprintf("git-resources")) - if err != nil { - return fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err) - } - defer os.RemoveAll(stackDir) - - if !gitUrl.IsPublic(httpTimeout) { - err = gitUrl.SetToken(token, httpTimeout) - if err != nil { - return err - } - } - - err = gitUrl.CloneGitRepo(stackDir) - if err != nil { - return err - } - - dir := path.Dir(path.Join(stackDir, gitUrl.Path)) - err = CopyAllDirFiles(dir, destDir) - if err != nil { - return err - } - } - return nil -} - func (g *Url) parseGitHubUrl(url *url.URL) error { var splitUrl []string var err error diff --git a/pkg/git/mock.go b/pkg/git/mock.go index a6dca5b7..a6b6c77d 100644 --- a/pkg/git/mock.go +++ b/pkg/git/mock.go @@ -17,9 +17,9 @@ package git import ( "fmt" - "io/ioutil" "net/url" "os" + "path/filepath" "strings" ) @@ -44,14 +44,24 @@ var mockExecute = func(baseDir string, cmd CommandType, args ...string) ([]byte, u, _ := url.Parse(args[1]) password, hasPassword := u.User.Password() + // private repository if hasPassword { switch password { case "valid-token": + _, err := os.Create(filepath.Clean(baseDir) + "/private-repo-resource.txt") + if err != nil { + return nil, fmt.Errorf("failed to create test resource: %v", err) + } return []byte("test"), nil default: return []byte(""), fmt.Errorf("not a valid token") } } + // public repository + _, err := os.Create(filepath.Clean(baseDir) + "/public-repo-resource.txt") + if err != nil { + return nil, fmt.Errorf("failed to create test resource: %v", err) + } return []byte("test"), nil } @@ -88,7 +98,7 @@ func (m *MockGitUrl) CloneGitRepo(destDir string) error { } } - _, err := mockExecute(destDir, "git", "clone", repoUrl, ".") + _, err := mockExecute(destDir, "git", "clone", repoUrl, destDir) if err != nil { if m.GetToken() == "" { @@ -108,46 +118,16 @@ func (m *MockGitUrl) CloneGitRepo(destDir string) error { return nil } -func (m *MockGitUrl) DownloadGitRepoResources(url string, destDir string, httpTimeout *int, token string) error { - gitUrl := m - if gitUrl.IsGitProviderRepo() && gitUrl.IsFile { - stackDir, err := ioutil.TempDir(os.TempDir(), fmt.Sprintf("git-resources")) - if err != nil { - return fmt.Errorf("failed to create dir: %s, error: %v", stackDir, err) - } - defer os.RemoveAll(stackDir) - - if !gitUrl.IsPublic(httpTimeout) { - err = m.SetToken(token, httpTimeout) - if err != nil { - return err - } - } - - err = gitUrl.CloneGitRepo(stackDir) - if err != nil { - return err - } - } - return nil -} - -func (m *MockGitUrl) SetToken(token string, httpTimeout *int) error { +func (m *MockGitUrl) SetToken(token string) error { m.token = token return nil } -func (m *MockGitUrl) IsPublic(httpTimeout *int) bool { - if *httpTimeout != 0 { +func (m *MockGitUrl) IsGitProviderRepo() bool { + switch m.Host { + case GitHubHost, RawGitHubHost, GitLabHost, BitbucketHost: + return true + default: return false } - return true -} - -func (m *MockGitUrl) GitRawFileAPI() string { - return "" -} - -func (m *MockGitUrl) IsGitProviderRepo() bool { - return true } diff --git a/pkg/util/util.go b/pkg/util/util.go index 6db76a8a..c49a542b 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -22,6 +22,8 @@ import ( "crypto/rand" "fmt" "github.com/devfile/library/v2/pkg/git" + gitpkg "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" "io" "io/ioutil" "math/big" @@ -1098,7 +1100,7 @@ func DownloadInMemory(params HTTPRequestParams) ([]byte, error) { ResponseHeaderTimeout: HTTPRequestResponseTimeout, }, Timeout: HTTPRequestResponseTimeout} - var g git.IGitUrl + var g git.Url var err error if IsGitProviderRepo(params.URL) { @@ -1111,7 +1113,7 @@ func DownloadInMemory(params HTTPRequestParams) ([]byte, error) { return downloadInMemoryWithClient(params, httpClient, g) } -func downloadInMemoryWithClient(params HTTPRequestParams, httpClient HTTPClient, g git.IGitUrl) ([]byte, error) { +func downloadInMemoryWithClient(params HTTPRequestParams, httpClient HTTPClient, g git.Url) ([]byte, error) { var url string url = params.URL req, err := http.NewRequest("GET", url, nil) @@ -1226,6 +1228,59 @@ func ValidateFile(filePath string) error { return nil } +// GetGitUrlComponentsFromRaw converts a raw GitHub file link to a map of the url components +// Deprecated: in favor of the method git.ParseGitUrl() with the devfile/library/v2/pkg/git package +func GetGitUrlComponentsFromRaw(rawGitURL string) (map[string]string, error) { + var urlComponents map[string]string + + err := ValidateURL(rawGitURL) + if err != nil { + return nil, err + } + + u, _ := url.Parse(rawGitURL) + // the url scheme (e.g. https://) is removed before splitting into the 5 components + urlPath := strings.SplitN(u.Host+u.Path, "/", 5) + + // raw GitHub url: https://raw.githubusercontent.com/devfile/registry/main/stacks/nodejs/devfile.yaml + // host: raw.githubusercontent.com + // username: devfile + // project: registry + // branch: main + // file: stacks/nodejs/devfile.yaml + if len(urlPath) == 5 { + urlComponents = map[string]string{ + "host": urlPath[0], + "username": urlPath[1], + "project": urlPath[2], + "branch": urlPath[3], + "file": urlPath[4], + } + } + + return urlComponents, nil +} + +// CloneGitRepo clones a GitHub repo to a destination directory +// Deprecated: in favor of the method git.CloneGitRepo() with the devfile/library/v2/pkg/git package +func CloneGitRepo(gitUrlComponents map[string]string, destDir string) error { + gitUrl := fmt.Sprintf("https://github.com/%s/%s.git", gitUrlComponents["username"], gitUrlComponents["project"]) + branch := fmt.Sprintf("refs/heads/%s", gitUrlComponents["branch"]) + + cloneOptions := &gitpkg.CloneOptions{ + URL: gitUrl, + ReferenceName: plumbing.ReferenceName(branch), + SingleBranch: true, + Depth: 1, + } + + _, err := gitpkg.PlainClone(destDir, false, cloneOptions) + if err != nil { + return err + } + return nil +} + // CopyFile copies file from source path to destination path func CopyFile(srcPath string, dstPath string, info os.FileInfo) error { // In order to avoid file overriding issue, do nothing if source path is equal to destination path