vendor: github.com/hashicorp/go-getter@v1.1.0

go get github.com/hashicorp/go-getter@v1.1.0
go mod tidy
go mod vendor
This commit is contained in:
Radek Simko 2019-02-21 08:52:47 +00:00
parent 725dfe8a54
commit b43e5e83f5
No known key found for this signature in database
GPG Key ID: 1F1C84FE689A88D7
44 changed files with 1375 additions and 381 deletions

10
go.mod
View File

@ -18,7 +18,6 @@ require (
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect
github.com/armon/go-radix v1.0.0 // indirect github.com/armon/go-radix v1.0.0 // indirect
github.com/aws/aws-sdk-go v1.16.36 github.com/aws/aws-sdk-go v1.16.36
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/blang/semver v3.5.1+incompatible github.com/blang/semver v3.5.1+incompatible
github.com/boltdb/bolt v1.3.1 // indirect github.com/boltdb/bolt v1.3.1 // indirect
@ -52,7 +51,7 @@ require (
github.com/hashicorp/go-azure-helpers v0.0.0-20190129193224-166dfd221bb2 github.com/hashicorp/go-azure-helpers v0.0.0-20190129193224-166dfd221bb2
github.com/hashicorp/go-checkpoint v0.5.0 github.com/hashicorp/go-checkpoint v0.5.0
github.com/hashicorp/go-cleanhttp v0.5.0 github.com/hashicorp/go-cleanhttp v0.5.0
github.com/hashicorp/go-getter v0.0.0-20180327010114-90bb99a48d86 github.com/hashicorp/go-getter v1.1.0
github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f
github.com/hashicorp/go-immutable-radix v0.0.0-20180129170900-7f3cd4390caa // indirect github.com/hashicorp/go-immutable-radix v0.0.0-20180129170900-7f3cd4390caa // indirect
github.com/hashicorp/go-msgpack v0.0.0-20150518234257-fa3f63826f7c // indirect github.com/hashicorp/go-msgpack v0.0.0-20150518234257-fa3f63826f7c // indirect
@ -60,11 +59,10 @@ require (
github.com/hashicorp/go-plugin v0.0.0-20190220160451-3f118e8ee104 github.com/hashicorp/go-plugin v0.0.0-20190220160451-3f118e8ee104
github.com/hashicorp/go-retryablehttp v0.5.1 github.com/hashicorp/go-retryablehttp v0.5.1
github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86 // indirect github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86 // indirect
github.com/hashicorp/go-tfe v0.3.8 github.com/hashicorp/go-tfe v0.3.8
github.com/hashicorp/go-uuid v1.0.0 github.com/hashicorp/go-uuid v1.0.0
github.com/hashicorp/go-version v1.0.0 github.com/hashicorp/go-version v1.1.0
github.com/hashicorp/golang-lru v0.5.0 // indirect github.com/hashicorp/golang-lru v0.5.0 // indirect
github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f
github.com/hashicorp/hcl2 v0.0.0-20190214011454-504b92060753 github.com/hashicorp/hcl2 v0.0.0-20190214011454-504b92060753
@ -84,8 +82,7 @@ require (
github.com/masterzen/azure-sdk-for-go v0.0.0-20161014135628-ee4f0065d00c // indirect github.com/masterzen/azure-sdk-for-go v0.0.0-20161014135628-ee4f0065d00c // indirect
github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9 // indirect github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9 // indirect
github.com/masterzen/winrm v0.0.0-20180224160350-7e40f93ae939 github.com/masterzen/winrm v0.0.0-20180224160350-7e40f93ae939
github.com/mattn/go-colorable v0.0.0-20160220075935-9cbef7c35391 github.com/mattn/go-colorable v0.0.9
github.com/mattn/go-isatty v0.0.4 // indirect
github.com/mattn/go-shellwords v1.0.1 github.com/mattn/go-shellwords v1.0.1
github.com/miekg/dns v1.0.8 // indirect github.com/miekg/dns v1.0.8 // indirect
github.com/mitchellh/cli v0.0.0-20171129193617-33edc47170b5 github.com/mitchellh/cli v0.0.0-20171129193617-33edc47170b5
@ -114,7 +111,6 @@ require (
github.com/terraform-providers/terraform-provider-openstack v1.15.0 github.com/terraform-providers/terraform-provider-openstack v1.15.0
github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 // indirect github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 // indirect
github.com/ugorji/go v0.0.0-20180813092308-00b869d2f4a5 // indirect github.com/ugorji/go v0.0.0-20180813092308-00b869d2f4a5 // indirect
github.com/ulikunitz/xz v0.5.4 // indirect
github.com/vmihailenco/msgpack v4.0.1+incompatible // indirect github.com/vmihailenco/msgpack v4.0.1+incompatible // indirect
github.com/xanzy/ssh-agent v0.2.0 github.com/xanzy/ssh-agent v0.2.0
github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18 // indirect github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18 // indirect

26
go.sum
View File

@ -45,6 +45,7 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZ
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
github.com/aws/aws-sdk-go v1.16.36 h1:POeH34ZME++pr7GBGh+ZO6Y5kOwSMQpqp5BGUgooJ6k= github.com/aws/aws-sdk-go v1.16.36 h1:POeH34ZME++pr7GBGh+ZO6Y5kOwSMQpqp5BGUgooJ6k=
github.com/aws/aws-sdk-go v1.16.36/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.16.36/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
@ -59,6 +60,7 @@ github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
github.com/bsm/go-vlq v0.0.0-20150828105119-ec6e8d4f5f4e/go.mod h1:N+BjUcTjSxc2mtRGSCPsat1kze3CUtvJN3/jTXlp29k= github.com/bsm/go-vlq v0.0.0-20150828105119-ec6e8d4f5f4e/go.mod h1:N+BjUcTjSxc2mtRGSCPsat1kze3CUtvJN3/jTXlp29k=
github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20161106042343-c914be64f07d h1:aG5FcWiZTOhPQzYIxwxSR1zEOxzL32fwr1CsaCfhO6w= github.com/chzyer/readline v0.0.0-20161106042343-c914be64f07d h1:aG5FcWiZTOhPQzYIxwxSR1zEOxzL32fwr1CsaCfhO6w=
@ -90,6 +92,7 @@ github.com/dylanmei/iso8601 v0.1.0 h1:812NGQDBcqquTfH5Yeo7lwR0nzx/cKdsmf3qMjPURU
github.com/dylanmei/iso8601 v0.1.0/go.mod h1:w9KhXSgIyROl1DefbMYIE7UVSIvELTbMrCfx+QkYnoQ= github.com/dylanmei/iso8601 v0.1.0/go.mod h1:w9KhXSgIyROl1DefbMYIE7UVSIvELTbMrCfx+QkYnoQ=
github.com/dylanmei/winrmtest v0.0.0-20170819153634-c2fbb09e6c08 h1:0bp6/GrNOrTDtSXe9YYGCwf8jp5Fb/b+4a6MTRm4qzY= github.com/dylanmei/winrmtest v0.0.0-20170819153634-c2fbb09e6c08 h1:0bp6/GrNOrTDtSXe9YYGCwf8jp5Fb/b+4a6MTRm4qzY=
github.com/dylanmei/winrmtest v0.0.0-20170819153634-c2fbb09e6c08/go.mod h1:VBVDFSBXCIW8JaHQpI8lldSKfYaLMzP9oyq6IJ4fhzY= github.com/dylanmei/winrmtest v0.0.0-20170819153634-c2fbb09e6c08/go.mod h1:VBVDFSBXCIW8JaHQpI8lldSKfYaLMzP9oyq6IJ4fhzY=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
@ -156,8 +159,8 @@ github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3m
github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg=
github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig= github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-getter v0.0.0-20180327010114-90bb99a48d86 h1:hLYM35twiyKH44g36g+GFYODcrZQetEAY4+zrJtGea0= github.com/hashicorp/go-getter v1.1.0 h1:iGVeg7L4V5FTFV3D6w+1NAyvth7BIWWSzD60pWloe2Q=
github.com/hashicorp/go-getter v0.0.0-20180327010114-90bb99a48d86/go.mod h1:6rdJFnhkXnzGOJbvkrdv4t9nLwKcVA+tmbQeUlkIzrU= github.com/hashicorp/go-getter v1.1.0/go.mod h1:q+PoBhh16brIKwJS9kt18jEtXHTg2EGkmrA9P7HVS+U=
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f h1:Yv9YzBlAETjy6AOX9eLBZ3nshNVRREgerT/3nvxlGho= github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f h1:Yv9YzBlAETjy6AOX9eLBZ3nshNVRREgerT/3nvxlGho=
github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
@ -184,8 +187,8 @@ github.com/hashicorp/go-tfe v0.3.8 h1:pUqxmnhZ7Dj3biugEEo2oGZ758zVQy70lx8p7p4JRE
github.com/hashicorp/go-tfe v0.3.8/go.mod h1:LHLchj07PCYgQqcyE5Sz+g4zrMNW+nALKbiSNTZedEs= github.com/hashicorp/go-tfe v0.3.8/go.mod h1:LHLchj07PCYgQqcyE5Sz+g4zrMNW+nALKbiSNTZedEs=
github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM= github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.0.0 h1:21MVWPKDphxa7ineQQTrCU5brh7OuVVAzGOCnnCPtE8= github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0=
github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f h1:UdxlrJz4JOnY8W+DbLISwf2B8WXEolNRA8BGCwI9jws= github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f h1:UdxlrJz4JOnY8W+DbLISwf2B8WXEolNRA8BGCwI9jws=
@ -210,6 +213,7 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKe
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
@ -243,10 +247,11 @@ github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9 h1:SmVbOZFWAly
github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc= github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc=
github.com/masterzen/winrm v0.0.0-20180224160350-7e40f93ae939 h1:cRFHA33ER97Xy5jmjS519OXCS/yE3AT3zdbQAg0Z53g= github.com/masterzen/winrm v0.0.0-20180224160350-7e40f93ae939 h1:cRFHA33ER97Xy5jmjS519OXCS/yE3AT3zdbQAg0Z53g=
github.com/masterzen/winrm v0.0.0-20180224160350-7e40f93ae939/go.mod h1:CfZSN7zwz5gJiFhZJz49Uzk7mEBHIceWmbFmYx7Hf7E= github.com/masterzen/winrm v0.0.0-20180224160350-7e40f93ae939/go.mod h1:CfZSN7zwz5gJiFhZJz49Uzk7mEBHIceWmbFmYx7Hf7E=
github.com/mattn/go-colorable v0.0.0-20160220075935-9cbef7c35391 h1:x4vT4RoTH2BNkPx0LgrBKeFuPQPviK1aSAIWG6ruc+Y= github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
github.com/mattn/go-colorable v0.0.0-20160220075935-9cbef7c35391/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-shellwords v1.0.1 h1:2/mQs/EosKUge1MHnAavnrNwa0wLnWDjG4dTYMGf/kI= github.com/mattn/go-shellwords v1.0.1 h1:2/mQs/EosKUge1MHnAavnrNwa0wLnWDjG4dTYMGf/kI=
github.com/mattn/go-shellwords v1.0.1/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-shellwords v1.0.1/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
@ -266,6 +271,8 @@ github.com/mitchellh/go-linereader v0.0.0-20141013185533-07bab5fdd958 h1:wN+5lV3
github.com/mitchellh/go-linereader v0.0.0-20141013185533-07bab5fdd958/go.mod h1:OaY7UOoTkkrX3wRwjpYRKafIkkyeD0UtweSHAWWiqQM= github.com/mitchellh/go-linereader v0.0.0-20141013185533-07bab5fdd958/go.mod h1:OaY7UOoTkkrX3wRwjpYRKafIkkyeD0UtweSHAWWiqQM=
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1:7GoSOOW2jpsfkntVKaS2rAr1TJqfcxotyaUcuxoZSzg= github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1:7GoSOOW2jpsfkntVKaS2rAr1TJqfcxotyaUcuxoZSzg=
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
@ -363,8 +370,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 h1:lYIiVD
github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v0.0.0-20180813092308-00b869d2f4a5 h1:cMjKdf4PxEBN9K5HaD9UMW8gkTbM0kMzkTa9SJe0WNQ= github.com/ugorji/go v0.0.0-20180813092308-00b869d2f4a5 h1:cMjKdf4PxEBN9K5HaD9UMW8gkTbM0kMzkTa9SJe0WNQ=
github.com/ugorji/go v0.0.0-20180813092308-00b869d2f4a5/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= github.com/ugorji/go v0.0.0-20180813092308-00b869d2f4a5/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
github.com/ulikunitz/xz v0.5.4 h1:zATC2OoZ8H1TZll3FpbX+ikwmadbO699PE06cIkm9oU= github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok=
github.com/ulikunitz/xz v0.5.4/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmihailenco/msgpack v4.0.1+incompatible h1:RMF1enSPeKTlXrXdOcqjFUElywVZjjC6pqse21bKbEU= github.com/vmihailenco/msgpack v4.0.1+incompatible h1:RMF1enSPeKTlXrXdOcqjFUElywVZjjC6pqse21bKbEU=
github.com/vmihailenco/msgpack v4.0.1+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.1+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
@ -404,6 +411,7 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181129055619-fae4c4e3ad76 h1:xx5MUFyRQRbPk6VjWjIE1epE/K5AoDD8QUN116NCy8k= golang.org/x/net v0.0.0-20181129055619-fae4c4e3ad76 h1:xx5MUFyRQRbPk6VjWjIE1epE/K5AoDD8QUN116NCy8k=
golang.org/x/net v0.0.0-20181129055619-fae4c4e3ad76/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181129055619-fae4c4e3ad76/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -424,6 +432,7 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc h1:WiYx1rIFmx8c0mXAFtv5D/mHyKe1+jmuP7PViuwqwuQ= golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc h1:WiYx1rIFmx8c0mXAFtv5D/mHyKe1+jmuP7PViuwqwuQ=
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
@ -461,6 +470,7 @@ google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 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 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-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=

View File

@ -9,15 +9,16 @@ addons:
language: go language: go
os:
- linux
- osx
go: go:
- 1.8.x - "1.11.x"
- 1.9.x
- master before_script:
- go build ./cmd/go-getter
branches: branches:
only: only:
- master - master
matrix:
allow_failures:
- go: master

View File

@ -97,7 +97,7 @@ would download the given HTTP URL using the Git protocol.
Forced protocols will also override any detectors. Forced protocols will also override any detectors.
In the absense of a forced protocol, detectors may be run on the URL, transforming In the absence of a forced protocol, detectors may be run on the URL, transforming
the protocol anyways. The above example would've used the Git protocol either the protocol anyways. The above example would've used the Git protocol either
way since the Git detector would've detected it was a GitHub URL. way since the Git detector would've detected it was a GitHub URL.
@ -155,20 +155,44 @@ For file downloads of any protocol, go-getter can automatically verify
a checksum for you. Note that checksumming only works for downloading files, a checksum for you. Note that checksumming only works for downloading files,
not directories, but checksumming will work for any protocol. not directories, but checksumming will work for any protocol.
To checksum a file, append a `checksum` query parameter to the URL. To checksum a file, append a `checksum` query parameter to the URL. go-getter
The paramter value should be in the format of `type:value`, where will parse out this query parameter automatically and use it to verify the
type is "md5", "sha1", "sha256", or "sha512". The "value" should be checksum. The parameter value can be in the format of `type:value` or just
the actual checksum value. go-getter will parse out this query parameter `value`, where type is "md5", "sha1", "sha256", "sha512" or "file" . The
automatically and use it to verify the checksum. An example URL "value" should be the actual checksum value or download URL for "file". When
is shown below: `type` part is omitted, type will be guessed based on the length of the
checksum string. Examples:
``` ```
./foo.txt?checksum=md5:b7d96c89d09d9e204f5fedc4d5d55b21 ./foo.txt?checksum=md5:b7d96c89d09d9e204f5fedc4d5d55b21
``` ```
```
./foo.txt?checksum=b7d96c89d09d9e204f5fedc4d5d55b21
```
```
./foo.txt?checksum=file:./foo.txt.sha256sum
```
When checksumming from a file - ex: with `checksum=file:url` - go-getter will
get the file linked in the URL after `file:` using the same configuration. For
example, in `file:http://releases.ubuntu.com/cosmic/MD5SUMS` go-getter will
download a checksum file under the aforementioned url using the http protocol.
All protocols supported by go-getter can be used. The checksum file will be
downloaded in a temporary file then parsed. The destination of the temporary
file can be changed by setting system specific environment variables: `TMPDIR`
for unix; `TMP`, `TEMP` or `USERPROFILE` on windows. Read godoc of
[os.TempDir](https://golang.org/pkg/os/#TempDir) for more information on the
temporary directory selection. Content of files are expected to be BSD or GNU
style. Once go-getter is done with the checksum file; it is deleted.
The checksum query parameter is never sent to the backend protocol The checksum query parameter is never sent to the backend protocol
implementation. It is used at a higher level by go-getter itself. implementation. It is used at a higher level by go-getter itself.
If the destination file exists and the checksums match: download
will be skipped.
### Unarchiving ### Unarchiving
go-getter will automatically unarchive files into a file or directory go-getter will automatically unarchive files into a file or directory
@ -215,11 +239,12 @@ from the URL before going to the final protocol downloader.
## Protocol-Specific Options ## Protocol-Specific Options
This section documents the protocol-specific options that can be specified This section documents the protocol-specific options that can be specified for
for go-getter. These options should be appended to the input as normal query go-getter. These options should be appended to the input as normal query
parameters. Depending on the usage of go-getter, applications may provide parameters ([HTTP headers](#headers) are an exception to this, however).
alternate ways of inputting options. For example, [Nomad](https://www.nomadproject.io) Depending on the usage of go-getter, applications may provide alternate ways of
provides a nice options block for specifying options rather than in the URL. inputting options. For example, [Nomad](https://www.nomadproject.io) provides a
nice options block for specifying options rather than in the URL.
## General (All Protocols) ## General (All Protocols)
@ -251,6 +276,9 @@ None
**Note**: Git 2.3+ is required to use this feature. **Note**: Git 2.3+ is required to use this feature.
* `depth` - The Git clone depth. The provided number specifies the last `n`
revisions to clone from the repository.
### Mercurial (`hg`) ### Mercurial (`hg`)
* `rev` - The Mercurial revision to checkout. * `rev` - The Mercurial revision to checkout.
@ -263,6 +291,13 @@ To use HTTP basic authentication with go-getter, simply prepend `username:passwo
hostname in the URL such as `https://Aladdin:OpenSesame@www.example.com/index.html`. All special hostname in the URL such as `https://Aladdin:OpenSesame@www.example.com/index.html`. All special
characters, including the username and password, must be URL encoded. characters, including the username and password, must be URL encoded.
#### Headers
Optional request headers can be added by supplying them in a custom
[`HttpGetter`](https://godoc.org/github.com/hashicorp/go-getter#HttpGetter)
(_not_ as query parameters like most other options). These headers will be sent
out on every request the getter in question makes.
### S3 (`s3`) ### S3 (`s3`)
S3 takes various access configurations in the URL. Note that it will also S3 takes various access configurations in the URL. Note that it will also

View File

@ -13,4 +13,4 @@ install:
go get -d -v -t ./... go get -d -v -t ./...
build_script: build_script:
- cmd: go test -v ./... - cmd: go test ./...

291
vendor/github.com/hashicorp/go-getter/checksum.go generated vendored Normal file
View File

@ -0,0 +1,291 @@
package getter
import (
"bufio"
"bytes"
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"encoding/hex"
"fmt"
"hash"
"io"
"net/url"
"os"
"path/filepath"
"strings"
urlhelper "github.com/hashicorp/go-getter/helper/url"
)
// fileChecksum helps verifying the checksum for a file.
type fileChecksum struct {
Type string
Hash hash.Hash
Value []byte
Filename string
}
// checksum is a simple method to compute the checksum of a source file
// and compare it to the given expected value.
func (c *fileChecksum) checksum(source string) error {
f, err := os.Open(source)
if err != nil {
return fmt.Errorf("Failed to open file for checksum: %s", err)
}
defer f.Close()
c.Hash.Reset()
if _, err := io.Copy(c.Hash, f); err != nil {
return fmt.Errorf("Failed to hash: %s", err)
}
if actual := c.Hash.Sum(nil); !bytes.Equal(actual, c.Value) {
return fmt.Errorf(
"Checksums did not match.\nExpected: %s\nGot: %s",
hex.EncodeToString(c.Value),
hex.EncodeToString(actual))
}
return nil
}
// extractChecksum will return a fileChecksum based on the 'checksum'
// parameter of u.
// ex:
// http://hashicorp.com/terraform?checksum=<checksumValue>
// http://hashicorp.com/terraform?checksum=<checksumType>:<checksumValue>
// http://hashicorp.com/terraform?checksum=file:<checksum_url>
// when checksumming from a file, extractChecksum will go get checksum_url
// in a temporary directory, parse the content of the file then delete it.
// Content of files are expected to be BSD style or GNU style.
//
// BSD-style checksum:
// MD5 (file1) = <checksum>
// MD5 (file2) = <checksum>
//
// GNU-style:
// <checksum> file1
// <checksum> *file2
//
// see parseChecksumLine for more detail on checksum file parsing
func (c *Client) extractChecksum(u *url.URL) (*fileChecksum, error) {
q := u.Query()
v := q.Get("checksum")
if v == "" {
return nil, nil
}
vs := strings.SplitN(v, ":", 2)
switch len(vs) {
case 2:
break // good
default:
// here, we try to guess the checksum from it's length
// if the type was not passed
return newChecksumFromValue(v, filepath.Base(u.EscapedPath()))
}
checksumType, checksumValue := vs[0], vs[1]
switch checksumType {
case "file":
return c.checksumFromFile(checksumValue, u)
default:
return newChecksumFromType(checksumType, checksumValue, filepath.Base(u.EscapedPath()))
}
}
func newChecksum(checksumValue, filename string) (*fileChecksum, error) {
c := &fileChecksum{
Filename: filename,
}
var err error
c.Value, err = hex.DecodeString(checksumValue)
if err != nil {
return nil, fmt.Errorf("invalid checksum: %s", err)
}
return c, nil
}
func newChecksumFromType(checksumType, checksumValue, filename string) (*fileChecksum, error) {
c, err := newChecksum(checksumValue, filename)
if err != nil {
return nil, err
}
c.Type = strings.ToLower(checksumType)
switch c.Type {
case "md5":
c.Hash = md5.New()
case "sha1":
c.Hash = sha1.New()
case "sha256":
c.Hash = sha256.New()
case "sha512":
c.Hash = sha512.New()
default:
return nil, fmt.Errorf(
"unsupported checksum type: %s", checksumType)
}
return c, nil
}
func newChecksumFromValue(checksumValue, filename string) (*fileChecksum, error) {
c, err := newChecksum(checksumValue, filename)
if err != nil {
return nil, err
}
switch len(c.Value) {
case md5.Size:
c.Hash = md5.New()
c.Type = "md5"
case sha1.Size:
c.Hash = sha1.New()
c.Type = "sha1"
case sha256.Size:
c.Hash = sha256.New()
c.Type = "sha256"
case sha512.Size:
c.Hash = sha512.New()
c.Type = "sha512"
default:
return nil, fmt.Errorf("Unknown type for checksum %s", checksumValue)
}
return c, nil
}
// checksumsFromFile will return all the fileChecksums found in file
//
// checksumsFromFile will try to guess the hashing algorithm based on content
// of checksum file
//
// checksumsFromFile will only return checksums for files that match file
// behind src
func (c *Client) checksumFromFile(checksumFile string, src *url.URL) (*fileChecksum, error) {
checksumFileURL, err := urlhelper.Parse(checksumFile)
if err != nil {
return nil, err
}
tempfile, err := tmpFile("", filepath.Base(checksumFileURL.Path))
if err != nil {
return nil, err
}
defer os.Remove(tempfile)
c2 := &Client{
Ctx: c.Ctx,
Getters: c.Getters,
Decompressors: c.Decompressors,
Detectors: c.Detectors,
Pwd: c.Pwd,
Dir: false,
Src: checksumFile,
Dst: tempfile,
ProgressListener: c.ProgressListener,
}
if err = c2.Get(); err != nil {
return nil, fmt.Errorf(
"Error downloading checksum file: %s", err)
}
filename := filepath.Base(src.Path)
absPath, err := filepath.Abs(src.Path)
if err != nil {
return nil, err
}
checksumFileDir := filepath.Dir(checksumFileURL.Path)
relpath, err := filepath.Rel(checksumFileDir, absPath)
switch {
case err == nil ||
err.Error() == "Rel: can't make "+absPath+" relative to "+checksumFileDir:
// ex: on windows C:\gopath\...\content.txt cannot be relative to \
// which is okay, may be another expected path will work.
break
default:
return nil, err
}
// possible file identifiers:
options := []string{
filename, // ubuntu-14.04.1-server-amd64.iso
"*" + filename, // *ubuntu-14.04.1-server-amd64.iso Standard checksum
"?" + filename, // ?ubuntu-14.04.1-server-amd64.iso shasum -p
relpath, // dir/ubuntu-14.04.1-server-amd64.iso
"./" + relpath, // ./dir/ubuntu-14.04.1-server-amd64.iso
absPath, // fullpath; set if local
}
f, err := os.Open(tempfile)
if err != nil {
return nil, fmt.Errorf(
"Error opening downloaded file: %s", err)
}
defer f.Close()
rd := bufio.NewReader(f)
for {
line, err := rd.ReadString('\n')
if err != nil {
if err != io.EOF {
return nil, fmt.Errorf(
"Error reading checksum file: %s", err)
}
break
}
checksum, err := parseChecksumLine(line)
if err != nil || checksum == nil {
continue
}
if checksum.Filename == "" {
// filename not sure, let's try
return checksum, nil
}
// make sure the checksum is for the right file
for _, option := range options {
if option != "" && checksum.Filename == option {
// any checksum will work so we return the first one
return checksum, nil
}
}
}
return nil, fmt.Errorf("no checksum found in: %s", checksumFile)
}
// parseChecksumLine takes a line from a checksum file and returns
// checksumType, checksumValue and filename parseChecksumLine guesses the style
// of the checksum BSD vs GNU by splitting the line and by counting the parts.
// of a line.
// for BSD type sums parseChecksumLine guesses the hashing algorithm
// by checking the length of the checksum.
func parseChecksumLine(line string) (*fileChecksum, error) {
parts := strings.Fields(line)
switch len(parts) {
case 4:
// BSD-style checksum:
// MD5 (file1) = <checksum>
// MD5 (file2) = <checksum>
if len(parts[1]) <= 2 ||
parts[1][0] != '(' || parts[1][len(parts[1])-1] != ')' {
return nil, fmt.Errorf(
"Unexpected BSD-style-checksum filename format: %s", line)
}
filename := parts[1][1 : len(parts[1])-1]
return newChecksumFromType(parts[0], parts[3], filename)
case 2:
// GNU-style:
// <checksum> file1
// <checksum> *file2
return newChecksumFromValue(parts[0], parts[1])
case 0:
return nil, nil // empty line
default:
return newChecksumFromValue(parts[0], "")
}
}

View File

@ -1,15 +1,8 @@
package getter package getter
import ( import (
"bytes" "context"
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"encoding/hex"
"fmt" "fmt"
"hash"
"io"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
@ -17,7 +10,7 @@ import (
"strings" "strings"
urlhelper "github.com/hashicorp/go-getter/helper/url" urlhelper "github.com/hashicorp/go-getter/helper/url"
"github.com/hashicorp/go-safetemp" safetemp "github.com/hashicorp/go-safetemp"
) )
// Client is a client for downloading things. // Client is a client for downloading things.
@ -26,6 +19,9 @@ import (
// Using a client directly allows more fine-grained control over how downloading // Using a client directly allows more fine-grained control over how downloading
// is done, as well as customizing the protocols supported. // is done, as well as customizing the protocols supported.
type Client struct { type Client struct {
// Ctx for cancellation
Ctx context.Context
// Src is the source URL to get. // Src is the source URL to get.
// //
// Dst is the path to save the downloaded thing as. If Dir is set to // Dst is the path to save the downloaded thing as. If Dir is set to
@ -62,10 +58,20 @@ type Client struct {
// //
// WARNING: deprecated. If Mode is set, that will take precedence. // WARNING: deprecated. If Mode is set, that will take precedence.
Dir bool Dir bool
// ProgressListener allows to track file downloads.
// By default a no op progress listener is used.
ProgressListener ProgressTracker
Options []ClientOption
} }
// Get downloads the configured source to the destination. // Get downloads the configured source to the destination.
func (c *Client) Get() error { func (c *Client) Get() error {
if err := c.Configure(c.Options...); err != nil {
return err
}
// Store this locally since there are cases we swap this // Store this locally since there are cases we swap this
mode := c.Mode mode := c.Mode
if mode == ClientModeInvalid { if mode == ClientModeInvalid {
@ -76,18 +82,7 @@ func (c *Client) Get() error {
} }
} }
// Default decompressor value src, err := Detect(c.Src, c.Pwd, c.Detectors)
decompressors := c.Decompressors
if decompressors == nil {
decompressors = Decompressors
}
// Detect the URL. This is safe if it is already detected.
detectors := c.Detectors
if detectors == nil {
detectors = Detectors
}
src, err := Detect(c.Src, c.Pwd, detectors)
if err != nil { if err != nil {
return err return err
} }
@ -119,12 +114,7 @@ func (c *Client) Get() error {
force = u.Scheme force = u.Scheme
} }
getters := c.Getters g, ok := c.Getters[force]
if getters == nil {
getters = Getters
}
g, ok := getters[force]
if !ok { if !ok {
return fmt.Errorf( return fmt.Errorf(
"download not supported for scheme '%s'", force) "download not supported for scheme '%s'", force)
@ -150,7 +140,7 @@ func (c *Client) Get() error {
if archiveV == "" { if archiveV == "" {
// We don't appear to... but is it part of the filename? // We don't appear to... but is it part of the filename?
matchingLen := 0 matchingLen := 0
for k, _ := range decompressors { for k := range c.Decompressors {
if strings.HasSuffix(u.Path, "."+k) && len(k) > matchingLen { if strings.HasSuffix(u.Path, "."+k) && len(k) > matchingLen {
archiveV = k archiveV = k
matchingLen = len(k) matchingLen = len(k)
@ -163,7 +153,7 @@ func (c *Client) Get() error {
// real path. // real path.
var decompressDst string var decompressDst string
var decompressDir bool var decompressDir bool
decompressor := decompressors[archiveV] decompressor := c.Decompressors[archiveV]
if decompressor != nil { if decompressor != nil {
// Create a temporary directory to store our archive. We delete // Create a temporary directory to store our archive. We delete
// this at the end of everything. // this at the end of everything.
@ -182,43 +172,15 @@ func (c *Client) Get() error {
mode = ClientModeFile mode = ClientModeFile
} }
// Determine if we have a checksum // Determine checksum if we have one
var checksumHash hash.Hash checksum, err := c.extractChecksum(u)
var checksumValue []byte
if v := q.Get("checksum"); v != "" {
// Delete the query parameter if we have it.
q.Del("checksum")
u.RawQuery = q.Encode()
// Determine the checksum hash type
checksumType := ""
idx := strings.Index(v, ":")
if idx > -1 {
checksumType = v[:idx]
}
switch checksumType {
case "md5":
checksumHash = md5.New()
case "sha1":
checksumHash = sha1.New()
case "sha256":
checksumHash = sha256.New()
case "sha512":
checksumHash = sha512.New()
default:
return fmt.Errorf(
"unsupported checksum type: %s", checksumType)
}
// Get the remainder of the value and parse it into bytes
b, err := hex.DecodeString(v[idx+1:])
if err != nil { if err != nil {
return fmt.Errorf("invalid checksum: %s", err) return fmt.Errorf("invalid checksum: %s", err)
} }
// Set our value // Delete the query parameter if we have it.
checksumValue = b q.Del("checksum")
} u.RawQuery = q.Encode()
if mode == ClientModeAny { if mode == ClientModeAny {
// Ask the getter which client mode to use // Ask the getter which client mode to use
@ -248,16 +210,25 @@ func (c *Client) Get() error {
// If we're not downloading a directory, then just download the file // If we're not downloading a directory, then just download the file
// and return. // and return.
if mode == ClientModeFile { if mode == ClientModeFile {
getFile := true
if checksum != nil {
if err := checksum.checksum(dst); err == nil {
// don't get the file if the checksum of dst is correct
getFile = false
}
}
if getFile {
err := g.GetFile(dst, u) err := g.GetFile(dst, u)
if err != nil { if err != nil {
return err return err
} }
if checksumHash != nil { if checksum != nil {
if err := checksum(dst, checksumHash, checksumValue); err != nil { if err := checksum.checksum(dst); err != nil {
return err return err
} }
} }
}
if decompressor != nil { if decompressor != nil {
// We have a decompressor, so decompress the current destination // We have a decompressor, so decompress the current destination
@ -291,7 +262,7 @@ func (c *Client) Get() error {
if decompressor == nil { if decompressor == nil {
// If we're getting a directory, then this is an error. You cannot // If we're getting a directory, then this is an error. You cannot
// checksum a directory. TODO: test // checksum a directory. TODO: test
if checksumHash != nil { if checksum != nil {
return fmt.Errorf( return fmt.Errorf(
"checksum cannot be specified for directory download") "checksum cannot be specified for directory download")
} }
@ -320,30 +291,7 @@ func (c *Client) Get() error {
return err return err
} }
return copyDir(realDst, subDir, false) return copyDir(c.Ctx, realDst, subDir, false)
}
return nil
}
// checksum is a simple method to compute the checksum of a source file
// and compare it to the given expected value.
func checksum(source string, h hash.Hash, v []byte) error {
f, err := os.Open(source)
if err != nil {
return fmt.Errorf("Failed to open file for checksum: %s", err)
}
defer f.Close()
if _, err := io.Copy(h, f); err != nil {
return fmt.Errorf("Failed to hash: %s", err)
}
if actual := h.Sum(nil); !bytes.Equal(actual, v) {
return fmt.Errorf(
"Checksums did not match.\nExpected: %s\nGot: %s",
hex.EncodeToString(v),
hex.EncodeToString(actual))
} }
return nil return nil

46
vendor/github.com/hashicorp/go-getter/client_option.go generated vendored Normal file
View File

@ -0,0 +1,46 @@
package getter
import "context"
// A ClientOption allows to configure a client
type ClientOption func(*Client) error
// Configure configures a client with options.
func (c *Client) Configure(opts ...ClientOption) error {
if c.Ctx == nil {
c.Ctx = context.Background()
}
c.Options = opts
for _, opt := range opts {
err := opt(c)
if err != nil {
return err
}
}
// Default decompressor values
if c.Decompressors == nil {
c.Decompressors = Decompressors
}
// Default detector values
if c.Detectors == nil {
c.Detectors = Detectors
}
// Default getter values
if c.Getters == nil {
c.Getters = Getters
}
for _, getter := range c.Getters {
getter.SetClient(c)
}
return nil
}
// WithContext allows to pass a context to operation
// in order to be able to cancel a download in progress.
func WithContext(ctx context.Context) func(*Client) error {
return func(c *Client) error {
c.Ctx = ctx
return nil
}
}

View File

@ -0,0 +1,38 @@
package getter
import (
"io"
)
// WithProgress allows for a user to track
// the progress of a download.
// For example by displaying a progress bar with
// current download.
// Not all getters have progress support yet.
func WithProgress(pl ProgressTracker) func(*Client) error {
return func(c *Client) error {
c.ProgressListener = pl
return nil
}
}
// ProgressTracker allows to track the progress of downloads.
type ProgressTracker interface {
// TrackProgress should be called when
// a new object is being downloaded.
// src is the location the file is
// downloaded from.
// currentSize is the current size of
// the file in case it is a partial
// download.
// totalSize is the total size in bytes,
// size can be zero if the file size
// is not known.
// stream is the file being downloaded, every
// written byte will add up to processed size.
//
// TrackProgress returns a ReadCloser that wraps the
// download in progress ( stream ).
// When the download is finished, body shall be closed.
TrackProgress(src string, currentSize, totalSize int64, stream io.ReadCloser) (body io.ReadCloser)
}

14
vendor/github.com/hashicorp/go-getter/common.go generated vendored Normal file
View File

@ -0,0 +1,14 @@
package getter
import (
"io/ioutil"
)
func tmpFile(dir, pattern string) (string, error) {
f, err := ioutil.TempFile(dir, pattern)
if err != nil {
return "", err
}
f.Close()
return f.Name(), nil
}

View File

@ -1,7 +1,7 @@
package getter package getter
import ( import (
"io" "context"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@ -11,7 +11,7 @@ import (
// should already exist. // should already exist.
// //
// If ignoreDot is set to true, then dot-prefixed files/folders are ignored. // If ignoreDot is set to true, then dot-prefixed files/folders are ignored.
func copyDir(dst string, src string, ignoreDot bool) error { func copyDir(ctx context.Context, dst string, src string, ignoreDot bool) error {
src, err := filepath.EvalSymlinks(src) src, err := filepath.EvalSymlinks(src)
if err != nil { if err != nil {
return err return err
@ -66,7 +66,7 @@ func copyDir(dst string, src string, ignoreDot bool) error {
} }
defer dstF.Close() defer dstF.Close()
if _, err := io.Copy(dstF, srcF); err != nil { if _, err := Copy(ctx, dstF, srcF); err != nil {
return err return err
} }

View File

@ -6,6 +6,7 @@ import (
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
"time"
) )
// untar is a shared helper for untarring an archive. The reader should provide // untar is a shared helper for untarring an archive. The reader should provide
@ -14,6 +15,7 @@ func untar(input io.Reader, dst, src string, dir bool) error {
tarR := tar.NewReader(input) tarR := tar.NewReader(input)
done := false done := false
dirHdrs := []*tar.Header{} dirHdrs := []*tar.Header{}
now := time.Now()
for { for {
hdr, err := tarR.Next() hdr, err := tarR.Next()
if err == io.EOF { if err == io.EOF {
@ -95,17 +97,37 @@ func untar(input io.Reader, dst, src string, dir bool) error {
return err return err
} }
// Set the access and modification time // Set the access and modification time if valid, otherwise default to current time
if err := os.Chtimes(path, hdr.AccessTime, hdr.ModTime); err != nil { aTime := now
mTime := now
if hdr.AccessTime.Unix() > 0 {
aTime = hdr.AccessTime
}
if hdr.ModTime.Unix() > 0 {
mTime = hdr.ModTime
}
if err := os.Chtimes(path, aTime, mTime); err != nil {
return err return err
} }
} }
// Adding a file or subdirectory changes the mtime of a directory // Perform a final pass over extracted directories to update metadata
// We therefore wait until we've extracted everything and then set the mtime and atime attributes
for _, dirHdr := range dirHdrs { for _, dirHdr := range dirHdrs {
path := filepath.Join(dst, dirHdr.Name) path := filepath.Join(dst, dirHdr.Name)
if err := os.Chtimes(path, dirHdr.AccessTime, dirHdr.ModTime); err != nil { // Chmod the directory since they might be created before we know the mode flags
if err := os.Chmod(path, dirHdr.FileInfo().Mode()); err != nil {
return err
}
// Set the mtime/atime attributes since they would have been changed during extraction
aTime := now
mTime := now
if dirHdr.AccessTime.Unix() > 0 {
aTime = dirHdr.AccessTime
}
if dirHdr.ModTime.Unix() > 0 {
mTime = dirHdr.ModTime
}
if err := os.Chtimes(path, aTime, mTime); err != nil {
return err return err
} }
} }

View File

@ -28,6 +28,8 @@ type TestDecompressCase struct {
// TestDecompressor is a helper function for testing generic decompressors. // TestDecompressor is a helper function for testing generic decompressors.
func TestDecompressor(t testing.T, d Decompressor, cases []TestDecompressCase) { func TestDecompressor(t testing.T, d Decompressor, cases []TestDecompressCase) {
t.Helper()
for _, tc := range cases { for _, tc := range cases {
t.Logf("Testing: %s", tc.Input) t.Logf("Testing: %s", tc.Input)
@ -72,10 +74,14 @@ func TestDecompressor(t testing.T, d Decompressor, cases []TestDecompressCase) {
if tc.Mtime != nil { if tc.Mtime != nil {
actual := fi.ModTime() actual := fi.ModTime()
if tc.Mtime.Unix() > 0 {
expected := *tc.Mtime expected := *tc.Mtime
if actual != expected { if actual != expected {
t.Fatalf("err %s: expected mtime '%s' for %s, got '%s'", tc.Input, expected.String(), dst, actual.String()) t.Fatalf("err %s: expected mtime '%s' for %s, got '%s'", tc.Input, expected.String(), dst, actual.String())
} }
} else if actual.Unix() <= 0 {
t.Fatalf("err %s: expected mtime to be > 0, got '%s'", actual.String())
}
} }
return return
@ -103,10 +109,15 @@ func TestDecompressor(t testing.T, d Decompressor, cases []TestDecompressCase) {
t.Fatalf("err: %s", err) t.Fatalf("err: %s", err)
} }
actual := fi.ModTime() actual := fi.ModTime()
if tc.Mtime.Unix() > 0 {
expected := *tc.Mtime expected := *tc.Mtime
if actual != expected { if actual != expected {
t.Fatalf("err %s: expected mtime '%s' for %s, got '%s'", tc.Input, expected.String(), path, actual.String()) t.Fatalf("err %s: expected mtime '%s' for %s, got '%s'", tc.Input, expected.String(), path, actual.String())
} }
} else if actual.Unix() < 0 {
t.Fatalf("err %s: expected mtime to be > 0, got '%s'", actual.String())
}
} }
} }
}() }()

View File

@ -23,6 +23,7 @@ var Detectors []Detector
func init() { func init() {
Detectors = []Detector{ Detectors = []Detector{
new(GitHubDetector), new(GitHubDetector),
new(GitDetector),
new(BitBucketDetector), new(BitBucketDetector),
new(S3Detector), new(S3Detector),
new(FileDetector), new(FileDetector),

26
vendor/github.com/hashicorp/go-getter/detect_git.go generated vendored Normal file
View File

@ -0,0 +1,26 @@
package getter
// GitDetector implements Detector to detect Git SSH URLs such as
// git@host.com:dir1/dir2 and converts them to proper URLs.
type GitDetector struct{}
func (d *GitDetector) Detect(src, _ string) (string, bool, error) {
if len(src) == 0 {
return "", false, nil
}
u, err := detectSSH(src)
if err != nil {
return "", true, err
}
if u == nil {
return "", false, nil
}
// We require the username to be "git" to assume that this is a Git URL
if u.User.Username() != "git" {
return "", false, nil
}
return "git::" + u.String(), true, nil
}

View File

@ -17,8 +17,6 @@ func (d *GitHubDetector) Detect(src, _ string) (string, bool, error) {
if strings.HasPrefix(src, "github.com/") { if strings.HasPrefix(src, "github.com/") {
return d.detectHTTP(src) return d.detectHTTP(src)
} else if strings.HasPrefix(src, "git@github.com:") {
return d.detectSSH(src)
} }
return "", false, nil return "", false, nil
@ -47,27 +45,3 @@ func (d *GitHubDetector) detectHTTP(src string) (string, bool, error) {
return "git::" + url.String(), true, nil return "git::" + url.String(), true, nil
} }
func (d *GitHubDetector) detectSSH(src string) (string, bool, error) {
idx := strings.Index(src, ":")
qidx := strings.Index(src, "?")
if qidx == -1 {
qidx = len(src)
}
var u url.URL
u.Scheme = "ssh"
u.User = url.User("git")
u.Host = "github.com"
u.Path = src[idx+1 : qidx]
if qidx < len(src) {
q, err := url.ParseQuery(src[qidx+1:])
if err != nil {
return "", true, fmt.Errorf("error parsing GitHub SSH URL: %s", err)
}
u.RawQuery = q.Encode()
}
return "git::" + u.String(), true, nil
}

49
vendor/github.com/hashicorp/go-getter/detect_ssh.go generated vendored Normal file
View File

@ -0,0 +1,49 @@
package getter
import (
"fmt"
"net/url"
"regexp"
"strings"
)
// Note that we do not have an SSH-getter currently so this file serves
// only to hold the detectSSH helper that is used by other detectors.
// sshPattern matches SCP-like SSH patterns (user@host:path)
var sshPattern = regexp.MustCompile("^(?:([^@]+)@)?([^:]+):/?(.+)$")
// detectSSH determines if the src string matches an SSH-like URL and
// converts it into a net.URL compatible string. This returns nil if the
// string doesn't match the SSH pattern.
//
// This function is tested indirectly via detect_git_test.go
func detectSSH(src string) (*url.URL, error) {
matched := sshPattern.FindStringSubmatch(src)
if matched == nil {
return nil, nil
}
user := matched[1]
host := matched[2]
path := matched[3]
qidx := strings.Index(path, "?")
if qidx == -1 {
qidx = len(path)
}
var u url.URL
u.Scheme = "ssh"
u.User = url.User(user)
u.Host = host
u.Path = path[0:qidx]
if qidx < len(path) {
q, err := url.ParseQuery(path[qidx+1:])
if err != nil {
return nil, fmt.Errorf("error parsing GitHub SSH URL: %s", err)
}
u.RawQuery = q.Encode()
}
return &u, nil
}

View File

@ -41,6 +41,11 @@ type Getter interface {
// ClientMode returns the mode based on the given URL. This is used to // ClientMode returns the mode based on the given URL. This is used to
// allow clients to let the getters decide which mode to use. // allow clients to let the getters decide which mode to use.
ClientMode(*url.URL) (ClientMode, error) ClientMode(*url.URL) (ClientMode, error)
// SetClient allows a getter to know it's client
// in order to access client's Get functions or
// progress tracking.
SetClient(*Client)
} }
// Getters is the mapping of scheme to the Getter implementation that will // Getters is the mapping of scheme to the Getter implementation that will
@ -74,12 +79,12 @@ func init() {
// //
// src is a URL, whereas dst is always just a file path to a folder. This // src is a URL, whereas dst is always just a file path to a folder. This
// folder doesn't need to exist. It will be created if it doesn't exist. // folder doesn't need to exist. It will be created if it doesn't exist.
func Get(dst, src string) error { func Get(dst, src string, opts ...ClientOption) error {
return (&Client{ return (&Client{
Src: src, Src: src,
Dst: dst, Dst: dst,
Dir: true, Dir: true,
Getters: Getters, Options: opts,
}).Get() }).Get()
} }
@ -89,23 +94,23 @@ func Get(dst, src string) error {
// dst must be a directory. If src is a file, it will be downloaded // dst must be a directory. If src is a file, it will be downloaded
// into dst with the basename of the URL. If src is a directory or // into dst with the basename of the URL. If src is a directory or
// archive, it will be unpacked directly into dst. // archive, it will be unpacked directly into dst.
func GetAny(dst, src string) error { func GetAny(dst, src string, opts ...ClientOption) error {
return (&Client{ return (&Client{
Src: src, Src: src,
Dst: dst, Dst: dst,
Mode: ClientModeAny, Mode: ClientModeAny,
Getters: Getters, Options: opts,
}).Get() }).Get()
} }
// GetFile downloads the file specified by src into the path specified by // GetFile downloads the file specified by src into the path specified by
// dst. // dst.
func GetFile(dst, src string) error { func GetFile(dst, src string, opts ...ClientOption) error {
return (&Client{ return (&Client{
Src: src, Src: src,
Dst: dst, Dst: dst,
Dir: false, Dir: false,
Getters: Getters, Options: opts,
}).Get() }).Get()
} }

20
vendor/github.com/hashicorp/go-getter/get_base.go generated vendored Normal file
View File

@ -0,0 +1,20 @@
package getter
import "context"
// getter is our base getter; it regroups
// fields all getters have in common.
type getter struct {
client *Client
}
func (g *getter) SetClient(c *Client) { g.client = c }
// Context tries to returns the Contex from the getter's
// client. otherwise context.Background() is returned.
func (g *getter) Context() context.Context {
if g == nil || g.client == nil {
return context.Background()
}
return g.client.Ctx
}

View File

@ -8,7 +8,11 @@ import (
// FileGetter is a Getter implementation that will download a module from // FileGetter is a Getter implementation that will download a module from
// a file scheme. // a file scheme.
type FileGetter struct { type FileGetter struct {
// Copy, if set to true, will copy data instead of using a symlink getter
// Copy, if set to true, will copy data instead of using a symlink. If
// false, attempts to symlink to speed up the operation and to lower the
// disk space usage. If the symlink fails, may attempt to copy on windows.
Copy bool Copy bool
} }

29
vendor/github.com/hashicorp/go-getter/get_file_copy.go generated vendored Normal file
View File

@ -0,0 +1,29 @@
package getter
import (
"context"
"io"
)
// readerFunc is syntactic sugar for read interface.
type readerFunc func(p []byte) (n int, err error)
func (rf readerFunc) Read(p []byte) (n int, err error) { return rf(p) }
// Copy is a io.Copy cancellable by context
func Copy(ctx context.Context, dst io.Writer, src io.Reader) (int64, error) {
// Copy will call the Reader and Writer interface multiple time, in order
// to copy by chunk (avoiding loading the whole file in memory).
return io.Copy(dst, readerFunc(func(p []byte) (int, error) {
select {
case <-ctx.Done():
// context has been canceled
// stop process and propagate "context canceled" error
return 0, ctx.Err()
default:
// otherwise just run default io.Reader implementation
return src.Read(p)
}
}))
}

View File

@ -4,7 +4,6 @@ package getter
import ( import (
"fmt" "fmt"
"io"
"net/url" "net/url"
"os" "os"
"path/filepath" "path/filepath"
@ -50,6 +49,7 @@ func (g *FileGetter) Get(dst string, u *url.URL) error {
} }
func (g *FileGetter) GetFile(dst string, u *url.URL) error { func (g *FileGetter) GetFile(dst string, u *url.URL) error {
ctx := g.Context()
path := u.Path path := u.Path
if u.RawPath != "" { if u.RawPath != "" {
path = u.RawPath path = u.RawPath
@ -98,6 +98,6 @@ func (g *FileGetter) GetFile(dst string, u *url.URL) error {
} }
defer dstF.Close() defer dstF.Close()
_, err = io.Copy(dstF, srcF) _, err = Copy(ctx, dstF, srcF)
return err return err
} }

View File

@ -4,15 +4,16 @@ package getter
import ( import (
"fmt" "fmt"
"io"
"net/url" "net/url"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strings" "strings"
"syscall"
) )
func (g *FileGetter) Get(dst string, u *url.URL) error { func (g *FileGetter) Get(dst string, u *url.URL) error {
ctx := g.Context()
path := u.Path path := u.Path
if u.RawPath != "" { if u.RawPath != "" {
path = u.RawPath path = u.RawPath
@ -51,7 +52,7 @@ func (g *FileGetter) Get(dst string, u *url.URL) error {
sourcePath := toBackslash(path) sourcePath := toBackslash(path)
// Use mklink to create a junction point // Use mklink to create a junction point
output, err := exec.Command("cmd", "/c", "mklink", "/J", dst, sourcePath).CombinedOutput() output, err := exec.CommandContext(ctx, "cmd", "/c", "mklink", "/J", dst, sourcePath).CombinedOutput()
if err != nil { if err != nil {
return fmt.Errorf("failed to run mklink %v %v: %v %q", dst, sourcePath, err, output) return fmt.Errorf("failed to run mklink %v %v: %v %q", dst, sourcePath, err, output)
} }
@ -60,6 +61,7 @@ func (g *FileGetter) Get(dst string, u *url.URL) error {
} }
func (g *FileGetter) GetFile(dst string, u *url.URL) error { func (g *FileGetter) GetFile(dst string, u *url.URL) error {
ctx := g.Context()
path := u.Path path := u.Path
if u.RawPath != "" { if u.RawPath != "" {
path = u.RawPath path = u.RawPath
@ -92,7 +94,21 @@ func (g *FileGetter) GetFile(dst string, u *url.URL) error {
// If we're not copying, just symlink and we're done // If we're not copying, just symlink and we're done
if !g.Copy { if !g.Copy {
return os.Symlink(path, dst) if err = os.Symlink(path, dst); err == nil {
return err
}
lerr, ok := err.(*os.LinkError)
if !ok {
return err
}
switch lerr.Err {
case syscall.ERROR_PRIVILEGE_NOT_HELD:
// no symlink privilege, let's
// fallback to a copy to avoid an error.
break
default:
return err
}
} }
// Copy // Copy
@ -108,7 +124,7 @@ func (g *FileGetter) GetFile(dst string, u *url.URL) error {
} }
defer dstF.Close() defer dstF.Close()
_, err = io.Copy(dstF, srcF) _, err = Copy(ctx, dstF, srcF)
return err return err
} }

View File

@ -1,6 +1,7 @@
package getter package getter
import ( import (
"context"
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
@ -8,28 +9,34 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"runtime"
"strconv"
"strings" "strings"
urlhelper "github.com/hashicorp/go-getter/helper/url" urlhelper "github.com/hashicorp/go-getter/helper/url"
"github.com/hashicorp/go-safetemp" safetemp "github.com/hashicorp/go-safetemp"
"github.com/hashicorp/go-version" version "github.com/hashicorp/go-version"
) )
// GitGetter is a Getter implementation that will download a module from // GitGetter is a Getter implementation that will download a module from
// a git repository. // a git repository.
type GitGetter struct{} type GitGetter struct {
getter
}
func (g *GitGetter) ClientMode(_ *url.URL) (ClientMode, error) { func (g *GitGetter) ClientMode(_ *url.URL) (ClientMode, error) {
return ClientModeDir, nil return ClientModeDir, nil
} }
func (g *GitGetter) Get(dst string, u *url.URL) error { func (g *GitGetter) Get(dst string, u *url.URL) error {
ctx := g.Context()
if _, err := exec.LookPath("git"); err != nil { if _, err := exec.LookPath("git"); err != nil {
return fmt.Errorf("git must be available and on the PATH") return fmt.Errorf("git must be available and on the PATH")
} }
// Extract some query parameters we use // Extract some query parameters we use
var ref, sshKey string var ref, sshKey string
var depth int
q := u.Query() q := u.Query()
if len(q) > 0 { if len(q) > 0 {
ref = q.Get("ref") ref = q.Get("ref")
@ -38,6 +45,11 @@ func (g *GitGetter) Get(dst string, u *url.URL) error {
sshKey = q.Get("sshkey") sshKey = q.Get("sshkey")
q.Del("sshkey") q.Del("sshkey")
if n, err := strconv.Atoi(q.Get("depth")); err == nil {
depth = n
}
q.Del("depth")
// Copy the URL // Copy the URL
var newU url.URL = *u var newU url.URL = *u
u = &newU u = &newU
@ -78,15 +90,35 @@ func (g *GitGetter) Get(dst string, u *url.URL) error {
} }
} }
// For SSH-style URLs, if they use the SCP syntax of host:path, then
// the URL will be mangled. We detect that here and correct the path.
// Example: host:path/bar will turn into host/path/bar
if u.Scheme == "ssh" {
if idx := strings.Index(u.Host, ":"); idx > -1 {
// Copy the URL so we don't modify the input
var newU url.URL = *u
u = &newU
// Path includes the part after the ':'.
u.Path = u.Host[idx+1:] + u.Path
if u.Path[0] != '/' {
u.Path = "/" + u.Path
}
// Host trims up to the :
u.Host = u.Host[:idx]
}
}
// Clone or update the repository // Clone or update the repository
_, err := os.Stat(dst) _, err := os.Stat(dst)
if err != nil && !os.IsNotExist(err) { if err != nil && !os.IsNotExist(err) {
return err return err
} }
if err == nil { if err == nil {
err = g.update(dst, sshKeyFile, ref) err = g.update(ctx, dst, sshKeyFile, ref, depth)
} else { } else {
err = g.clone(dst, sshKeyFile, u) err = g.clone(ctx, dst, sshKeyFile, u, depth)
} }
if err != nil { if err != nil {
return err return err
@ -100,7 +132,7 @@ func (g *GitGetter) Get(dst string, u *url.URL) error {
} }
// Lastly, download any/all submodules. // Lastly, download any/all submodules.
return g.fetchSubmodules(dst, sshKeyFile) return g.fetchSubmodules(ctx, dst, sshKeyFile, depth)
} }
// GetFile for Git doesn't support updating at this time. It will download // GetFile for Git doesn't support updating at this time. It will download
@ -138,16 +170,23 @@ func (g *GitGetter) checkout(dst string, ref string) error {
return getRunCommand(cmd) return getRunCommand(cmd)
} }
func (g *GitGetter) clone(dst, sshKeyFile string, u *url.URL) error { func (g *GitGetter) clone(ctx context.Context, dst, sshKeyFile string, u *url.URL, depth int) error {
cmd := exec.Command("git", "clone", u.String(), dst) args := []string{"clone"}
if depth > 0 {
args = append(args, "--depth", strconv.Itoa(depth))
}
args = append(args, u.String(), dst)
cmd := exec.CommandContext(ctx, "git", args...)
setupGitEnv(cmd, sshKeyFile) setupGitEnv(cmd, sshKeyFile)
return getRunCommand(cmd) return getRunCommand(cmd)
} }
func (g *GitGetter) update(dst, sshKeyFile, ref string) error { func (g *GitGetter) update(ctx context.Context, dst, sshKeyFile, ref string, depth int) error {
// Determine if we're a branch. If we're NOT a branch, then we just // Determine if we're a branch. If we're NOT a branch, then we just
// switch to master prior to checking out // switch to master prior to checking out
cmd := exec.Command("git", "show-ref", "-q", "--verify", "refs/heads/"+ref) cmd := exec.CommandContext(ctx, "git", "show-ref", "-q", "--verify", "refs/heads/"+ref)
cmd.Dir = dst cmd.Dir = dst
if getRunCommand(cmd) != nil { if getRunCommand(cmd) != nil {
@ -162,15 +201,24 @@ func (g *GitGetter) update(dst, sshKeyFile, ref string) error {
return err return err
} }
if depth > 0 {
cmd = exec.Command("git", "pull", "--depth", strconv.Itoa(depth), "--ff-only")
} else {
cmd = exec.Command("git", "pull", "--ff-only") cmd = exec.Command("git", "pull", "--ff-only")
}
cmd.Dir = dst cmd.Dir = dst
setupGitEnv(cmd, sshKeyFile) setupGitEnv(cmd, sshKeyFile)
return getRunCommand(cmd) return getRunCommand(cmd)
} }
// fetchSubmodules downloads any configured submodules recursively. // fetchSubmodules downloads any configured submodules recursively.
func (g *GitGetter) fetchSubmodules(dst, sshKeyFile string) error { func (g *GitGetter) fetchSubmodules(ctx context.Context, dst, sshKeyFile string, depth int) error {
cmd := exec.Command("git", "submodule", "update", "--init", "--recursive") args := []string{"submodule", "update", "--init", "--recursive"}
if depth > 0 {
args = append(args, "--depth", strconv.Itoa(depth))
}
cmd := exec.CommandContext(ctx, "git", args...)
cmd.Dir = dst cmd.Dir = dst
setupGitEnv(cmd, sshKeyFile) setupGitEnv(cmd, sshKeyFile)
return getRunCommand(cmd) return getRunCommand(cmd)
@ -187,7 +235,7 @@ func setupGitEnv(cmd *exec.Cmd, sshKeyFile string) {
// with versions of Go < 1.9. // with versions of Go < 1.9.
env := os.Environ() env := os.Environ()
for i, v := range env { for i, v := range env {
if strings.HasPrefix(v, gitSSHCommand) { if strings.HasPrefix(v, gitSSHCommand) && len(v) > len(gitSSHCommand) {
sshCmd = []string{v} sshCmd = []string{v}
env[i], env[len(env)-1] = env[len(env)-1], env[i] env[i], env[len(env)-1] = env[len(env)-1], env[i]
@ -202,6 +250,9 @@ func setupGitEnv(cmd *exec.Cmd, sshKeyFile string) {
if sshKeyFile != "" { if sshKeyFile != "" {
// We have an SSH key temp file configured, tell ssh about this. // We have an SSH key temp file configured, tell ssh about this.
if runtime.GOOS == "windows" {
sshKeyFile = strings.Replace(sshKeyFile, `\`, `/`, -1)
}
sshCmd = append(sshCmd, "-i", sshKeyFile) sshCmd = append(sshCmd, "-i", sshKeyFile)
} }
@ -224,11 +275,20 @@ func checkGitVersion(min string) error {
} }
fields := strings.Fields(string(out)) fields := strings.Fields(string(out))
if len(fields) != 3 { if len(fields) < 3 {
return fmt.Errorf("Unexpected 'git version' output: %q", string(out)) return fmt.Errorf("Unexpected 'git version' output: %q", string(out))
} }
v := fields[2]
if runtime.GOOS == "windows" && strings.Contains(v, ".windows.") {
// on windows, git version will return for example:
// git version 2.20.1.windows.1
// Which does not follow the semantic versionning specs
// https://semver.org. We remove that part in order for
// go-version to not error.
v = v[:strings.Index(v, ".windows.")]
}
have, err := version.NewVersion(fields[2]) have, err := version.NewVersion(v)
if err != nil { if err != nil {
return err return err
} }

View File

@ -1,6 +1,7 @@
package getter package getter
import ( import (
"context"
"fmt" "fmt"
"net/url" "net/url"
"os" "os"
@ -9,18 +10,21 @@ import (
"runtime" "runtime"
urlhelper "github.com/hashicorp/go-getter/helper/url" urlhelper "github.com/hashicorp/go-getter/helper/url"
"github.com/hashicorp/go-safetemp" safetemp "github.com/hashicorp/go-safetemp"
) )
// HgGetter is a Getter implementation that will download a module from // HgGetter is a Getter implementation that will download a module from
// a Mercurial repository. // a Mercurial repository.
type HgGetter struct{} type HgGetter struct {
getter
}
func (g *HgGetter) ClientMode(_ *url.URL) (ClientMode, error) { func (g *HgGetter) ClientMode(_ *url.URL) (ClientMode, error) {
return ClientModeDir, nil return ClientModeDir, nil
} }
func (g *HgGetter) Get(dst string, u *url.URL) error { func (g *HgGetter) Get(dst string, u *url.URL) error {
ctx := g.Context()
if _, err := exec.LookPath("hg"); err != nil { if _, err := exec.LookPath("hg"); err != nil {
return fmt.Errorf("hg must be available and on the PATH") return fmt.Errorf("hg must be available and on the PATH")
} }
@ -58,7 +62,7 @@ func (g *HgGetter) Get(dst string, u *url.URL) error {
return err return err
} }
return g.update(dst, newURL, rev) return g.update(ctx, dst, newURL, rev)
} }
// GetFile for Hg doesn't support updating at this time. It will download // GetFile for Hg doesn't support updating at this time. It will download
@ -93,7 +97,7 @@ func (g *HgGetter) GetFile(dst string, u *url.URL) error {
return err return err
} }
fg := &FileGetter{Copy: true} fg := &FileGetter{Copy: true, getter: g.getter}
return fg.GetFile(dst, u) return fg.GetFile(dst, u)
} }
@ -108,13 +112,13 @@ func (g *HgGetter) pull(dst string, u *url.URL) error {
return getRunCommand(cmd) return getRunCommand(cmd)
} }
func (g *HgGetter) update(dst string, u *url.URL, rev string) error { func (g *HgGetter) update(ctx context.Context, dst string, u *url.URL, rev string) error {
args := []string{"update"} args := []string{"update"}
if rev != "" { if rev != "" {
args = append(args, rev) args = append(args, rev)
} }
cmd := exec.Command("hg", args...) cmd := exec.CommandContext(ctx, "hg", args...)
cmd.Dir = dst cmd.Dir = dst
return getRunCommand(cmd) return getRunCommand(cmd)
} }

View File

@ -1,6 +1,7 @@
package getter package getter
import ( import (
"context"
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"io" "io"
@ -8,9 +9,10 @@ import (
"net/url" "net/url"
"os" "os"
"path/filepath" "path/filepath"
"strconv"
"strings" "strings"
"github.com/hashicorp/go-safetemp" safetemp "github.com/hashicorp/go-safetemp"
) )
// HttpGetter is a Getter implementation that will download from an HTTP // HttpGetter is a Getter implementation that will download from an HTTP
@ -18,7 +20,7 @@ import (
// //
// For file downloads, HTTP is used directly. // For file downloads, HTTP is used directly.
// //
// The protocol for downloading a directory from an HTTP endpoing is as follows: // The protocol for downloading a directory from an HTTP endpoint is as follows:
// //
// An HTTP GET request is made to the URL with the additional GET parameter // An HTTP GET request is made to the URL with the additional GET parameter
// "terraform-get=1". This lets you handle that scenario specially if you // "terraform-get=1". This lets you handle that scenario specially if you
@ -34,6 +36,8 @@ import (
// formed URL. The shorthand syntax of "github.com/foo/bar" or relative // formed URL. The shorthand syntax of "github.com/foo/bar" or relative
// paths are not allowed. // paths are not allowed.
type HttpGetter struct { type HttpGetter struct {
getter
// Netrc, if true, will lookup and use auth information found // Netrc, if true, will lookup and use auth information found
// in the user's netrc file if available. // in the user's netrc file if available.
Netrc bool Netrc bool
@ -41,6 +45,12 @@ type HttpGetter struct {
// Client is the http.Client to use for Get requests. // Client is the http.Client to use for Get requests.
// This defaults to a cleanhttp.DefaultClient if left unset. // This defaults to a cleanhttp.DefaultClient if left unset.
Client *http.Client Client *http.Client
// Header contains optional request header fields that should be included
// with every HTTP request. Note that the zero value of this field is nil,
// and as such it needs to be initialized before use, via something like
// make(http.Header).
Header http.Header
} }
func (g *HttpGetter) ClientMode(u *url.URL) (ClientMode, error) { func (g *HttpGetter) ClientMode(u *url.URL) (ClientMode, error) {
@ -51,6 +61,7 @@ func (g *HttpGetter) ClientMode(u *url.URL) (ClientMode, error) {
} }
func (g *HttpGetter) Get(dst string, u *url.URL) error { func (g *HttpGetter) Get(dst string, u *url.URL) error {
ctx := g.Context()
// Copy the URL so we can modify it // Copy the URL so we can modify it
var newU url.URL = *u var newU url.URL = *u
u = &newU u = &newU
@ -72,10 +83,17 @@ func (g *HttpGetter) Get(dst string, u *url.URL) error {
u.RawQuery = q.Encode() u.RawQuery = q.Encode()
// Get the URL // Get the URL
resp, err := g.Client.Get(u.String()) req, err := http.NewRequest("GET", u.String(), nil)
if err != nil { if err != nil {
return err return err
} }
req.Header = g.Header
resp, err := g.Client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close() defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 { if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return fmt.Errorf("bad response code: %d", resp.StatusCode) return fmt.Errorf("bad response code: %d", resp.StatusCode)
@ -99,57 +117,107 @@ func (g *HttpGetter) Get(dst string, u *url.URL) error {
// into a temporary directory, then copy over the proper subdir. // into a temporary directory, then copy over the proper subdir.
source, subDir := SourceDirSubdir(source) source, subDir := SourceDirSubdir(source)
if subDir == "" { if subDir == "" {
return Get(dst, source) var opts []ClientOption
if g.client != nil {
opts = g.client.Options
}
return Get(dst, source, opts...)
} }
// We have a subdir, time to jump some hoops // We have a subdir, time to jump some hoops
return g.getSubdir(dst, source, subDir) return g.getSubdir(ctx, dst, source, subDir)
} }
func (g *HttpGetter) GetFile(dst string, u *url.URL) error { func (g *HttpGetter) GetFile(dst string, src *url.URL) error {
ctx := g.Context()
if g.Netrc { if g.Netrc {
// Add auth from netrc if we can // Add auth from netrc if we can
if err := addAuthFromNetrc(u); err != nil { if err := addAuthFromNetrc(src); err != nil {
return err return err
} }
} }
// Create all the parent directories if needed
if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
return err
}
f, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE, os.FileMode(0666))
if err != nil {
return err
}
defer f.Close()
if g.Client == nil { if g.Client == nil {
g.Client = httpClient g.Client = httpClient
} }
resp, err := g.Client.Get(u.String()) var currentFileSize int64
// We first make a HEAD request so we can check
// if the server supports range queries. If the server/URL doesn't
// support HEAD requests, we just fall back to GET.
req, err := http.NewRequest("HEAD", src.String(), nil)
if err != nil { if err != nil {
return err return err
} }
defer resp.Body.Close() if g.Header != nil {
if resp.StatusCode != 200 { req.Header = g.Header
}
headResp, err := g.Client.Do(req)
if err == nil && headResp != nil {
headResp.Body.Close()
if headResp.StatusCode == 200 {
// If the HEAD request succeeded, then attempt to set the range
// query if we can.
if headResp.Header.Get("Accept-Ranges") == "bytes" {
if fi, err := f.Stat(); err == nil {
if _, err = f.Seek(0, os.SEEK_END); err == nil {
req.Header.Set("Range", fmt.Sprintf("bytes=%d-", fi.Size()))
currentFileSize = fi.Size()
totalFileSize, _ := strconv.ParseInt(headResp.Header.Get("Content-Length"), 10, 64)
if currentFileSize >= totalFileSize {
// file already present
return nil
}
}
}
}
}
}
req.Method = "GET"
resp, err := g.Client.Do(req)
if err != nil {
return err
}
switch resp.StatusCode {
case http.StatusOK, http.StatusPartialContent:
// all good
default:
resp.Body.Close()
return fmt.Errorf("bad response code: %d", resp.StatusCode) return fmt.Errorf("bad response code: %d", resp.StatusCode)
} }
// Create all the parent directories body := resp.Body
if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
return err
}
f, err := os.Create(dst) if g.client != nil && g.client.ProgressListener != nil {
if err != nil { // track download
return err fn := filepath.Base(src.EscapedPath())
body = g.client.ProgressListener.TrackProgress(fn, currentFileSize, currentFileSize+resp.ContentLength, resp.Body)
} }
defer body.Close()
n, err := io.Copy(f, resp.Body) n, err := Copy(ctx, f, body)
if err == nil && n < resp.ContentLength { if err == nil && n < resp.ContentLength {
err = io.ErrShortWrite err = io.ErrShortWrite
} }
if err1 := f.Close(); err == nil {
err = err1
}
return err return err
} }
// getSubdir downloads the source into the destination, but with // getSubdir downloads the source into the destination, but with
// the proper subdir. // the proper subdir.
func (g *HttpGetter) getSubdir(dst, source, subDir string) error { func (g *HttpGetter) getSubdir(ctx context.Context, dst, source, subDir string) error {
// Create a temporary directory to store the full source. This has to be // Create a temporary directory to store the full source. This has to be
// a non-existent directory. // a non-existent directory.
td, tdcloser, err := safetemp.Dir("", "getter") td, tdcloser, err := safetemp.Dir("", "getter")
@ -158,8 +226,12 @@ func (g *HttpGetter) getSubdir(dst, source, subDir string) error {
} }
defer tdcloser.Close() defer tdcloser.Close()
var opts []ClientOption
if g.client != nil {
opts = g.client.Options
}
// Download that into the given directory // Download that into the given directory
if err := Get(td, source); err != nil { if err := Get(td, source, opts...); err != nil {
return err return err
} }
@ -185,7 +257,7 @@ func (g *HttpGetter) getSubdir(dst, source, subDir string) error {
return err return err
} }
return copyDir(dst, sourcePath, false) return copyDir(ctx, dst, sourcePath, false)
} }
// parseMeta looks for the first meta tag in the given reader that // parseMeta looks for the first meta tag in the given reader that

View File

@ -6,6 +6,8 @@ import (
// MockGetter is an implementation of Getter that can be used for tests. // MockGetter is an implementation of Getter that can be used for tests.
type MockGetter struct { type MockGetter struct {
getter
// Proxy, if set, will be called after recording the calls below. // Proxy, if set, will be called after recording the calls below.
// If it isn't set, then the *Err values will be returned. // If it isn't set, then the *Err values will be returned.
Proxy Getter Proxy Getter

View File

@ -1,8 +1,8 @@
package getter package getter
import ( import (
"context"
"fmt" "fmt"
"io"
"net/url" "net/url"
"os" "os"
"path/filepath" "path/filepath"
@ -18,7 +18,9 @@ import (
// S3Getter is a Getter implementation that will download a module from // S3Getter is a Getter implementation that will download a module from
// a S3 bucket. // a S3 bucket.
type S3Getter struct{} type S3Getter struct {
getter
}
func (g *S3Getter) ClientMode(u *url.URL) (ClientMode, error) { func (g *S3Getter) ClientMode(u *url.URL) (ClientMode, error) {
// Parse URL // Parse URL
@ -60,6 +62,8 @@ func (g *S3Getter) ClientMode(u *url.URL) (ClientMode, error) {
} }
func (g *S3Getter) Get(dst string, u *url.URL) error { func (g *S3Getter) Get(dst string, u *url.URL) error {
ctx := g.Context()
// Parse URL // Parse URL
region, bucket, path, _, creds, err := g.parseUrl(u) region, bucket, path, _, creds, err := g.parseUrl(u)
if err != nil { if err != nil {
@ -124,7 +128,7 @@ func (g *S3Getter) Get(dst string, u *url.URL) error {
} }
objDst = filepath.Join(dst, objDst) objDst = filepath.Join(dst, objDst)
if err := g.getObject(client, objDst, bucket, objPath, ""); err != nil { if err := g.getObject(ctx, client, objDst, bucket, objPath, ""); err != nil {
return err return err
} }
} }
@ -134,6 +138,7 @@ func (g *S3Getter) Get(dst string, u *url.URL) error {
} }
func (g *S3Getter) GetFile(dst string, u *url.URL) error { func (g *S3Getter) GetFile(dst string, u *url.URL) error {
ctx := g.Context()
region, bucket, path, version, creds, err := g.parseUrl(u) region, bucket, path, version, creds, err := g.parseUrl(u)
if err != nil { if err != nil {
return err return err
@ -142,10 +147,10 @@ func (g *S3Getter) GetFile(dst string, u *url.URL) error {
config := g.getAWSConfig(region, u, creds) config := g.getAWSConfig(region, u, creds)
sess := session.New(config) sess := session.New(config)
client := s3.New(sess) client := s3.New(sess)
return g.getObject(client, dst, bucket, path, version) return g.getObject(ctx, client, dst, bucket, path, version)
} }
func (g *S3Getter) getObject(client *s3.S3, dst, bucket, key, version string) error { func (g *S3Getter) getObject(ctx context.Context, client *s3.S3, dst, bucket, key, version string) error {
req := &s3.GetObjectInput{ req := &s3.GetObjectInput{
Bucket: aws.String(bucket), Bucket: aws.String(bucket),
Key: aws.String(key), Key: aws.String(key),
@ -170,7 +175,7 @@ func (g *S3Getter) getObject(client *s3.S3, dst, bucket, key, version string) er
} }
defer f.Close() defer f.Close()
_, err = io.Copy(f, resp.Body) _, err = Copy(ctx, f, resp.Body)
return err return err
} }

24
vendor/github.com/hashicorp/go-getter/go.mod generated vendored Normal file
View File

@ -0,0 +1,24 @@
module github.com/hashicorp/go-getter
require (
github.com/aws/aws-sdk-go v1.15.78
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d
github.com/cheggaaa/pb v1.0.27
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.7.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.0
github.com/hashicorp/go-safetemp v1.0.0
github.com/hashicorp/go-version v1.1.0
github.com/mattn/go-colorable v0.0.9 // indirect
github.com/mattn/go-isatty v0.0.4 // indirect
github.com/mattn/go-runewidth v0.0.4 // indirect
github.com/mitchellh/go-homedir v1.0.0
github.com/mitchellh/go-testing-interface v1.0.0
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.2.2 // indirect
github.com/ulikunitz/xz v0.5.5
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a // indirect
golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06 // indirect
golang.org/x/text v0.3.0 // indirect
gopkg.in/cheggaaa/pb.v1 v1.0.27 // indirect
)

44
vendor/github.com/hashicorp/go-getter/go.sum generated vendored Normal file
View File

@ -0,0 +1,44 @@
github.com/aws/aws-sdk-go v1.15.78 h1:LaXy6lWR0YK7LKyuU0QWy2ws/LWTPfYV/UgfiBu4tvY=
github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
github.com/cheggaaa/pb v1.0.27 h1:wIkZHkNfC7R6GI5w7l/PdAdzXzlrbcI3p8OAlnkTsnc=
github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
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/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
github.com/hashicorp/go-version v1.0.0 h1:21MVWPKDphxa7ineQQTrCU5brh7OuVVAzGOCnnCPtE8=
github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0=
github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
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/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok=
github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06 h1:0oC8rFnE+74kEmuHZ46F6KHsMr5Gx2gUQPuNz28iQZM=
golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/cheggaaa/pb.v1 v1.0.27 h1:kJdccidYzt3CaHD1crCFTS1hxyhSi059NhOFUf03YFo=
gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=

View File

@ -11,19 +11,18 @@ func parse(rawURL string) (*url.URL, error) {
// Make sure we're using "/" since URLs are "/"-based. // Make sure we're using "/" since URLs are "/"-based.
rawURL = filepath.ToSlash(rawURL) rawURL = filepath.ToSlash(rawURL)
if len(rawURL) > 1 && rawURL[1] == ':' {
// Assume we're dealing with a drive letter. In which case we
// force the 'file' scheme to avoid "net/url" URL.String() prepending
// our url with "./".
rawURL = "file://" + rawURL
}
u, err := url.Parse(rawURL) u, err := url.Parse(rawURL)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if len(rawURL) > 1 && rawURL[1] == ':' {
// Assume we're dealing with a drive letter file path where the drive
// letter has been parsed into the URL Scheme, and the rest of the path
// has been parsed into the URL Path without the leading ':' character.
u.Path = fmt.Sprintf("%s:%s", string(rawURL[0]), u.Path)
u.Scheme = ""
}
if len(u.Host) > 1 && u.Host[1] == ':' && strings.HasPrefix(rawURL, "file://") { if len(u.Host) > 1 && u.Host[1] == ':' && strings.HasPrefix(rawURL, "file://") {
// Assume we're dealing with a drive letter file path where the drive // Assume we're dealing with a drive letter file path where the drive
// letter has been parsed into the URL Host. // letter has been parsed into the URL Host.

View File

@ -6,18 +6,31 @@ import (
"strings" "strings"
) )
// SourceDirSubdir takes a source and returns a tuple of the URL without // SourceDirSubdir takes a source URL and returns a tuple of the URL without
// the subdir and the URL with the subdir. // the subdir and the subdir.
//
// ex:
// dom.com/path/?q=p => dom.com/path/?q=p, ""
// proto://dom.com/path//*?q=p => proto://dom.com/path?q=p, "*"
// proto://dom.com/path//path2?q=p => proto://dom.com/path?q=p, "path2"
//
func SourceDirSubdir(src string) (string, string) { func SourceDirSubdir(src string) (string, string) {
// Calcaulate an offset to avoid accidentally marking the scheme
// URL might contains another url in query parameters
stop := len(src)
if idx := strings.Index(src, "?"); idx > -1 {
stop = idx
}
// Calculate an offset to avoid accidentally marking the scheme
// as the dir. // as the dir.
var offset int var offset int
if idx := strings.Index(src, "://"); idx > -1 { if idx := strings.Index(src[:stop], "://"); idx > -1 {
offset = idx + 3 offset = idx + 3
} }
// First see if we even have an explicit subdir // First see if we even have an explicit subdir
idx := strings.Index(src[offset:], "//") idx := strings.Index(src[offset:stop], "//")
if idx == -1 { if idx == -1 {
return src, "" return src, ""
} }

View File

@ -10,15 +10,26 @@ import (
) )
// The compiled regular expression used to test the validity of a version. // The compiled regular expression used to test the validity of a version.
var versionRegexp *regexp.Regexp var (
versionRegexp *regexp.Regexp
semverRegexp *regexp.Regexp
)
// The raw regular expression string used for testing the validity // The raw regular expression string used for testing the validity
// of a version. // of a version.
const VersionRegexpRaw string = `v?([0-9]+(\.[0-9]+)*?)` + const (
VersionRegexpRaw string = `v?([0-9]+(\.[0-9]+)*?)` +
`(-([0-9]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)|(-?([A-Za-z\-~]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)))?` + `(-([0-9]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)|(-?([A-Za-z\-~]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)))?` +
`(\+([0-9A-Za-z\-~]+(\.[0-9A-Za-z\-~]+)*))?` + `(\+([0-9A-Za-z\-~]+(\.[0-9A-Za-z\-~]+)*))?` +
`?` `?`
// SemverRegexpRaw requires a separator between version and prerelease
SemverRegexpRaw string = `v?([0-9]+(\.[0-9]+)*?)` +
`(-([0-9]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)|(-([A-Za-z\-~]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)))?` +
`(\+([0-9A-Za-z\-~]+(\.[0-9A-Za-z\-~]+)*))?` +
`?`
)
// Version represents a single version. // Version represents a single version.
type Version struct { type Version struct {
metadata string metadata string
@ -30,12 +41,24 @@ type Version struct {
func init() { func init() {
versionRegexp = regexp.MustCompile("^" + VersionRegexpRaw + "$") versionRegexp = regexp.MustCompile("^" + VersionRegexpRaw + "$")
semverRegexp = regexp.MustCompile("^" + SemverRegexpRaw + "$")
} }
// NewVersion parses the given version and returns a new // NewVersion parses the given version and returns a new
// Version. // Version.
func NewVersion(v string) (*Version, error) { func NewVersion(v string) (*Version, error) {
matches := versionRegexp.FindStringSubmatch(v) return newVersion(v, versionRegexp)
}
// NewSemver parses the given version and returns a new
// Version that adheres strictly to SemVer specs
// https://semver.org/
func NewSemver(v string) (*Version, error) {
return newVersion(v, semverRegexp)
}
func newVersion(v string, pattern *regexp.Regexp) (*Version, error) {
matches := pattern.FindStringSubmatch(v)
if matches == nil { if matches == nil {
return nil, fmt.Errorf("Malformed version: %s", v) return nil, fmt.Errorf("Malformed version: %s", v)
} }

9
vendor/github.com/mattn/go-colorable/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,9 @@
language: go
go:
- tip
before_install:
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
script:
- $HOME/gopath/bin/goveralls -repotoken xnXqRGwgW3SXIguzxf90ZSK1GPYZPaGrw

View File

@ -1,5 +1,10 @@
# go-colorable # go-colorable
[![Godoc Reference](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable)
[![Build Status](https://travis-ci.org/mattn/go-colorable.svg?branch=master)](https://travis-ci.org/mattn/go-colorable)
[![Coverage Status](https://coveralls.io/repos/github/mattn/go-colorable/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-colorable?branch=master)
[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable)
Colorable writer for windows. Colorable writer for windows.
For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.) For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.)

View File

@ -0,0 +1,29 @@
// +build appengine
package colorable
import (
"io"
"os"
_ "github.com/mattn/go-isatty"
)
// NewColorable return new instance of Writer which handle escape sequence.
func NewColorable(file *os.File) io.Writer {
if file == nil {
panic("nil passed instead of *os.File to NewColorable()")
}
return file
}
// NewColorableStdout return new instance of Writer which handle escape sequence for stdout.
func NewColorableStdout() io.Writer {
return os.Stdout
}
// NewColorableStderr return new instance of Writer which handle escape sequence for stderr.
func NewColorableStderr() io.Writer {
return os.Stderr
}

View File

@ -1,12 +1,16 @@
// +build !windows // +build !windows
// +build !appengine
package colorable package colorable
import ( import (
"io" "io"
"os" "os"
_ "github.com/mattn/go-isatty"
) )
// NewColorable return new instance of Writer which handle escape sequence.
func NewColorable(file *os.File) io.Writer { func NewColorable(file *os.File) io.Writer {
if file == nil { if file == nil {
panic("nil passed instead of *os.File to NewColorable()") panic("nil passed instead of *os.File to NewColorable()")
@ -15,10 +19,12 @@ func NewColorable(file *os.File) io.Writer {
return file return file
} }
// NewColorableStdout return new instance of Writer which handle escape sequence for stdout.
func NewColorableStdout() io.Writer { func NewColorableStdout() io.Writer {
return os.Stdout return os.Stdout
} }
// NewColorableStderr return new instance of Writer which handle escape sequence for stderr.
func NewColorableStderr() io.Writer { func NewColorableStderr() io.Writer {
return os.Stderr return os.Stderr
} }

View File

@ -1,8 +1,10 @@
// +build windows
// +build !appengine
package colorable package colorable
import ( import (
"bytes" "bytes"
"fmt"
"io" "io"
"math" "math"
"os" "os"
@ -52,6 +54,11 @@ type consoleScreenBufferInfo struct {
maximumWindowSize coord maximumWindowSize coord
} }
type consoleCursorInfo struct {
size dword
visible int32
}
var ( var (
kernel32 = syscall.NewLazyDLL("kernel32.dll") kernel32 = syscall.NewLazyDLL("kernel32.dll")
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
@ -59,15 +66,20 @@ var (
procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW") procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW")
procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute") procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute")
procGetConsoleCursorInfo = kernel32.NewProc("GetConsoleCursorInfo")
procSetConsoleCursorInfo = kernel32.NewProc("SetConsoleCursorInfo")
procSetConsoleTitle = kernel32.NewProc("SetConsoleTitleW")
) )
// Writer provide colorable Writer to the console
type Writer struct { type Writer struct {
out io.Writer out io.Writer
handle syscall.Handle handle syscall.Handle
lastbuf bytes.Buffer
oldattr word oldattr word
oldpos coord
} }
// NewColorable return new instance of Writer which handle escape sequence from File.
func NewColorable(file *os.File) io.Writer { func NewColorable(file *os.File) io.Writer {
if file == nil { if file == nil {
panic("nil passed instead of *os.File to NewColorable()") panic("nil passed instead of *os.File to NewColorable()")
@ -77,16 +89,17 @@ func NewColorable(file *os.File) io.Writer {
var csbi consoleScreenBufferInfo var csbi consoleScreenBufferInfo
handle := syscall.Handle(file.Fd()) handle := syscall.Handle(file.Fd())
procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
return &Writer{out: file, handle: handle, oldattr: csbi.attributes} return &Writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}}
} else {
return file
} }
return file
} }
// NewColorableStdout return new instance of Writer which handle escape sequence for stdout.
func NewColorableStdout() io.Writer { func NewColorableStdout() io.Writer {
return NewColorable(os.Stdout) return NewColorable(os.Stdout)
} }
// NewColorableStderr return new instance of Writer which handle escape sequence for stderr.
func NewColorableStderr() io.Writer { func NewColorableStderr() io.Writer {
return NewColorable(os.Stderr) return NewColorable(os.Stderr)
} }
@ -350,45 +363,83 @@ var color256 = map[int]int{
255: 0xeeeeee, 255: 0xeeeeee,
} }
// `\033]0;TITLESTR\007`
func doTitleSequence(er *bytes.Reader) error {
var c byte
var err error
c, err = er.ReadByte()
if err != nil {
return err
}
if c != '0' && c != '2' {
return nil
}
c, err = er.ReadByte()
if err != nil {
return err
}
if c != ';' {
return nil
}
title := make([]byte, 0, 80)
for {
c, err = er.ReadByte()
if err != nil {
return err
}
if c == 0x07 || c == '\n' {
break
}
title = append(title, c)
}
if len(title) > 0 {
title8, err := syscall.UTF16PtrFromString(string(title))
if err == nil {
procSetConsoleTitle.Call(uintptr(unsafe.Pointer(title8)))
}
}
return nil
}
// Write write data on console
func (w *Writer) Write(data []byte) (n int, err error) { func (w *Writer) Write(data []byte) (n int, err error) {
var csbi consoleScreenBufferInfo var csbi consoleScreenBufferInfo
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
er := bytes.NewBuffer(data) er := bytes.NewReader(data)
var bw [1]byte
loop: loop:
for { for {
r1, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) c1, err := er.ReadByte()
if r1 == 0 {
break loop
}
c1, _, err := er.ReadRune()
if err != nil { if err != nil {
break loop break loop
} }
if c1 != 0x1b { if c1 != 0x1b {
fmt.Fprint(w.out, string(c1)) bw[0] = c1
w.out.Write(bw[:])
continue continue
} }
c2, _, err := er.ReadRune() c2, err := er.ReadByte()
if err != nil { if err != nil {
w.lastbuf.WriteRune(c1)
break loop break loop
} }
if c2 == ']' {
if err := doTitleSequence(er); err != nil {
break loop
}
continue
}
if c2 != 0x5b { if c2 != 0x5b {
w.lastbuf.WriteRune(c1)
w.lastbuf.WriteRune(c2)
continue continue
} }
var buf bytes.Buffer var buf bytes.Buffer
var m rune var m byte
for { for {
c, _, err := er.ReadRune() c, err := er.ReadByte()
if err != nil { if err != nil {
w.lastbuf.WriteRune(c1)
w.lastbuf.WriteRune(c2)
w.lastbuf.Write(buf.Bytes())
break loop break loop
} }
if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {
@ -398,7 +449,6 @@ loop:
buf.Write([]byte(string(c))) buf.Write([]byte(string(c)))
} }
var csbi consoleScreenBufferInfo
switch m { switch m {
case 'A': case 'A':
n, err = strconv.Atoi(buf.String()) n, err = strconv.Atoi(buf.String())
@ -422,19 +472,16 @@ loop:
continue continue
} }
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
csbi.cursorPosition.x -= short(n) csbi.cursorPosition.x += short(n)
procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
case 'D': case 'D':
n, err = strconv.Atoi(buf.String()) n, err = strconv.Atoi(buf.String())
if err != nil { if err != nil {
continue continue
} }
if n, err = strconv.Atoi(buf.String()); err == nil {
var csbi consoleScreenBufferInfo
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
csbi.cursorPosition.x += short(n) csbi.cursorPosition.x -= short(n)
procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
}
case 'E': case 'E':
n, err = strconv.Atoi(buf.String()) n, err = strconv.Atoi(buf.String())
if err != nil { if err != nil {
@ -459,13 +506,20 @@ loop:
continue continue
} }
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
csbi.cursorPosition.x = short(n) csbi.cursorPosition.x = short(n - 1)
procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
case 'H': case 'H', 'f':
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
if buf.Len() > 0 {
token := strings.Split(buf.String(), ";") token := strings.Split(buf.String(), ";")
if len(token) != 2 { switch len(token) {
case 1:
n1, err := strconv.Atoi(token[0])
if err != nil {
continue continue
} }
csbi.cursorPosition.y = short(n1 - 1)
case 2:
n1, err := strconv.Atoi(token[0]) n1, err := strconv.Atoi(token[0])
if err != nil { if err != nil {
continue continue
@ -474,46 +528,63 @@ loop:
if err != nil { if err != nil {
continue continue
} }
csbi.cursorPosition.x = short(n2) csbi.cursorPosition.x = short(n2 - 1)
csbi.cursorPosition.x = short(n1) csbi.cursorPosition.y = short(n1 - 1)
}
} else {
csbi.cursorPosition.y = 0
}
procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
case 'J': case 'J':
n, err := strconv.Atoi(buf.String()) n := 0
if buf.Len() > 0 {
n, err = strconv.Atoi(buf.String())
if err != nil { if err != nil {
continue continue
} }
}
var count, written dword
var cursor coord var cursor coord
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
switch n { switch n {
case 0: case 0:
cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}
count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x)
case 1: case 1:
cursor = coord{x: csbi.window.left, y: csbi.window.top} cursor = coord{x: csbi.window.left, y: csbi.window.top}
count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.window.top-csbi.cursorPosition.y)*csbi.size.x)
case 2: case 2:
cursor = coord{x: csbi.window.left, y: csbi.window.top} cursor = coord{x: csbi.window.left, y: csbi.window.top}
}
var count, written dword
count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x) count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x)
}
procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
case 'K': case 'K':
n, err := strconv.Atoi(buf.String()) n := 0
if buf.Len() > 0 {
n, err = strconv.Atoi(buf.String())
if err != nil { if err != nil {
continue continue
} }
}
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
var cursor coord var cursor coord
var count, written dword
switch n { switch n {
case 0: case 0:
cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} cursor = coord{x: csbi.cursorPosition.x + 1, y: csbi.cursorPosition.y}
count = dword(csbi.size.x - csbi.cursorPosition.x - 1)
case 1: case 1:
cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y}
count = dword(csbi.size.x - csbi.cursorPosition.x)
case 2: case 2:
cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y}
count = dword(csbi.size.x)
} }
var count, written dword
count = dword(csbi.size.x - csbi.cursorPosition.x)
procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
case 'm': case 'm':
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
attr := csbi.attributes attr := csbi.attributes
cs := buf.String() cs := buf.String()
if cs == "" { if cs == "" {
@ -521,7 +592,7 @@ loop:
continue continue
} }
token := strings.Split(cs, ";") token := strings.Split(cs, ";")
for i := 0; i < len(token); i += 1 { for i := 0; i < len(token); i++ {
ns := token[i] ns := token[i]
if n, err = strconv.Atoi(ns); err == nil { if n, err = strconv.Atoi(ns); err == nil {
switch { switch {
@ -531,12 +602,12 @@ loop:
attr |= foregroundIntensity attr |= foregroundIntensity
case n == 7: case n == 7:
attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)
case 22 == n || n == 25 || n == 25: case n == 22 || n == 25:
attr |= foregroundIntensity attr |= foregroundIntensity
case n == 27: case n == 27:
attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)
case 30 <= n && n <= 37: case 30 <= n && n <= 37:
attr = (attr & backgroundMask) attr &= backgroundMask
if (n-30)&1 != 0 { if (n-30)&1 != 0 {
attr |= foregroundRed attr |= foregroundRed
} }
@ -563,7 +634,7 @@ loop:
attr &= backgroundMask attr &= backgroundMask
attr |= w.oldattr & foregroundMask attr |= w.oldattr & foregroundMask
case 40 <= n && n <= 47: case 40 <= n && n <= 47:
attr = (attr & foregroundMask) attr &= foregroundMask
if (n-40)&1 != 0 { if (n-40)&1 != 0 {
attr |= backgroundRed attr |= backgroundRed
} }
@ -617,9 +688,39 @@ loop:
procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr)) procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr))
} }
} }
case 'h':
var ci consoleCursorInfo
cs := buf.String()
if cs == "5>" {
procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
ci.visible = 0
procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
} else if cs == "?25" {
procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
ci.visible = 1
procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
}
case 'l':
var ci consoleCursorInfo
cs := buf.String()
if cs == "5>" {
procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
ci.visible = 1
procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
} else if cs == "?25" {
procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
ci.visible = 0
procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
}
case 's':
procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
w.oldpos = csbi.cursorPosition
case 'u':
procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&w.oldpos)))
} }
} }
return len(data) - w.lastbuf.Len(), nil
return len(data), nil
} }
type consoleColor struct { type consoleColor struct {
@ -663,22 +764,22 @@ func (c consoleColor) backgroundAttr() (attr word) {
} }
var color16 = []consoleColor{ var color16 = []consoleColor{
consoleColor{0x000000, false, false, false, false}, {0x000000, false, false, false, false},
consoleColor{0x000080, false, false, true, false}, {0x000080, false, false, true, false},
consoleColor{0x008000, false, true, false, false}, {0x008000, false, true, false, false},
consoleColor{0x008080, false, true, true, false}, {0x008080, false, true, true, false},
consoleColor{0x800000, true, false, false, false}, {0x800000, true, false, false, false},
consoleColor{0x800080, true, false, true, false}, {0x800080, true, false, true, false},
consoleColor{0x808000, true, true, false, false}, {0x808000, true, true, false, false},
consoleColor{0xc0c0c0, true, true, true, false}, {0xc0c0c0, true, true, true, false},
consoleColor{0x808080, false, false, false, true}, {0x808080, false, false, false, true},
consoleColor{0x0000ff, false, false, true, true}, {0x0000ff, false, false, true, true},
consoleColor{0x00ff00, false, true, false, true}, {0x00ff00, false, true, false, true},
consoleColor{0x00ffff, false, true, true, true}, {0x00ffff, false, true, true, true},
consoleColor{0xff0000, true, false, false, true}, {0xff0000, true, false, false, true},
consoleColor{0xff00ff, true, false, true, true}, {0xff00ff, true, false, true, true},
consoleColor{0xffff00, true, true, false, true}, {0xffff00, true, true, false, true},
consoleColor{0xffffff, true, true, true, true}, {0xffffff, true, true, true, true},
} }
type hsv struct { type hsv struct {

55
vendor/github.com/mattn/go-colorable/noncolorable.go generated vendored Normal file
View File

@ -0,0 +1,55 @@
package colorable
import (
"bytes"
"io"
)
// NonColorable hold writer but remove escape sequence.
type NonColorable struct {
out io.Writer
}
// NewNonColorable return new instance of Writer which remove escape sequence from Writer.
func NewNonColorable(w io.Writer) io.Writer {
return &NonColorable{out: w}
}
// Write write data on console
func (w *NonColorable) Write(data []byte) (n int, err error) {
er := bytes.NewReader(data)
var bw [1]byte
loop:
for {
c1, err := er.ReadByte()
if err != nil {
break loop
}
if c1 != 0x1b {
bw[0] = c1
w.out.Write(bw[:])
continue
}
c2, err := er.ReadByte()
if err != nil {
break loop
}
if c2 != 0x5b {
continue
}
var buf bytes.Buffer
for {
c, err := er.ReadByte()
if err != nil {
break loop
}
if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {
break
}
buf.Write([]byte(string(c)))
}
}
return len(data), nil
}

View File

@ -0,0 +1 @@
module github.com/mitchellh/go-testing-interface

View File

@ -12,22 +12,23 @@ have been developed over a long time and are highly optimized. However
there are a number of improvements planned and I'm very optimistic about there are a number of improvements planned and I'm very optimistic about
parallel compression and decompression. Stay tuned! parallel compression and decompression. Stay tuned!
# Using the API ## Using the API
The following example program shows how to use the API. The following example program shows how to use the API.
package main ```go
package main
import ( import (
"bytes" "bytes"
"io" "io"
"log" "log"
"os" "os"
"github.com/ulikunitz/xz" "github.com/ulikunitz/xz"
) )
func main() { func main() {
const text = "The quick brown fox jumps over the lazy dog.\n" const text = "The quick brown fox jumps over the lazy dog.\n"
var buf bytes.Buffer var buf bytes.Buffer
// compress text // compress text
@ -49,9 +50,10 @@ The following example program shows how to use the API.
if _, err = io.Copy(os.Stdout, r); err != nil { if _, err = io.Copy(os.Stdout, r); err != nil {
log.Fatalf("io.Copy error %s", err) log.Fatalf("io.Copy error %s", err)
} }
} }
```
# Using the gxz compression tool ## Using the gxz compression tool
The package includes a gxz command line utility for compression and The package includes a gxz command line utility for compression and
decompression. decompression.

View File

@ -86,6 +86,10 @@
## Log ## Log
### 2018-10-28
Release v0.5.5 fixes issues #19 observing ErrLimit outputs.
### 2017-06-05 ### 2017-06-05
Release v0.5.4 fixes issues #15 of another problem with the padding size Release v0.5.4 fixes issues #15 of another problem with the padding size

View File

@ -11,7 +11,7 @@ import (
// opLenMargin provides the upper limit of the number of bytes required // opLenMargin provides the upper limit of the number of bytes required
// to encode a single operation. // to encode a single operation.
const opLenMargin = 10 const opLenMargin = 16
// compressFlags control the compression process. // compressFlags control the compression process.
type compressFlags uint32 type compressFlags uint32

10
vendor/modules.txt vendored
View File

@ -270,7 +270,7 @@ github.com/hashicorp/go-azure-helpers/storage
github.com/hashicorp/go-checkpoint github.com/hashicorp/go-checkpoint
# github.com/hashicorp/go-cleanhttp v0.5.0 # github.com/hashicorp/go-cleanhttp v0.5.0
github.com/hashicorp/go-cleanhttp github.com/hashicorp/go-cleanhttp
# github.com/hashicorp/go-getter v0.0.0-20180327010114-90bb99a48d86 # github.com/hashicorp/go-getter v1.1.0
github.com/hashicorp/go-getter github.com/hashicorp/go-getter
github.com/hashicorp/go-getter/helper/url github.com/hashicorp/go-getter/helper/url
# github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f # github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f
@ -292,7 +292,7 @@ github.com/hashicorp/go-slug
github.com/hashicorp/go-tfe github.com/hashicorp/go-tfe
# github.com/hashicorp/go-uuid v1.0.0 # github.com/hashicorp/go-uuid v1.0.0
github.com/hashicorp/go-uuid github.com/hashicorp/go-uuid
# github.com/hashicorp/go-version v1.0.0 # github.com/hashicorp/go-version v1.1.0
github.com/hashicorp/go-version github.com/hashicorp/go-version
# github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f # github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f
github.com/hashicorp/hcl github.com/hashicorp/hcl
@ -366,7 +366,7 @@ github.com/masterzen/simplexml/dom
# github.com/masterzen/winrm v0.0.0-20180224160350-7e40f93ae939 # github.com/masterzen/winrm v0.0.0-20180224160350-7e40f93ae939
github.com/masterzen/winrm github.com/masterzen/winrm
github.com/masterzen/winrm/soap github.com/masterzen/winrm/soap
# github.com/mattn/go-colorable v0.0.0-20160220075935-9cbef7c35391 # github.com/mattn/go-colorable v0.0.9
github.com/mattn/go-colorable github.com/mattn/go-colorable
# github.com/mattn/go-isatty v0.0.4 # github.com/mattn/go-isatty v0.0.4
github.com/mattn/go-isatty github.com/mattn/go-isatty
@ -382,7 +382,7 @@ github.com/mitchellh/copystructure
github.com/mitchellh/go-homedir github.com/mitchellh/go-homedir
# github.com/mitchellh/go-linereader v0.0.0-20141013185533-07bab5fdd958 # github.com/mitchellh/go-linereader v0.0.0-20141013185533-07bab5fdd958
github.com/mitchellh/go-linereader github.com/mitchellh/go-linereader
# github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 # github.com/mitchellh/go-testing-interface v1.0.0
github.com/mitchellh/go-testing-interface github.com/mitchellh/go-testing-interface
# github.com/mitchellh/go-wordwrap v1.0.0 # github.com/mitchellh/go-wordwrap v1.0.0
github.com/mitchellh/go-wordwrap github.com/mitchellh/go-wordwrap
@ -420,7 +420,7 @@ github.com/svanharmelen/jsonapi
github.com/terraform-providers/terraform-provider-openstack/openstack github.com/terraform-providers/terraform-provider-openstack/openstack
# github.com/ugorji/go v0.0.0-20180813092308-00b869d2f4a5 # github.com/ugorji/go v0.0.0-20180813092308-00b869d2f4a5
github.com/ugorji/go/codec github.com/ugorji/go/codec
# github.com/ulikunitz/xz v0.5.4 # github.com/ulikunitz/xz v0.5.5
github.com/ulikunitz/xz github.com/ulikunitz/xz
github.com/ulikunitz/xz/internal/xlog github.com/ulikunitz/xz/internal/xlog
github.com/ulikunitz/xz/lzma github.com/ulikunitz/xz/lzma