1
1
Fork 0
mirror of https://github.com/mcuadros/ascode synced 2024-04-27 12:25:06 +02:00

starlark/types: Resource.HCL enconding directly from starlark.Value

This commit is contained in:
Máximo Cuadros 2020-04-13 04:21:35 +02:00
parent bac0f66196
commit 8b962d26cc
No known key found for this signature in database
GPG Key ID: 17A5DFEDC735AE4B
11 changed files with 243 additions and 64 deletions

View File

@ -5,7 +5,7 @@ import (
"io/ioutil"
"os"
"github.com/hashicorp/hcl2/hclwrite"
"github.com/hashicorp/hcl/v2/hclwrite"
"github.com/jessevdk/go-flags"
"go.starlark.net/starlark"
)

5
go.mod
View File

@ -7,12 +7,12 @@ require (
github.com/containers/image/v5 v5.2.1
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/go-git/go-git/v5 v5.0.0
github.com/gobs/args v0.0.0-20180315064131-86002b4df18c
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect
github.com/hashicorp/go-hclog v0.11.0
github.com/hashicorp/go-plugin v1.0.1-0.20190610192547-a1bc61569a26
github.com/hashicorp/hcl2 v0.0.0-20190618163856-0b64543c968c
github.com/hashicorp/hcl/v2 v2.3.0
github.com/hashicorp/hcl2 v0.0.0-00010101000000-000000000000
github.com/hashicorp/terraform v0.12.23
github.com/jessevdk/go-flags v1.4.0
github.com/kr/text v0.2.0 // indirect
@ -20,7 +20,6 @@ require (
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/oklog/ulid/v2 v2.0.2
github.com/qri-io/starlib v0.4.2-0.20200326221746-d3997998591b
github.com/rogpeppe/go-internal v1.5.2
github.com/sergi/go-diff v1.1.0 // indirect
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 // indirect
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c // indirect

26
go.sum
View File

@ -60,7 +60,6 @@ github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki
github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE=
github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/agl/ed25519 v0.0.0-20150830182803-278e1ec8e8a6/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190329064014-6e358769c32a h1:APorzFpCcv6wtD5vmRWYqNm4N55kbepL7c7kTq9XI6A=
@ -70,7 +69,6 @@ github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190103054945-8205d1f41e70/go.mod h1
github.com/aliyun/aliyun-tablestore-go-sdk v4.1.2+incompatible h1:ABQ7FF+IxSFHDMOTtjCfmMDMHiCq6EsAoCV/9sFinaM=
github.com/aliyun/aliyun-tablestore-go-sdk v4.1.2+incompatible/go.mod h1:LDQHRZylxvcg8H7wBIDfvO5g/cy4/sz1iucBlc2l3Jw=
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/antchfx/xpath v0.0.0-20190129040759-c8489ed3251e h1:ptBAamGVd6CfRsUtyHD+goy2JGhv1QC32v3gqM8mYAM=
github.com/antchfx/xpath v0.0.0-20190129040759-c8489ed3251e/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=
github.com/antchfx/xquery v0.0.0-20180515051857-ad5b8c7a47b0 h1:JaCC8jz0zdMLk2m+qCCVLLLM/PL93p84w4pK3aJWj60=
@ -90,7 +88,6 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
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-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
github.com/aws/aws-sdk-go v1.25.3 h1:uM16hIw9BotjZKMZlX05SN2EFtaWfi/NonPKIARiBLQ=
github.com/aws/aws-sdk-go v1.25.3/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
@ -183,27 +180,14 @@ 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/winrmtest v0.0.0-20190225150635-99b7fe2fddf1 h1:r1oACdS2XYiAWcfF8BJXkoU8l1J71KehGR+d99yWEDA=
github.com/dylanmei/winrmtest v0.0.0-20190225150635-99b7fe2fddf1/go.mod h1:lcy9/2gH1jn/VCLouHA6tOEwLoNVd4GW6zhuKLmHC2Y=
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/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
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/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
github.com/ghodss/yaml v0.0.0-20161207003320-04f313413ffd/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM=
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-git v1.0.0 h1:YcN9iDGDoXuIw0vHls6rINwV416HYa0EB2X+RBsyYp4=
github.com/go-git/go-git v4.7.0+incompatible h1:+W9rgGY4DOKKdX2x6HxSR7HNeTxqiKrOvKnuittYVdA=
github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
github.com/go-git/go-git/v5 v5.0.0 h1:k5RWPm4iJwYtfWoxIJy4wJX9ON7ihPeZZYC1fLYDnpg=
github.com/go-git/go-git/v5 v5.0.0/go.mod h1:oYD8y9kWsGINPFJoLdaScGCN6dlKg23blmClfZwtUVA=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
@ -329,6 +313,7 @@ github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+
github.com/hashicorp/golang-lru v0.5.1/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/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90=
github.com/hashicorp/hcl/v2 v2.3.0 h1:iRly8YaMwTBAKhn1Ybk7VSdzbnopghktCD031P8ggUE=
github.com/hashicorp/hcl/v2 v2.3.0/go.mod h1:d+FwDBbOLvpAM3Z6J7gPj/VoAGkNe/gm352ZhjJ/Zv8=
@ -349,8 +334,6 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
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=
@ -371,8 +354,6 @@ github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVY
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/keybase/go-crypto v0.0.0-20161004153544-93f5b35093ba/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
@ -538,8 +519,6 @@ github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDa
github.com/qri-io/starlib v0.4.2-0.20200326221746-d3997998591b h1:n460ZPlc7+1evliXpUzGhIVr080j5c+2zsXuThfEGGM=
github.com/qri-io/starlib v0.4.2-0.20200326221746-d3997998591b/go.mod h1:7DPO4domFU579Ga6E61sB9VFNaniPVwJP5C4bBCu3wA=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.5.2 h1:qLvObTrvO/XRCqmkKxUlOBc48bI3efyDuAZe25QiF0w=
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
@ -780,15 +759,12 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk=
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=

View File

@ -125,6 +125,10 @@ func (c *Attribute) Attr(name string) (starlark.Value, error) {
return NewAttributeWithPath(c.r, c.t.AttributeType(name), name, path), nil
}
func (c *Attribute) String() string {
return c.sString.GoString()
}
// AttrNames honors the starlark.HasAttrs interface.
func (c *Attribute) AttrNames() []string {
return []string{"__resource__", "__type__"}

View File

@ -2,11 +2,15 @@ package types
import (
"fmt"
"math/big"
"regexp"
"sort"
"unicode"
"unicode/utf8"
"github.com/hashicorp/hcl2/hcl"
"github.com/hashicorp/hcl2/hcl/hclsyntax"
"github.com/hashicorp/hcl2/hclwrite"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/hashicorp/hcl/v2/hclwrite"
"github.com/zclconf/go-cty/cty"
"go.starlark.net/starlark"
)
@ -151,15 +155,8 @@ func (r *Resource) doToHCLAttributes(body *hclwrite.Body) {
return nil
}
if c, ok := v.v.(*Attribute); ok {
body.SetAttributeTraversal(v.Name, hcl.Traversal{
hcl.TraverseRoot{Name: c.String()},
})
return nil
}
body.SetAttributeValue(v.Name, v.Cty())
tokens := appendTokensForValue(v.v, nil)
body.SetAttributeRaw(v.Name, tokens)
return nil
})
@ -230,3 +227,178 @@ func (r *Resource) doToHCLProvisioner(body *hclwrite.Body) {
p.ToHCL(body)
}
}
var containsInterpolation = regexp.MustCompile(`(?mU)\$\{.*\}`)
func appendTokensForValue(val starlark.Value, toks hclwrite.Tokens) hclwrite.Tokens {
switch v := val.(type) {
case starlark.NoneType:
toks = append(toks, &hclwrite.Token{
Type: hclsyntax.TokenIdent,
Bytes: []byte(`null`),
})
case starlark.Bool:
var src []byte
if v {
src = []byte(`true`)
} else {
src = []byte(`false`)
}
toks = append(toks, &hclwrite.Token{
Type: hclsyntax.TokenIdent,
Bytes: src,
})
case starlark.Float:
bf := big.NewFloat(float64(v))
srcStr := bf.Text('f', -1)
toks = append(toks, &hclwrite.Token{
Type: hclsyntax.TokenNumberLit,
Bytes: []byte(srcStr),
})
case starlark.Int:
bf := v.BigInt()
srcStr := bf.Text('2')
toks = append(toks, &hclwrite.Token{
Type: hclsyntax.TokenNumberLit,
Bytes: []byte(srcStr),
})
case starlark.String:
src := []byte(v.GoString())
if !containsInterpolation.Match(src) {
src = escapeQuotedStringLit(v.GoString())
}
toks = append(toks, &hclwrite.Token{
Type: hclsyntax.TokenOQuote,
Bytes: []byte{'"'},
})
if len(src) > 0 {
toks = append(toks, &hclwrite.Token{
Type: hclsyntax.TokenQuotedLit,
Bytes: []byte(src),
})
}
toks = append(toks, &hclwrite.Token{
Type: hclsyntax.TokenCQuote,
Bytes: []byte{'"'},
})
case *starlark.List:
toks = append(toks, &hclwrite.Token{
Type: hclsyntax.TokenOBrack,
Bytes: []byte{'['},
})
for i := 0; i < v.Len(); i++ {
if i > 0 {
toks = append(toks, &hclwrite.Token{
Type: hclsyntax.TokenComma,
Bytes: []byte{','},
})
}
toks = appendTokensForValue(v.Index(i), toks)
}
toks = append(toks, &hclwrite.Token{
Type: hclsyntax.TokenCBrack,
Bytes: []byte{']'},
})
case *starlark.Dict:
toks = append(toks, &hclwrite.Token{
Type: hclsyntax.TokenOBrace,
Bytes: []byte{'{'},
})
i := 0
for _, eKey := range v.Keys() {
if i > 0 {
toks = append(toks, &hclwrite.Token{
Type: hclsyntax.TokenComma,
Bytes: []byte{','},
})
}
eVal, _, _ := v.Get(eKey)
if hclsyntax.ValidIdentifier(eKey.(starlark.String).GoString()) {
toks = append(toks, &hclwrite.Token{
Type: hclsyntax.TokenIdent,
Bytes: []byte(eKey.(starlark.String).GoString()),
})
} else {
toks = appendTokensForValue(eKey, toks)
}
toks = append(toks, &hclwrite.Token{
Type: hclsyntax.TokenEqual,
Bytes: []byte{'='},
})
toks = appendTokensForValue(eVal, toks)
i++
}
toks = append(toks, &hclwrite.Token{
Type: hclsyntax.TokenCBrace,
Bytes: []byte{'}'},
})
case *Attribute:
toks = append(toks, &hclwrite.Token{
Type: hclsyntax.TokenIdent,
Bytes: []byte(v.sString.String()),
})
default:
panic(fmt.Sprintf("cannot produce tokens for %#v", val))
}
return toks
}
func escapeQuotedStringLit(s string) []byte {
if len(s) == 0 {
return nil
}
buf := make([]byte, 0, len(s))
for i, r := range s {
switch r {
case '\n':
buf = append(buf, '\\', 'n')
case '\r':
buf = append(buf, '\\', 'r')
case '\t':
buf = append(buf, '\\', 't')
case '"':
buf = append(buf, '\\', '"')
case '\\':
buf = append(buf, '\\', '\\')
case '$', '%':
buf = appendRune(buf, r)
remain := s[i+1:]
if len(remain) > 0 && remain[0] == '{' {
// Double up our template introducer symbol to escape it.
buf = appendRune(buf, r)
}
default:
if !unicode.IsPrint(r) {
var fmted string
if r < 65536 {
fmted = fmt.Sprintf("\\u%04x", r)
} else {
fmted = fmt.Sprintf("\\U%08x", r)
}
buf = append(buf, fmted...)
} else {
buf = appendRune(buf, r)
}
}
}
return buf
}
func appendRune(b []byte, r rune) []byte {
l := utf8.RuneLen(r)
for i := 0; i < l; i++ {
b = append(b, 0) // make room at the end of our buffer
}
ch := b[len(b)-l:]
utf8.EncodeRune(ch, r)
return b
}

