From 8903ae4bd82a71f0bab6ecb0e94868dc01891af0 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Fri, 10 May 2024 08:51:30 +0200 Subject: [PATCH 01/10] feat(remote): support include git remote --- go.mod | 25 ++- go.sum | 155 ++++++++++++++++-- taskfile/node.go | 16 +- taskfile/node_file.go | 3 + taskfile/node_git.go | 113 +++++++++++++ taskfile/node_git_test.go | 36 ++++ taskfile/node_http.go | 1 - taskfile/node_test.go | 12 ++ website/docs/experiments/remote_taskfiles.mdx | 7 + 9 files changed, 344 insertions(+), 24 deletions(-) create mode 100644 taskfile/node_git.go create mode 100644 taskfile/node_git_test.go create mode 100644 taskfile/node_test.go diff --git a/go.mod b/go.mod index 1c323236c6..697ab59869 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,8 @@ require ( github.com/davecgh/go-spew v1.1.1 github.com/dominikbraun/graph v0.23.0 github.com/fatih/color v1.17.0 + github.com/go-git/go-billy/v5 v5.5.0 + github.com/go-git/go-git/v5 v5.12.0 github.com/go-task/slim-sprig/v3 v3.0.0 github.com/go-task/template v0.1.0 github.com/joho/godotenv v1.5.1 @@ -19,6 +21,7 @@ require ( github.com/sajari/fuzzy v1.0.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 + github.com/whilp/git-urls v1.0.0 github.com/zeebo/xxh3 v1.0.2 golang.org/x/sync v0.8.0 golang.org/x/term v0.24.0 @@ -27,13 +30,33 @@ require ( ) require ( + dario.cat/mergo v1.0.0 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/ProtonMail/go-crypto v1.0.0 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/dlclark/regexp2 v1.11.0 // indirect - github.com/klauspost/cpuid/v2 v2.0.9 // indirect + github.com/emirpasic/gods v1.18.1 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/muesli/cancelreader v0.2.2 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/skeema/knownhosts v1.2.2 // indirect github.com/stretchr/objx v0.5.2 // indirect golang.org/x/sys v0.25.0 // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.22.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/tools v0.17.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect ) diff --git a/go.sum b/go.sum index 232baa2794..6e7d730a1f 100644 --- a/go.sum +++ b/go.sum @@ -1,39 +1,80 @@ +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Ladicle/tabwriter v1.0.0 h1:DZQqPvMumBDwVNElso13afjYLNp0Z7pHqHnu0r4t9Dg= github.com/Ladicle/tabwriter v1.0.0/go.mod h1:c4MdCjxQyTbGuQO/gvqJ+IA/89UEwrsD6hUCW98dyp4= -github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= -github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= +github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/alecthomas/assert/v2 v2.7.0 h1:QtqSACNS3tF7oasA8CU6A6sXZSBDqnm7RfpLl9bZqbE= github.com/alecthomas/assert/v2 v2.7.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/chroma/v2 v2.14.0 h1:R3+wzpnUArGcQz7fCETQBzO5n9IMNi13iIs46aU4V9E= github.com/alecthomas/chroma/v2 v2.14.0/go.mod h1:QolEbTfmUHIMVpBqxeDnNBj2uoeI4EbYP4i6n68SG4I= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= +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/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dominikbraun/graph v0.23.0 h1:TdZB4pPqCLFxYhdyMFb1TBdFxp8XLcJfTTBQucVPgCo= github.com/dominikbraun/graph v0.23.0/go.mod h1:yOjYyogZLY1LSG9E33JWZJiq5k83Qy2C6POAuiViluc= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= -github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= -github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= +github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/go-task/template v0.1.0 h1:ym/r2G937RZA1bsgiWedNnY9e5kxDT+3YcoAnuIetTE= -github.com/go-task/template v0.1.0/go.mod h1:RgwRaZK+kni/hJJ7/AaOE2lPQFPbAdji/DyhC6pxo4k= +github.com/go-task/template v0.0.0-20240602015157-960e6f576656 h1:knZZ4zVdTBQnevBz0zSES++4Mr7wr+cHopLvHabIgkA= +github.com/go-task/template v0.0.0-20240602015157-960e6f576656/go.mod h1:RgwRaZK+kni/hJJ7/AaOE2lPQFPbAdji/DyhC6pxo4k= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +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/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -45,12 +86,16 @@ github.com/mattn/go-zglob v0.0.6 h1:mP8RnmCgho4oaUYDIDn6GNxYk+qJGUs8fJLn+twYj2A= github.com/mattn/go-zglob v0.0.6/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY= github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= -github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= -github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= github.com/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/radovskyb/watcher v1.0.7 h1:AYePLih6dpmS32vlHfhCeli8127LzkIgwJGcwwe8tUE= @@ -59,27 +104,101 @@ github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/sajari/fuzzy v1.0.0 h1:+FmwVvJErsd0d0hAPlj4CxqxUtQY/fOoY0DwX4ykpRY= github.com/sajari/fuzzy v1.0.0/go.mod h1:OjYR6KxoWOe9+dOlXeiCJd4dIbED4Oo8wpS89o0pwOo= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/whilp/git-urls v1.0.0 h1:95f6UMWN5FKW71ECsXRUd3FVYiXdrE7aX4NZKcPmIjU= +github.com/whilp/git-urls v1.0.0/go.mod h1:J16SAmobsqc3Qcy98brfl5f5+e0clUvg1krgwk/qCfE= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/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.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= mvdan.cc/sh/v3 v3.9.0 h1:it14fyjCdQUk4jf/aYxLO3FG8jFarR9GzMCtnlvvD7c= diff --git a/taskfile/node.go b/taskfile/node.go index 56b25a16aa..4b79db81c5 100644 --- a/taskfile/node.go +++ b/taskfile/node.go @@ -2,6 +2,7 @@ package taskfile import ( "context" + giturls "github.com/whilp/git-urls" "os" "path/filepath" "strings" @@ -48,11 +49,11 @@ func NewNode( ) (Node, error) { var node Node var err error - switch getScheme(entrypoint) { - case "http", "https": + if isGitNode(entrypoint) { + node, err = NewGitNode(entrypoint, dir, insecure, opts...) + } else if getScheme(entrypoint) == "http" || getScheme(entrypoint) == "https" { node, err = NewHTTPNode(l, entrypoint, dir, insecure, timeout, opts...) - default: - // If no other scheme matches, we assume it's a file + } else { node, err = NewFileNode(l, entrypoint, dir, opts...) } if node.Remote() && !experiments.RemoteTaskfiles.Enabled { @@ -90,3 +91,10 @@ func getDefaultDir(entrypoint, dir string) string { return dir } + +// TODO handle error +func isGitNode(entrypoint string) bool { + u, _ := giturls.Parse(entrypoint) + u.Path = strings.TrimSuffix(u.Path, "/") + return strings.HasSuffix(u.Path, ".git") && (u.Scheme == "git" || u.Scheme == "ssh" || u.Scheme == "https" || u.Scheme == "http") +} diff --git a/taskfile/node_file.go b/taskfile/node_file.go index 3e5ec9d69e..4ea9001c43 100644 --- a/taskfile/node_file.go +++ b/taskfile/node_file.go @@ -81,6 +81,9 @@ func (node *FileNode) ResolveEntrypoint(entrypoint string) (string, error) { if strings.Contains(entrypoint, "://") { return entrypoint, nil } + if strings.HasPrefix(entrypoint, "git") { + return entrypoint, nil + } path, err := execext.Expand(entrypoint) if err != nil { diff --git a/taskfile/node_git.go b/taskfile/node_git.go new file mode 100644 index 0000000000..94d546ed16 --- /dev/null +++ b/taskfile/node_git.go @@ -0,0 +1,113 @@ +package taskfile + +import ( + "context" + "fmt" + "github.com/go-git/go-billy/v5/memfs" + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/storage/memory" + "github.com/go-task/task/v3/errors" + "github.com/go-task/task/v3/internal/execext" + "github.com/go-task/task/v3/internal/filepathext" + giturls "github.com/whilp/git-urls" + "io" + "net/url" + "path/filepath" + "strings" +) + +// An GitNode is a node that reads a Taskfile from a remote location via HTTP. +type GitNode struct { + *BaseNode + URL *url.URL + rawUrl string + ref string + path string +} + +func NewGitNode( + entrypoint string, + dir string, + insecure bool, + opts ...NodeOption, +) (*GitNode, error) { + base := NewBaseNode(dir, opts...) + u, err := giturls.Parse(entrypoint) + if err != nil { + return nil, err + } + refQuery := u.Query().Get("ref") + ref, path := func() (string, string) { + x := strings.Split(refQuery, "//") + return x[0], x[1] + }() + + rawUrl := u.String() + u.RawQuery = "" + + if u.Scheme == "http" && !insecure { + return nil, &errors.TaskfileNotSecureError{URI: entrypoint} + } + + return &GitNode{ + BaseNode: base, + URL: u, + rawUrl: rawUrl, + ref: ref, + path: path, + }, nil +} + +func (node *GitNode) Location() string { + return node.rawUrl +} + +func (node *GitNode) Remote() bool { + return true +} + +func (node *GitNode) Read(_ context.Context) ([]byte, error) { + fs := memfs.New() + storer := memory.NewStorage() + _, err := git.Clone(storer, fs, &git.CloneOptions{ + URL: node.URL.String(), + ReferenceName: plumbing.ReferenceName(node.ref), + Depth: 1, + }) + if err != nil { + return nil, err + } + file, err := fs.Open(node.path) + if err != nil { + return nil, err + } + // Read the entire response body + b, err := io.ReadAll(file) + if err != nil { + return nil, err + } + + return b, nil +} + +func (node *GitNode) ResolveEntrypoint(entrypoint string) (string, error) { + dir, _ := filepath.Split(node.path) + return fmt.Sprintf("%s?ref=%s//%s", node.URL, node.ref, filepath.Join(dir, entrypoint)), nil +} + +func (node *GitNode) ResolveDir(dir string) (string, error) { + path, err := execext.Expand(dir) + if err != nil { + return "", err + } + + if filepathext.IsAbs(path) { + return path, nil + } + + // NOTE: Uses the directory of the entrypoint (Taskfile), not the current working directory + // This means that files are included relative to one another + entrypointDir := filepath.Dir(node.Dir()) + return filepathext.SmartJoin(entrypointDir, path), nil +} diff --git a/taskfile/node_git_test.go b/taskfile/node_git_test.go new file mode 100644 index 0000000000..12301bb33c --- /dev/null +++ b/taskfile/node_git_test.go @@ -0,0 +1,36 @@ +package taskfile + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestGitNode(t *testing.T) { + node, err := NewGitNode("git@github.com:foo/bar.git?ref=main//Taskfile.yml", "", false) + assert.NoError(t, err) + assert.Equal(t, "main", node.ref) + assert.Equal(t, "Taskfile.yml", node.path) + assert.Equal(t, "ssh://git@github.com/foo/bar.git?ref=main//Taskfile.yml", node.rawUrl) + assert.Equal(t, "ssh://git@github.com/foo/bar.git", node.URL.String()) + entrypoint, err := node.ResolveEntrypoint("common.yml") + assert.NoError(t, err) + assert.Equal(t, "ssh://git@github.com/foo/bar.git?ref=main//common.yml", entrypoint) +} + +func TestGitNode_WithoutRef(t *testing.T) { + node, err := NewGitNode("git@github.com/foo/bar?ref=main//Taskfile.yml", "", false) + assert.NoError(t, err) + assert.Equal(t, "main", node.ref) + assert.Equal(t, "Taskfile.yml", node.path) + assert.Equal(t, "github.com/foo/bar?ref=main//Taskfile.yml", node.rawUrl) + assert.Equal(t, "github.com/foo/bar", node.URL.String()) +} + +func TestGitNode_WithoutPath(t *testing.T) { + node, err := NewGitNode("git@github.com/foo/bar?ref=main//Taskfile.yml", "", false) + assert.NoError(t, err) + assert.Equal(t, "main", node.ref) + assert.Equal(t, "Taskfile.yml", node.path) + assert.Equal(t, "github.com/foo/bar?ref=main//Taskfile.yml", node.rawUrl) + assert.Equal(t, "github.com/foo/bar", node.URL.String()) +} diff --git a/taskfile/node_http.go b/taskfile/node_http.go index fa415d3c1f..d6fb2201bf 100644 --- a/taskfile/node_http.go +++ b/taskfile/node_http.go @@ -74,7 +74,6 @@ func (node *HTTPNode) Read(ctx context.Context) ([]byte, error) { return nil, errors.TaskfileFetchFailedError{URI: node.URL.String()} } defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { return nil, errors.TaskfileFetchFailedError{ URI: node.URL.String(), diff --git a/taskfile/node_test.go b/taskfile/node_test.go new file mode 100644 index 0000000000..fb1673c1ad --- /dev/null +++ b/taskfile/node_test.go @@ -0,0 +1,12 @@ +package taskfile + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestIsGitNode(t *testing.T) { + assert.True(t, isGitNode("https://github.com/foo/bar.git")) + assert.True(t, isGitNode("https://github.com/foo/bar.git?ref=v1//taskfile/common.yml")) + assert.True(t, isGitNode("git@github.com/foo/bar?ref=main//Taskfile.yml")) +} diff --git a/website/docs/experiments/remote_taskfiles.mdx b/website/docs/experiments/remote_taskfiles.mdx index 8a85ccd0b6..8c6ecfcc60 100644 --- a/website/docs/experiments/remote_taskfiles.mdx +++ b/website/docs/experiments/remote_taskfiles.mdx @@ -62,6 +62,13 @@ includes: `TOKEN=my-token task my-remote-namespace:hello` will be resolved by Task to `https://my-token@raw.githubusercontent.com/my-org/my-repo/main/Taskfile.yml` +## Git nodes + +You can also include a Taskfile from a Git node. We currently support only "scp-style" addresses like `git@example.com/foo/bar?ref=v1//Taskfiles.yml` + +You need to follow this pattern : `.git?ref=//`. +The `ref` parameter can be a branch name or a tag, and the `path` is the path to the Taskfile in the repository. + ## Security Running commands from sources that you do not control is always a potential From 1a8a905f376c9cc6c3348152542034c8309b9acb Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Fri, 10 May 2024 22:54:57 +0200 Subject: [PATCH 02/10] add tests --- taskfile/node_git_test.go | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/taskfile/node_git_test.go b/taskfile/node_git_test.go index 12301bb33c..ffd33ba15f 100644 --- a/taskfile/node_git_test.go +++ b/taskfile/node_git_test.go @@ -5,7 +5,7 @@ import ( "testing" ) -func TestGitNode(t *testing.T) { +func TestGitNode_ssh(t *testing.T) { node, err := NewGitNode("git@github.com:foo/bar.git?ref=main//Taskfile.yml", "", false) assert.NoError(t, err) assert.Equal(t, "main", node.ref) @@ -17,20 +17,38 @@ func TestGitNode(t *testing.T) { assert.Equal(t, "ssh://git@github.com/foo/bar.git?ref=main//common.yml", entrypoint) } -func TestGitNode_WithoutRef(t *testing.T) { - node, err := NewGitNode("git@github.com/foo/bar?ref=main//Taskfile.yml", "", false) +func TestGitNode_sshWithDir(t *testing.T) { + node, err := NewGitNode("git@github.com:foo/bar.git?ref=main//directory/Taskfile.yml", "", false) assert.NoError(t, err) assert.Equal(t, "main", node.ref) - assert.Equal(t, "Taskfile.yml", node.path) - assert.Equal(t, "github.com/foo/bar?ref=main//Taskfile.yml", node.rawUrl) - assert.Equal(t, "github.com/foo/bar", node.URL.String()) + assert.Equal(t, "directory/Taskfile.yml", node.path) + assert.Equal(t, "ssh://git@github.com/foo/bar.git?ref=main//directory/Taskfile.yml", node.rawUrl) + assert.Equal(t, "ssh://git@github.com/foo/bar.git", node.URL.String()) + entrypoint, err := node.ResolveEntrypoint("common.yml") + assert.NoError(t, err) + assert.Equal(t, "ssh://git@github.com/foo/bar.git?ref=main//directory/common.yml", entrypoint) } -func TestGitNode_WithoutPath(t *testing.T) { - node, err := NewGitNode("git@github.com/foo/bar?ref=main//Taskfile.yml", "", false) +func TestGitNode_https(t *testing.T) { + node, err := NewGitNode("https://github.com/foo/bar.git?ref=main//Taskfile.yml", "", false) assert.NoError(t, err) assert.Equal(t, "main", node.ref) assert.Equal(t, "Taskfile.yml", node.path) - assert.Equal(t, "github.com/foo/bar?ref=main//Taskfile.yml", node.rawUrl) - assert.Equal(t, "github.com/foo/bar", node.URL.String()) + assert.Equal(t, "https://github.com/foo/bar.git?ref=main//Taskfile.yml", node.rawUrl) + assert.Equal(t, "https://github.com/foo/bar.git", node.URL.String()) + entrypoint, err := node.ResolveEntrypoint("common.yml") + assert.NoError(t, err) + assert.Equal(t, "https://github.com/foo/bar.git?ref=main//common.yml", entrypoint) +} + +func TestGitNode_httpsWithDir(t *testing.T) { + node, err := NewGitNode("https://github.com/foo/bar.git?ref=main//directory/Taskfile.yml", "", false) + assert.NoError(t, err) + assert.Equal(t, "main", node.ref) + assert.Equal(t, "directory/Taskfile.yml", node.path) + assert.Equal(t, "https://github.com/foo/bar.git?ref=main//directory/Taskfile.yml", node.rawUrl) + assert.Equal(t, "https://github.com/foo/bar.git", node.URL.String()) + entrypoint, err := node.ResolveEntrypoint("common.yml") + assert.NoError(t, err) + assert.Equal(t, "https://github.com/foo/bar.git?ref=main//directory/common.yml", entrypoint) } From 89e3e77086102eefa7db824e5cf59d5cf71d0839 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Sat, 11 May 2024 14:03:06 +0200 Subject: [PATCH 03/10] lint --- taskfile/node.go | 17 ++++++++++++----- taskfile/node_git.go | 12 +++++++----- taskfile/node_git_test.go | 3 ++- taskfile/node_test.go | 21 +++++++++++++++++---- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/taskfile/node.go b/taskfile/node.go index 4b79db81c5..f8f4133e5e 100644 --- a/taskfile/node.go +++ b/taskfile/node.go @@ -2,12 +2,13 @@ package taskfile import ( "context" - giturls "github.com/whilp/git-urls" "os" "path/filepath" "strings" "time" + giturls "github.com/whilp/git-urls" + "github.com/go-task/task/v3/errors" "github.com/go-task/task/v3/internal/experiments" "github.com/go-task/task/v3/internal/logger" @@ -49,7 +50,11 @@ func NewNode( ) (Node, error) { var node Node var err error - if isGitNode(entrypoint) { + isGit, err := isGitNode(entrypoint) + if err != nil { + return nil, err + } + if isGit { node, err = NewGitNode(entrypoint, dir, insecure, opts...) } else if getScheme(entrypoint) == "http" || getScheme(entrypoint) == "https" { node, err = NewHTTPNode(l, entrypoint, dir, insecure, timeout, opts...) @@ -92,9 +97,11 @@ func getDefaultDir(entrypoint, dir string) string { return dir } -// TODO handle error -func isGitNode(entrypoint string) bool { +func isGitNode(entrypoint string) (bool, error) { u, _ := giturls.Parse(entrypoint) + if u == nil { + return false, nil + } u.Path = strings.TrimSuffix(u.Path, "/") - return strings.HasSuffix(u.Path, ".git") && (u.Scheme == "git" || u.Scheme == "ssh" || u.Scheme == "https" || u.Scheme == "http") + return strings.HasSuffix(u.Path, ".git") && (u.Scheme == "git" || u.Scheme == "ssh" || u.Scheme == "https" || u.Scheme == "http"), nil } diff --git a/taskfile/node_git.go b/taskfile/node_git.go index 94d546ed16..3b544f9869 100644 --- a/taskfile/node_git.go +++ b/taskfile/node_git.go @@ -3,18 +3,20 @@ package taskfile import ( "context" "fmt" + "io" + "net/url" + "path/filepath" + "strings" + "github.com/go-git/go-billy/v5/memfs" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/storage/memory" + giturls "github.com/whilp/git-urls" + "github.com/go-task/task/v3/errors" "github.com/go-task/task/v3/internal/execext" "github.com/go-task/task/v3/internal/filepathext" - giturls "github.com/whilp/git-urls" - "io" - "net/url" - "path/filepath" - "strings" ) // An GitNode is a node that reads a Taskfile from a remote location via HTTP. diff --git a/taskfile/node_git_test.go b/taskfile/node_git_test.go index ffd33ba15f..60a44a0ad5 100644 --- a/taskfile/node_git_test.go +++ b/taskfile/node_git_test.go @@ -1,8 +1,9 @@ package taskfile import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func TestGitNode_ssh(t *testing.T) { diff --git a/taskfile/node_test.go b/taskfile/node_test.go index fb1673c1ad..d46cea577e 100644 --- a/taskfile/node_test.go +++ b/taskfile/node_test.go @@ -1,12 +1,25 @@ package taskfile import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func TestIsGitNode(t *testing.T) { - assert.True(t, isGitNode("https://github.com/foo/bar.git")) - assert.True(t, isGitNode("https://github.com/foo/bar.git?ref=v1//taskfile/common.yml")) - assert.True(t, isGitNode("git@github.com/foo/bar?ref=main//Taskfile.yml")) + isGit, err := isGitNode("https://github.com/foo/bar.git") + assert.NoError(t, err) + assert.True(t, isGit) + isGit, err = isGitNode("https://github.com/foo/bar.git?ref=v1//taskfile/common.yml") + assert.NoError(t, err) + assert.True(t, isGit) + isGit, err = isGitNode("git@github.com:foo/bar.git?ref=main//Taskfile.yml") + assert.NoError(t, err) + assert.True(t, isGit) +} + +func TestIsNotGitNode(t *testing.T) { + isGit, err := isGitNode("https://github.com/foo/common.yml") + assert.NoError(t, err) + assert.False(t, isGit) } From d02ca301fb28a7feed61d5c1cd88179a607d1e09 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Sat, 11 May 2024 14:03:28 +0200 Subject: [PATCH 04/10] add testdata --- testdata/git/Taskfile.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 testdata/git/Taskfile.yml diff --git a/testdata/git/Taskfile.yml b/testdata/git/Taskfile.yml new file mode 100644 index 0000000000..0a3ed65ca6 --- /dev/null +++ b/testdata/git/Taskfile.yml @@ -0,0 +1,18 @@ +version: '3' + +silent: false + +includes: + rust: 'git@github.com:pbstck/taskfiles.git?ref=v1//taskfile/rust.yml' + go_http: https://github.com/pbstck/taskfiles.git?ref=v1//taskfile/go.yml + +tasks: + default: + env: + CC: x86_64-w64-mingw32-gcc + CGO_ENABLED: 1 + CGO_ENABLED2: 1.1 + GOOS: windows + GOARCH: amd64 + cmds: + - echo CC=$CC CGO_ENABLED=$CGO_ENABLED CGO_ENABLED2=$CGO_ENABLED2 GOOS=$GOOS GOARCH=$GOARCH From 7b91e280480762a6a8c8e29f44e0750e6aacb2fd Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Sat, 11 May 2024 15:15:17 +0200 Subject: [PATCH 05/10] update docs --- taskfile/node_git.go | 2 +- testdata/git/Taskfile.yml | 18 ------------------ website/docs/experiments/remote_taskfiles.mdx | 4 +++- 3 files changed, 4 insertions(+), 20 deletions(-) delete mode 100644 testdata/git/Taskfile.yml diff --git a/taskfile/node_git.go b/taskfile/node_git.go index 3b544f9869..c8379e2d33 100644 --- a/taskfile/node_git.go +++ b/taskfile/node_git.go @@ -19,7 +19,7 @@ import ( "github.com/go-task/task/v3/internal/filepathext" ) -// An GitNode is a node that reads a Taskfile from a remote location via HTTP. +// An GitNode is a node that reads a Taskfile from a remote location via Git. type GitNode struct { *BaseNode URL *url.URL diff --git a/testdata/git/Taskfile.yml b/testdata/git/Taskfile.yml deleted file mode 100644 index 0a3ed65ca6..0000000000 --- a/testdata/git/Taskfile.yml +++ /dev/null @@ -1,18 +0,0 @@ -version: '3' - -silent: false - -includes: - rust: 'git@github.com:pbstck/taskfiles.git?ref=v1//taskfile/rust.yml' - go_http: https://github.com/pbstck/taskfiles.git?ref=v1//taskfile/go.yml - -tasks: - default: - env: - CC: x86_64-w64-mingw32-gcc - CGO_ENABLED: 1 - CGO_ENABLED2: 1.1 - GOOS: windows - GOARCH: amd64 - cmds: - - echo CC=$CC CGO_ENABLED=$CGO_ENABLED CGO_ENABLED2=$CGO_ENABLED2 GOOS=$GOOS GOARCH=$GOARCH diff --git a/website/docs/experiments/remote_taskfiles.mdx b/website/docs/experiments/remote_taskfiles.mdx index 8c6ecfcc60..5fd3733d2b 100644 --- a/website/docs/experiments/remote_taskfiles.mdx +++ b/website/docs/experiments/remote_taskfiles.mdx @@ -64,11 +64,13 @@ includes: ## Git nodes -You can also include a Taskfile from a Git node. We currently support only "scp-style" addresses like `git@example.com/foo/bar?ref=v1//Taskfiles.yml` +You can also include a Taskfile from a Git node. We currently support ssh-style and http / https addresses like `git@example.com/foo/bar?ref=v1//Taskfiles.yml` and `https://example.com/foo/bar.git?ref=v1//Taskfiles.yml`. You need to follow this pattern : `.git?ref=//`. The `ref` parameter can be a branch name or a tag, and the `path` is the path to the Taskfile in the repository. +If you want to use the SSH protocol, you need to make sure that your ssh-agent has your private ssh keys added so that they can be used during authentication. + ## Security Running commands from sources that you do not control is always a potential From 511659caa481929c1e72338bc1996679856e1cea Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Fri, 28 Jun 2024 18:55:58 +0200 Subject: [PATCH 06/10] refactor node.go by switching to a switch --- taskfile/node.go | 34 +++++++++++++++++++++------------- taskfile/node_git.go | 4 ++++ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/taskfile/node.go b/taskfile/node.go index f8f4133e5e..8275e910b0 100644 --- a/taskfile/node.go +++ b/taskfile/node.go @@ -50,28 +50,41 @@ func NewNode( ) (Node, error) { var node Node var err error - isGit, err := isGitNode(entrypoint) + scheme, err := getScheme(entrypoint) if err != nil { return nil, err } - if isGit { + + switch scheme { + case "git": node, err = NewGitNode(entrypoint, dir, insecure, opts...) - } else if getScheme(entrypoint) == "http" || getScheme(entrypoint) == "https" { + case "http", "https": node, err = NewHTTPNode(l, entrypoint, dir, insecure, timeout, opts...) - } else { + default: node, err = NewFileNode(l, entrypoint, dir, opts...) + } + if node.Remote() && !experiments.RemoteTaskfiles.Enabled { return nil, errors.New("task: Remote taskfiles are not enabled. You can read more about this experiment and how to enable it at https://taskfile.dev/experiments/remote-taskfiles") } return node, err } -func getScheme(uri string) string { +func getScheme(uri string) (string, error) { + u, _ := giturls.Parse(uri) + if u == nil { + return "", nil + } + u.Path = strings.TrimSuffix(u.Path, "/") + if strings.HasSuffix(u.Path, ".git") && (u.Scheme == "git" || u.Scheme == "ssh" || u.Scheme == "https" || u.Scheme == "http") { + return "git", nil + } + if i := strings.Index(uri, "://"); i != -1 { - return uri[:i] + return uri[:i], nil } - return "" + return "", nil } func getDefaultDir(entrypoint, dir string) string { @@ -98,10 +111,5 @@ func getDefaultDir(entrypoint, dir string) string { } func isGitNode(entrypoint string) (bool, error) { - u, _ := giturls.Parse(entrypoint) - if u == nil { - return false, nil - } - u.Path = strings.TrimSuffix(u.Path, "/") - return strings.HasSuffix(u.Path, ".git") && (u.Scheme == "git" || u.Scheme == "ssh" || u.Scheme == "https" || u.Scheme == "http"), nil + } diff --git a/taskfile/node_git.go b/taskfile/node_git.go index c8379e2d33..d91c110399 100644 --- a/taskfile/node_git.go +++ b/taskfile/node_git.go @@ -113,3 +113,7 @@ func (node *GitNode) ResolveDir(dir string) (string, error) { entrypointDir := filepath.Dir(node.Dir()) return filepathext.SmartJoin(entrypointDir, path), nil } + +func (node *GitNode) FilenameAndLastDir() (string, string) { + return "", filepath.Base(node.Entrypoint) +} From 1594cc4ca54a4703903ef9187a3a6b1654f0fb11 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Fri, 28 Jun 2024 19:23:00 +0200 Subject: [PATCH 07/10] fix test --- taskfile/node.go | 4 ---- taskfile/node_git.go | 3 +-- taskfile/node_git_test.go | 20 ++++++++++++++++++++ taskfile/node_test.go | 21 +++++++++------------ 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/taskfile/node.go b/taskfile/node.go index 8275e910b0..1d79ac27ce 100644 --- a/taskfile/node.go +++ b/taskfile/node.go @@ -109,7 +109,3 @@ func getDefaultDir(entrypoint, dir string) string { return dir } - -func isGitNode(entrypoint string) (bool, error) { - -} diff --git a/taskfile/node_git.go b/taskfile/node_git.go index d91c110399..6620cb590e 100644 --- a/taskfile/node_git.go +++ b/taskfile/node_git.go @@ -51,7 +51,6 @@ func NewGitNode( if u.Scheme == "http" && !insecure { return nil, &errors.TaskfileNotSecureError{URI: entrypoint} } - return &GitNode{ BaseNode: base, URL: u, @@ -115,5 +114,5 @@ func (node *GitNode) ResolveDir(dir string) (string, error) { } func (node *GitNode) FilenameAndLastDir() (string, string) { - return "", filepath.Base(node.Entrypoint) + return filepath.Base(node.path), filepath.Base(filepath.Dir(node.path)) } diff --git a/taskfile/node_git_test.go b/taskfile/node_git_test.go index 60a44a0ad5..3363ac15d2 100644 --- a/taskfile/node_git_test.go +++ b/taskfile/node_git_test.go @@ -53,3 +53,23 @@ func TestGitNode_httpsWithDir(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "https://github.com/foo/bar.git?ref=main//directory/common.yml", entrypoint) } + +func TestGitNode_FilenameAndDir(t *testing.T) { + node, err := NewGitNode("https://github.com/foo/bar.git?ref=main//directory/Taskfile.yml", "", false) + assert.NoError(t, err) + filename, dir := node.FilenameAndLastDir() + assert.Equal(t, "Taskfile.yml", filename) + assert.Equal(t, "directory", dir) + + node, err = NewGitNode("https://github.com/foo/bar.git?ref=main//Taskfile.yml", "", false) + assert.NoError(t, err) + filename, dir = node.FilenameAndLastDir() + assert.Equal(t, "Taskfile.yml", filename) + assert.Equal(t, ".", dir) + + node, err = NewGitNode("https://github.com/foo/bar.git?ref=main//multiple/directory/Taskfile.yml", "", false) + assert.NoError(t, err) + filename, dir = node.FilenameAndLastDir() + assert.Equal(t, "Taskfile.yml", filename) + assert.Equal(t, "directory", dir) +} diff --git a/taskfile/node_test.go b/taskfile/node_test.go index d46cea577e..77651981a2 100644 --- a/taskfile/node_test.go +++ b/taskfile/node_test.go @@ -6,20 +6,17 @@ import ( "github.com/stretchr/testify/assert" ) -func TestIsGitNode(t *testing.T) { - isGit, err := isGitNode("https://github.com/foo/bar.git") +func TestScheme(t *testing.T) { + scheme, err := getScheme("https://github.com/foo/bar.git") assert.NoError(t, err) - assert.True(t, isGit) - isGit, err = isGitNode("https://github.com/foo/bar.git?ref=v1//taskfile/common.yml") + assert.Equal(t, "git", scheme) + scheme, err = getScheme("https://github.com/foo/bar.git?ref=v1//taskfile/common.yml") assert.NoError(t, err) - assert.True(t, isGit) - isGit, err = isGitNode("git@github.com:foo/bar.git?ref=main//Taskfile.yml") + assert.Equal(t, "git", scheme) + scheme, err = getScheme("git@github.com:foo/bar.git?ref=main//Taskfile.yml") assert.NoError(t, err) - assert.True(t, isGit) -} - -func TestIsNotGitNode(t *testing.T) { - isGit, err := isGitNode("https://github.com/foo/common.yml") + assert.Equal(t, "git", scheme) + scheme, err = getScheme("https://github.com/foo/common.yml") assert.NoError(t, err) - assert.False(t, isGit) + assert.Equal(t, "https", scheme) } From 9d01fc9fff722392f4d44d04c8b81db3051b63c6 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Fri, 28 Jun 2024 19:24:52 +0200 Subject: [PATCH 08/10] chore: Empty-Commit to trigger CI From 4754f1ff8640812caf518365a55c45144cd41c62 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Mon, 12 Aug 2024 21:34:15 +0200 Subject: [PATCH 09/10] refactor: use go-getter url --- taskfile/node.go | 8 ++--- taskfile/node_git.go | 16 +++++++--- taskfile/node_git_test.go | 30 +++++++++---------- website/docs/experiments/remote_taskfiles.mdx | 7 +++-- 4 files changed, 34 insertions(+), 27 deletions(-) diff --git a/taskfile/node.go b/taskfile/node.go index 1d79ac27ce..8f09bc5e1d 100644 --- a/taskfile/node.go +++ b/taskfile/node.go @@ -54,7 +54,6 @@ func NewNode( if err != nil { return nil, err } - switch scheme { case "git": node, err = NewGitNode(entrypoint, dir, insecure, opts...) @@ -72,12 +71,11 @@ func NewNode( } func getScheme(uri string) (string, error) { - u, _ := giturls.Parse(uri) + u, err := giturls.Parse(uri) if u == nil { - return "", nil + return "", err } - u.Path = strings.TrimSuffix(u.Path, "/") - if strings.HasSuffix(u.Path, ".git") && (u.Scheme == "git" || u.Scheme == "ssh" || u.Scheme == "https" || u.Scheme == "http") { + if strings.HasSuffix(strings.Split(u.Path, "//")[0], ".git") && (u.Scheme == "git" || u.Scheme == "ssh" || u.Scheme == "https" || u.Scheme == "http") { return "git", nil } diff --git a/taskfile/node_git.go b/taskfile/node_git.go index 6620cb590e..c9a2c45710 100644 --- a/taskfile/node_git.go +++ b/taskfile/node_git.go @@ -39,14 +39,17 @@ func NewGitNode( if err != nil { return nil, err } - refQuery := u.Query().Get("ref") - ref, path := func() (string, string) { - x := strings.Split(refQuery, "//") + + basePath, path := func() (string, string) { + x := strings.Split(u.Path, "//") return x[0], x[1] }() + ref := u.Query().Get("ref") rawUrl := u.String() + u.RawQuery = "" + u.Path = basePath if u.Scheme == "http" && !insecure { return nil, &errors.TaskfileNotSecureError{URI: entrypoint} @@ -74,6 +77,7 @@ func (node *GitNode) Read(_ context.Context) ([]byte, error) { _, err := git.Clone(storer, fs, &git.CloneOptions{ URL: node.URL.String(), ReferenceName: plumbing.ReferenceName(node.ref), + SingleBranch: true, Depth: 1, }) if err != nil { @@ -94,7 +98,11 @@ func (node *GitNode) Read(_ context.Context) ([]byte, error) { func (node *GitNode) ResolveEntrypoint(entrypoint string) (string, error) { dir, _ := filepath.Split(node.path) - return fmt.Sprintf("%s?ref=%s//%s", node.URL, node.ref, filepath.Join(dir, entrypoint)), nil + resolvedEntrypoint := fmt.Sprintf("%s//%s", node.URL, filepath.Join(dir, entrypoint)) + if node.ref != "" { + return fmt.Sprintf("%s//%s?ref=%s", resolvedEntrypoint, node.ref), nil + } + return resolvedEntrypoint, nil } func (node *GitNode) ResolveDir(dir string) (string, error) { diff --git a/taskfile/node_git_test.go b/taskfile/node_git_test.go index 3363ac15d2..bac6862638 100644 --- a/taskfile/node_git_test.go +++ b/taskfile/node_git_test.go @@ -7,67 +7,67 @@ import ( ) func TestGitNode_ssh(t *testing.T) { - node, err := NewGitNode("git@github.com:foo/bar.git?ref=main//Taskfile.yml", "", false) + node, err := NewGitNode("git@github.com:foo/bar.git//Taskfile.yml?ref=main", "", false) assert.NoError(t, err) assert.Equal(t, "main", node.ref) assert.Equal(t, "Taskfile.yml", node.path) - assert.Equal(t, "ssh://git@github.com/foo/bar.git?ref=main//Taskfile.yml", node.rawUrl) + assert.Equal(t, "ssh://git@github.com/foo/bar.git//Taskfile.yml?ref=main", node.rawUrl) assert.Equal(t, "ssh://git@github.com/foo/bar.git", node.URL.String()) entrypoint, err := node.ResolveEntrypoint("common.yml") assert.NoError(t, err) - assert.Equal(t, "ssh://git@github.com/foo/bar.git?ref=main//common.yml", entrypoint) + assert.Equal(t, "ssh://git@github.com/foo/bar.git//common.yml?ref=main", entrypoint) } func TestGitNode_sshWithDir(t *testing.T) { - node, err := NewGitNode("git@github.com:foo/bar.git?ref=main//directory/Taskfile.yml", "", false) + node, err := NewGitNode("git@github.com:foo/bar.git//directory/Taskfile.yml?ref=main", "", false) assert.NoError(t, err) assert.Equal(t, "main", node.ref) assert.Equal(t, "directory/Taskfile.yml", node.path) - assert.Equal(t, "ssh://git@github.com/foo/bar.git?ref=main//directory/Taskfile.yml", node.rawUrl) + assert.Equal(t, "ssh://git@github.com/foo/bar.git//directory/Taskfile.yml?ref=main", node.rawUrl) assert.Equal(t, "ssh://git@github.com/foo/bar.git", node.URL.String()) entrypoint, err := node.ResolveEntrypoint("common.yml") assert.NoError(t, err) - assert.Equal(t, "ssh://git@github.com/foo/bar.git?ref=main//directory/common.yml", entrypoint) + assert.Equal(t, "ssh://git@github.com/foo/bar.git//directory/common.yml?ref=main", entrypoint) } func TestGitNode_https(t *testing.T) { - node, err := NewGitNode("https://github.com/foo/bar.git?ref=main//Taskfile.yml", "", false) + node, err := NewGitNode("https://github.com/foo/bar.git//Taskfile.yml?ref=main", "", false) assert.NoError(t, err) assert.Equal(t, "main", node.ref) assert.Equal(t, "Taskfile.yml", node.path) - assert.Equal(t, "https://github.com/foo/bar.git?ref=main//Taskfile.yml", node.rawUrl) + assert.Equal(t, "https://github.com/foo/bar.git//Taskfile.yml?ref=main", node.rawUrl) assert.Equal(t, "https://github.com/foo/bar.git", node.URL.String()) entrypoint, err := node.ResolveEntrypoint("common.yml") assert.NoError(t, err) - assert.Equal(t, "https://github.com/foo/bar.git?ref=main//common.yml", entrypoint) + assert.Equal(t, "https://github.com/foo/bar.git//common.yml?ref=main", entrypoint) } func TestGitNode_httpsWithDir(t *testing.T) { - node, err := NewGitNode("https://github.com/foo/bar.git?ref=main//directory/Taskfile.yml", "", false) + node, err := NewGitNode("https://github.com/foo/bar.git//directory/Taskfile.yml?ref=main", "", false) assert.NoError(t, err) assert.Equal(t, "main", node.ref) assert.Equal(t, "directory/Taskfile.yml", node.path) - assert.Equal(t, "https://github.com/foo/bar.git?ref=main//directory/Taskfile.yml", node.rawUrl) + assert.Equal(t, "https://github.com/foo/bar.git//directory/Taskfile.yml?ref=main", node.rawUrl) assert.Equal(t, "https://github.com/foo/bar.git", node.URL.String()) entrypoint, err := node.ResolveEntrypoint("common.yml") assert.NoError(t, err) - assert.Equal(t, "https://github.com/foo/bar.git?ref=main//directory/common.yml", entrypoint) + assert.Equal(t, "https://github.com/foo/bar.git//directory/common.yml?ref=main", entrypoint) } func TestGitNode_FilenameAndDir(t *testing.T) { - node, err := NewGitNode("https://github.com/foo/bar.git?ref=main//directory/Taskfile.yml", "", false) + node, err := NewGitNode("https://github.com/foo/bar.git//directory/Taskfile.yml?ref=main", "", false) assert.NoError(t, err) filename, dir := node.FilenameAndLastDir() assert.Equal(t, "Taskfile.yml", filename) assert.Equal(t, "directory", dir) - node, err = NewGitNode("https://github.com/foo/bar.git?ref=main//Taskfile.yml", "", false) + node, err = NewGitNode("https://github.com/foo/bar.git//Taskfile.yml?ref=main", "", false) assert.NoError(t, err) filename, dir = node.FilenameAndLastDir() assert.Equal(t, "Taskfile.yml", filename) assert.Equal(t, ".", dir) - node, err = NewGitNode("https://github.com/foo/bar.git?ref=main//multiple/directory/Taskfile.yml", "", false) + node, err = NewGitNode("https://github.com/foo/bar.git//multiple/directory/Taskfile.yml?ref=main", "", false) assert.NoError(t, err) filename, dir = node.FilenameAndLastDir() assert.Equal(t, "Taskfile.yml", filename) diff --git a/website/docs/experiments/remote_taskfiles.mdx b/website/docs/experiments/remote_taskfiles.mdx index 5fd3733d2b..45e6617edf 100644 --- a/website/docs/experiments/remote_taskfiles.mdx +++ b/website/docs/experiments/remote_taskfiles.mdx @@ -64,10 +64,11 @@ includes: ## Git nodes -You can also include a Taskfile from a Git node. We currently support ssh-style and http / https addresses like `git@example.com/foo/bar?ref=v1//Taskfiles.yml` and `https://example.com/foo/bar.git?ref=v1//Taskfiles.yml`. +You can also include a Taskfile from a Git node. We currently support ssh-style and http / https addresses like `git@example.com/foo/bar.git//Taskfiles.yml?ref=v1` and `https://example.com/foo/bar.git//Taskfiles.yml?ref=v1`. -You need to follow this pattern : `.git?ref=//`. -The `ref` parameter can be a branch name or a tag, and the `path` is the path to the Taskfile in the repository. +You need to follow this pattern : `.git//?ref=`. +The `ref` parameter, optional, can be a branch name or a tag, if not provided it'll pick up the default branch. +The `path` is the path to the Taskfile in the repository. If you want to use the SSH protocol, you need to make sure that your ssh-agent has your private ssh keys added so that they can be used during authentication. From cea84c25ce391bdb0044ab1d421cc599924257c9 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Sat, 14 Sep 2024 12:21:21 +0200 Subject: [PATCH 10/10] go mod tidy --- go.mod | 12 +++++------- go.sum | 46 +++++++++++++++++++++++--------------------- taskfile/node_git.go | 2 +- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index 697ab59869..19d436d8f1 100644 --- a/go.mod +++ b/go.mod @@ -50,13 +50,11 @@ require ( github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/skeema/knownhosts v1.2.2 // indirect github.com/stretchr/objx v0.5.2 // indirect - golang.org/x/sys v0.25.0 // indirect - gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.22.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/tools v0.17.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/tools v0.21.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect ) diff --git a/go.sum b/go.sum index 6e7d730a1f..0cea97a66a 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Ladicle/tabwriter v1.0.0 h1:DZQqPvMumBDwVNElso13afjYLNp0Z7pHqHnu0r4t9Dg= github.com/Ladicle/tabwriter v1.0.0/go.mod h1:c4MdCjxQyTbGuQO/gvqJ+IA/89UEwrsD6hUCW98dyp4= -github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= -github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= +github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= @@ -40,8 +40,6 @@ github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= -github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= -github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= @@ -52,10 +50,12 @@ github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMj github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= +github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= +github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/go-task/template v0.0.0-20240602015157-960e6f576656 h1:knZZ4zVdTBQnevBz0zSES++4Mr7wr+cHopLvHabIgkA= -github.com/go-task/template v0.0.0-20240602015157-960e6f576656/go.mod h1:RgwRaZK+kni/hJJ7/AaOE2lPQFPbAdji/DyhC6pxo4k= +github.com/go-task/template v0.1.0 h1:ym/r2G937RZA1bsgiWedNnY9e5kxDT+3YcoAnuIetTE= +github.com/go-task/template v0.1.0/go.mod h1:RgwRaZK+kni/hJJ7/AaOE2lPQFPbAdji/DyhC6pxo4k= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -86,6 +86,8 @@ github.com/mattn/go-zglob v0.0.6 h1:mP8RnmCgho4oaUYDIDn6GNxYk+qJGUs8fJLn+twYj2A= github.com/mattn/go-zglob v0.0.6/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY= github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= +github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= +github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= @@ -132,12 +134,12 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -145,13 +147,13 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -166,15 +168,15 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -182,14 +184,14 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/taskfile/node_git.go b/taskfile/node_git.go index c9a2c45710..26d287a129 100644 --- a/taskfile/node_git.go +++ b/taskfile/node_git.go @@ -100,7 +100,7 @@ func (node *GitNode) ResolveEntrypoint(entrypoint string) (string, error) { dir, _ := filepath.Split(node.path) resolvedEntrypoint := fmt.Sprintf("%s//%s", node.URL, filepath.Join(dir, entrypoint)) if node.ref != "" { - return fmt.Sprintf("%s//%s?ref=%s", resolvedEntrypoint, node.ref), nil + return fmt.Sprintf("%s?ref=%s", resolvedEntrypoint, node.ref), nil } return resolvedEntrypoint, nil }