1
0
mirror of https://github.com/openshift/installer.git synced 2026-02-05 15:47:14 +01:00

Bump terraform-exec version

So that we can send terraform debug logs to a file.
This commit is contained in:
Rafael Fonseca
2022-10-28 10:31:04 +02:00
parent b1e2e1b45e
commit 1c69206124
31 changed files with 517 additions and 497 deletions

7
go.mod
View File

@@ -41,7 +41,7 @@ require (
github.com/gophercloud/gophercloud v0.24.0
github.com/gophercloud/utils v0.0.0-20220307143606-8e7800759d16
github.com/h2non/filetype v1.0.12
github.com/hashicorp/terraform-exec v0.16.1
github.com/hashicorp/terraform-exec v0.17.3
github.com/jongio/azidext/go/azidext v0.4.0
github.com/kdomanski/iso9660 v0.2.1
github.com/libvirt/libvirt-go v5.10.0+incompatible
@@ -102,7 +102,7 @@ require (
require (
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371 // indirect
github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace // indirect
github.com/zclconf/go-cty v1.10.0 // indirect
github.com/zclconf/go-cty v1.11.0 // indirect
go.mongodb.org/mongo-driver v1.8.3 // indirect
go.opencensus.io v0.23.0 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
@@ -179,8 +179,7 @@ require (
github.com/hashicorp/go-hclog v1.2.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.0 // indirect
github.com/hashicorp/go-version v1.5.0 // indirect
github.com/hashicorp/hc-install v0.3.2 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/terraform-json v0.14.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect

36
go.sum
View File

@@ -145,9 +145,7 @@ github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy86
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/sprig v2.20.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
@@ -164,7 +162,6 @@ github.com/PaesslerAG/jsonpath v0.1.0/go.mod h1:4BzmtoM/PI8fPO4aQGIusjGxGir2BzcV
github.com/PaesslerAG/jsonpath v0.1.1 h1:c1/AToHQMVsduPAa4Vh6xp2U0evy4t8SWp8imEsylIk=
github.com/PaesslerAG/jsonpath v0.1.1/go.mod h1:lVboNxFGal/VwW6d9JzIy56bUsYAP6tH/x80vjnCseY=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
@@ -175,7 +172,6 @@ github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmx
github.com/a8m/tree v0.0.0-20210115125333-10a5fd5b637d/go.mod h1:FSdwKX97koS5efgm8WevNf7XS3PqtyFkKDDXrz778cg=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/ajeddeloh/go-json v0.0.0-20170920214419-6a2fe990e083/go.mod h1:otnto4/Icqn88WCcM4bhIJNSgsh9VLBuspyyCfvof9c=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@@ -378,7 +374,6 @@ github.com/emicklei/go-restful v2.15.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQm
github.com/emicklei/go-restful/v3 v3.8.0 h1:eCZ8ulSerjdAiaNpF7GxXIE7ZCMo1moN1qX+S609eVw=
github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -426,20 +421,14 @@ github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/go-bindata/go-bindata v3.1.2+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo=
github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/go-critic/go-critic v0.3.5-0.20190526074819-1df300866540/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA=
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34=
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0=
github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4=
github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@@ -833,8 +822,6 @@ github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBt
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
@@ -855,24 +842,23 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.5.0 h1:O293SZ2Eg+AAYijkVK3jR786Am1bhDEh2GHT0tIVE5E=
github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47/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/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hc-install v0.3.2 h1:oiQdJZvXmkNcRcEOOfM5n+VTsvNjWQeOjfAoO6dKSH8=
github.com/hashicorp/hc-install v0.3.2/go.mod h1:xMG6Tr8Fw1WFjlxH0A9v61cW15pFwgEGqEz0V4jisHs=
github.com/hashicorp/hc-install v0.4.0 h1:cZkRFr1WVa0Ty6x5fTvL1TuO1flul231rWkGH92oYYk=
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hashicorp/terraform-exec v0.16.1 h1:NAwZFJW2L2SaCBVZoVaH8LPImLOGbPLkSHy0IYbs2uE=
github.com/hashicorp/terraform-exec v0.16.1/go.mod h1:aj0lVshy8l+MHhFNoijNHtqTJQI3Xlowv5EOsEaGO7M=
github.com/hashicorp/terraform-exec v0.17.3 h1:MX14Kvnka/oWGmIkyuyvL6POx25ZmKrjlaclkx3eErU=
github.com/hashicorp/terraform-exec v0.17.3/go.mod h1:+NELG0EqQekJzhvikkeQsOAZpsw0cv/03rbeQJqscAI=
github.com/hashicorp/terraform-json v0.14.0 h1:sh9iZ1Y8IFJLx+xQiKHGud6/TSUCM0N8e17dKDpqV7s=
github.com/hashicorp/terraform-json v0.14.0/go.mod h1:5A9HIWPkk4e5aeeXIBbkcOvaZbIYnAIkEyqP2pNSckM=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
@@ -898,10 +884,8 @@ github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHF
github.com/jackc/pgtype v1.11.0 h1:u4uiGPz/1hryuXzyaBhSk6dnIyyG2683olG2OV+UUgs=
github.com/jackc/pgx/v4 v4.16.0 h1:4k1tROTJctHotannFYzu77dY3bgtMRymQP7tXQjqpPk=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/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.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas=
@@ -946,7 +930,6 @@ github.com/kdomanski/iso9660 v0.2.1 h1:IepyfCeEqx77rZeOM4XZgWB4XJWEF7Jp+1ehMTrSE
github.com/kdomanski/iso9660 v0.2.1/go.mod h1:LY50s7BlG+ES6V99oxYGd0ub9giLrKdHZb3LLOweBj0=
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
@@ -1011,7 +994,6 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
@@ -1301,7 +1283,6 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg
github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4=
github.com/securego/gosec v0.0.0-20191002120514-e680875ea14d/go.mod h1:w5+eXa0mYznDkHaMCXA4XYffjlH+cy1oyKbfzJXa2Do=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
@@ -1442,7 +1423,6 @@ github.com/vmware/vmw-guestinfo v0.0.0-20170707015358-25eff159a728/go.mod h1:x9o
github.com/vmware/vmw-guestinfo v0.0.0-20220317130741-510905f0efa3/go.mod h1:CSBTxrhePCm0cmXNKDGeu+6bOQzpaEklfCqEpn89JWk=
github.com/vmware/vmw-ovflib v0.0.0-20170608004843-1f217b9dc714/go.mod h1:jiPk45kn7klhByRvUq5i2vo1RtHKBHj+iWGFpxbXuuI=
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
@@ -1469,8 +1449,9 @@ github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0=
github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
github.com/zclconf/go-cty v1.11.0 h1:726SxLdi2SDnjY+BStqB9J1hNp4+2WlzyXLuimibIe0=
github.com/zclconf/go-cty v1.11.0/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA=
github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
@@ -1648,7 +1629,6 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
@@ -1792,12 +1772,10 @@ golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View File

@@ -1,3 +1,16 @@
# 1.6.0 (June 28, 2022)
FEATURES:
- Add `Prerelease` function to `Constraint` to return true if the version includes a prerelease field ([#100](https://github.com/hashicorp/go-version/pull/100))
# 1.5.0 (May 18, 2022)
FEATURES:
- Use `encoding` `TextMarshaler` & `TextUnmarshaler` instead of JSON equivalents ([#95](https://github.com/hashicorp/go-version/pull/95))
- Add JSON handlers to allow parsing from/to JSON ([#93](https://github.com/hashicorp/go-version/pull/93))
# 1.4.0 (January 5, 2022)
FEATURES:

View File

@@ -163,6 +163,12 @@ func (c *Constraint) Check(v *Version) bool {
return c.f(v, c.check)
}
// Prerelease returns true if the version underlying this constraint
// contains a prerelease field.
func (c *Constraint) Prerelease() bool {
return len(c.check.Prerelease()) > 0
}
func (c *Constraint) String() string {
return c.original
}

View File

@@ -1,6 +1,6 @@
package version
const version = "0.16.1"
const version = "0.17.3"
// ModuleVersion returns the current version of the github.com/hashicorp/terraform-exec Go module.
// This is a function to allow for future possible enhancement using debug.BuildInfo.

View File

@@ -1,9 +1,11 @@
package tfexec
import (
"bufio"
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
@@ -17,10 +19,12 @@ import (
const (
checkpointDisableEnvVar = "CHECKPOINT_DISABLE"
cliArgsEnvVar = "TF_CLI_ARGS"
logEnvVar = "TF_LOG"
inputEnvVar = "TF_INPUT"
automationEnvVar = "TF_IN_AUTOMATION"
logEnvVar = "TF_LOG"
logCoreEnvVar = "TF_LOG_CORE"
logPathEnvVar = "TF_LOG_PATH"
logProviderEnvVar = "TF_LOG_PROVIDER"
reattachEnvVar = "TF_REATTACH_PROVIDERS"
appendUserAgentEnvVar = "TF_APPEND_USER_AGENT"
workspaceEnvVar = "TF_WORKSPACE"
@@ -35,8 +39,10 @@ var prohibitedEnvVars = []string{
cliArgsEnvVar,
inputEnvVar,
automationEnvVar,
logPathEnvVar,
logEnvVar,
logCoreEnvVar,
logPathEnvVar,
logProviderEnvVar,
reattachEnvVar,
appendUserAgentEnvVar,
workspaceEnvVar,
@@ -146,11 +152,14 @@ func (tf *Terraform) buildEnv(mergeEnv map[string]string) []string {
if tf.logPath == "" {
// so logging can't pollute our stderr output
env[logEnvVar] = ""
env[logCoreEnvVar] = ""
env[logPathEnvVar] = ""
env[logProviderEnvVar] = ""
} else {
env[logEnvVar] = tf.log
env[logCoreEnvVar] = tf.logCore
env[logPathEnvVar] = tf.logPath
// Log levels other than TRACE are currently unreliable, the CLI recommends using TRACE only.
env[logEnvVar] = "TRACE"
env[logProviderEnvVar] = tf.logProvider
}
// constant automation override env vars
@@ -171,7 +180,7 @@ func (tf *Terraform) buildEnv(mergeEnv map[string]string) []string {
}
func (tf *Terraform) buildTerraformCmd(ctx context.Context, mergeEnv map[string]string, args ...string) *exec.Cmd {
cmd := exec.Command(tf.execPath, args...)
cmd := exec.CommandContext(ctx, tf.execPath, args...)
cmd.Env = tf.buildEnv(mergeEnv)
cmd.Dir = tf.workingDir
@@ -230,3 +239,36 @@ func mergeWriters(writers ...io.Writer) io.Writer {
}
return io.MultiWriter(compact...)
}
func writeOutput(ctx context.Context, r io.ReadCloser, w io.Writer) error {
// ReadBytes will block until bytes are read, which can cause a delay in
// returning even if the command's context has been canceled. Use a separate
// goroutine to prompt ReadBytes to return on cancel
closeCtx, closeCancel := context.WithCancel(ctx)
defer closeCancel()
go func() {
select {
case <-ctx.Done():
r.Close()
case <-closeCtx.Done():
return
}
}()
buf := bufio.NewReader(r)
for {
line, err := buf.ReadBytes('\n')
if len(line) > 0 {
if _, err := w.Write(line); err != nil {
return err
}
}
if err != nil {
if errors.Is(err, io.EOF) {
return nil
}
return err
}
}
}

View File

@@ -7,26 +7,12 @@ import (
"context"
"os/exec"
"strings"
"sync"
)
func (tf *Terraform) runTerraformCmd(ctx context.Context, cmd *exec.Cmd) error {
var errBuf strings.Builder
cmd.Stdout = mergeWriters(cmd.Stdout, tf.stdout)
cmd.Stderr = mergeWriters(cmd.Stderr, tf.stderr, &errBuf)
go func() {
<-ctx.Done()
if ctx.Err() == context.DeadlineExceeded || ctx.Err() == context.Canceled {
if cmd != nil && cmd.Process != nil && cmd.ProcessState != nil {
err := cmd.Process.Kill()
if err != nil {
tf.logger.Printf("error from kill: %s", err)
}
}
}
}()
// check for early cancellation
select {
case <-ctx.Done():
@@ -34,7 +20,52 @@ func (tf *Terraform) runTerraformCmd(ctx context.Context, cmd *exec.Cmd) error {
default:
}
err := cmd.Run()
// Read stdout / stderr logs from pipe instead of setting cmd.Stdout and
// cmd.Stderr because it can cause hanging when killing the command
// https://github.com/golang/go/issues/23019
stdoutWriter := mergeWriters(cmd.Stdout, tf.stdout)
stderrWriter := mergeWriters(tf.stderr, &errBuf)
cmd.Stderr = nil
cmd.Stdout = nil
stdoutPipe, err := cmd.StdoutPipe()
if err != nil {
return err
}
stderrPipe, err := cmd.StderrPipe()
if err != nil {
return err
}
err = cmd.Start()
if err == nil && ctx.Err() != nil {
err = ctx.Err()
}
if err != nil {
return tf.wrapExitError(ctx, err, "")
}
var errStdout, errStderr error
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
errStdout = writeOutput(ctx, stdoutPipe, stdoutWriter)
}()
wg.Add(1)
go func() {
defer wg.Done()
errStderr = writeOutput(ctx, stderrPipe, stderrWriter)
}()
// Reads from pipes must be completed before calling cmd.Wait(). Otherwise
// can cause a race condition
wg.Wait()
err = cmd.Wait()
if err == nil && ctx.Err() != nil {
err = ctx.Err()
}
@@ -42,5 +73,13 @@ func (tf *Terraform) runTerraformCmd(ctx context.Context, cmd *exec.Cmd) error {
return tf.wrapExitError(ctx, err, errBuf.String())
}
// Return error if there was an issue reading the std out/err
if errStdout != nil && ctx.Err() != nil {
return tf.wrapExitError(ctx, errStdout, errBuf.String())
}
if errStderr != nil && ctx.Err() != nil {
return tf.wrapExitError(ctx, errStderr, errBuf.String())
}
return nil
}

View File

@@ -4,15 +4,13 @@ import (
"context"
"os/exec"
"strings"
"sync"
"syscall"
)
func (tf *Terraform) runTerraformCmd(ctx context.Context, cmd *exec.Cmd) error {
var errBuf strings.Builder
cmd.Stdout = mergeWriters(cmd.Stdout, tf.stdout)
cmd.Stderr = mergeWriters(cmd.Stderr, tf.stderr, &errBuf)
cmd.SysProcAttr = &syscall.SysProcAttr{
// kill children if parent is dead
Pdeathsig: syscall.SIGKILL,
@@ -20,21 +18,6 @@ func (tf *Terraform) runTerraformCmd(ctx context.Context, cmd *exec.Cmd) error {
Setpgid: true,
}
go func() {
<-ctx.Done()
if ctx.Err() == context.DeadlineExceeded || ctx.Err() == context.Canceled {
if cmd != nil && cmd.Process != nil && cmd.ProcessState != nil {
// send SIGINT to process group
err := syscall.Kill(-cmd.Process.Pid, syscall.SIGINT)
if err != nil {
tf.logger.Printf("error from SIGINT: %s", err)
}
}
// TODO: send a kill if it doesn't respond for a bit?
}
}()
// check for early cancellation
select {
case <-ctx.Done():
@@ -42,7 +25,52 @@ func (tf *Terraform) runTerraformCmd(ctx context.Context, cmd *exec.Cmd) error {
default:
}
err := cmd.Run()
// Read stdout / stderr logs from pipe instead of setting cmd.Stdout and
// cmd.Stderr because it can cause hanging when killing the command
// https://github.com/golang/go/issues/23019
stdoutWriter := mergeWriters(cmd.Stdout, tf.stdout)
stderrWriter := mergeWriters(tf.stderr, &errBuf)
cmd.Stderr = nil
cmd.Stdout = nil
stdoutPipe, err := cmd.StdoutPipe()
if err != nil {
return err
}
stderrPipe, err := cmd.StderrPipe()
if err != nil {
return err
}
err = cmd.Start()
if err == nil && ctx.Err() != nil {
err = ctx.Err()
}
if err != nil {
return tf.wrapExitError(ctx, err, "")
}
var errStdout, errStderr error
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
errStdout = writeOutput(ctx, stdoutPipe, stdoutWriter)
}()
wg.Add(1)
go func() {
defer wg.Done()
errStderr = writeOutput(ctx, stderrPipe, stderrWriter)
}()
// Reads from pipes must be completed before calling cmd.Wait(). Otherwise
// can cause a race condition
wg.Wait()
err = cmd.Wait()
if err == nil && ctx.Err() != nil {
err = ctx.Err()
}
@@ -50,5 +78,13 @@ func (tf *Terraform) runTerraformCmd(ctx context.Context, cmd *exec.Cmd) error {
return tf.wrapExitError(ctx, err, errBuf.String())
}
// Return error if there was an issue reading the std out/err
if errStdout != nil && ctx.Err() != nil {
return tf.wrapExitError(ctx, errStdout, errBuf.String())
}
if errStderr != nil && ctx.Err() != nil {
return tf.wrapExitError(ctx, errStderr, errBuf.String())
}
return nil
}

View File

@@ -46,6 +46,7 @@ var (
statePlanReadErrRegexp = regexp.MustCompile(
`Terraform couldn't read the given file as a state or plan file.|` +
`Error: Failed to read the given file as a state or plan file`)
lockIdInvalidErrRegexp = regexp.MustCompile(`Failed to unlock state: `)
)
func (tf *Terraform) wrapExitError(ctx context.Context, err error, stderr string) error {
@@ -160,6 +161,8 @@ func (tf *Terraform) wrapExitError(ctx context.Context, err error, stderr string
}
case statePlanReadErrRegexp.MatchString(stderr):
return &ErrStatePlanRead{stderr: stderr}
case lockIdInvalidErrRegexp.MatchString(stderr):
return &ErrLockIdInvalid{stderr: stderr}
}
return fmt.Errorf("%w\n%s", &unwrapper{exitErr, ctxErr}, stderr)
@@ -256,6 +259,16 @@ func (e *ErrNoConfig) Error() string {
return e.stderr
}
type ErrLockIdInvalid struct {
unwrapper
stderr string
}
func (e *ErrLockIdInvalid) Error() string {
return e.stderr
}
// ErrCLIUsage is returned when the combination of flags or arguments is incorrect.
//
// CLI indicates usage errors in three different ways: either

View File

@@ -2,6 +2,7 @@ package tfexec
import (
"context"
"fmt"
"os/exec"
)
@@ -21,7 +22,10 @@ func (opt *DirOption) configureForceUnlock(conf *forceUnlockConfig) {
// ForceUnlock represents the `terraform force-unlock` command
func (tf *Terraform) ForceUnlock(ctx context.Context, lockID string, opts ...ForceUnlockOption) error {
unlockCmd := tf.forceUnlockCmd(ctx, lockID, opts...)
unlockCmd, err := tf.forceUnlockCmd(ctx, lockID, opts...)
if err != nil {
return err
}
if err := tf.runTerraformCmd(ctx, unlockCmd); err != nil {
return err
@@ -30,21 +34,25 @@ func (tf *Terraform) ForceUnlock(ctx context.Context, lockID string, opts ...For
return nil
}
func (tf *Terraform) forceUnlockCmd(ctx context.Context, lockID string, opts ...ForceUnlockOption) *exec.Cmd {
func (tf *Terraform) forceUnlockCmd(ctx context.Context, lockID string, opts ...ForceUnlockOption) (*exec.Cmd, error) {
c := defaultForceUnlockOptions
for _, o := range opts {
o.configureForceUnlock(&c)
}
args := []string{"force-unlock", "-force"}
args := []string{"force-unlock", "-no-color", "-force"}
// positional arguments
args = append(args, lockID)
// optional positional arguments
if c.dir != "" {
err := tf.compatible(ctx, nil, tf0_15_0)
if err != nil {
return nil, fmt.Errorf("[DIR] option was removed in Terraform v0.15.0")
}
args = append(args, c.dir)
}
return tf.buildTerraformCmd(ctx, nil, args...)
return tf.buildTerraformCmd(ctx, nil, args...), nil
}

View File

@@ -52,6 +52,10 @@ func (opt *DirOption) configureInit(conf *initConfig) {
conf.dir = opt.path
}
func (opt *ForceCopyOption) configureInit(conf *initConfig) {
conf.forceCopy = opt.forceCopy
}
func (opt *FromModuleOption) configureInit(conf *initConfig) {
conf.fromModule = opt.source
}
@@ -116,7 +120,7 @@ func (tf *Terraform) initCmd(ctx context.Context, opts ...InitOption) (*exec.Cmd
o.configureInit(&c)
}
args := []string{"init", "-no-color", "-force-copy", "-input=false"}
args := []string{"init", "-no-color", "-input=false"}
// string opts: only pass if set
if c.fromModule != "" {
@@ -144,6 +148,10 @@ func (tf *Terraform) initCmd(ctx context.Context, opts ...InitOption) (*exec.Cmd
args = append(args, "-verify-plugins="+fmt.Sprint(c.verifyPlugins))
}
if c.forceCopy {
args = append(args, "-force-copy")
}
// unary flags: pass if true
if c.reconfigure {
args = append(args, "-reconfigure")

View File

@@ -0,0 +1,55 @@
package tfexec
import (
"bytes"
"context"
"os/exec"
)
type statePullConfig struct {
reattachInfo ReattachInfo
}
var defaultStatePullConfig = statePullConfig{}
type StatePullOption interface {
configureShow(*statePullConfig)
}
func (opt *ReattachOption) configureStatePull(conf *statePullConfig) {
conf.reattachInfo = opt.info
}
func (tf *Terraform) StatePull(ctx context.Context, opts ...StatePullOption) (string, error) {
c := defaultStatePullConfig
for _, o := range opts {
o.configureShow(&c)
}
mergeEnv := map[string]string{}
if c.reattachInfo != nil {
reattachStr, err := c.reattachInfo.marshalString()
if err != nil {
return "", err
}
mergeEnv[reattachEnvVar] = reattachStr
}
cmd := tf.statePullCmd(ctx, mergeEnv)
var ret bytes.Buffer
cmd.Stdout = &ret
err := tf.runTerraformCmd(ctx, cmd)
if err != nil {
return "", err
}
return ret.String(), nil
}
func (tf *Terraform) statePullCmd(ctx context.Context, mergeEnv map[string]string) *exec.Cmd {
args := []string{"state", "pull"}
return tf.buildTerraformCmd(ctx, mergeEnv, args...)
}

View File

@@ -0,0 +1,67 @@
package tfexec
import (
"context"
"os/exec"
"strconv"
)
type statePushConfig struct {
force bool
lock bool
lockTimeout string
}
var defaultStatePushOptions = statePushConfig{
lock: false,
lockTimeout: "0s",
}
// StatePushCmdOption represents options used in the Refresh method.
type StatePushCmdOption interface {
configureStatePush(*statePushConfig)
}
func (opt *ForceOption) configureStatePush(conf *statePushConfig) {
conf.force = opt.force
}
func (opt *LockOption) configureStatePush(conf *statePushConfig) {
conf.lock = opt.lock
}
func (opt *LockTimeoutOption) configureStatePush(conf *statePushConfig) {
conf.lockTimeout = opt.timeout
}
func (tf *Terraform) StatePush(ctx context.Context, path string, opts ...StatePushCmdOption) error {
cmd, err := tf.statePushCmd(ctx, path, opts...)
if err != nil {
return err
}
return tf.runTerraformCmd(ctx, cmd)
}
func (tf *Terraform) statePushCmd(ctx context.Context, path string, opts ...StatePushCmdOption) (*exec.Cmd, error) {
c := defaultStatePushOptions
for _, o := range opts {
o.configureStatePush(&c)
}
args := []string{"state", "push"}
if c.force {
args = append(args, "-force")
}
args = append(args, "-lock="+strconv.FormatBool(c.lock))
if c.lockTimeout != "" {
args = append(args, "-lock-timeout="+c.lockTimeout)
}
args = append(args, path)
return tf.buildTerraformCmd(ctx, nil, args...), nil
}

View File

@@ -48,11 +48,22 @@ type Terraform struct {
skipProviderVerify bool
env map[string]string
stdout io.Writer
stderr io.Writer
logger printfer
stdout io.Writer
stderr io.Writer
logger printfer
// TF_LOG environment variable, defaults to TRACE if logPath is set.
log string
// TF_LOG_CORE environment variable
logCore string
// TF_LOG_PATH environment variable
logPath string
// TF_LOG_PROVIDER environment variable
logProvider string
versionLock sync.Mutex
execVersion *version.Version
provVersions map[string]*version.Version
@@ -122,10 +133,58 @@ func (tf *Terraform) SetStderr(w io.Writer) {
tf.stderr = w
}
// SetLog sets the TF_LOG environment variable for Terraform CLI execution.
// This must be combined with a call to SetLogPath to take effect.
//
// This is only compatible with Terraform CLI 0.15.0 or later as setting the
// log level was unreliable in earlier versions. It will default to TRACE when
// SetLogPath is called on versions 0.14.11 and earlier, or if SetLogCore and
// SetLogProvider have not been called before SetLogPath on versions 0.15.0 and
// later.
func (tf *Terraform) SetLog(log string) error {
err := tf.compatible(context.Background(), tf0_15_0, nil)
if err != nil {
return err
}
tf.log = log
return nil
}
// SetLogCore sets the TF_LOG_CORE environment variable for Terraform CLI
// execution. This must be combined with a call to SetLogPath to take effect.
//
// This is only compatible with Terraform CLI 0.15.0 or later.
func (tf *Terraform) SetLogCore(logCore string) error {
err := tf.compatible(context.Background(), tf0_15_0, nil)
if err != nil {
return err
}
tf.logCore = logCore
return nil
}
// SetLogPath sets the TF_LOG_PATH environment variable for Terraform CLI
// execution.
func (tf *Terraform) SetLogPath(path string) error {
tf.logPath = path
// Prevent setting the log path without enabling logging
if tf.log == "" && tf.logCore == "" && tf.logProvider == "" {
tf.log = "TRACE"
}
return nil
}
// SetLogProvider sets the TF_LOG_PROVIDER environment variable for Terraform
// CLI execution. This must be combined with a call to SetLogPath to take
// effect.
//
// This is only compatible with Terraform CLI 0.15.0 or later.
func (tf *Terraform) SetLogProvider(logProvider string) error {
err := tf.compatible(context.Background(), tf0_15_0, nil)
if err != nil {
return err
}
tf.logProvider = logProvider
return nil
}

View File

@@ -49,6 +49,18 @@ type CapsuleOps struct {
// pointer identity of the encapsulated value.
RawEquals func(a, b interface{}) bool
// HashKey provides a hashing function for values of the corresponding
// capsule type. If defined, cty will use the resulting hashes as part
// of the implementation of sets whose element type is or contains the
// corresponding capsule type.
//
// If a capsule type defines HashValue then the function _must_ return
// an equal hash value for any two values that would cause Equals or
// RawEquals to return true when given those values. If a given type
// does not uphold that assumption then sets including this type will
// not behave correctly.
HashKey func(v interface{}) string
// ConversionFrom can provide conversions from the corresponding type to
// some other type when values of the corresponding type are used with
// the "convert" package. (The main cty package does not use this operation.)

View File

@@ -66,7 +66,7 @@ func elementIterator(val Value) ElementIterator {
idx: -1,
}
case val.ty.IsSetType():
rawSet := val.v.(set.Set)
rawSet := val.v.(set.Set[interface{}])
return &setElementIterator{
ety: val.ty.ElementType(),
setIt: rawSet.Iterator(),
@@ -139,7 +139,7 @@ func (it *mapElementIterator) Next() bool {
type setElementIterator struct {
ety Type
setIt *set.Iterator
setIt *set.Iterator[interface{}]
}
func (it *setElementIterator) Element() (Value, Value) {

View File

@@ -1,204 +0,0 @@
package cty
import (
"bytes"
"encoding/gob"
"errors"
"fmt"
"math/big"
"github.com/zclconf/go-cty/cty/set"
)
// GobEncode is an implementation of the gob.GobEncoder interface, which
// allows Values to be included in structures encoded with encoding/gob.
//
// Currently it is not possible to represent values of capsule types in gob,
// because the types themselves cannot be represented.
func (val Value) GobEncode() ([]byte, error) {
if val.IsMarked() {
return nil, errors.New("value is marked")
}
buf := &bytes.Buffer{}
enc := gob.NewEncoder(buf)
gv := gobValue{
Version: 0,
Ty: val.ty,
V: val.v,
}
err := enc.Encode(gv)
if err != nil {
return nil, fmt.Errorf("error encoding cty.Value: %s", err)
}
return buf.Bytes(), nil
}
// GobDecode is an implementation of the gob.GobDecoder interface, which
// inverts the operation performed by GobEncode. See the documentation of
// GobEncode for considerations when using cty.Value instances with gob.
func (val *Value) GobDecode(buf []byte) error {
r := bytes.NewReader(buf)
dec := gob.NewDecoder(r)
var gv gobValue
err := dec.Decode(&gv)
if err != nil {
return fmt.Errorf("error decoding cty.Value: %s", err)
}
if gv.Version != 0 {
return fmt.Errorf("unsupported cty.Value encoding version %d; only 0 is supported", gv.Version)
}
// Because big.Float.GobEncode is implemented with a pointer reciever,
// gob encoding of an interface{} containing a *big.Float value does not
// round-trip correctly, emerging instead as a non-pointer big.Float.
// The rest of cty expects all number values to be represented by
// *big.Float, so we'll fix that up here.
gv.V = gobDecodeFixNumberPtr(gv.V, gv.Ty)
val.ty = gv.Ty
val.v = gv.V
return nil
}
// GobEncode is an implementation of the gob.GobEncoder interface, which
// allows Types to be included in structures encoded with encoding/gob.
//
// Currently it is not possible to represent capsule types in gob.
func (t Type) GobEncode() ([]byte, error) {
buf := &bytes.Buffer{}
enc := gob.NewEncoder(buf)
gt := gobType{
Version: 0,
Impl: t.typeImpl,
}
err := enc.Encode(gt)
if err != nil {
return nil, fmt.Errorf("error encoding cty.Type: %s", err)
}
return buf.Bytes(), nil
}
// GobDecode is an implementatino of the gob.GobDecoder interface, which
// reverses the encoding performed by GobEncode to allow types to be recovered
// from gob buffers.
func (t *Type) GobDecode(buf []byte) error {
r := bytes.NewReader(buf)
dec := gob.NewDecoder(r)
var gt gobType
err := dec.Decode(&gt)
if err != nil {
return fmt.Errorf("error decoding cty.Type: %s", err)
}
if gt.Version != 0 {
return fmt.Errorf("unsupported cty.Type encoding version %d; only 0 is supported", gt.Version)
}
t.typeImpl = gt.Impl
return nil
}
// Capsule types cannot currently be gob-encoded, because they rely on pointer
// equality and we have no way to recover the original pointer on decode.
func (t *capsuleType) GobEncode() ([]byte, error) {
return nil, fmt.Errorf("cannot gob-encode capsule type %q", t.FriendlyName(friendlyTypeName))
}
func (t *capsuleType) GobDecode() ([]byte, error) {
return nil, fmt.Errorf("cannot gob-decode capsule type %q", t.FriendlyName(friendlyTypeName))
}
type gobValue struct {
Version int
Ty Type
V interface{}
}
type gobType struct {
Version int
Impl typeImpl
}
type gobCapsuleTypeImpl struct {
}
// goDecodeFixNumberPtr fixes an unfortunate quirk of round-tripping cty.Number
// values through gob: the big.Float.GobEncode method is implemented on a
// pointer receiver, and so it loses the "pointer-ness" of the value on
// encode, causing the values to emerge the other end as big.Float rather than
// *big.Float as we expect elsewhere in cty.
//
// The implementation of gobDecodeFixNumberPtr mutates the given raw value
// during its work, and may either return the same value mutated or a new
// value. Callers must no longer use whatever value they pass as "raw" after
// this function is called.
func gobDecodeFixNumberPtr(raw interface{}, ty Type) interface{} {
// Unfortunately we need to work recursively here because number values
// might be embedded in structural or collection type values.
switch {
case ty.Equals(Number):
if bf, ok := raw.(big.Float); ok {
return &bf // wrap in pointer
}
case ty.IsMapType() && ty.ElementType().Equals(Number):
if m, ok := raw.(map[string]interface{}); ok {
for k, v := range m {
m[k] = gobDecodeFixNumberPtr(v, ty.ElementType())
}
}
case ty.IsListType() && ty.ElementType().Equals(Number):
if s, ok := raw.([]interface{}); ok {
for i, v := range s {
s[i] = gobDecodeFixNumberPtr(v, ty.ElementType())
}
}
case ty.IsSetType() && ty.ElementType().Equals(Number):
if s, ok := raw.(set.Set); ok {
newS := set.NewSet(s.Rules())
for it := s.Iterator(); it.Next(); {
newV := gobDecodeFixNumberPtr(it.Value(), ty.ElementType())
newS.Add(newV)
}
return newS
}
case ty.IsObjectType():
if m, ok := raw.(map[string]interface{}); ok {
for k, v := range m {
aty := ty.AttributeType(k)
m[k] = gobDecodeFixNumberPtr(v, aty)
}
}
case ty.IsTupleType():
if s, ok := raw.([]interface{}); ok {
for i, v := range s {
ety := ty.TupleElementType(i)
s[i] = gobDecodeFixNumberPtr(v, ety)
}
}
}
return raw
}
// gobDecodeFixNumberPtrVal is a helper wrapper around gobDecodeFixNumberPtr
// that works with already-constructed values. This is primarily for testing,
// to fix up intentionally-invalid number values for the parts of the test
// code that need them to be valid, such as calling GoString on them.
func gobDecodeFixNumberPtrVal(v Value) Value {
raw := gobDecodeFixNumberPtr(v.v, v.ty)
return Value{
v: raw,
ty: v.ty,
}
}

View File

@@ -51,7 +51,7 @@ func (t typeMap) GoString() string {
return fmt.Sprintf("cty.Map(%#v)", t.ElementTypeT)
}
// IsMapType returns true if the given type is a list type, regardless of its
// IsMapType returns true if the given type is a map type, regardless of its
// element type.
func (t Type) IsMapType() bool {
_, ok := t.typeImpl.(typeMap)

View File

@@ -11,14 +11,14 @@ import (
// to talk about a subset of paths within a value that meet some criteria,
// without directly modifying the values at those paths.
type PathSet struct {
set set.Set
set set.Set[Path]
}
// NewPathSet creates and returns a PathSet, with initial contents optionally
// set by the given arguments.
func NewPathSet(paths ...Path) PathSet {
ret := PathSet{
set: set.NewSet(pathSetRules{}),
set: set.NewSet(set.Rules[Path](pathSetRules{})),
}
for _, path := range paths {
@@ -61,7 +61,7 @@ func (s PathSet) List() []Path {
}
ret := make([]Path, 0, s.set.Length())
for it := s.set.Iterator(); it.Next(); {
ret = append(ret, it.Value().(Path))
ret = append(ret, it.Value())
}
return ret
}
@@ -134,8 +134,7 @@ var indexStepPlaceholder = []byte("#")
type pathSetRules struct {
}
func (r pathSetRules) Hash(v interface{}) int {
path := v.(Path)
func (r pathSetRules) Hash(path Path) int {
hash := crc64.New(crc64Table)
for _, rawStep := range path {
@@ -159,10 +158,7 @@ func (r pathSetRules) Hash(v interface{}) int {
return int(hash.Sum64())
}
func (r pathSetRules) Equivalent(a, b interface{}) bool {
aPath := a.(Path)
bPath := b.(Path)
func (r pathSetRules) Equivalent(aPath, bPath Path) bool {
if len(aPath) != len(bPath) {
return false
}
@@ -198,7 +194,7 @@ func (r pathSetRules) Equivalent(a, b interface{}) bool {
}
// SameRules is true if both Rules instances are pathSetRules structs.
func (r pathSetRules) SameRules(other set.Rules) bool {
func (r pathSetRules) SameRules(other set.Rules[Path]) bool {
_, ok := other.(pathSetRules)
return ok
}

View File

@@ -74,6 +74,8 @@ func rawNumberEqual(a, b *big.Float) bool {
return false
case a == nil: // b == nil too then, due to previous case
return true
case a.Sign() != b.Sign():
return false
default:
// This format and precision matches that used by cty/json.Marshal,
// and thus achieves our definition of "two numbers are equal if

View File

@@ -1,76 +0,0 @@
package set
import (
"bytes"
"encoding/gob"
"fmt"
)
// GobEncode is an implementation of the interface gob.GobEncoder, allowing
// sets to be included in structures encoded via gob.
//
// The set rules are included in the serialized value, so the caller must
// register its concrete rules type with gob.Register before using a
// set in a gob, and possibly also implement GobEncode/GobDecode to customize
// how any parameters are persisted.
//
// The set elements are also included, so if they are of non-primitive types
// they too must be registered with gob.
//
// If the produced gob values will persist for a long time, the caller must
// ensure compatibility of the rules implementation. In particular, if the
// definition of element equivalence changes between encoding and decoding
// then two distinct stored elements may be considered equivalent on decoding,
// causing the recovered set to have fewer elements than when it was stored.
func (s Set) GobEncode() ([]byte, error) {
gs := gobSet{
Version: 0,
Rules: s.rules,
Values: s.Values(),
}
buf := &bytes.Buffer{}
enc := gob.NewEncoder(buf)
err := enc.Encode(gs)
if err != nil {
return nil, fmt.Errorf("error encoding set.Set: %s", err)
}
return buf.Bytes(), nil
}
// GobDecode is the opposite of GobEncode. See GobEncode for information
// on the requirements for and caveats of including set values in gobs.
func (s *Set) GobDecode(buf []byte) error {
r := bytes.NewReader(buf)
dec := gob.NewDecoder(r)
var gs gobSet
err := dec.Decode(&gs)
if err != nil {
return fmt.Errorf("error decoding set.Set: %s", err)
}
if gs.Version != 0 {
return fmt.Errorf("unsupported set.Set encoding version %d; need 0", gs.Version)
}
victim := NewSetFromSlice(gs.Rules, gs.Values)
s.vals = victim.vals
s.rules = victim.rules
return nil
}
type gobSet struct {
Version int
Rules Rules
// The bucket-based representation is for efficient in-memory access, but
// for serialization it's enough to just retain the values themselves,
// which we can re-bucket using the rules (which may have changed!) when
// we re-inflate.
Values []interface{}
}
func init() {
gob.Register([]interface{}(nil))
}

View File

@@ -1,15 +1,15 @@
package set
type Iterator struct {
vals []interface{}
type Iterator[T any] struct {
vals []T
idx int
}
func (it *Iterator) Value() interface{} {
func (it *Iterator[T]) Value() T {
return it.vals[it.idx]
}
func (it *Iterator) Next() bool {
func (it *Iterator[T]) Next() bool {
it.idx++
return it.idx < len(it.vals)
}

View File

@@ -7,10 +7,10 @@ import (
// Add inserts the given value into the receiving Set.
//
// This mutates the set in-place. This operation is not thread-safe.
func (s Set) Add(val interface{}) {
func (s Set[T]) Add(val T) {
hv := s.rules.Hash(val)
if _, ok := s.vals[hv]; !ok {
s.vals[hv] = make([]interface{}, 0, 1)
s.vals[hv] = make([]T, 0, 1)
}
bucket := s.vals[hv]
@@ -26,7 +26,7 @@ func (s Set) Add(val interface{}) {
// Remove deletes the given value from the receiving set, if indeed it was
// there in the first place. If the value is not present, this is a no-op.
func (s Set) Remove(val interface{}) {
func (s Set[T]) Remove(val T) {
hv := s.rules.Hash(val)
bucket, ok := s.vals[hv]
if !ok {
@@ -35,7 +35,7 @@ func (s Set) Remove(val interface{}) {
for i, ev := range bucket {
if s.rules.Equivalent(val, ev) {
newBucket := make([]interface{}, 0, len(bucket)-1)
newBucket := make([]T, 0, len(bucket)-1)
newBucket = append(newBucket, bucket[:i]...)
newBucket = append(newBucket, bucket[i+1:]...)
if len(newBucket) > 0 {
@@ -50,7 +50,7 @@ func (s Set) Remove(val interface{}) {
// Has returns true if the given value is in the receiving set, or false if
// it is not.
func (s Set) Has(val interface{}) bool {
func (s Set[T]) Has(val T) bool {
hv := s.rules.Hash(val)
bucket, ok := s.vals[hv]
if !ok {
@@ -67,7 +67,7 @@ func (s Set) Has(val interface{}) bool {
// Copy performs a shallow copy of the receiving set, returning a new set
// with the same rules and elements.
func (s Set) Copy() Set {
func (s Set[T]) Copy() Set[T] {
ret := NewSet(s.rules)
for k, v := range s.vals {
ret.vals[k] = v
@@ -92,10 +92,10 @@ func (s Set) Copy() Set {
//
// Once an iterator has been created for a set, the set *must not* be mutated
// until the iterator is no longer in use.
func (s Set) Iterator() *Iterator {
func (s Set[T]) Iterator() *Iterator[T] {
vals := s.Values()
return &Iterator{
return &Iterator[T]{
vals: vals,
idx: -1,
}
@@ -103,7 +103,7 @@ func (s Set) Iterator() *Iterator {
// EachValue calls the given callback once for each value in the set, in an
// undefined order that callers should not depend on.
func (s Set) EachValue(cb func(interface{})) {
func (s Set[T]) EachValue(cb func(T)) {
it := s.Iterator()
for it.Next() {
cb(it.Value())
@@ -114,8 +114,8 @@ func (s Set) EachValue(cb func(interface{})) {
// an order then the result is in that order. If no order is provided or if
// it is not a total order then the result order is undefined, but consistent
// for a particular set value within a specific release of cty.
func (s Set) Values() []interface{} {
var ret []interface{}
func (s Set[T]) Values() []T {
var ret []T
// Sort the bucketIds to ensure that we always traverse in a
// consistent order.
bucketIDs := make([]int, 0, len(s.vals))
@@ -128,7 +128,7 @@ func (s Set) Values() []interface{} {
ret = append(ret, s.vals[bucketID]...)
}
if orderRules, ok := s.rules.(OrderedRules); ok {
if orderRules, ok := s.rules.(OrderedRules[T]); ok {
sort.SliceStable(ret, func(i, j int) bool {
return orderRules.Less(ret[i], ret[j])
})
@@ -138,7 +138,7 @@ func (s Set) Values() []interface{} {
}
// Length returns the number of values in the set.
func (s Set) Length() int {
func (s Set[T]) Length() int {
var count int
for _, bucket := range s.vals {
count = count + len(bucket)
@@ -149,13 +149,13 @@ func (s Set) Length() int {
// Union returns a new set that contains all of the members of both the
// receiving set and the given set. Both sets must have the same rules, or
// else this function will panic.
func (s1 Set) Union(s2 Set) Set {
func (s1 Set[T]) Union(s2 Set[T]) Set[T] {
mustHaveSameRules(s1, s2)
rs := NewSet(s1.rules)
s1.EachValue(func(v interface{}) {
s1.EachValue(func(v T) {
rs.Add(v)
})
s2.EachValue(func(v interface{}) {
s2.EachValue(func(v T) {
rs.Add(v)
})
return rs
@@ -164,10 +164,10 @@ func (s1 Set) Union(s2 Set) Set {
// Intersection returns a new set that contains the values that both the
// receiver and given sets have in common. Both sets must have the same rules,
// or else this function will panic.
func (s1 Set) Intersection(s2 Set) Set {
func (s1 Set[T]) Intersection(s2 Set[T]) Set[T] {
mustHaveSameRules(s1, s2)
rs := NewSet(s1.rules)
s1.EachValue(func(v interface{}) {
s1.EachValue(func(v T) {
if s2.Has(v) {
rs.Add(v)
}
@@ -178,10 +178,10 @@ func (s1 Set) Intersection(s2 Set) Set {
// Subtract returns a new set that contains all of the values from the receiver
// that are not also in the given set. Both sets must have the same rules,
// or else this function will panic.
func (s1 Set) Subtract(s2 Set) Set {
func (s1 Set[T]) Subtract(s2 Set[T]) Set[T] {
mustHaveSameRules(s1, s2)
rs := NewSet(s1.rules)
s1.EachValue(func(v interface{}) {
s1.EachValue(func(v T) {
if !s2.Has(v) {
rs.Add(v)
}
@@ -193,15 +193,15 @@ func (s1 Set) Subtract(s2 Set) Set {
// both the receiver and given sets, except those that both sets have in
// common. Both sets must have the same rules, or else this function will
// panic.
func (s1 Set) SymmetricDifference(s2 Set) Set {
func (s1 Set[T]) SymmetricDifference(s2 Set[T]) Set[T] {
mustHaveSameRules(s1, s2)
rs := NewSet(s1.rules)
s1.EachValue(func(v interface{}) {
s1.EachValue(func(v T) {
if !s2.Has(v) {
rs.Add(v)
}
})
s2.EachValue(func(v interface{}) {
s2.EachValue(func(v T) {
if !s1.Has(v) {
rs.Add(v)
}

View File

@@ -4,13 +4,13 @@ package set
//
// Each Set has a Rules instance, whose methods must satisfy the interface
// contracts given below for any value that will be added to the set.
type Rules interface {
type Rules[T any] interface {
// Hash returns an int that somewhat-uniquely identifies the given value.
//
// A good hash function will minimize collisions for values that will be
// added to the set, though collisions *are* permitted. Collisions will
// simply reduce the efficiency of operations on the set.
Hash(interface{}) int
Hash(T) int
// Equivalent returns true if and only if the two values are considered
// equivalent for the sake of set membership. Two values that are
@@ -21,11 +21,11 @@ type Rules interface {
// Two values that are equivalent *must* result in the same hash value,
// though it is *not* required that two values with the same hash value
// be equivalent.
Equivalent(interface{}, interface{}) bool
Equivalent(T, T) bool
// SameRules returns true if the instance is equivalent to another Rules
// instance.
SameRules(Rules) bool
// instance over the same element type.
SameRules(Rules[T]) bool
}
// OrderedRules is an extension of Rules that can apply a partial order to
@@ -37,8 +37,8 @@ type Rules interface {
// is undefined but consistent for a particular version of cty. The exact
// order in that case is not part of the contract and is subject to change
// between versions.
type OrderedRules interface {
Rules
type OrderedRules[T any] interface {
Rules[T]
// Less returns true if and only if the first argument should sort before
// the second argument. If the second argument should sort before the first

View File

@@ -19,20 +19,20 @@ import (
// Set operations are not optimized to minimize memory pressure. Mutating
// a set will generally create garbage and so should perhaps be avoided in
// tight loops where memory pressure is a concern.
type Set struct {
vals map[int][]interface{}
rules Rules
type Set[T any] struct {
vals map[int][]T
rules Rules[T]
}
// NewSet returns an empty set with the membership rules given.
func NewSet(rules Rules) Set {
return Set{
vals: map[int][]interface{}{},
func NewSet[T any](rules Rules[T]) Set[T] {
return Set[T]{
vals: map[int][]T{},
rules: rules,
}
}
func NewSetFromSlice(rules Rules, vals []interface{}) Set {
func NewSetFromSlice[T any](rules Rules[T], vals []T) Set[T] {
s := NewSet(rules)
for _, v := range vals {
s.Add(v)
@@ -40,11 +40,11 @@ func NewSetFromSlice(rules Rules, vals []interface{}) Set {
return s
}
func sameRules(s1 Set, s2 Set) bool {
func sameRules[T any](s1 Set[T], s2 Set[T]) bool {
return s1.rules.SameRules(s2.rules)
}
func mustHaveSameRules(s1 Set, s2 Set) {
func mustHaveSameRules[T any](s1 Set[T], s2 Set[T]) {
if !sameRules(s1, s2) {
panic(fmt.Errorf("incompatible set rules: %#v, %#v", s1.rules, s2.rules))
}
@@ -52,11 +52,11 @@ func mustHaveSameRules(s1 Set, s2 Set) {
// HasRules returns true if and only if the receiving set has the given rules
// instance as its rules.
func (s Set) HasRules(rules Rules) bool {
func (s Set[T]) HasRules(rules Rules[T]) bool {
return s.rules.SameRules(rules)
}
// Rules returns the receiving set's rules instance.
func (s Set) Rules() Rules {
func (s Set[T]) Rules() Rules[T] {
return s.rules
}

View File

@@ -21,15 +21,15 @@ type ValueSet struct {
// ValueSet is just a thin wrapper around a set.Set with our value-oriented
// "rules" applied. We do this so that the caller can work in terms of
// cty.Value objects even though the set internals use the raw values.
s set.Set
s set.Set[interface{}]
}
// NewValueSet creates and returns a new ValueSet with the given element type.
func NewValueSet(ety Type) ValueSet {
return newValueSet(set.NewSet(setRules{Type: ety}))
return newValueSet(set.NewSet(newSetRules(ety)))
}
func newValueSet(s set.Set) ValueSet {
func newValueSet(s set.Set[interface{}]) ValueSet {
return ValueSet{
s: s,
}

View File

@@ -21,7 +21,11 @@ type setRules struct {
Type Type
}
var _ set.OrderedRules = setRules{}
var _ set.OrderedRules[interface{}] = setRules{}
func newSetRules(ety Type) set.Rules[interface{}] {
return setRules{ety}
}
// Hash returns a hash value for the receiver that can be used for equality
// checks where some inaccuracy is tolerable.
@@ -67,7 +71,7 @@ func (r setRules) Equivalent(v1 interface{}, v2 interface{}) bool {
// SameRules is only true if the other Rules instance is also a setRules struct,
// and the types are considered equal.
func (r setRules) SameRules(other set.Rules) bool {
func (r setRules) SameRules(other set.Rules[interface{}]) bool {
rules, ok := other.(setRules)
if !ok {
return false
@@ -250,6 +254,25 @@ func appendSetHashBytes(val Value, buf *bytes.Buffer, marks ValueMarks) {
return
}
if val.ty.IsCapsuleType() {
buf.WriteRune('«')
ops := val.ty.CapsuleOps()
if ops != nil && ops.HashKey != nil {
key := ops.HashKey(val.EncapsulatedValue())
buf.WriteString(fmt.Sprintf("%q", key))
} else {
// If there isn't an explicit hash implementation then we'll
// just generate the same hash value for every value of this
// type, which is logically fine but less efficient for
// larger sets because we'll have to bucket all values
// together and scan over them with Equals to determine
// set membership.
buf.WriteRune('?')
}
buf.WriteRune('»')
return
}
// should never get down here
panic("unsupported type in set hash")
panic(fmt.Sprintf("unsupported type %#v in set hash", val.ty))
}

View File

@@ -1,57 +0,0 @@
package cty
import (
"encoding/gob"
"fmt"
"math/big"
"strings"
"github.com/zclconf/go-cty/cty/set"
)
// InternalTypesToRegister is a slice of values that covers all of the
// internal types used in the representation of cty.Type and cty.Value
// across all cty Types.
//
// This is intended to be used to register these types with encoding
// packages that require registration of types used in interfaces, such as
// encoding/gob, thus allowing cty types and values to be included in streams
// created from those packages. However, registering with gob is not necessary
// since that is done automatically as a side-effect of importing this package.
//
// Callers should not do anything with the values here except pass them on
// verbatim to a registration function.
//
// If the calling application uses Capsule types that wrap local structs either
// directly or indirectly, these structs may also need to be registered in
// order to support encoding and decoding of values of these types. That is the
// responsibility of the calling application.
var InternalTypesToRegister []interface{}
func init() {
InternalTypesToRegister = []interface{}{
primitiveType{},
typeList{},
typeMap{},
typeObject{},
typeSet{},
setRules{},
set.Set{},
typeTuple{},
big.Float{},
capsuleType{},
[]interface{}(nil),
map[string]interface{}(nil),
}
// Register these with gob here, rather than in gob.go, to ensure
// that this will always happen after we build the above.
for _, tv := range InternalTypesToRegister {
typeName := fmt.Sprintf("%T", tv)
if strings.HasPrefix(typeName, "cty.") {
gob.RegisterName(fmt.Sprintf("github.com/zclconf/go-cty/%s", typeName), tv)
} else {
gob.Register(tv)
}
}
}

View File

@@ -287,7 +287,7 @@ func SetVal(vals []Value) Value {
rawList[i] = val.v
}
rawVal := set.NewSetFromSlice(setRules{elementType}, rawList)
rawVal := set.NewSetFromSlice(set.Rules[interface{}](setRules{elementType}), rawList)
return Value{
ty: Set(elementType),
@@ -334,7 +334,7 @@ func SetValFromValueSet(s ValueSet) Value {
func SetValEmpty(element Type) Value {
return Value{
ty: Set(element),
v: set.NewSet(setRules{element}),
v: set.NewSet(set.Rules[interface{}](setRules{element})),
}
}

View File

@@ -47,6 +47,9 @@ func (val Value) GoString() string {
}
return "cty.False"
case Number:
if f, ok := val.v.(big.Float); ok {
panic(fmt.Sprintf("number value contains big.Float value %s, rather than pointer to big.Float", f.Text('g', -1)))
}
fv := val.v.(*big.Float)
// We'll try to use NumberIntVal or NumberFloatVal if we can, since
// the fully-general initializer call is pretty ugly-looking.
@@ -265,8 +268,8 @@ func (val Value) Equals(other Value) Value {
}
}
case ty.IsSetType():
s1 := val.v.(set.Set)
s2 := other.v.(set.Set)
s1 := val.v.(set.Set[interface{}])
s2 := other.v.(set.Set[interface{}])
equal := true
// Two sets are equal if all of their values are known and all values
@@ -983,7 +986,7 @@ func (val Value) HasElement(elem Value) Value {
return False
}
s := val.v.(set.Set)
s := val.v.(set.Set[interface{}])
return BoolVal(s.Has(elem.v))
}
@@ -1017,7 +1020,7 @@ func (val Value) Length() Value {
// may or may not be equal to other elements in the set, and thus they
// may or may not coalesce with other elements and produce fewer
// items in the resulting set.
storeLength := int64(val.v.(set.Set).Length())
storeLength := int64(val.v.(set.Set[interface{}]).Length())
if storeLength == 1 || val.IsWhollyKnown() {
// If our set is wholly known then we know its length.
//
@@ -1078,7 +1081,7 @@ func (val Value) LengthInt() int {
// compatibility with callers that were relying on LengthInt rather
// than calling Length. Instead of panicking when a set contains an
// unknown value, LengthInt returns the largest possible length.
return val.v.(set.Set).Length()
return val.v.(set.Set[interface{}]).Length()
case val.ty.IsMapType():
return len(val.v.(map[string]interface{}))

12
vendor/modules.txt vendored
View File

@@ -596,13 +596,11 @@ github.com/hashicorp/go-multierror
# github.com/hashicorp/go-retryablehttp v0.7.0
## explicit; go 1.13
github.com/hashicorp/go-retryablehttp
# github.com/hashicorp/go-version v1.5.0
# github.com/hashicorp/go-version v1.6.0
## explicit
github.com/hashicorp/go-version
# github.com/hashicorp/hc-install v0.3.2
## explicit; go 1.16
# github.com/hashicorp/terraform-exec v0.16.1
## explicit; go 1.17
# github.com/hashicorp/terraform-exec v0.17.3
## explicit; go 1.18
github.com/hashicorp/terraform-exec/internal/version
github.com/hashicorp/terraform-exec/tfexec
# github.com/hashicorp/terraform-json v0.14.0
@@ -919,8 +917,8 @@ github.com/vmware/govmomi/vim25/progress
github.com/vmware/govmomi/vim25/soap
github.com/vmware/govmomi/vim25/types
github.com/vmware/govmomi/vim25/xml
# github.com/zclconf/go-cty v1.10.0
## explicit; go 1.12
# github.com/zclconf/go-cty v1.11.0
## explicit; go 1.18
github.com/zclconf/go-cty/cty
github.com/zclconf/go-cty/cty/set
# go.mongodb.org/mongo-driver v1.8.3