View File

@ -8,7 +8,7 @@ ami = aws.data.ami()
web = aws.resource.instance()
web.ami = ami.id
assert.eq(type(web.ami), "Attribute<string>")
assert.eq(str(web.ami), '"${data.aws_ami.id_2.id}"')
assert.eq(str(web.ami), "${data.aws_ami.id_2.id}")
assert.eq(web.ami.__resource__, ami)
assert.eq(web.ami.__type__, "string")
@ -18,35 +18,35 @@ assert.eq("__type__" in dir(web.ami), True)
# attribute of set
table = aws.data.dynamodb_table()
assert.eq(str(table.ttl), '"${data.aws_dynamodb_table.id_4.ttl}"')
assert.eq(str(table.ttl[0]), '"${data.aws_dynamodb_table.id_4.ttl.0}"')
assert.eq(str(table.ttl[0].attribute_name), '"${data.aws_dynamodb_table.id_4.ttl.0.attribute_name}"')
assert.eq(str(table.ttl), "${data.aws_dynamodb_table.id_4.ttl}")
assert.eq(str(table.ttl[0]), "${data.aws_dynamodb_table.id_4.ttl.0}")
assert.eq(str(table.ttl[0].attribute_name), "${data.aws_dynamodb_table.id_4.ttl.0.attribute_name}")
# attribute of list
instance = aws.data.instance()
assert.eq(str(instance.credit_specification), '"${data.aws_instance.id_5.credit_specification}"')
assert.eq(str(instance.credit_specification[0]), '"${data.aws_instance.id_5.credit_specification.0}"')
assert.eq(str(instance.credit_specification[0].cpu_credits), '"${data.aws_instance.id_5.credit_specification.0.cpu_credits}"')
assert.eq(str(instance.credit_specification), "${data.aws_instance.id_5.credit_specification}")
assert.eq(str(instance.credit_specification[0]), "${data.aws_instance.id_5.credit_specification.0}")
assert.eq(str(instance.credit_specification[0].cpu_credits), "${data.aws_instance.id_5.credit_specification.0.cpu_credits}")
# attribute of block
attribute = str(aws.resource.instance().root_block_device.volume_size)
assert.eq(attribute, '"${aws_instance.id_6.root_block_device.0.volume_size}"')
assert.eq(attribute, "${aws_instance.id_6.root_block_device.0.volume_size}")
# attribute on data source
assert.eq(str(aws.resource.instance().id), '"${aws_instance.id_7.id}"')
assert.eq(str(aws.resource.instance().id), "${aws_instance.id_7.id}")
# attribute on resource
assert.eq(str(aws.data.ami().id), '"${data.aws_ami.id_8.id}"')
assert.eq(str(aws.data.ami().id), "${data.aws_ami.id_8.id}")
gcp = tf.provider("google", "3.13.0")
# attribute on list with MaxItem:1
cluster = gcp.resource.container_cluster("foo")
assert.eq(str(cluster.master_auth.client_certificate), '"${google_container_cluster.foo.master_auth.0.client_certificate}"')
assert.eq(str(cluster.master_auth.client_certificate), "${google_container_cluster.foo.master_auth.0.client_certificate}")
# attr non-object
assert.fails(lambda: web.ami.foo, "Attribute<string> it's not a object")
# fn wrapping
assert.eq(str(fn("base64encode", web.ami)), '"${base64encode(data.aws_ami.id_2.id)}"')
assert.eq(str(fn("base64encode", web.ami)), "${base64encode(data.aws_ami.id_2.id)}")

View File

@ -11,4 +11,4 @@ instance.ami = ami.id
print(instance.ami)
# Output:
# "${aws_ami.ubuntu.id}"
# ${aws_ami.ubuntu.id}

View File

@ -11,4 +11,32 @@ assert.eq(hcl(helm), "" +
' kubernetes {\n' + \
' token = "foo"\n' + \
' }\n' + \
'}\n\n')
google = tf.provider("google", "3.16.0", "default")
sa = google.resource.service_account("sa")
sa.account_id = "service-account"
m = google.resource.storage_bucket_iam_member(sa.account_id+"-admin")
m.bucket = "main-storage"
m.role = "roles/storage.objectAdmin"
m.member = "serviceAccount:%s" % sa.email
# hcl with interpoaltion
assert.eq(hcl(google), "" +
'provider "google" {\n' + \
' alias = "default"\n' + \
' version = "3.16.0"\n' + \
'}\n' + \
'\n' + \
'resource "google_service_account" "sa" {\n' + \
' provider = google.default\n' + \
' account_id = "service-account"\n' + \
'}\n' + \
'\n' + \
'resource "google_storage_bucket_iam_member" "service-account-admin" {\n' + \
' provider = google.default\n' + \
' bucket = "main-storage"\n' + \
' member = "serviceAccount:${google_service_account.sa.email}"\n' + \
' role = "roles/storage.objectAdmin"\n' + \
'}\n\n')

View File

@ -32,7 +32,7 @@ assert.fails(lambda: qux.foo, "Resource<data> has no .foo field or method")
# attr id
assert.eq(type(qux.id), "Attribute<string>")
assert.eq(str(qux.id), '"${data.ignition_user.id_2.id}"')
assert.eq(str(qux.id), "${data.ignition_user.id_2.id}")
aws = tf.provider("aws", "2.13.0")
# attr output assignation
@ -58,7 +58,7 @@ assert.eq("__kind__" in dir(web), True)
assert.eq("__dict__" in dir(web), True)
# attr optional computed
assert.eq(str(group.name), '"${aws_autoscaling_group.id_6.name}"')
assert.eq(str(group.name), "${aws_autoscaling_group.id_6.name}")
group.name = "foo"
assert.eq(group.name, "foo")
@ -124,7 +124,7 @@ assert.eq(ignition.data.user(groups=["foo"]), ignition.data.user(groups=["foo"])
# constructor with name
quux = ignition.data.user("quux")
assert.eq(str(quux.id), '"${data.ignition_user.quux.id}"')
assert.eq(str(quux.id), "${data.ignition_user.quux.id}")
# constructor from kwargs
bar = ignition.data.user(uid=42, system=True)
@ -135,7 +135,7 @@ assert.eq(bar.system, True)
fred = ignition.data.user("fred", uid=42, system=True)
assert.eq(fred.uid, 42)
assert.eq(fred.system, True)
assert.eq(str(fred.id), '"${data.ignition_user.fred.id}"')
assert.eq(str(fred.id), "${data.ignition_user.fred.id}")
# constructor from dict
foo = ignition.data.user({"uid": 42, "system": True})
@ -146,13 +146,13 @@ assert.eq(foo.system, True)
baz = ignition.data.user("baz", {"uid": 42, "system": True})
assert.eq(baz.uid, 42)
assert.eq(baz.system, True)
assert.eq(str(baz.id), '"${data.ignition_user.baz.id}"')
assert.eq(str(baz.id), "${data.ignition_user.baz.id}")
# constructor from dict with name and kwargs
baz = ignition.data.user("baz", {"uid": 42, "system": True}, uid=84)
assert.eq(baz.uid, 84)
assert.eq(baz.system, True)
assert.eq(str(baz.id), '"${data.ignition_user.baz.id}"')
assert.eq(str(baz.id), "${data.ignition_user.baz.id}")
assert.eq(bar, foo)

View File

@ -27,14 +27,14 @@ func MustTypeFromStarlark(typ string) *Type {
// NewTypeFromStarlark returns a Type from a given starlark type string.
func NewTypeFromStarlark(typ string) (*Type, error) {
t := &Type{}
t.typ = typ
complex := strings.SplitN(typ, "<", 2)
if len(complex) == 2 {
typ = complex[0]
}
t := &Type{}
t.typ = typ
switch typ {
case "bool":
t.cty = cty.Bool

View File

@ -81,7 +81,7 @@ func (v *Value) Cty() cty.Value {
case "Attribute":
return cty.StringVal(v.v.(*Attribute).GoString())
default:
return cty.StringVal(fmt.Sprintf("unhandled: %s", v.t.typ))
panic(fmt.Sprintf("unhandled: %s", v.t.Starlark()))
}
}