diff --git a/Gopkg.lock b/Gopkg.lock
index bad46b33..6c2cba5f 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -28,6 +28,14 @@
pruneopts = ""
revision = "cff30e1d23fc9e800b2b5b4b41ef1817dda07e9f"
+[[projects]]
+ digest = "1:5d47691333460db6ac83ced03c79b4bdb9aff3e322be24affb7855bed8affc6c"
+ name = "github.com/dave/jennifer"
+ packages = ["jen"]
+ pruneopts = ""
+ revision = "14e399b6b5e8456c66c45c955fc27b568bacb5c9"
+ version = "v1.3.0"
+
[[projects]]
digest = "1:aaeffbff5bd24654cb4c190ed75d6c7b57b4f5d6741914c1a7a6bb7447e756c5"
name = "github.com/deckarep/golang-set"
@@ -549,6 +557,7 @@
analyzer-name = "dep"
analyzer-version = 1
input-imports = [
+ "github.com/dave/jennifer/jen",
"github.com/ethereum/go-ethereum",
"github.com/ethereum/go-ethereum/accounts/abi",
"github.com/ethereum/go-ethereum/accounts/abi/bind",
diff --git a/cmd/backfillMakerLogs.go b/cmd/backfillMakerLogs.go
deleted file mode 100644
index f6681c78..00000000
--- a/cmd/backfillMakerLogs.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// VulcanizeDB
-// Copyright © 2018 Vulcanize
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-package cmd
-
-import (
- log "github.com/sirupsen/logrus"
- "github.com/spf13/cobra"
- "github.com/vulcanize/vulcanizedb/libraries/shared"
- "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
- "github.com/vulcanize/vulcanizedb/pkg/transformers"
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
-)
-
-// backfillMakerLogsCmd represents the backfillMakerLogs command
-var backfillMakerLogsCmd = &cobra.Command{
- Use: "backfillMakerLogs",
- Short: "Backfill Maker event logs",
- Long: `Backfills Maker event logs based on previously populated block Header records.
-This currently includes logs related to Multi-collateral Dai (frob), Auctions (flip-kick),
-and Price Feeds (ETH/USD, MKR/USD, and REP/USD - LogValue).
-
-vulcanizedb backfillMakerLogs --config environments/local.toml
-
-This command expects a light sync to have been run, and the presence of header records in the Vulcanize database.`,
- Run: func(cmd *cobra.Command, args []string) {
- backfillMakerLogs()
- },
-}
-
-func backfillMakerLogs() {
- blockChain := getBlockChain()
- db, err := postgres.NewDB(databaseConfig, blockChain.Node())
- if err != nil {
- log.Fatal("Failed to initialize database.")
- }
-
- watcher := shared.NewEventWatcher(db, blockChain)
-
- watcher.AddTransformers(transformers.TransformerInitializers())
- err = watcher.Execute(constants.HeaderMissing)
- if err != nil {
- // TODO Handle watcher error in backfillMakerLogs
- }
-}
-
-func init() {
- rootCmd.AddCommand(backfillMakerLogsCmd)
-}
diff --git a/cmd/composeAndExecute.go b/cmd/composeAndExecute.go
new file mode 100644
index 00000000..4f647802
--- /dev/null
+++ b/cmd/composeAndExecute.go
@@ -0,0 +1,121 @@
+// Copyright © 2019 Vulcanize, Inc
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package cmd
+
+import (
+ "fmt"
+ "log"
+ "os"
+ "plugin"
+ "time"
+
+ "github.com/spf13/cobra"
+
+ "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
+ "github.com/vulcanize/vulcanizedb/libraries/shared/watcher"
+ "github.com/vulcanize/vulcanizedb/pkg/autogen"
+ "github.com/vulcanize/vulcanizedb/utils"
+)
+
+// executePluginCmd represents the execute command
+var composeAndExecuteCmd = &cobra.Command{
+ Use: "composeAndExecute",
+ Short: "Composes, loads, and executes transformer initializer plugin",
+ Long: `This command needs a config .toml file of form:
+
+[database]
+ name = "vulcanize_public"
+ hostname = "localhost"
+ user = "vulcanize"
+ password = "vulcanize"
+ port = 5432
+
+[client]
+ ipcPath = "http://kovan0.vulcanize.io:8545"
+
+[exporter]
+ filePath = "~/go/src/github.com/vulcanize/vulcanizedb/plugins"
+ fileName = "exporter"
+ [exporter.transformers]
+ transformerImport1 = "github.com/path_to/transformerInitializer1"
+ transformerImport2 = "github.com/path_to/transformerInitializer2"
+
+Note: If any of the imported transformer need additional
+config variables do not forget to include those as well
+
+This information is used to write and build a .so with an arbitrary transformer
+set composed from the transformer imports specified in the config file
+This .so is loaded as a plugin and the set of transformer initializers is
+loaded into and executed over by a generic watcher`,
+ Run: func(cmd *cobra.Command, args []string) {
+ composeAndExecute()
+ },
+}
+
+func composeAndExecute() {
+ generator := autogen.NewGenerator(autogenConfig)
+ err := generator.GenerateTransformerPlugin()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ ticker := time.NewTicker(pollingInterval)
+ defer ticker.Stop()
+
+ blockChain := getBlockChain()
+ db := utils.LoadPostgres(databaseConfig, blockChain.Node())
+
+ _, pluginPath, err := autogen.GetPaths(autogenConfig)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ plug, err := plugin.Open(pluginPath)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ symExporter, err := plug.Lookup("Exporter")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ exporter, ok := symExporter.(Exporter)
+ if !ok {
+ fmt.Println("plugged-in symbol not of type Exporter")
+ os.Exit(1)
+ }
+
+ initializers := exporter.Export()
+ w := watcher.NewWatcher(&db, blockChain)
+ w.AddTransformers(initializers)
+
+ for range ticker.C {
+ err := w.Execute()
+ if err != nil {
+ // TODO Handle watcher errors in composeAndExecute
+ }
+ }
+}
+
+type Exporter interface {
+ Export() []transformer.TransformerInitializer
+}
+
+func init() {
+ rootCmd.AddCommand(composeAndExecuteCmd)
+ composeAndExecuteCmd.Flags().Int64VarP(&startingBlockNumber, "starting-block-number", "s", 0, "Block number to start transformer execution from")
+}
diff --git a/cmd/continuousLogSync.go b/cmd/continuousLogSync.go
deleted file mode 100644
index aa7f9c0f..00000000
--- a/cmd/continuousLogSync.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// VulcanizeDB
-// Copyright © 2018 Vulcanize
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-package cmd
-
-import (
- "fmt"
- "time"
-
- log "github.com/sirupsen/logrus"
- "github.com/spf13/cobra"
-
- "github.com/vulcanize/vulcanizedb/libraries/shared"
- "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
- "github.com/vulcanize/vulcanizedb/pkg/transformers"
- shared2 "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
-)
-
-// continuousLogSyncCmd represents the continuousLogSync command
-var continuousLogSyncCmd = &cobra.Command{
- Use: "continuousLogSync",
- Short: "Continuously sync logs at the head of the chain",
- Long: fmt.Sprintf(`Continously syncs logs based on the configured transformers.
-
-vulcanizedb continousLogSync --config environments/local.toml
-
-Available transformers for (optional) selection with --transformers:
-%v
-
-This command expects a light sync to have been run, and the presence of header records in the Vulcanize database.`,
- constants.AllTransformerLabels()),
- Run: func(cmd *cobra.Command, args []string) {
- syncMakerLogs()
- },
-}
-
-var transformerNames []string
-var recheckHeadersArg bool
-
-func syncMakerLogs() {
- ticker := time.NewTicker(pollingInterval)
- defer ticker.Stop()
-
- blockChain := getBlockChain()
- db, err := postgres.NewDB(databaseConfig, blockChain.Node())
- if err != nil {
- log.Fatal("Failed to initialize database.")
- }
-
- initializers := getTransformerInitializers(transformerNames)
-
- watcher := shared.NewEventWatcher(db, blockChain)
- watcher.AddTransformers(initializers)
-
- for range ticker.C {
- if recheckHeadersArg {
- err = watcher.Execute(constants.HeaderRecheck)
- } else {
- err = watcher.Execute(constants.HeaderMissing)
- }
- if err != nil {
- // TODO Handle watcher errors in ContinuousLogSync
- }
- }
-}
-
-func getTransformerInitializers(transformerNames []string) []shared2.TransformerInitializer {
- var initializers []shared2.TransformerInitializer
-
- if transformerNames[0] == "all" {
- initializers = transformers.TransformerInitializers()
- } else {
- initializerMap := buildTransformerInitializerMap()
- for _, transformerName := range transformerNames {
- initializers = append(initializers, initializerMap[transformerName])
- }
- }
- return initializers
-}
-
-func buildTransformerInitializerMap() map[string]shared2.TransformerInitializer {
- initializerMap := make(map[string]shared2.TransformerInitializer)
-
- initializerMap[constants.BiteLabel] = transformers.GetBiteTransformer().NewTransformer
- initializerMap[constants.CatFileChopLumpLabel] = transformers.GetCatFileChopLumpTransformer().NewLogNoteTransformer
- initializerMap[constants.CatFileFlipLabel] = transformers.GetCatFileFlipTransformer().NewLogNoteTransformer
- initializerMap[constants.CatFilePitVowLabel] = transformers.GetCatFilePitVowTransformer().NewLogNoteTransformer
- initializerMap[constants.DealLabel] = transformers.GetDealTransformer().NewLogNoteTransformer
- initializerMap[constants.DentLabel] = transformers.GetDentTransformer().NewLogNoteTransformer
- initializerMap[constants.DripDripLabel] = transformers.GetDripDripTransformer().NewLogNoteTransformer
- initializerMap[constants.DripFileIlkLabel] = transformers.GetDripFileIlkTransformer().NewLogNoteTransformer
- initializerMap[constants.DripFileRepoLabel] = transformers.GetDripFileRepoTransformer().NewLogNoteTransformer
- initializerMap[constants.DripFileVowLabel] = transformers.GetDripFileVowTransformer().NewLogNoteTransformer
- initializerMap[constants.FlapKickLabel] = transformers.GetFlapKickTransformer().NewTransformer
- initializerMap[constants.FlipKickLabel] = transformers.GetFlipKickTransformer().NewTransformer
- initializerMap[constants.FlopKickLabel] = transformers.GetFlopKickTransformer().NewTransformer
- initializerMap[constants.FrobLabel] = transformers.GetFrobTransformer().NewTransformer
- initializerMap[constants.PitFileDebtCeilingLabel] = transformers.GetPitFileDebtCeilingTransformer().NewLogNoteTransformer
- initializerMap[constants.PitFileIlkLabel] = transformers.GetPitFileIlkTransformer().NewLogNoteTransformer
- initializerMap[constants.PriceFeedLabel] = transformers.GetPriceFeedTransformer().NewLogNoteTransformer
- initializerMap[constants.TendLabel] = transformers.GetTendTransformer().NewLogNoteTransformer
- initializerMap[constants.VatFluxLabel] = transformers.GetVatFluxTransformer().NewLogNoteTransformer
- initializerMap[constants.VatFoldLabel] = transformers.GetVatFoldTransformer().NewLogNoteTransformer
- initializerMap[constants.VatGrabLabel] = transformers.GetVatGrabTransformer().NewLogNoteTransformer
- initializerMap[constants.VatHealLabel] = transformers.GetVatHealTransformer().NewLogNoteTransformer
- initializerMap[constants.VatInitLabel] = transformers.GetVatInitTransformer().NewLogNoteTransformer
- initializerMap[constants.VatMoveLabel] = transformers.GetVatMoveTransformer().NewLogNoteTransformer
- initializerMap[constants.VatSlipLabel] = transformers.GetVatSlipTransformer().NewLogNoteTransformer
- initializerMap[constants.VatTollLabel] = transformers.GetVatTollTransformer().NewLogNoteTransformer
- initializerMap[constants.VatTuneLabel] = transformers.GetVatTuneTransformer().NewLogNoteTransformer
- initializerMap[constants.VowFlogLabel] = transformers.GetFlogTransformer().NewLogNoteTransformer
-
- return initializerMap
-}
-
-func init() {
- rootCmd.AddCommand(continuousLogSyncCmd)
- continuousLogSyncCmd.Flags().StringSliceVar(&transformerNames, "transformers", []string{"all"}, "transformer names to be run during this command")
- continuousLogSyncCmd.Flags().BoolVar(&recheckHeadersArg, "recheckHeaders", false, "checks headers that are already checked for each transformer.")
-}
diff --git a/cmd/root.go b/cmd/root.go
index 6b72c593..af2ea008 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -28,6 +28,7 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
+ "github.com/vulcanize/vulcanizedb/pkg/autogen"
"github.com/vulcanize/vulcanizedb/pkg/config"
"github.com/vulcanize/vulcanizedb/pkg/geth"
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
@@ -38,6 +39,7 @@ import (
var (
cfgFile string
databaseConfig config.Database
+ autogenConfig autogen.Config
ipc string
levelDbPath string
startingBlockNumber int64
@@ -53,7 +55,7 @@ const (
var rootCmd = &cobra.Command{
Use: "vulcanizedb",
- PersistentPreRun: database,
+ PersistentPreRun: configure,
}
func Execute() {
@@ -63,7 +65,7 @@ func Execute() {
}
}
-func database(cmd *cobra.Command, args []string) {
+func configure(cmd *cobra.Command, args []string) {
ipc = viper.GetString("client.ipcpath")
levelDbPath = viper.GetString("client.leveldbpath")
storageDiffsPath = viper.GetString("filesystem.storageDiffsPath")
@@ -74,6 +76,11 @@ func database(cmd *cobra.Command, args []string) {
User: viper.GetString("database.user"),
Password: viper.GetString("database.password"),
}
+ autogenConfig = autogen.Config{
+ FilePath: viper.GetString("exporter.filePath"),
+ FileName: viper.GetString("exporter.fileName"),
+ Imports: viper.GetStringMapString("exporter.transformers"),
+ }
viper.Set("database.config", databaseConfig)
}
@@ -93,6 +100,8 @@ func init() {
rootCmd.PersistentFlags().String("client-levelDbPath", "", "location of levelDb chaindata")
rootCmd.PersistentFlags().String("datadog-name", "vulcanize-test", "datadog service name")
rootCmd.PersistentFlags().String("filesystem-storageDiffsPath", "", "location of storage diffs csv file")
+ rootCmd.PersistentFlags().String("exporter-path", "~/go/src/github.com/vulcanize/vulcanizedb/plugins", "file path to transformer exporter plugin")
+ rootCmd.PersistentFlags().String("exporter-name", "exporter", "name of exporter plugin")
viper.BindPFlag("database.name", rootCmd.PersistentFlags().Lookup("database-name"))
viper.BindPFlag("database.port", rootCmd.PersistentFlags().Lookup("database-port"))
@@ -103,6 +112,8 @@ func init() {
viper.BindPFlag("client.levelDbPath", rootCmd.PersistentFlags().Lookup("client-levelDbPath"))
viper.BindPFlag("datadog.name", rootCmd.PersistentFlags().Lookup("datadog-name"))
viper.BindPFlag("filesystem.storageDiffsPath", rootCmd.PersistentFlags().Lookup("filesystem-storageDiffsPath"))
+ viper.BindPFlag("exporter.filePath", rootCmd.PersistentFlags().Lookup("exporter-path"))
+ viper.BindPFlag("exporter.fileName", rootCmd.PersistentFlags().Lookup("exporter-name"))
}
func initConfig() {
diff --git a/environments/compose.toml b/environments/compose.toml
new file mode 100644
index 00000000..eb3b43d4
--- /dev/null
+++ b/environments/compose.toml
@@ -0,0 +1,82 @@
+[database]
+ name = "vulcanize_public"
+ hostname = "localhost"
+ user = "vulcanize"
+ password = "vulcanize"
+ port = 5432
+
+[client]
+ ipcPath = "http://kovan0.vulcanize.io:8545"
+
+[datadog]
+ name = "maker_vdb_staging"
+
+[exporter]
+ filePath = "$GOPATH/src/github.com/vulcanize/vulcanizedb/plugins/"
+ fileName = "exporter"
+ [exporter.transformers]
+ bite = "github.com/vulcanize/mcd_transformers/transformers/bite"
+ cat_chop_lump = "github.com/vulcanize/maker_transformers/cat/chop_lump"
+ cat_flip = "github.com/vulcanize/mcd_transformers/transformers/cat/flip"
+ cat_pit_vow = "github.com/vulcanize/mcd_transformers/transformers/cat/pit_vow"
+ deal = "github.com/vulcanize/mcd_transformers/transformers/deal"
+ dent = "github.com/vulcanize/mcd_transformers/transformers/dent"
+ drip_drip = "github.com/vulcanize/mcd_transformers/transformers/drip_drip"
+ drip_file_ilk = "github.com/vulcanize/mcd_transformers/transformers/drip_file/ilk"
+ drip_file_repo = "github.com/vulcanize/mcd_transformers/transformers/drip_file/repo"
+ drip_file_vow = "github.com/vulcanize/mcd_transformers/transformers/drip_file/vow"
+ flap_kick = "github.com/vulcanize/mcd_transformers/transformers/flap_kick"
+ flip_kick = "github.com/vulcanize/mcd_transformers/transformers/flip_kick"
+ flop_kick = "github.com/vulcanize/mcd_transformers/transformers/flop_kick"
+ frob = "github.com/vulcanize/mcd_transformers/transformers/frob"
+ pit_file_debt_ceiling = "github.com/vulcanize/mcd_transformers/transformers/pit_file/debt_ceiling"
+ pit_file_ilk = "github.com/vulcanize/mcd_transformers/transformers/pit_file/ilk"
+ price_feeds = "github.com/vulcanize/mcd_transformers/transformers/price_feeds"
+ tend = "github.com/vulcanize/mcd_transformers/transformers/tend"
+ vat_flux = "github.com/vulcanize/mcd_transformers/transformers/vat_flux"
+ vat_fold = "github.com/vulcanize/mcd_transformers/transformers/vat_fold"
+ vat_grab = "github.com/vulcanize/mcd_transformers/transformers/vat_grab"
+ vat_heal = "github.com/vulcanize/mcd_transformers/transformers/vat_heal"
+ vat_init = "github.com/vulcanize/mcd_transformers/transformers/vat_init"
+ vat_move = "github.com/vulcanize/mcd_transformers/transformers/vat_move"
+ vat_slip = "github.com/vulcanize/mcd_transformers/transformers/vat_slip"
+ vat_toll = "github.com/vulcanize/mcd_transformers/transformers/vat_toll"
+ vat_tune = "github.com/vulcanize/mcd_transformers/transformers/vat_tune"
+ vow_flog = "github.com/vulcanize/mcd_transformers/transformers/vow_flog"
+
+[contract]
+ [contract.address]
+ cat = "0x2f34f22a00ee4b7a8f8bbc4eaee1658774c624e0"
+ drip = "0x891c04639a5edcae088e546fa125b5d7fb6a2b9d"
+ eth_flip = "0x32D496Ad866D110060866B7125981C73642cc509"
+ mcd_flap = "0x8868BAd8e74FcA4505676D1B5B21EcC23328d132"
+ mcd_flop = "0x6191C9b0086c2eBF92300cC507009b53996FbFFa"
+ pep = "0xB1997239Cfc3d15578A3a09730f7f84A90BB4975"
+ pip = "0x9FfFE440258B79c5d6604001674A4722FfC0f7Bc"
+ pit = "0xe7cf3198787c9a4daac73371a38f29aaeeced87e"
+ rep = "0xf88bbdc1e2718f8857f30a180076ec38d53cf296"
+ vat = "0xcd726790550afcd77e9a7a47e86a3f9010af126b"
+ vow = "0x3728e9777B2a0a611ee0F89e00E01044ce4736d1"
+ [contract.abi]
+ cat = '[{"constant":true,"inputs":[],"name":"vat","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x36569e77"},{"constant":true,"inputs":[],"name":"vow","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x626cb3c5"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"flips","outputs":[{"name":"ilk","type":"bytes32"},{"name":"urn","type":"bytes32"},{"name":"ink","type":"uint256"},{"name":"tab","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x70d9235a"},{"constant":true,"inputs":[],"name":"nflip","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x76181a51"},{"constant":true,"inputs":[],"name":"live","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x957aa58c"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"wards","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xbf353dbb"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"ilks","outputs":[{"name":"flip","type":"address"},{"name":"chop","type":"uint256"},{"name":"lump","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xd9638d36"},{"constant":true,"inputs":[],"name":"pit","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xf03c7c6e"},{"inputs":[{"name":"vat_","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor","signature":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"ilk","type":"bytes32"},{"indexed":true,"name":"urn","type":"bytes32"},{"indexed":false,"name":"ink","type":"uint256"},{"indexed":false,"name":"art","type":"uint256"},{"indexed":false,"name":"tab","type":"uint256"},{"indexed":false,"name":"flip","type":"uint256"},{"indexed":false,"name":"iArt","type":"uint256"}],"name":"Bite","type":"event","signature":"0x99b5620489b6ef926d4518936cfec15d305452712b88bd59da2d9c10fb0953e8"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event","signature":"0x644843f351d3fba4abcd60109eaff9f54bac8fb8ccf0bab941009c21df21cf31"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"rely","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x65fae35e"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"deny","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x9c52a7f1"},{"constant":false,"inputs":[{"name":"ilk","type":"bytes32"},{"name":"what","type":"bytes32"},{"name":"data","type":"uint256"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x1a0b287e"},{"constant":false,"inputs":[{"name":"what","type":"bytes32"},{"name":"data","type":"address"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xd4e8be83"},{"constant":false,"inputs":[{"name":"ilk","type":"bytes32"},{"name":"what","type":"bytes32"},{"name":"flip","type":"address"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xebecb39d"},{"constant":false,"inputs":[{"name":"ilk","type":"bytes32"},{"name":"urn","type":"bytes32"}],"name":"bite","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x72f7b593"},{"constant":false,"inputs":[{"name":"n","type":"uint256"},{"name":"wad","type":"uint256"}],"name":"flip","outputs":[{"name":"id","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xe6f95917"}]'
+ drip = '[{"constant":true,"inputs":[],"name":"vat","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x36569e77"},{"constant":true,"inputs":[],"name":"repo","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x56ff3122"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"wards","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xbf353dbb"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"ilks","outputs":[{"name":"vow","type":"bytes32"},{"name":"tax","type":"uint256"},{"name":"rho","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xd9638d36"},{"inputs":[{"name":"vat_","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor","signature":"constructor"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event","signature":"0x644843f351d3fba4abcd60109eaff9f54bac8fb8ccf0bab941009c21df21cf31"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"rely","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x65fae35e"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"deny","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x9c52a7f1"},{"constant":true,"inputs":[],"name":"era","outputs":[{"name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x143e55e0"},{"constant":false,"inputs":[{"name":"ilk","type":"bytes32"},{"name":"vow","type":"bytes32"},{"name":"tax","type":"uint256"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x1a0b287e"},{"constant":false,"inputs":[{"name":"what","type":"bytes32"},{"name":"data","type":"uint256"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x29ae8114"},{"constant":false,"inputs":[{"name":"ilk","type":"bytes32"}],"name":"drip","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x44e2a5a8"}]'
+ mcd_flap = '[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"bids","outputs":[{"name":"bid","type":"uint256"},{"name":"lot","type":"uint256"},{"name":"guy","type":"address"},{"name":"tic","type":"uint48"},{"name":"end","type":"uint48"},{"name":"gal","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ttl","outputs":[{"name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"gem","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"beg","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tau","outputs":[{"name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kicks","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"dai","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"dai_","type":"address"},{"name":"gem_","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"uint256"},{"indexed":false,"name":"lot","type":"uint256"},{"indexed":false,"name":"bid","type":"uint256"},{"indexed":false,"name":"gal","type":"address"},{"indexed":false,"name":"end","type":"uint48"}],"name":"Kick","type":"event"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"},{"constant":false,"inputs":[{"name":"gal","type":"address"},{"name":"lot","type":"uint256"},{"name":"bid","type":"uint256"}],"name":"kick","outputs":[{"name":"id","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"lot","type":"uint256"},{"name":"bid","type":"uint256"}],"name":"tend","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"id","type":"uint256"}],"name":"deal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]'
+ eth_flip = '[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"bids","outputs":[{"name":"bid","type":"uint256"},{"name":"lot","type":"uint256"},{"name":"guy","type":"address"},{"name":"tic","type":"uint48"},{"name":"end","type":"uint48"},{"name":"urn","type":"bytes32"},{"name":"gal","type":"address"},{"name":"tab","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x4423c5f1"},{"constant":true,"inputs":[],"name":"ttl","outputs":[{"name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x4e8b1dd5"},{"constant":true,"inputs":[],"name":"gem","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x7bd2bea7"},{"constant":true,"inputs":[],"name":"beg","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x7d780d82"},{"constant":true,"inputs":[],"name":"tau","outputs":[{"name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xcfc4af55"},{"constant":true,"inputs":[],"name":"kicks","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xcfdd3302"},{"constant":true,"inputs":[],"name":"dai","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xf4b9fa75"},{"inputs":[{"name":"dai_","type":"address"},{"name":"gem_","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor","signature":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"uint256"},{"indexed":false,"name":"lot","type":"uint256"},{"indexed":false,"name":"bid","type":"uint256"},{"indexed":false,"name":"gal","type":"address"},{"indexed":false,"name":"end","type":"uint48"},{"indexed":true,"name":"urn","type":"bytes32"},{"indexed":false,"name":"tab","type":"uint256"}],"name":"Kick","type":"event","signature":"0xbac86238bdba81d21995024470425ecb370078fa62b7271b90cf28cbd1e3e87e"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event","signature":"0x644843f351d3fba4abcd60109eaff9f54bac8fb8ccf0bab941009c21df21cf31"},{"constant":true,"inputs":[],"name":"era","outputs":[{"name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x143e55e0"},{"constant":false,"inputs":[{"name":"urn","type":"bytes32"},{"name":"gal","type":"address"},{"name":"tab","type":"uint256"},{"name":"lot","type":"uint256"},{"name":"bid","type":"uint256"}],"name":"kick","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xeae19d9e"},{"constant":false,"inputs":[{"name":"id","type":"uint256"}],"name":"tick","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xfc7b6aee"},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"lot","type":"uint256"},{"name":"bid","type":"uint256"}],"name":"tend","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x4b43ed12"},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"lot","type":"uint256"},{"name":"bid","type":"uint256"}],"name":"dent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x5ff3a382"},{"constant":false,"inputs":[{"name":"id","type":"uint256"}],"name":"deal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xc959c42b"}]'
+ mcd_flop = '[{"constant":true,"inputs":[],"name":"era","outputs":[{"name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"bids","outputs":[{"name":"bid","type":"uint256"},{"name":"lot","type":"uint256"},{"name":"guy","type":"address"},{"name":"tic","type":"uint48"},{"name":"end","type":"uint48"},{"name":"vow","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ttl","outputs":[{"name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"lot","type":"uint256"},{"name":"bid","type":"uint256"}],"name":"dent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"rely","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"gem","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"beg","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"deny","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"gal","type":"address"},{"name":"lot","type":"uint256"},{"name":"bid","type":"uint256"}],"name":"kick","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"wards","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"id","type":"uint256"}],"name":"deal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"tau","outputs":[{"name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kicks","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"dai","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"dai_","type":"address"},{"name":"gem_","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"uint256"},{"indexed":false,"name":"lot","type":"uint256"},{"indexed":false,"name":"bid","type":"uint256"},{"indexed":false,"name":"gal","type":"address"},{"indexed":false,"name":"end","type":"uint48"}],"name":"Kick","type":"event"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"}]'
+ medianizer = '[{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"","type":"bytes32"}],"name":"poke","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"poke","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"compute","outputs":[{"name":"","type":"bytes32"},{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"wat","type":"address"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wat","type":"address"}],"name":"unset","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"indexes","outputs":[{"name":"","type":"bytes12"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"next","outputs":[{"name":"","type":"bytes12"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"read","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"peek","outputs":[{"name":"","type":"bytes32"},{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes12"}],"name":"values","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"min_","type":"uint96"}],"name":"setMin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"void","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"pos","type":"bytes12"},{"name":"wat","type":"address"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"pos","type":"bytes12"}],"name":"unset","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"next_","type":"bytes12"}],"name":"setNext","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"min","outputs":[{"name":"","type":"uint96"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"val","type":"bytes32"}],"name":"LogValue","type":"event"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"}]]'
+ # TODO: replace with updated ABI when contract is deployed (with no pit file stability fee method + modified Frob event)
+ pit = '[{"constant":true,"inputs":[],"name":"vat","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x36569e77"},{"constant":true,"inputs":[],"name":"live","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x957aa58c"},{"constant":true,"inputs":[],"name":"drip","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x9f678cca"},{"constant":true,"inputs":[],"name":"Line","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xbabe8a3f"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"wards","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xbf353dbb"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"ilks","outputs":[{"name":"spot","type":"uint256"},{"name":"line","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xd9638d36"},{"inputs":[{"name":"vat_","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor","signature":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"ilk","type":"bytes32"},{"indexed":true,"name":"urn","type":"bytes32"},{"indexed":false,"name":"ink","type":"uint256"},{"indexed":false,"name":"art","type":"uint256"},{"indexed":false,"name":"dink","type":"int256"},{"indexed":false,"name":"dart","type":"int256"},{"indexed":false,"name":"iArt","type":"uint256"}],"name":"Frob","type":"event","signature":"0xb2afa28318bcc689926b52835d844de174ef8de97e982a85c0199d584920791b"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event","signature":"0x644843f351d3fba4abcd60109eaff9f54bac8fb8ccf0bab941009c21df21cf31"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"rely","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x65fae35e"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"deny","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x9c52a7f1"},{"constant":false,"inputs":[{"name":"ilk","type":"bytes32"},{"name":"what","type":"bytes32"},{"name":"data","type":"uint256"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x1a0b287e"},{"constant":false,"inputs":[{"name":"what","type":"bytes32"},{"name":"data","type":"uint256"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x29ae8114"},{"constant":false,"inputs":[{"name":"what","type":"bytes32"},{"name":"data","type":"address"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xd4e8be83"},{"constant":false,"inputs":[{"name":"ilk","type":"bytes32"},{"name":"dink","type":"int256"},{"name":"dart","type":"int256"}],"name":"frob","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x5a984ded"}]'
+ vat = '[{"constant":true,"inputs":[],"name":"debt","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x0dca59c1"},{"constant":true,"inputs":[{"name":"","type":"bytes32"},{"name":"","type":"bytes32"}],"name":"urns","outputs":[{"name":"ink","type":"uint256"},{"name":"art","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x26e27482"},{"constant":true,"inputs":[],"name":"vice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x2d61a355"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"sin","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xa60f1d3e"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"wards","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xbf353dbb"},{"constant":true,"inputs":[{"name":"","type":"bytes32"},{"name":"","type":"bytes32"}],"name":"gem","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xc0912683"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"ilks","outputs":[{"name":"take","type":"uint256"},{"name":"rate","type":"uint256"},{"name":"Ink","type":"uint256"},{"name":"Art","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xd9638d36"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"dai","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xf53e4e69"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor","signature":"constructor"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":true,"name":"too","type":"bytes32"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"Note","type":"event","signature":"0x8c2dbbc2b33ffaa77c104b777e574a8a4ff79829dfee8b66f4dc63e3f8067152"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"rely","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x65fae35e"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"deny","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x9c52a7f1"},{"constant":false,"inputs":[{"name":"ilk","type":"bytes32"}],"name":"init","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x3b663195"},{"constant":false,"inputs":[{"name":"ilk","type":"bytes32"},{"name":"guy","type":"bytes32"},{"name":"rad","type":"int256"}],"name":"slip","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x42066cbb"},{"constant":false,"inputs":[{"name":"ilk","type":"bytes32"},{"name":"src","type":"bytes32"},{"name":"dst","type":"bytes32"},{"name":"rad","type":"int256"}],"name":"flux","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xa6e41821"},{"constant":false,"inputs":[{"name":"src","type":"bytes32"},{"name":"dst","type":"bytes32"},{"name":"rad","type":"int256"}],"name":"move","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x78f19470"},{"constant":false,"inputs":[{"name":"i","type":"bytes32"},{"name":"u","type":"bytes32"},{"name":"v","type":"bytes32"},{"name":"w","type":"bytes32"},{"name":"dink","type":"int256"},{"name":"dart","type":"int256"}],"name":"tune","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x5dd6471a"},{"constant":false,"inputs":[{"name":"i","type":"bytes32"},{"name":"u","type":"bytes32"},{"name":"v","type":"bytes32"},{"name":"w","type":"bytes32"},{"name":"dink","type":"int256"},{"name":"dart","type":"int256"}],"name":"grab","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x3690ae4c"},{"constant":false,"inputs":[{"name":"u","type":"bytes32"},{"name":"v","type":"bytes32"},{"name":"rad","type":"int256"}],"name":"heal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x990a5f63"},{"constant":false,"inputs":[{"name":"i","type":"bytes32"},{"name":"u","type":"bytes32"},{"name":"rate","type":"int256"}],"name":"fold","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xe6a6a64d"},{"constant":false,"inputs":[{"name":"i","type":"bytes32"},{"name":"u","type":"bytes32"},{"name":"take","type":"int256"}],"name":"toll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x09b7a0b5"}]'
+ vow = '[{"constant":true,"inputs":[],"name":"Awe","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"Joy","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"flap","outputs":[{"name":"id","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"hump","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"kiss","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"what","type":"bytes32"},{"name":"data","type":"uint256"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"Ash","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"era","type":"uint48"}],"name":"flog","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"vat","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"Woe","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"wait","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"rely","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"bump","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"tab","type":"uint256"}],"name":"fess","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"row","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint48"}],"name":"sin","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"}],"name":"deny","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"flop","outputs":[{"name":"id","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"wards","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"sump","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"Sin","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"what","type":"bytes32"},{"name":"addr","type":"address"}],"name":"file","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"cow","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"heal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"}]'
+ [contract.deployment-block]
+ cat = 8751794
+ drip = 8762197
+ eth_flip = 8535561
+ mcd_flap = 8535544
+ mcd_flop = 8535545
+ pep = 8760655
+ pip = 8760588
+ pit = 8535538
+ rep = 8760681
+ vat = 8535536
+ vow = 8751792
diff --git a/pkg/transformers/shared/transformer.go b/libraries/shared/transformer/transformer.go
similarity index 61%
rename from pkg/transformers/shared/transformer.go
rename to libraries/shared/transformer/transformer.go
index 7d3c7164..e9e68a5e 100644
--- a/pkg/transformers/shared/transformer.go
+++ b/libraries/shared/transformer/transformer.go
@@ -1,20 +1,7 @@
-// VulcanizeDB
-// Copyright © 2018 Vulcanize
+// Auto-gen this code for different transformer interfaces/configs
+// based on config file to allow for more modularity
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-package shared
+package transformer
import (
"github.com/ethereum/go-ethereum/common"
diff --git a/libraries/shared/transformer/transformer_suite_test.go b/libraries/shared/transformer/transformer_suite_test.go
new file mode 100644
index 00000000..83486c5e
--- /dev/null
+++ b/libraries/shared/transformer/transformer_suite_test.go
@@ -0,0 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package transformer_test
+
+import (
+ "io/ioutil"
+ "log"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestShared(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Shared Transformer Suite")
+}
+
+var _ = BeforeSuite(func() {
+ log.SetOutput(ioutil.Discard)
+})
diff --git a/libraries/shared/transformer/transformer_test.go b/libraries/shared/transformer/transformer_test.go
new file mode 100644
index 00000000..bc6e0255
--- /dev/null
+++ b/libraries/shared/transformer/transformer_test.go
@@ -0,0 +1,17 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package transformer_test
diff --git a/libraries/shared/event_watcher.go b/libraries/shared/watcher/event_watcher.go
similarity index 85%
rename from libraries/shared/event_watcher.go
rename to libraries/shared/watcher/event_watcher.go
index bdcf0554..ef11caef 100644
--- a/libraries/shared/event_watcher.go
+++ b/libraries/shared/watcher/event_watcher.go
@@ -14,12 +14,15 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-package shared
+package watcher
import (
"fmt"
+
"github.com/ethereum/go-ethereum/common"
log "github.com/sirupsen/logrus"
+
+ "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
@@ -27,7 +30,7 @@ import (
)
type EventWatcher struct {
- Transformers []shared.Transformer
+ Transformers []transformer.Transformer
DB *postgres.DB
Fetcher shared.LogFetcher
Chunker shared.Chunker
@@ -47,16 +50,16 @@ func NewEventWatcher(db *postgres.DB, bc core.BlockChain) EventWatcher {
}
// Adds transformers to the watcher and updates the chunker, so that it will consider the new transformers.
-func (watcher *EventWatcher) AddTransformers(initializers []shared.TransformerInitializer) {
+func (watcher *EventWatcher) AddTransformers(initializers []transformer.TransformerInitializer) {
var contractAddresses []common.Address
var topic0s []common.Hash
- var configs []shared.TransformerConfig
+ var configs []transformer.TransformerConfig
for _, initializer := range initializers {
- transformer := initializer(watcher.DB)
- watcher.Transformers = append(watcher.Transformers, transformer)
+ t := initializer(watcher.DB)
+ watcher.Transformers = append(watcher.Transformers, t)
- config := transformer.GetConfig()
+ config := t.GetConfig()
configs = append(configs, config)
if watcher.StartingBlock == nil {
@@ -65,7 +68,7 @@ func (watcher *EventWatcher) AddTransformers(initializers []shared.TransformerIn
watcher.StartingBlock = &config.StartingBlockNumber
}
- addresses := shared.HexStringsToAddresses(config.ContractAddresses)
+ addresses := transformer.HexStringsToAddresses(config.ContractAddresses)
contractAddresses = append(contractAddresses, addresses...)
topic0s = append(topic0s, common.HexToHash(config.Topic))
}
@@ -105,10 +108,10 @@ func (watcher *EventWatcher) Execute(recheckHeaders constants.TransformerExecuti
// Can't quit early and mark as checked if there are no logs. If we are running continuousLogSync,
// not all logs we're interested in might have been fetched.
- for _, transformer := range watcher.Transformers {
- transformerName := transformer.GetConfig().TransformerName
+ for _, t := range watcher.Transformers {
+ transformerName := t.GetConfig().TransformerName
logChunk := chunkedLogs[transformerName]
- err = transformer.Execute(logChunk, header, constants.HeaderMissing)
+ err = t.Execute(logChunk, header, constants.HeaderMissing)
if err != nil {
log.Errorf("%v transformer failed to execute in watcher: %v", transformerName, err)
return err
diff --git a/libraries/shared/event_watcher_test.go b/libraries/shared/watcher/event_watcher_test.go
similarity index 66%
rename from libraries/shared/event_watcher_test.go
rename to libraries/shared/watcher/event_watcher_test.go
index 485b3682..345756ab 100644
--- a/libraries/shared/event_watcher_test.go
+++ b/libraries/shared/watcher/event_watcher_test.go
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-package shared_test
+package watcher_test
import (
"errors"
@@ -25,85 +25,85 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
- "github.com/vulcanize/vulcanizedb/libraries/shared"
+ "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
+ "github.com/vulcanize/vulcanizedb/libraries/shared/watcher"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
"github.com/vulcanize/vulcanizedb/pkg/fakes"
- shared2 "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data/mocks"
"github.com/vulcanize/vulcanizedb/test_config"
)
-var _ = Describe("EventWatcher", func() {
+var _ = Describe("Watcher", func() {
It("initialises correctly", func() {
db := test_config.NewTestDB(core.Node{ID: "testNode"})
bc := fakes.NewMockBlockChain()
- watcher := shared.NewEventWatcher(db, bc)
+ w := watcher.NewEventWatcher(db, bc)
- Expect(watcher.DB).To(Equal(db))
- Expect(watcher.Fetcher).NotTo(BeNil())
- Expect(watcher.Chunker).NotTo(BeNil())
+ Expect(w.DB).To(Equal(db))
+ Expect(w.Fetcher).NotTo(BeNil())
+ Expect(w.Chunker).NotTo(BeNil())
})
It("adds transformers", func() {
- watcher := shared.NewEventWatcher(nil, nil)
+ w := watcher.NewEventWatcher(nil, nil)
fakeTransformer := &mocks.MockTransformer{}
fakeTransformer.SetTransformerConfig(mocks.FakeTransformerConfig)
- watcher.AddTransformers([]shared2.TransformerInitializer{fakeTransformer.FakeTransformerInitializer})
+ w.AddTransformers([]transformer.TransformerInitializer{fakeTransformer.FakeTransformerInitializer})
- Expect(len(watcher.Transformers)).To(Equal(1))
- Expect(watcher.Transformers).To(ConsistOf(fakeTransformer))
- Expect(watcher.Topics).To(Equal([]common.Hash{common.HexToHash("FakeTopic")}))
- Expect(watcher.Addresses).To(Equal([]common.Address{common.HexToAddress("FakeAddress")}))
+ Expect(len(w.Transformers)).To(Equal(1))
+ Expect(w.Transformers).To(ConsistOf(fakeTransformer))
+ Expect(w.Topics).To(Equal([]common.Hash{common.HexToHash("FakeTopic")}))
+ Expect(w.Addresses).To(Equal([]common.Address{common.HexToAddress("FakeAddress")}))
})
It("adds transformers from multiple sources", func() {
- watcher := shared.NewEventWatcher(nil, nil)
+ w := watcher.NewEventWatcher(nil, nil)
fakeTransformer1 := &mocks.MockTransformer{}
fakeTransformer1.SetTransformerConfig(mocks.FakeTransformerConfig)
fakeTransformer2 := &mocks.MockTransformer{}
fakeTransformer2.SetTransformerConfig(mocks.FakeTransformerConfig)
- watcher.AddTransformers([]shared2.TransformerInitializer{fakeTransformer1.FakeTransformerInitializer})
- watcher.AddTransformers([]shared2.TransformerInitializer{fakeTransformer2.FakeTransformerInitializer})
+ w.AddTransformers([]transformer.TransformerInitializer{fakeTransformer1.FakeTransformerInitializer})
+ w.AddTransformers([]transformer.TransformerInitializer{fakeTransformer2.FakeTransformerInitializer})
- Expect(len(watcher.Transformers)).To(Equal(2))
- Expect(watcher.Topics).To(Equal([]common.Hash{common.HexToHash("FakeTopic"),
+ Expect(len(w.Transformers)).To(Equal(2))
+ Expect(w.Topics).To(Equal([]common.Hash{common.HexToHash("FakeTopic"),
common.HexToHash("FakeTopic")}))
- Expect(watcher.Addresses).To(Equal([]common.Address{common.HexToAddress("FakeAddress"),
+ Expect(w.Addresses).To(Equal([]common.Address{common.HexToAddress("FakeAddress"),
common.HexToAddress("FakeAddress")}))
})
It("calculates earliest starting block number", func() {
fakeTransformer1 := &mocks.MockTransformer{}
- fakeTransformer1.SetTransformerConfig(shared2.TransformerConfig{StartingBlockNumber: 5})
+ fakeTransformer1.SetTransformerConfig(transformer.TransformerConfig{StartingBlockNumber: 5})
fakeTransformer2 := &mocks.MockTransformer{}
- fakeTransformer2.SetTransformerConfig(shared2.TransformerConfig{StartingBlockNumber: 3})
+ fakeTransformer2.SetTransformerConfig(transformer.TransformerConfig{StartingBlockNumber: 3})
- watcher := shared.NewEventWatcher(nil, nil)
- watcher.AddTransformers([]shared2.TransformerInitializer{
+ w := watcher.NewEventWatcher(nil, nil)
+ w.AddTransformers([]transformer.TransformerInitializer{
fakeTransformer1.FakeTransformerInitializer,
fakeTransformer2.FakeTransformerInitializer,
})
- Expect(*watcher.StartingBlock).To(Equal(int64(3)))
+ Expect(*w.StartingBlock).To(Equal(int64(3)))
})
It("returns an error when run without transformers", func() {
- watcher := shared.NewEventWatcher(nil, nil)
- err := watcher.Execute(constants.HeaderMissing)
+ w := watcher.NewEventWatcher(nil, nil)
+ err := w.Execute(constants.HeaderMissing)
Expect(err).To(MatchError("No transformers added to watcher"))
})
Describe("with missing headers", func() {
var (
db *postgres.DB
- watcher shared.EventWatcher
+ w watcher.EventWatcher
mockBlockChain fakes.MockBlockChain
headerRepository repositories.HeaderRepository
repository mocks.MockWatcherRepository
@@ -118,27 +118,25 @@ var _ = Describe("EventWatcher", func() {
Expect(err).NotTo(HaveOccurred())
repository = mocks.MockWatcherRepository{}
- watcher = shared.NewEventWatcher(db, &mockBlockChain)
+ w = watcher.NewEventWatcher(db, &mockBlockChain)
})
It("executes each transformer", func() {
fakeTransformer := &mocks.MockTransformer{}
- watcher.AddTransformers([]shared2.TransformerInitializer{fakeTransformer.FakeTransformerInitializer})
+ w.AddTransformers([]transformer.TransformerInitializer{fakeTransformer.FakeTransformerInitializer})
repository.SetMissingHeaders([]core.Header{fakes.FakeHeader})
- err := watcher.Execute(constants.HeaderMissing)
-
+ err := w.Execute(constants.HeaderMissing)
Expect(err).NotTo(HaveOccurred())
Expect(fakeTransformer.ExecuteWasCalled).To(BeTrue())
})
It("returns an error if transformer returns an error", func() {
fakeTransformer := &mocks.MockTransformer{ExecuteError: errors.New("Something bad happened")}
- watcher.AddTransformers([]shared2.TransformerInitializer{fakeTransformer.FakeTransformerInitializer})
+ w.AddTransformers([]transformer.TransformerInitializer{fakeTransformer.FakeTransformerInitializer})
repository.SetMissingHeaders([]core.Header{fakes.FakeHeader})
- err := watcher.Execute(constants.HeaderMissing)
-
+ err := w.Execute(constants.HeaderMissing)
Expect(err).To(HaveOccurred())
Expect(fakeTransformer.ExecuteWasCalled).To(BeFalse())
})
@@ -147,10 +145,10 @@ var _ = Describe("EventWatcher", func() {
transformerA := &mocks.MockTransformer{}
transformerB := &mocks.MockTransformer{}
- configA := shared2.TransformerConfig{TransformerName: "transformerA",
+ configA := transformer.TransformerConfig{TransformerName: "transformerA",
ContractAddresses: []string{"0x000000000000000000000000000000000000000A"},
Topic: "0xA"}
- configB := shared2.TransformerConfig{TransformerName: "transformerB",
+ configB := transformer.TransformerConfig{TransformerName: "transformerB",
ContractAddresses: []string{"0x000000000000000000000000000000000000000b"},
Topic: "0xB"}
@@ -164,11 +162,11 @@ var _ = Describe("EventWatcher", func() {
mockBlockChain.SetGetEthLogsWithCustomQueryReturnLogs([]types.Log{logA, logB})
repository.SetMissingHeaders([]core.Header{fakes.FakeHeader})
- watcher = shared.NewEventWatcher(db, &mockBlockChain)
- watcher.AddTransformers([]shared2.TransformerInitializer{
+ w = watcher.NewEventWatcher(db, &mockBlockChain)
+ w.AddTransformers([]transformer.TransformerInitializer{
transformerA.FakeTransformerInitializer, transformerB.FakeTransformerInitializer})
- err := watcher.Execute(constants.HeaderMissing)
+ err := w.Execute(constants.HeaderMissing)
Expect(err).NotTo(HaveOccurred())
Expect(transformerA.PassedLogs).To(Equal([]types.Log{logA}))
Expect(transformerB.PassedLogs).To(Equal([]types.Log{logB}))
@@ -184,17 +182,17 @@ var _ = Describe("EventWatcher", func() {
It("fetches logs for added transformers", func() {
addresses := []string{"0xA", "0xB"}
topic := "0x1"
- fakeTransformer.SetTransformerConfig(shared2.TransformerConfig{
+ fakeTransformer.SetTransformerConfig(transformer.TransformerConfig{
Topic: topic, ContractAddresses: addresses})
- watcher.AddTransformers([]shared2.TransformerInitializer{fakeTransformer.FakeTransformerInitializer})
+ w.AddTransformers([]transformer.TransformerInitializer{fakeTransformer.FakeTransformerInitializer})
- err := watcher.Execute(constants.HeaderMissing)
+ err := w.Execute(constants.HeaderMissing)
Expect(err).NotTo(HaveOccurred())
fakeHash := common.HexToHash(fakes.FakeHeader.Hash)
mockBlockChain.AssertGetEthLogsWithCustomQueryCalledWith(ethereum.FilterQuery{
BlockHash: &fakeHash,
- Addresses: shared2.HexStringsToAddresses(addresses),
+ Addresses: transformer.HexStringsToAddresses(addresses),
Topics: [][]common.Hash{{common.HexToHash(topic)}},
})
})
@@ -203,8 +201,8 @@ var _ = Describe("EventWatcher", func() {
fetcherError := errors.New("FetcherError")
mockBlockChain.SetGetEthLogsWithCustomQueryErr(fetcherError)
- watcher.AddTransformers([]shared2.TransformerInitializer{fakeTransformer.FakeTransformerInitializer})
- err := watcher.Execute(constants.HeaderMissing)
+ w.AddTransformers([]transformer.TransformerInitializer{fakeTransformer.FakeTransformerInitializer})
+ err := w.Execute(constants.HeaderMissing)
Expect(err).To(MatchError(fetcherError))
})
})
diff --git a/libraries/shared/shared_suite_test.go b/libraries/shared/watcher/watcher_suite_test.go
similarity index 94%
rename from libraries/shared/shared_suite_test.go
rename to libraries/shared/watcher/watcher_suite_test.go
index 3e3b5fcc..2425d502 100644
--- a/libraries/shared/shared_suite_test.go
+++ b/libraries/shared/watcher/watcher_suite_test.go
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-package shared_test
+package watcher_test
import (
log "github.com/sirupsen/logrus"
@@ -27,7 +27,7 @@ import (
func TestShared(t *testing.T) {
RegisterFailHandler(Fail)
- RunSpecs(t, "Shared Suite")
+ RunSpecs(t, "Shared Watcher Suite")
}
var _ = BeforeSuite(func() {
diff --git a/pkg/autogen/config.go b/pkg/autogen/config.go
new file mode 100644
index 00000000..ed81472e
--- /dev/null
+++ b/pkg/autogen/config.go
@@ -0,0 +1,23 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package autogen
+
+type Config struct {
+ Imports map[string]string // Map of import alias to import path
+ FilePath string
+ FileName string
+}
diff --git a/pkg/autogen/generator.go b/pkg/autogen/generator.go
new file mode 100644
index 00000000..ca6c39ae
--- /dev/null
+++ b/pkg/autogen/generator.go
@@ -0,0 +1,138 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package autogen
+
+import (
+ "errors"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+
+ . "github.com/dave/jennifer/jen"
+ "github.com/mitchellh/go-homedir"
+)
+
+type Generator interface {
+ GenerateTransformerPlugin() error
+}
+
+type generator struct {
+ *Config
+}
+
+func NewGenerator(config Config) *generator {
+ return &generator{
+ Config: &config,
+ }
+}
+
+func (g *generator) GenerateTransformerPlugin() error {
+ if g.Config == nil {
+ return errors.New("generator needs a config file")
+ }
+ if g.Config.FilePath == "" {
+ return errors.New("generator is missing file path")
+ }
+ if len(g.Config.Imports) < 1 {
+ return errors.New("generator needs to be configured with imports")
+ }
+
+ // Create file path
+ goFile, soFile, err := GetPaths(*g.Config)
+ if err != nil {
+ return err
+ }
+
+ // Clear previous .go and .so files if they exist
+ err = ClearFiles(goFile, soFile)
+ if err != nil {
+ return err
+ }
+
+ // Begin code generation
+ f := NewFile("main")
+ f.HeaderComment("This exporter is generated to export the configured transformer initializers")
+
+ // Import TransformerInitializers
+ f.ImportAlias("github.com/vulcanize/vulcanizedb/libraries/shared/transformer", "interface")
+ for alias, imp := range g.Config.Imports {
+ f.ImportAlias(imp, alias)
+ }
+
+ // Collect TransformerInitializer names
+ importedInitializers := make([]Code, 0, len(g.Config.Imports))
+ for _, path := range g.Config.Imports {
+ importedInitializers = append(importedInitializers, Qual(path, "TransformerInitializer"))
+ }
+
+ // Create Exporter variable with method to export a set of the configured TransformerInitializers
+ f.Type().Id("exporter").String()
+ f.Var().Id("Exporter").Id("exporter")
+ f.Func().Params(
+ Id("e").Id("exporter"),
+ ).Id("Export").Params().Index().Qual(
+ "github.com/vulcanize/vulcanizedb/libraries/shared/transformer",
+ "TransformerInitializer").Block(
+ Return(Index().Qual(
+ "github.com/vulcanize/vulcanizedb/libraries/shared/transformer",
+ "TransformerInitializer").Values(importedInitializers...)))
+
+ // Write code to destination file
+ err = f.Save(goFile)
+ if err != nil {
+ return err
+ }
+
+ // Build the .go file into a .so plugin
+ return exec.Command("go", "build", "-buildmode=plugin", "-o", soFile, goFile).Run()
+}
+
+func GetPaths(config Config) (string, string, error) {
+ path, err := homedir.Expand(filepath.Clean(config.FilePath))
+ if err != nil {
+ return "", "", err
+ }
+ if strings.Contains(path, "$GOPATH") {
+ env := os.Getenv("GOPATH")
+ spl := strings.Split(path, "$GOPATH")[1]
+ path = filepath.Join(env, spl)
+ }
+
+ name := strings.Split(config.FileName, ".")[0]
+ goFile := filepath.Join(path, name+".go")
+ soFile := filepath.Join(path, name+".so")
+
+ return goFile, soFile, nil
+}
+
+func ClearFiles(files ...string) error {
+ for _, file := range files {
+ if _, err := os.Stat(file); err == nil {
+ err = os.Remove(file)
+ if err != nil {
+ return err
+ }
+ } else if os.IsNotExist(err) {
+ // fall through
+ } else {
+ return err
+ }
+ }
+
+ return nil
+}
diff --git a/pkg/autogen/generator_suite_test.go b/pkg/autogen/generator_suite_test.go
new file mode 100644
index 00000000..3ebcedca
--- /dev/null
+++ b/pkg/autogen/generator_suite_test.go
@@ -0,0 +1,35 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package autogen_test
+
+import (
+ "io/ioutil"
+ "log"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func TestRepository(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Autogen Suite Test")
+}
+
+var _ = BeforeSuite(func() {
+ log.SetOutput(ioutil.Discard)
+})
diff --git a/pkg/autogen/generator_test.go b/pkg/autogen/generator_test.go
new file mode 100644
index 00000000..bc60d980
--- /dev/null
+++ b/pkg/autogen/generator_test.go
@@ -0,0 +1,138 @@
+// VulcanizeDB
+// Copyright © 2018 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package autogen_test
+
+import (
+ "plugin"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ "github.com/spf13/viper"
+
+ "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
+ "github.com/vulcanize/vulcanizedb/libraries/shared/watcher"
+ "github.com/vulcanize/vulcanizedb/pkg/autogen"
+ "github.com/vulcanize/vulcanizedb/pkg/autogen/test_helpers"
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
+ "github.com/vulcanize/vulcanizedb/pkg/transformers/bite"
+)
+
+var testConfig = autogen.Config{
+ Imports: map[string]string{
+ "bite": "github.com/vulcanize/vulcanizedb/pkg/autogen/test_helpers/bite",
+ "deal": "github.com/vulcanize/vulcanizedb/pkg/autogen/test_helpers/deal",
+ },
+ FileName: "testTransformerSet",
+ FilePath: "$GOPATH/src/github.com/vulcanize/vulcanizedb/pkg/autogen/test_helpers/test/",
+}
+
+var targetConfig = autogen.Config{
+ Imports: map[string]string{
+ "bite": "github.com/vulcanize/vulcanizedb/pkg/autogen/test_helpers/bite",
+ "deal": "github.com/vulcanize/vulcanizedb/pkg/autogen/test_helpers/deal",
+ },
+ FileName: "targetTransformerSet",
+ FilePath: "$GOPATH/src/github.com/vulcanize/vulcanizedb/pkg/autogen/test_helpers/target/",
+}
+
+type Exporter interface {
+ Export() []transformer.TransformerInitializer
+}
+
+var _ = Describe("Generator test", func() {
+ var g autogen.Generator
+ var goPath, soPath string
+ var err error
+ var bc core.BlockChain
+ var db *postgres.DB
+ var hr repositories.HeaderRepository
+ var headerID int64
+ viper.SetConfigName("compose")
+ viper.AddConfigPath("$GOPATH/src/github.com/vulcanize/vulcanizedb/environments/")
+
+ BeforeEach(func() {
+ goPath, soPath, err = autogen.GetPaths(testConfig)
+ Expect(err).ToNot(HaveOccurred())
+ g = autogen.NewGenerator(testConfig)
+ err = g.GenerateTransformerPlugin()
+ Expect(err).ToNot(HaveOccurred())
+ })
+
+ AfterEach(func() {
+ err := autogen.ClearFiles(goPath, soPath)
+ Expect(err).ToNot(HaveOccurred())
+ })
+
+ Describe("GenerateTransformerPlugin", func() {
+ It("It bundles the specified transformer initializers into a Exporter object and creates .so", func() {
+ plug, err := plugin.Open(soPath)
+ Expect(err).ToNot(HaveOccurred())
+ symExporter, err := plug.Lookup("Exporter")
+ Expect(err).ToNot(HaveOccurred())
+ exporter, ok := symExporter.(Exporter)
+ Expect(ok).To(Equal(true))
+ initializers := exporter.Export()
+ Expect(len(initializers)).To(Equal(2))
+ })
+
+ It("Loads our generated Exporter and uses it to import an arbitrary set of TransformerInitializers that we can execute over", func() {
+ db, bc = test_helpers.SetupDBandBC()
+ defer test_helpers.TearDown(db)
+
+ hr = repositories.NewHeaderRepository(db)
+ header1, err := bc.GetHeaderByNumber(9377319)
+ Expect(err).ToNot(HaveOccurred())
+ headerID, err = hr.CreateOrUpdateHeader(header1)
+ Expect(err).ToNot(HaveOccurred())
+
+ plug, err := plugin.Open(soPath)
+ Expect(err).ToNot(HaveOccurred())
+ symExporter, err := plug.Lookup("Exporter")
+ Expect(err).ToNot(HaveOccurred())
+ exporter, ok := symExporter.(Exporter)
+ Expect(ok).To(Equal(true))
+ initializers := exporter.Export()
+
+ w := watcher.NewWatcher(db, bc)
+ w.AddTransformers(initializers)
+ err = w.Execute()
+ Expect(err).ToNot(HaveOccurred())
+
+ type model struct {
+ bite.BiteModel
+ Id int64 `db:"id"`
+ HeaderId int64 `db:"header_id"`
+ }
+
+ returned := model{}
+
+ err = db.Get(&returned, `SELECT * FROM maker.bite WHERE header_id = $1`, headerID)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(returned.Ilk).To(Equal("ETH"))
+ Expect(returned.Urn).To(Equal("0x0000d8b4147eDa80Fec7122AE16DA2479Cbd7ffB"))
+ Expect(returned.Ink).To(Equal("80000000000000000000"))
+ Expect(returned.Art).To(Equal("11000000000000000000000"))
+ Expect(returned.IArt).To(Equal("12496609999999999999992"))
+ Expect(returned.Tab).To(Equal("11000000000000000000000"))
+ Expect(returned.NFlip).To(Equal("7"))
+ Expect(returned.TransactionIndex).To(Equal(uint(1)))
+ Expect(returned.LogIndex).To(Equal(uint(4)))
+ })
+ })
+})
diff --git a/pkg/autogen/test_helpers/bite/initializer.go b/pkg/autogen/test_helpers/bite/initializer.go
new file mode 100644
index 00000000..1ce446dd
--- /dev/null
+++ b/pkg/autogen/test_helpers/bite/initializer.go
@@ -0,0 +1,8 @@
+package bite
+
+import (
+ "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
+ "github.com/vulcanize/vulcanizedb/pkg/transformers"
+)
+
+var TransformerInitializer transformer.TransformerInitializer = transformers.GetBiteTransformer().NewTransformer
diff --git a/pkg/autogen/test_helpers/database.go b/pkg/autogen/test_helpers/database.go
new file mode 100644
index 00000000..66d6cc0e
--- /dev/null
+++ b/pkg/autogen/test_helpers/database.go
@@ -0,0 +1,65 @@
+package test_helpers
+
+import (
+ "github.com/ethereum/go-ethereum/ethclient"
+ "github.com/ethereum/go-ethereum/rpc"
+ . "github.com/onsi/gomega"
+
+ "github.com/vulcanize/vulcanizedb/pkg/config"
+ "github.com/vulcanize/vulcanizedb/pkg/core"
+ "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/geth"
+ "github.com/vulcanize/vulcanizedb/pkg/geth/client"
+ rpc2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
+ "github.com/vulcanize/vulcanizedb/pkg/geth/node"
+)
+
+func SetupDBandBC() (*postgres.DB, core.BlockChain) {
+ infuraIPC := "http://kovan0.vulcanize.io:8545"
+ rawRpcClient, err := rpc.Dial(infuraIPC)
+ Expect(err).NotTo(HaveOccurred())
+ rpcClient := client.NewRpcClient(rawRpcClient, infuraIPC)
+ ethClient := ethclient.NewClient(rawRpcClient)
+ blockChainClient := client.NewEthClient(ethClient)
+ node := node.MakeNode(rpcClient)
+ transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
+ blockChain := geth.NewBlockChain(blockChainClient, rpcClient, node, transactionConverter)
+
+ db, err := postgres.NewDB(config.Database{
+ Hostname: "localhost",
+ Name: "vulcanize_private",
+ Port: 5432,
+ }, blockChain.Node())
+ Expect(err).NotTo(HaveOccurred())
+
+ return db, blockChain
+}
+
+func TearDown(db *postgres.DB) {
+ tx, err := db.Begin()
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DELETE FROM headers`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DELETE FROM logs`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DELETE FROM log_filters`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DELETE FROM transactions`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DELETE FROM receipts`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DELETE FROM checked_headers`)
+ Expect(err).NotTo(HaveOccurred())
+
+ _, err = tx.Exec(`DELETE FROM maker.bite`)
+ Expect(err).NotTo(HaveOccurred())
+
+ err = tx.Commit()
+ Expect(err).NotTo(HaveOccurred())
+}
diff --git a/pkg/autogen/test_helpers/deal/initializer.go b/pkg/autogen/test_helpers/deal/initializer.go
new file mode 100644
index 00000000..84a44263
--- /dev/null
+++ b/pkg/autogen/test_helpers/deal/initializer.go
@@ -0,0 +1,8 @@
+package deal
+
+import (
+ "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
+ "github.com/vulcanize/vulcanizedb/pkg/transformers"
+)
+
+var TransformerInitializer transformer.TransformerInitializer = transformers.GetDealTransformer().NewLogNoteTransformer
diff --git a/pkg/autogen/test_helpers/test/README.md b/pkg/autogen/test_helpers/test/README.md
new file mode 100644
index 00000000..6a93702e
--- /dev/null
+++ b/pkg/autogen/test_helpers/test/README.md
@@ -0,0 +1,3 @@
+### Test
+
+This empty directory is for holding the output code generated, and then deleted, during the generator_tests
\ No newline at end of file
diff --git a/pkg/omni/full/transformer/transformer_test.go b/pkg/omni/full/transformer/transformer_test.go
index 9d68143c..171b1618 100644
--- a/pkg/omni/full/transformer/transformer_test.go
+++ b/pkg/omni/full/transformer/transformer_test.go
@@ -324,7 +324,7 @@ var _ = Describe("Transformer", func() {
Expect(res.Address).To(Equal("0x0000000000000000000000000000000000000000"))
Expect(res.TokenName).To(Equal(""))
- err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ceMADEUPaaf4HASHc186badTHIS288IS625bFAKE' AND block = '6194636'", ensAddr)).StructScan(&res)
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM full_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ceMADEUPaaf4HASHc186badTHItransformers.8IS625bFAKE' AND block = '6194636'", ensAddr)).StructScan(&res)
Expect(err).To(HaveOccurred())
})
diff --git a/pkg/omni/light/transformer/transformer_test.go b/pkg/omni/light/transformer/transformer_test.go
index db805532..a5c69515 100644
--- a/pkg/omni/light/transformer/transformer_test.go
+++ b/pkg/omni/light/transformer/transformer_test.go
@@ -331,7 +331,7 @@ var _ = Describe("Transformer", func() {
Expect(res.Address).To(Equal("0x0000000000000000000000000000000000000000"))
Expect(res.TokenName).To(Equal(""))
- err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ceMADEUPaaf4HASHc186badTHIS288IS625bFAKE' AND block = '6885696'", ensAddr)).StructScan(&res)
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ceMADEUPaaf4HASHc186badTHItransformers.8IS625bFAKE' AND block = '6885696'", ensAddr)).StructScan(&res)
Expect(err).To(HaveOccurred())
})
@@ -491,7 +491,7 @@ var _ = Describe("Transformer", func() {
Expect(owner.Address).To(Equal("0x0000000000000000000000000000000000000000"))
Expect(owner.TokenName).To(Equal(""))
- err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ceMADEUPaaf4HASHc186badTHIS288IS625bFAKE' AND block = '6885696'", ensAddr)).StructScan(&owner)
+ err = db.QueryRowx(fmt.Sprintf("SELECT * FROM light_%s.owner_method WHERE node_ = '0x95832c7a47ff8a7840e28b78ceMADEUPaaf4HASHc186badTHItransformers.8IS625bFAKE' AND block = '6885696'", ensAddr)).StructScan(&owner)
Expect(err).To(HaveOccurred())
bal := test_helpers.BalanceOf{}
diff --git a/pkg/transformers/bite/config.go b/pkg/transformers/bite/config.go
index e6fcff04..c965f212 100644
--- a/pkg/transformers/bite/config.go
+++ b/pkg/transformers/bite/config.go
@@ -17,12 +17,12 @@
package bite
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetBiteConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetBiteConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.BiteLabel,
ContractAddresses: []string{constants.CatContractAddress()},
ContractAbi: constants.CatABI(),
diff --git a/pkg/transformers/cat_file/chop_lump/config.go b/pkg/transformers/cat_file/chop_lump/config.go
index 01c32106..8398b16e 100644
--- a/pkg/transformers/cat_file/chop_lump/config.go
+++ b/pkg/transformers/cat_file/chop_lump/config.go
@@ -17,12 +17,12 @@
package chop_lump
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetCatFileChopLumpConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetCatFileChopLumpConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.CatFileChopLumpLabel,
ContractAddresses: []string{constants.CatContractAddress()},
ContractAbi: constants.CatABI(),
diff --git a/pkg/transformers/cat_file/flip/config.go b/pkg/transformers/cat_file/flip/config.go
index f8401d2d..b8e010fc 100644
--- a/pkg/transformers/cat_file/flip/config.go
+++ b/pkg/transformers/cat_file/flip/config.go
@@ -17,12 +17,12 @@
package flip
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetCatFileFlipConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetCatFileFlipConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.CatFileFlipLabel,
ContractAddresses: []string{constants.CatContractAddress()},
ContractAbi: constants.CatABI(),
diff --git a/pkg/transformers/cat_file/pit_vow/config.go b/pkg/transformers/cat_file/pit_vow/config.go
index 4db102a5..8db450b9 100644
--- a/pkg/transformers/cat_file/pit_vow/config.go
+++ b/pkg/transformers/cat_file/pit_vow/config.go
@@ -17,12 +17,12 @@
package pit_vow
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetCatFilePitVowConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetCatFilePitVowConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.CatFilePitVowLabel,
ContractAddresses: []string{constants.CatContractAddress()},
ContractAbi: constants.CatABI(),
diff --git a/pkg/transformers/deal/config.go b/pkg/transformers/deal/config.go
index f9f77f77..398a1738 100644
--- a/pkg/transformers/deal/config.go
+++ b/pkg/transformers/deal/config.go
@@ -17,12 +17,13 @@
package deal
import (
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetDealConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetDealConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.DealLabel,
ContractAddresses: []string{constants.FlapperContractAddress(), constants.FlipperContractAddress(), constants.FlopperContractAddress()},
ContractAbi: constants.FlipperABI(),
diff --git a/pkg/transformers/dent/config.go b/pkg/transformers/dent/config.go
index c6703946..e1cd5cfd 100644
--- a/pkg/transformers/dent/config.go
+++ b/pkg/transformers/dent/config.go
@@ -17,12 +17,13 @@
package dent
import (
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetDentConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetDentConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.DentLabel,
ContractAddresses: []string{constants.FlipperContractAddress(), constants.FlopperContractAddress()},
ContractAbi: constants.FlipperABI(),
diff --git a/pkg/transformers/drip_drip/config.go b/pkg/transformers/drip_drip/config.go
index 6ad1921f..4411ce03 100644
--- a/pkg/transformers/drip_drip/config.go
+++ b/pkg/transformers/drip_drip/config.go
@@ -17,12 +17,12 @@
package drip_drip
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetDripDripConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetDripDripConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
ContractAddresses: []string{constants.DripContractAddress()},
ContractAbi: constants.DripABI(),
Topic: constants.GetDripDripSignature(),
diff --git a/pkg/transformers/drip_file/ilk/config.go b/pkg/transformers/drip_file/ilk/config.go
index 1ada59ba..ffb202e5 100644
--- a/pkg/transformers/drip_file/ilk/config.go
+++ b/pkg/transformers/drip_file/ilk/config.go
@@ -17,12 +17,12 @@
package ilk
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetDripFileIlkConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetDripFileIlkConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.DripFileIlkLabel,
ContractAddresses: []string{constants.DripContractAddress()},
ContractAbi: constants.DripABI(),
diff --git a/pkg/transformers/drip_file/repo/config.go b/pkg/transformers/drip_file/repo/config.go
index ecbf0e3f..56ec6248 100644
--- a/pkg/transformers/drip_file/repo/config.go
+++ b/pkg/transformers/drip_file/repo/config.go
@@ -17,12 +17,12 @@
package repo
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetDripFileRepoConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetDripFileRepoConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.DripFileRepoLabel,
ContractAddresses: []string{constants.DripContractAddress()},
ContractAbi: constants.DripABI(),
diff --git a/pkg/transformers/drip_file/vow/config.go b/pkg/transformers/drip_file/vow/config.go
index e296bb09..9910a149 100644
--- a/pkg/transformers/drip_file/vow/config.go
+++ b/pkg/transformers/drip_file/vow/config.go
@@ -17,12 +17,12 @@
package vow
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetDripFileVowConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetDripFileVowConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.DripFileVowLabel,
ContractAddresses: []string{constants.DripContractAddress()},
ContractAbi: constants.DripABI(),
diff --git a/pkg/transformers/factories/log_note_transformer.go b/pkg/transformers/factories/log_note_transformer.go
index c22c5a42..08092b8c 100644
--- a/pkg/transformers/factories/log_note_transformer.go
+++ b/pkg/transformers/factories/log_note_transformer.go
@@ -20,19 +20,19 @@ import (
"github.com/ethereum/go-ethereum/core/types"
log "github.com/sirupsen/logrus"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
type LogNoteTransformer struct {
- Config shared.TransformerConfig
+ Config shared_t.TransformerConfig
Converter LogNoteConverter
Repository Repository
}
-func (transformer LogNoteTransformer) NewLogNoteTransformer(db *postgres.DB) shared.Transformer {
+func (transformer LogNoteTransformer) NewLogNoteTransformer(db *postgres.DB) shared_t.Transformer {
transformer.Repository.SetDB(db)
return transformer
}
@@ -68,6 +68,6 @@ func (transformer LogNoteTransformer) GetName() string {
return transformer.Config.TransformerName
}
-func (transformer LogNoteTransformer) GetConfig() shared.TransformerConfig {
+func (transformer LogNoteTransformer) GetConfig() shared_t.TransformerConfig {
return transformer.Config
}
diff --git a/pkg/transformers/factories/log_note_transformer_test.go b/pkg/transformers/factories/log_note_transformer_test.go
index 851472f8..fa35624f 100644
--- a/pkg/transformers/factories/log_note_transformer_test.go
+++ b/pkg/transformers/factories/log_note_transformer_test.go
@@ -17,17 +17,19 @@
package factories_test
import (
+ "math/rand"
+
"github.com/ethereum/go-ethereum/core/types"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/fakes"
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data/mocks"
- "math/rand"
)
var _ = Describe("LogNoteTransformer", func() {
@@ -35,7 +37,7 @@ var _ = Describe("LogNoteTransformer", func() {
repository mocks.MockRepository
converter mocks.MockLogNoteConverter
headerOne core.Header
- transformer shared.Transformer
+ transformer shared_t.Transformer
model test_data.GenericModel
config = test_data.GenericTestConfig
logs = test_data.GenericTestLogs
diff --git a/pkg/transformers/factories/transformer.go b/pkg/transformers/factories/transformer.go
index cca34a66..9ed98e77 100644
--- a/pkg/transformers/factories/transformer.go
+++ b/pkg/transformers/factories/transformer.go
@@ -20,19 +20,19 @@ import (
"github.com/ethereum/go-ethereum/core/types"
log "github.com/sirupsen/logrus"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
type Transformer struct {
- Config shared.TransformerConfig
+ Config shared_t.TransformerConfig
Converter Converter
Repository Repository
}
-func (transformer Transformer) NewTransformer(db *postgres.DB) shared.Transformer {
+func (transformer Transformer) NewTransformer(db *postgres.DB) shared_t.Transformer {
transformer.Repository.SetDB(db)
return transformer
}
@@ -75,6 +75,6 @@ func (transformer Transformer) GetName() string {
return transformer.Config.TransformerName
}
-func (transformer Transformer) GetConfig() shared.TransformerConfig {
+func (transformer Transformer) GetConfig() shared_t.TransformerConfig {
return transformer.Config
}
diff --git a/pkg/transformers/factories/transformer_test.go b/pkg/transformers/factories/transformer_test.go
index 3f8c0039..ce5ffc98 100644
--- a/pkg/transformers/factories/transformer_test.go
+++ b/pkg/transformers/factories/transformer_test.go
@@ -17,24 +17,26 @@
package factories_test
import (
+ "math/rand"
+
"github.com/ethereum/go-ethereum/core/types"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/fakes"
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data/mocks"
- "math/rand"
)
var _ = Describe("Transformer", func() {
var (
repository mocks.MockRepository
converter mocks.MockConverter
- transformer shared.Transformer
+ transformer shared_t.Transformer
headerOne core.Header
config = test_data.GenericTestConfig
logs = test_data.GenericTestLogs
diff --git a/pkg/transformers/flap_kick/config.go b/pkg/transformers/flap_kick/config.go
index 70c5b7c9..914d86d8 100644
--- a/pkg/transformers/flap_kick/config.go
+++ b/pkg/transformers/flap_kick/config.go
@@ -17,12 +17,12 @@
package flap_kick
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetFlapKickConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetFlapKickConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.FlapKickLabel,
ContractAddresses: []string{constants.FlapperContractAddress()},
ContractAbi: constants.FlapperABI(),
diff --git a/pkg/transformers/flip_kick/config.go b/pkg/transformers/flip_kick/config.go
index 7fa8d908..63e786be 100644
--- a/pkg/transformers/flip_kick/config.go
+++ b/pkg/transformers/flip_kick/config.go
@@ -17,12 +17,12 @@
package flip_kick
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetFlipKickConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetFlipKickConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.FlipKickLabel,
ContractAddresses: []string{constants.FlipperContractAddress()},
ContractAbi: constants.FlipperABI(),
diff --git a/pkg/transformers/flop_kick/config.go b/pkg/transformers/flop_kick/config.go
index 5356dbe3..c3f3c5bc 100644
--- a/pkg/transformers/flop_kick/config.go
+++ b/pkg/transformers/flop_kick/config.go
@@ -17,12 +17,12 @@
package flop_kick
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetFlopKickConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetFlopKickConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.FlopKickLabel,
ContractAddresses: []string{constants.FlopperContractAddress()},
ContractAbi: constants.FlopperABI(),
diff --git a/pkg/transformers/frob/config.go b/pkg/transformers/frob/config.go
index 5c91231a..3499d39d 100644
--- a/pkg/transformers/frob/config.go
+++ b/pkg/transformers/frob/config.go
@@ -17,12 +17,12 @@
package frob
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetFrobConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetFrobConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.FrobLabel,
ContractAddresses: []string{constants.PitContractAddress()},
ContractAbi: constants.PitABI(),
diff --git a/pkg/transformers/integration_tests/bite.go b/pkg/transformers/integration_tests/bite.go
index 28c1cb8c..9ebd3c67 100644
--- a/pkg/transformers/integration_tests/bite.go
+++ b/pkg/transformers/integration_tests/bite.go
@@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/geth"
"github.com/vulcanize/vulcanizedb/pkg/transformers/bite"
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
@@ -33,7 +34,7 @@ import (
"github.com/vulcanize/vulcanizedb/test_config"
)
-var testBiteConfig = shared.TransformerConfig{
+var testBiteConfig = shared_t.TransformerConfig{
TransformerName: constants.BiteLabel,
ContractAddresses: []string{test_data.KovanCatContractAddress},
ContractAbi: test_data.KovanCatABI,
diff --git a/pkg/transformers/integration_tests/cat_file.go b/pkg/transformers/integration_tests/cat_file.go
index 48ce0c37..8657422d 100644
--- a/pkg/transformers/integration_tests/cat_file.go
+++ b/pkg/transformers/integration_tests/cat_file.go
@@ -29,6 +29,7 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
@@ -66,7 +67,7 @@ var _ = Describe("Cat File transformer", func() {
header, err := persistHeader(db, chopLumpBlockNumber, blockChain)
Expect(err).NotTo(HaveOccurred())
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.CatFileChopLumpLabel,
ContractAddresses: []string{test_data.KovanCatContractAddress},
ContractAbi: test_data.KovanCatABI,
@@ -162,7 +163,7 @@ var _ = Describe("Cat File transformer", func() {
header, err := persistHeader(db, flipBlockNumber, blockChain)
Expect(err).NotTo(HaveOccurred())
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.CatFileFlipLabel,
ContractAddresses: []string{test_data.KovanCatContractAddress},
ContractAbi: test_data.KovanCatABI,
@@ -250,7 +251,7 @@ var _ = Describe("Cat File transformer", func() {
header, err := persistHeader(db, pitVowBlockNumber, blockChain)
Expect(err).NotTo(HaveOccurred())
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.CatFilePitVowLabel,
ContractAddresses: []string{test_data.KovanCatContractAddress},
ContractAbi: test_data.KovanCatABI,
diff --git a/pkg/transformers/integration_tests/deal.go b/pkg/transformers/integration_tests/deal.go
index 8e8a6908..c8a7f361 100644
--- a/pkg/transformers/integration_tests/deal.go
+++ b/pkg/transformers/integration_tests/deal.go
@@ -23,6 +23,7 @@ import (
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
"github.com/vulcanize/vulcanizedb/pkg/transformers/deal"
@@ -35,7 +36,7 @@ var _ = Describe("Deal transformer", func() {
var (
db *postgres.DB
blockChain core.BlockChain
- config shared.TransformerConfig
+ config shared_t.TransformerConfig
initializer factories.LogNoteTransformer
fetcher *shared.Fetcher
addresses []common.Address
@@ -50,7 +51,7 @@ var _ = Describe("Deal transformer", func() {
db = test_config.NewTestDB(blockChain.Node())
test_config.CleanTestDB(db)
- config = shared.TransformerConfig{
+ config = shared_t.TransformerConfig{
TransformerName: constants.DealLabel,
ContractAddresses: []string{test_data.KovanFlapperContractAddress, test_data.KovanFlipperContractAddress, test_data.KovanFlopperContractAddress},
ContractAbi: test_data.KovanFlipperABI,
@@ -66,7 +67,7 @@ var _ = Describe("Deal transformer", func() {
}
fetcher = shared.NewFetcher(blockChain)
- addresses = shared.HexStringsToAddresses(config.ContractAddresses)
+ addresses = shared_t.HexStringsToAddresses(config.ContractAddresses)
topics = []common.Hash{common.HexToHash(config.Topic)}
})
diff --git a/pkg/transformers/integration_tests/dent.go b/pkg/transformers/integration_tests/dent.go
index aa12143a..70c1aaf0 100644
--- a/pkg/transformers/integration_tests/dent.go
+++ b/pkg/transformers/integration_tests/dent.go
@@ -7,6 +7,7 @@ import (
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
"github.com/vulcanize/vulcanizedb/pkg/transformers/dent"
@@ -20,8 +21,8 @@ var _ = Describe("Dent transformer", func() {
db *postgres.DB
blockChain core.BlockChain
fetcher *shared.Fetcher
- transformer shared.Transformer
- config shared.TransformerConfig
+ transformer shared_t.Transformer
+ config shared_t.TransformerConfig
addresses []common.Address
topics []common.Hash
initializer factories.LogNoteTransformer
@@ -35,7 +36,7 @@ var _ = Describe("Dent transformer", func() {
db = test_config.NewTestDB(blockChain.Node())
test_config.CleanTestDB(db)
- config = shared.TransformerConfig{
+ config = shared_t.TransformerConfig{
TransformerName: constants.DentLabel,
ContractAddresses: []string{test_data.KovanFlipperContractAddress, test_data.KovanFlopperContractAddress},
ContractAbi: test_data.KovanFlipperABI,
@@ -44,7 +45,7 @@ var _ = Describe("Dent transformer", func() {
EndingBlockNumber: -1,
}
- addresses = shared.HexStringsToAddresses(config.ContractAddresses)
+ addresses = shared_t.HexStringsToAddresses(config.ContractAddresses)
topics = []common.Hash{common.HexToHash(config.Topic)}
fetcher = shared.NewFetcher(blockChain)
diff --git a/pkg/transformers/integration_tests/drip_drip.go b/pkg/transformers/integration_tests/drip_drip.go
index f369a529..ee747542 100644
--- a/pkg/transformers/integration_tests/drip_drip.go
+++ b/pkg/transformers/integration_tests/drip_drip.go
@@ -20,14 +20,16 @@ import (
"github.com/ethereum/go-ethereum/common"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/transformers/drip_drip"
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
"strconv"
- "github.com/vulcanize/vulcanizedb/pkg/transformers/drip_drip"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
"github.com/vulcanize/vulcanizedb/test_config"
)
@@ -36,7 +38,7 @@ var _ = Describe("DripDrip Transformer", func() {
var (
db *postgres.DB
blockChain core.BlockChain
- config shared.TransformerConfig
+ config shared_t.TransformerConfig
)
BeforeEach(func() {
@@ -47,7 +49,7 @@ var _ = Describe("DripDrip Transformer", func() {
db = test_config.NewTestDB(blockChain.Node())
test_config.CleanTestDB(db)
- config = shared.TransformerConfig{
+ config = shared_t.TransformerConfig{
ContractAddresses: []string{test_data.KovanDripContractAddress},
ContractAbi: test_data.KovanDripABI,
Topic: test_data.KovanDripDripSignature,
@@ -73,7 +75,7 @@ var _ = Describe("DripDrip Transformer", func() {
fetcher := shared.NewFetcher(blockChain)
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(config.ContractAddresses),
+ shared_t.HexStringsToAddresses(config.ContractAddresses),
[]common.Hash{common.HexToHash(config.Topic)},
header)
Expect(err).NotTo(HaveOccurred())
@@ -109,7 +111,7 @@ var _ = Describe("DripDrip Transformer", func() {
fetcher := shared.NewFetcher(blockChain)
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(config.ContractAddresses),
+ shared_t.HexStringsToAddresses(config.ContractAddresses),
[]common.Hash{common.HexToHash(config.Topic)},
header)
Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/transformers/integration_tests/drip_file_vow.go b/pkg/transformers/integration_tests/drip_file_vow.go
index 459e33eb..3e522444 100644
--- a/pkg/transformers/integration_tests/drip_file_vow.go
+++ b/pkg/transformers/integration_tests/drip_file_vow.go
@@ -20,13 +20,15 @@ import (
"github.com/ethereum/go-ethereum/common"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
+ "github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file/vow"
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
- "github.com/vulcanize/vulcanizedb/pkg/transformers/drip_file/vow"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
"github.com/vulcanize/vulcanizedb/test_config"
)
@@ -48,7 +50,7 @@ var _ = Describe("Drip File Vow LogNoteTransformer", func() {
It("transforms DripFileVow log events", func() {
blockNumber := int64(8762197)
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.DripFileVowLabel,
ContractAddresses: []string{test_data.KovanDripContractAddress},
ContractAbi: test_data.KovanDripABI,
@@ -69,7 +71,7 @@ var _ = Describe("Drip File Vow LogNoteTransformer", func() {
fetcher := shared.NewFetcher(blockChain)
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(config.ContractAddresses),
+ shared_t.HexStringsToAddresses(config.ContractAddresses),
[]common.Hash{common.HexToHash(config.Topic)},
header)
Expect(err).NotTo(HaveOccurred())
@@ -88,7 +90,7 @@ var _ = Describe("Drip File Vow LogNoteTransformer", func() {
It("rechecks drip file vow event", func() {
blockNumber := int64(8762197)
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.DripFileVowLabel,
ContractAddresses: []string{test_data.KovanDripContractAddress},
ContractAbi: test_data.KovanDripABI,
@@ -109,7 +111,7 @@ var _ = Describe("Drip File Vow LogNoteTransformer", func() {
fetcher := shared.NewFetcher(blockChain)
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(config.ContractAddresses),
+ shared_t.HexStringsToAddresses(config.ContractAddresses),
[]common.Hash{common.HexToHash(config.Topic)},
header)
Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/transformers/integration_tests/flap_kick.go b/pkg/transformers/integration_tests/flap_kick.go
index 4aecc055..f8803533 100644
--- a/pkg/transformers/integration_tests/flap_kick.go
+++ b/pkg/transformers/integration_tests/flap_kick.go
@@ -27,6 +27,7 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
"github.com/vulcanize/vulcanizedb/pkg/transformers/flap_kick"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
@@ -50,7 +51,7 @@ var _ = Describe("FlapKick Transformer", func() {
It("fetches and transforms a FlapKick event from Kovan chain", func() {
blockNumber := int64(9002933)
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.FlapKickLabel,
ContractAddresses: []string{test_data.KovanFlapperContractAddress},
ContractAbi: test_data.KovanFlapperABI,
@@ -70,7 +71,7 @@ var _ = Describe("FlapKick Transformer", func() {
fetcher := shared.NewFetcher(blockChain)
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(config.ContractAddresses),
+ shared_t.HexStringsToAddresses(config.ContractAddresses),
[]common.Hash{common.HexToHash(config.Topic)},
header)
Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/transformers/integration_tests/flip_kick.go b/pkg/transformers/integration_tests/flip_kick.go
index 0068db7a..d062faea 100644
--- a/pkg/transformers/integration_tests/flip_kick.go
+++ b/pkg/transformers/integration_tests/flip_kick.go
@@ -24,6 +24,7 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/geth"
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
"github.com/vulcanize/vulcanizedb/pkg/transformers/flip_kick"
@@ -59,7 +60,7 @@ var _ = Describe("FlipKick Transformer", func() {
It("fetches and transforms a FlipKick event from Kovan chain", func() {
blockNumber := int64(8956476)
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.FlipKickLabel,
ContractAddresses: []string{test_data.KovanFlipperContractAddress},
ContractAbi: test_data.KovanFlipperABI,
@@ -86,7 +87,7 @@ var _ = Describe("FlipKick Transformer", func() {
fetcher := shared.NewFetcher(blockChain)
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(config.ContractAddresses),
+ shared_t.HexStringsToAddresses(config.ContractAddresses),
[]common.Hash{common.HexToHash(config.Topic)},
header)
Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/transformers/integration_tests/flop_kick.go b/pkg/transformers/integration_tests/flop_kick.go
index 78e26751..7d73217f 100644
--- a/pkg/transformers/integration_tests/flop_kick.go
+++ b/pkg/transformers/integration_tests/flop_kick.go
@@ -24,6 +24,7 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
"github.com/vulcanize/vulcanizedb/pkg/geth"
@@ -39,7 +40,7 @@ var _ = Describe("FlopKick Transformer", func() {
var (
db *postgres.DB
blockChain core.BlockChain
- config shared.TransformerConfig
+ config shared_t.TransformerConfig
initializer factories.Transformer
fetcher shared.LogFetcher
addresses []common.Address
@@ -54,7 +55,7 @@ var _ = Describe("FlopKick Transformer", func() {
db = test_config.NewTestDB(blockChain.Node())
test_config.CleanTestDB(db)
- config = shared.TransformerConfig{
+ config = shared_t.TransformerConfig{
TransformerName: constants.FlopKickLabel,
ContractAddresses: []string{test_data.KovanFlopperContractAddress},
ContractAbi: test_data.KovanFlopperABI,
@@ -70,7 +71,7 @@ var _ = Describe("FlopKick Transformer", func() {
}
fetcher = shared.NewFetcher(blockChain)
- addresses = shared.HexStringsToAddresses(config.ContractAddresses)
+ addresses = shared_t.HexStringsToAddresses(config.ContractAddresses)
topics = []common.Hash{common.HexToHash(config.Topic)}
})
diff --git a/pkg/transformers/integration_tests/frob.go b/pkg/transformers/integration_tests/frob.go
index 43ef42d9..333f0b0c 100644
--- a/pkg/transformers/integration_tests/frob.go
+++ b/pkg/transformers/integration_tests/frob.go
@@ -23,6 +23,7 @@ import (
. "github.com/onsi/gomega"
"strconv"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
"github.com/vulcanize/vulcanizedb/pkg/geth"
@@ -39,7 +40,7 @@ var _ = Describe("Frob Transformer", func() {
db *postgres.DB
blockChain core.BlockChain
fetcher *shared.Fetcher
- config shared.TransformerConfig
+ config shared_t.TransformerConfig
initializer factories.Transformer
)
@@ -52,7 +53,7 @@ var _ = Describe("Frob Transformer", func() {
test_config.CleanTestDB(db)
fetcher = shared.NewFetcher(blockChain)
- config = shared.TransformerConfig{
+ config = shared_t.TransformerConfig{
TransformerName: constants.FrobLabel,
ContractAddresses: []string{test_data.KovanPitContractAddress},
ContractAbi: test_data.KovanPitABI,
@@ -77,7 +78,7 @@ var _ = Describe("Frob Transformer", func() {
Expect(err).NotTo(HaveOccurred())
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(config.ContractAddresses),
+ shared_t.HexStringsToAddresses(config.ContractAddresses),
[]common.Hash{common.HexToHash(config.Topic)},
header)
Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/transformers/integration_tests/pit_file_debt_ceiling.go b/pkg/transformers/integration_tests/pit_file_debt_ceiling.go
index 94cf232d..19c49afb 100644
--- a/pkg/transformers/integration_tests/pit_file_debt_ceiling.go
+++ b/pkg/transformers/integration_tests/pit_file_debt_ceiling.go
@@ -27,6 +27,7 @@ import (
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/debt_ceiling"
"github.com/vulcanize/vulcanizedb/test_config"
)
@@ -48,7 +49,7 @@ var _ = Describe("PitFileDebtCeiling LogNoteTransformer", func() {
It("fetches and transforms a PitFileDebtCeiling event from Kovan chain", func() {
blockNumber := int64(8535578)
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.PitFileDebtCeilingLabel,
ContractAddresses: []string{test_data.KovanPitContractAddress},
ContractAbi: test_data.KovanPitABI,
@@ -62,7 +63,7 @@ var _ = Describe("PitFileDebtCeiling LogNoteTransformer", func() {
fetcher := shared.NewFetcher(blockChain)
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(config.ContractAddresses),
+ shared_t.HexStringsToAddresses(config.ContractAddresses),
[]common.Hash{common.HexToHash(config.Topic)},
header)
Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/transformers/integration_tests/pit_file_ilk.go b/pkg/transformers/integration_tests/pit_file_ilk.go
index 9c8c221c..7d35f6a5 100644
--- a/pkg/transformers/integration_tests/pit_file_ilk.go
+++ b/pkg/transformers/integration_tests/pit_file_ilk.go
@@ -26,6 +26,7 @@ import (
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
"strconv"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/ilk"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
@@ -48,7 +49,7 @@ var _ = Describe("PitFileIlk LogNoteTransformer", func() {
Expect(err).NotTo(HaveOccurred())
db = test_config.NewTestDB(blockChain.Node())
test_config.CleanTestDB(db)
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.PitFileIlkLabel,
ContractAddresses: []string{test_data.KovanPitContractAddress},
ContractAbi: test_data.KovanPitABI,
@@ -57,7 +58,7 @@ var _ = Describe("PitFileIlk LogNoteTransformer", func() {
EndingBlockNumber: -1,
}
- addresses = shared.HexStringsToAddresses(config.ContractAddresses)
+ addresses = shared_t.HexStringsToAddresses(config.ContractAddresses)
topics = []common.Hash{common.HexToHash(config.Topic)}
initializer = factories.LogNoteTransformer{
diff --git a/pkg/transformers/integration_tests/price_feeds.go b/pkg/transformers/integration_tests/price_feeds.go
index 7bb27945..43ce7bd2 100644
--- a/pkg/transformers/integration_tests/price_feeds.go
+++ b/pkg/transformers/integration_tests/price_feeds.go
@@ -9,6 +9,7 @@ import (
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
@@ -21,7 +22,7 @@ var _ = Describe("Price feeds transformer", func() {
var (
db *postgres.DB
blockChain core.BlockChain
- config shared.TransformerConfig
+ config shared_t.TransformerConfig
fetcher *shared.Fetcher
initializer factories.LogNoteTransformer
topics []common.Hash
@@ -35,7 +36,7 @@ var _ = Describe("Price feeds transformer", func() {
db = test_config.NewTestDB(blockChain.Node())
test_config.CleanTestDB(db)
- config = shared.TransformerConfig{
+ config = shared_t.TransformerConfig{
TransformerName: constants.PriceFeedLabel,
ContractAddresses: []string{
test_data.KovanPepContractAddress,
@@ -69,7 +70,7 @@ var _ = Describe("Price feeds transformer", func() {
initializer.Config.EndingBlockNumber = blockNumber
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(addresses),
+ shared_t.HexStringsToAddresses(addresses),
topics,
header)
Expect(err).NotTo(HaveOccurred())
@@ -134,7 +135,7 @@ var _ = Describe("Price feeds transformer", func() {
initializer.Config.EndingBlockNumber = blockNumber
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(addresses),
+ shared_t.HexStringsToAddresses(addresses),
topics,
header)
Expect(err).NotTo(HaveOccurred())
@@ -160,7 +161,7 @@ var _ = Describe("Price feeds transformer", func() {
initializer.Config.EndingBlockNumber = blockNumber
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(addresses),
+ shared_t.HexStringsToAddresses(addresses),
topics,
header)
Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/transformers/integration_tests/tend.go b/pkg/transformers/integration_tests/tend.go
index b621bc66..9555e663 100644
--- a/pkg/transformers/integration_tests/tend.go
+++ b/pkg/transformers/integration_tests/tend.go
@@ -20,6 +20,7 @@ import (
"github.com/ethereum/go-ethereum/common"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
@@ -34,7 +35,7 @@ var _ = Describe("Tend LogNoteTransformer", func() {
var (
db *postgres.DB
blockChain core.BlockChain
- config shared.TransformerConfig
+ config shared_t.TransformerConfig
fetcher *shared.Fetcher
initializer factories.LogNoteTransformer
addresses []common.Address
@@ -49,7 +50,7 @@ var _ = Describe("Tend LogNoteTransformer", func() {
db = test_config.NewTestDB(blockChain.Node())
test_config.CleanTestDB(db)
- config = shared.TransformerConfig{
+ config = shared_t.TransformerConfig{
TransformerName: constants.TendLabel,
ContractAddresses: []string{test_data.KovanFlapperContractAddress, test_data.KovanFlipperContractAddress},
ContractAbi: test_data.KovanFlipperABI,
@@ -59,7 +60,7 @@ var _ = Describe("Tend LogNoteTransformer", func() {
}
fetcher = shared.NewFetcher(blockChain)
- addresses = shared.HexStringsToAddresses(config.ContractAddresses)
+ addresses = shared_t.HexStringsToAddresses(config.ContractAddresses)
topics = []common.Hash{common.HexToHash(config.Topic)}
initializer = factories.LogNoteTransformer{
diff --git a/pkg/transformers/integration_tests/vat_flux.go b/pkg/transformers/integration_tests/vat_flux.go
index f2bb9433..896688ea 100644
--- a/pkg/transformers/integration_tests/vat_flux.go
+++ b/pkg/transformers/integration_tests/vat_flux.go
@@ -24,6 +24,7 @@ import (
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
"strconv"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/vat_flux"
@@ -33,7 +34,7 @@ import (
var _ = Describe("VatFlux LogNoteTransformer", func() {
It("transforms VatFlux log events", func() {
blockNumber := int64(9004474)
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.VatFluxLabel,
ContractAddresses: []string{test_data.KovanVatContractAddress},
ContractAbi: test_data.KovanVatABI,
@@ -55,7 +56,7 @@ var _ = Describe("VatFlux LogNoteTransformer", func() {
fetcher := shared.NewFetcher(blockChain)
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(config.ContractAddresses),
+ shared_t.HexStringsToAddresses(config.ContractAddresses),
[]common.Hash{common.HexToHash(config.Topic)},
header)
Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/transformers/integration_tests/vat_fold.go b/pkg/transformers/integration_tests/vat_fold.go
index 39bb93f4..92e1ea12 100644
--- a/pkg/transformers/integration_tests/vat_fold.go
+++ b/pkg/transformers/integration_tests/vat_fold.go
@@ -27,6 +27,7 @@ import (
"github.com/vulcanize/vulcanizedb/test_config"
"strconv"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/vat_fold"
@@ -49,7 +50,7 @@ var _ = Describe("VatFold Transformer", func() {
It("transforms VatFold log events", func() {
blockNumber := int64(9367233)
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.VatFoldLabel,
ContractAddresses: []string{test_data.KovanVatContractAddress},
ContractAbi: test_data.KovanVatABI,
@@ -63,7 +64,7 @@ var _ = Describe("VatFold Transformer", func() {
fetcher := shared.NewFetcher(blockChain)
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(config.ContractAddresses),
+ shared_t.HexStringsToAddresses(config.ContractAddresses),
[]common.Hash{common.HexToHash(config.Topic)},
header)
Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/transformers/integration_tests/vat_grab.go b/pkg/transformers/integration_tests/vat_grab.go
index 19360710..07546ded 100644
--- a/pkg/transformers/integration_tests/vat_grab.go
+++ b/pkg/transformers/integration_tests/vat_grab.go
@@ -26,6 +26,7 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/vat_grab"
@@ -35,7 +36,7 @@ import (
var _ = Describe("Vat Grab Transformer", func() {
It("transforms VatGrab log events", func() {
blockNumber := int64(8958230)
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.VatGrabLabel,
ContractAddresses: []string{test_data.KovanVatContractAddress},
ContractAbi: test_data.KovanVatABI,
@@ -57,7 +58,7 @@ var _ = Describe("Vat Grab Transformer", func() {
fetcher := shared.NewFetcher(blockChain)
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(config.ContractAddresses),
+ shared_t.HexStringsToAddresses(config.ContractAddresses),
[]common.Hash{common.HexToHash(config.Topic)},
header)
Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/transformers/integration_tests/vat_heal.go b/pkg/transformers/integration_tests/vat_heal.go
index e59b861f..54d0ab5c 100644
--- a/pkg/transformers/integration_tests/vat_heal.go
+++ b/pkg/transformers/integration_tests/vat_heal.go
@@ -23,6 +23,7 @@ import (
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/vat_heal"
@@ -32,7 +33,7 @@ import (
var _ = Describe("VatHeal Transformer", func() {
It("transforms VatHeal log events", func() {
blockNumber := int64(8935578)
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.VatHealLabel,
ContractAddresses: []string{test_data.KovanVatContractAddress},
ContractAbi: test_data.KovanVatABI,
@@ -54,7 +55,7 @@ var _ = Describe("VatHeal Transformer", func() {
fetcher := shared.NewFetcher(blockChain)
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(config.ContractAddresses),
+ shared_t.HexStringsToAddresses(config.ContractAddresses),
[]common.Hash{common.HexToHash(config.Topic)},
header)
Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/transformers/integration_tests/vat_init.go b/pkg/transformers/integration_tests/vat_init.go
index 0835e396..23c9beb8 100644
--- a/pkg/transformers/integration_tests/vat_init.go
+++ b/pkg/transformers/integration_tests/vat_init.go
@@ -26,6 +26,7 @@ import (
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
"strconv"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/vat_init"
"github.com/vulcanize/vulcanizedb/test_config"
)
@@ -33,7 +34,7 @@ import (
var _ = Describe("VatInit LogNoteTransformer", func() {
It("transforms VatInit log events", func() {
blockNumber := int64(8535561)
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.VatInitLabel,
ContractAddresses: []string{test_data.KovanVatContractAddress},
ContractAbi: test_data.KovanVatABI,
@@ -55,7 +56,7 @@ var _ = Describe("VatInit LogNoteTransformer", func() {
fetcher := shared.NewFetcher(blockChain)
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(config.ContractAddresses),
+ shared_t.HexStringsToAddresses(config.ContractAddresses),
[]common.Hash{common.HexToHash(config.Topic)},
header)
Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/transformers/integration_tests/vat_move.go b/pkg/transformers/integration_tests/vat_move.go
index ffa3b2ed..6a1c7517 100644
--- a/pkg/transformers/integration_tests/vat_move.go
+++ b/pkg/transformers/integration_tests/vat_move.go
@@ -25,6 +25,7 @@ import (
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/vat_move"
"github.com/vulcanize/vulcanizedb/test_config"
)
@@ -32,7 +33,7 @@ import (
var _ = Describe("VatMove LogNoteTransformer", func() {
It("transforms VatMove log events", func() {
blockNumber := int64(9004628)
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.VatMoveLabel,
ContractAddresses: []string{test_data.KovanVatContractAddress},
ContractAbi: test_data.KovanVatABI,
@@ -54,7 +55,7 @@ var _ = Describe("VatMove LogNoteTransformer", func() {
fetcher := shared.NewFetcher(blockChain)
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(config.ContractAddresses),
+ shared_t.HexStringsToAddresses(config.ContractAddresses),
[]common.Hash{common.HexToHash(config.Topic)},
header)
Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/transformers/integration_tests/vat_slip.go b/pkg/transformers/integration_tests/vat_slip.go
index f5ba2560..5b723c5c 100644
--- a/pkg/transformers/integration_tests/vat_slip.go
+++ b/pkg/transformers/integration_tests/vat_slip.go
@@ -8,6 +8,7 @@ import (
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
"strconv"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
@@ -33,7 +34,7 @@ var _ = Describe("Vat slip transformer", func() {
It("persists vat slip event", func() {
blockNumber := int64(8953655)
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.VatSlipLabel,
ContractAddresses: []string{test_data.KovanVatContractAddress},
ContractAbi: test_data.KovanVatABI,
@@ -47,7 +48,7 @@ var _ = Describe("Vat slip transformer", func() {
fetcher := shared.NewFetcher(blockChain)
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(config.ContractAddresses),
+ shared_t.HexStringsToAddresses(config.ContractAddresses),
[]common.Hash{common.HexToHash(config.Topic)},
header)
Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/transformers/integration_tests/vat_tune.go b/pkg/transformers/integration_tests/vat_tune.go
index c962f278..674d963d 100644
--- a/pkg/transformers/integration_tests/vat_tune.go
+++ b/pkg/transformers/integration_tests/vat_tune.go
@@ -26,6 +26,7 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/vat_tune"
@@ -35,7 +36,7 @@ import (
var _ = Describe("VatTune LogNoteTransformer", func() {
It("transforms VatTune log events", func() {
blockNumber := int64(8761670)
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.VatTuneLabel,
ContractAddresses: []string{test_data.KovanVatContractAddress},
ContractAbi: test_data.KovanVatABI,
@@ -57,7 +58,7 @@ var _ = Describe("VatTune LogNoteTransformer", func() {
fetcher := shared.NewFetcher(blockChain)
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(config.ContractAddresses),
+ shared_t.HexStringsToAddresses(config.ContractAddresses),
[]common.Hash{common.HexToHash(config.Topic)},
header)
Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/transformers/integration_tests/vow_flog.go b/pkg/transformers/integration_tests/vow_flog.go
index 545a7680..e8aedb3f 100644
--- a/pkg/transformers/integration_tests/vow_flog.go
+++ b/pkg/transformers/integration_tests/vow_flog.go
@@ -25,6 +25,7 @@ import (
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/factories"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/vow_flog"
@@ -48,7 +49,7 @@ var _ = Describe("VowFlog LogNoteTransformer", func() {
It("transforms VowFlog log events", func() {
blockNumber := int64(8946819)
- config := shared.TransformerConfig{
+ config := shared_t.TransformerConfig{
TransformerName: constants.VowFlogLabel,
ContractAddresses: []string{test_data.KovanVowContractAddress},
ContractAbi: test_data.KovanVowABI,
@@ -62,7 +63,7 @@ var _ = Describe("VowFlog LogNoteTransformer", func() {
fetcher := shared.NewFetcher(blockChain)
logs, err := fetcher.FetchLogs(
- shared.HexStringsToAddresses(config.ContractAddresses),
+ shared_t.HexStringsToAddresses(config.ContractAddresses),
[]common.Hash{common.HexToHash(config.Topic)},
header)
Expect(err).NotTo(HaveOccurred())
diff --git a/pkg/transformers/pit_file/debt_ceiling/config.go b/pkg/transformers/pit_file/debt_ceiling/config.go
index 70ab91fc..356432be 100644
--- a/pkg/transformers/pit_file/debt_ceiling/config.go
+++ b/pkg/transformers/pit_file/debt_ceiling/config.go
@@ -17,12 +17,12 @@
package debt_ceiling
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetDebtCeilingFileConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetDebtCeilingFileConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.PitFileDebtCeilingLabel,
ContractAddresses: []string{constants.PitContractAddress()},
ContractAbi: constants.PitABI(),
diff --git a/pkg/transformers/pit_file/ilk/config.go b/pkg/transformers/pit_file/ilk/config.go
index 6ac0374e..4b29caaf 100644
--- a/pkg/transformers/pit_file/ilk/config.go
+++ b/pkg/transformers/pit_file/ilk/config.go
@@ -17,12 +17,12 @@
package ilk
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetIlkFileConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetIlkFileConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.PitFileIlkLabel,
ContractAddresses: []string{constants.PitContractAddress()},
ContractAbi: constants.PitABI(),
diff --git a/pkg/transformers/price_feeds/config.go b/pkg/transformers/price_feeds/config.go
index bff9a8ec..437ba879 100644
--- a/pkg/transformers/price_feeds/config.go
+++ b/pkg/transformers/price_feeds/config.go
@@ -17,12 +17,13 @@
package price_feeds
import (
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetPriceFeedConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetPriceFeedConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.PriceFeedLabel,
ContractAddresses: []string{
constants.PepContractAddress(), constants.PipContractAddress(), constants.RepContractAddress(),
diff --git a/pkg/transformers/shared/log_chunker.go b/pkg/transformers/shared/log_chunker.go
index 183bb7d3..75e1062a 100644
--- a/pkg/transformers/shared/log_chunker.go
+++ b/pkg/transformers/shared/log_chunker.go
@@ -20,10 +20,12 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"strings"
+
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
)
type Chunker interface {
- AddConfigs(transformerConfigs []TransformerConfig)
+ AddConfigs(transformerConfigs []shared_t.TransformerConfig)
ChunkLogs(logs []types.Log) map[string][]types.Log
}
@@ -42,7 +44,7 @@ func NewLogChunker() *LogChunker {
}
// Configures the chunker by adding more addreses and topics to consider.
-func (chunker *LogChunker) AddConfigs(transformerConfigs []TransformerConfig) {
+func (chunker *LogChunker) AddConfigs(transformerConfigs []shared_t.TransformerConfig) {
for _, config := range transformerConfigs {
for _, address := range config.ContractAddresses {
var lowerCaseAddress = strings.ToLower(address)
diff --git a/pkg/transformers/shared/log_chunker_test.go b/pkg/transformers/shared/log_chunker_test.go
index cc75d7aa..c783c40b 100644
--- a/pkg/transformers/shared/log_chunker_test.go
+++ b/pkg/transformers/shared/log_chunker_test.go
@@ -21,34 +21,35 @@ import (
"github.com/ethereum/go-ethereum/core/types"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
)
var _ = Describe("Log chunker", func() {
var (
- configs []shared.TransformerConfig
+ configs []shared_t.TransformerConfig
chunker *shared.LogChunker
)
BeforeEach(func() {
- configA := shared.TransformerConfig{
+ configA := shared_t.TransformerConfig{
TransformerName: "TransformerA",
ContractAddresses: []string{"0x00000000000000000000000000000000000000A1", "0x00000000000000000000000000000000000000A2"},
Topic: "0xA",
}
- configB := shared.TransformerConfig{
+ configB := shared_t.TransformerConfig{
TransformerName: "TransformerB",
ContractAddresses: []string{"0x00000000000000000000000000000000000000B1"},
Topic: "0xB",
}
- configC := shared.TransformerConfig{
+ configC := shared_t.TransformerConfig{
TransformerName: "TransformerC",
ContractAddresses: []string{"0x00000000000000000000000000000000000000A2"},
Topic: "0xC",
}
- configs = []shared.TransformerConfig{configA, configB, configC}
+ configs = []shared_t.TransformerConfig{configA, configB, configC}
chunker = shared.NewLogChunker()
chunker.AddConfigs(configs)
})
@@ -71,24 +72,24 @@ var _ = Describe("Log chunker", func() {
Describe("AddConfigs", func() {
It("can add more configs later", func() {
- configD := shared.TransformerConfig{
+ configD := shared_t.TransformerConfig{
TransformerName: "TransformerD",
ContractAddresses: []string{"0x000000000000000000000000000000000000000D"},
Topic: "0xD",
}
- chunker.AddConfigs([]shared.TransformerConfig{configD})
+ chunker.AddConfigs([]shared_t.TransformerConfig{configD})
Expect(chunker.AddressToNames).To(ContainElement([]string{"TransformerD"}))
Expect(chunker.NameToTopic0).To(ContainElement(common.HexToHash("0xD")))
})
It("lower cases address", func() {
- configD := shared.TransformerConfig{
+ configD := shared_t.TransformerConfig{
TransformerName: "TransformerD",
ContractAddresses: []string{"0x000000000000000000000000000000000000000D"},
Topic: "0xD",
}
- chunker.AddConfigs([]shared.TransformerConfig{configD})
+ chunker.AddConfigs([]shared_t.TransformerConfig{configD})
Expect(chunker.AddressToNames["0x000000000000000000000000000000000000000d"]).To(Equal([]string{"TransformerD"}))
})
diff --git a/pkg/transformers/tend/config.go b/pkg/transformers/tend/config.go
index 8013e97d..8fc4f0c2 100644
--- a/pkg/transformers/tend/config.go
+++ b/pkg/transformers/tend/config.go
@@ -17,12 +17,13 @@
package tend
import (
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetTendConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetTendConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.TendLabel,
ContractAddresses: []string{constants.FlapperContractAddress(), constants.FlipperContractAddress()},
ContractAbi: constants.FlipperABI(),
diff --git a/pkg/transformers/test_data/generic.go b/pkg/transformers/test_data/generic.go
index db5c8a0f..d373dd6c 100644
--- a/pkg/transformers/test_data/generic.go
+++ b/pkg/transformers/test_data/generic.go
@@ -17,11 +17,12 @@
package test_data
import (
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"math/rand"
"time"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
)
type GenericModel struct{}
@@ -37,7 +38,7 @@ var GenericTestLogs = []types.Log{{
BlockNumber: uint64(startingBlockNumber),
}}
-var GenericTestConfig = shared.TransformerConfig{
+var GenericTestConfig = shared_t.TransformerConfig{
TransformerName: "generic-test-transformer",
ContractAddresses: []string{address},
ContractAbi: randomString(100),
diff --git a/pkg/transformers/test_data/mocks/transformer.go b/pkg/transformers/test_data/mocks/transformer.go
index 452e5794..f0d5da49 100644
--- a/pkg/transformers/test_data/mocks/transformer.go
+++ b/pkg/transformers/test_data/mocks/transformer.go
@@ -2,9 +2,10 @@ package mocks
import (
"github.com/ethereum/go-ethereum/core/types"
+
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
@@ -13,7 +14,7 @@ type MockTransformer struct {
ExecuteError error
PassedLogs []types.Log
PassedHeader core.Header
- config shared.TransformerConfig
+ config shared_t.TransformerConfig
}
func (mh *MockTransformer) Execute(logs []types.Log, header core.Header, recheckHeaders constants.TransformerExecution) error {
@@ -26,19 +27,19 @@ func (mh *MockTransformer) Execute(logs []types.Log, header core.Header, recheck
return nil
}
-func (mh *MockTransformer) GetConfig() shared.TransformerConfig {
+func (mh *MockTransformer) GetConfig() shared_t.TransformerConfig {
return mh.config
}
-func (mh *MockTransformer) SetTransformerConfig(config shared.TransformerConfig) {
+func (mh *MockTransformer) SetTransformerConfig(config shared_t.TransformerConfig) {
mh.config = config
}
-func (mh *MockTransformer) FakeTransformerInitializer(db *postgres.DB) shared.Transformer {
+func (mh *MockTransformer) FakeTransformerInitializer(db *postgres.DB) shared_t.Transformer {
return mh
}
-var FakeTransformerConfig = shared.TransformerConfig{
+var FakeTransformerConfig = shared_t.TransformerConfig{
TransformerName: "FakeTransformer",
ContractAddresses: []string{"FakeAddress"},
Topic: "FakeTopic",
diff --git a/pkg/transformers/transformers.go b/pkg/transformers/transformers.go
index 3e5625fb..04acc76e 100644
--- a/pkg/transformers/transformers.go
+++ b/pkg/transformers/transformers.go
@@ -17,6 +17,7 @@
package transformers
import (
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/bite"
"github.com/vulcanize/vulcanizedb/pkg/transformers/cat_file/chop_lump"
"github.com/vulcanize/vulcanizedb/pkg/transformers/cat_file/flip"
@@ -35,7 +36,6 @@ import (
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/debt_ceiling"
"github.com/vulcanize/vulcanizedb/pkg/transformers/pit_file/ilk"
"github.com/vulcanize/vulcanizedb/pkg/transformers/price_feeds"
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
"github.com/vulcanize/vulcanizedb/pkg/transformers/tend"
"github.com/vulcanize/vulcanizedb/pkg/transformers/vat_flux"
"github.com/vulcanize/vulcanizedb/pkg/transformers/vat_fold"
@@ -315,7 +315,7 @@ func getLogNoteTransformers() []factories.LogNoteTransformer {
// `TransformerInitializers` returns a list of functions, that given a db pointer
// will return a `shared.Transformer`
-func TransformerInitializers() (initializers []shared.TransformerInitializer) {
+func TransformerInitializers() (initializers []shared_t.TransformerInitializer) {
for _, transformer := range getLogNoteTransformers() {
initializers = append(initializers, transformer.NewLogNoteTransformer)
}
diff --git a/pkg/transformers/vat_flux/config.go b/pkg/transformers/vat_flux/config.go
index e33d8d34..f4b347eb 100644
--- a/pkg/transformers/vat_flux/config.go
+++ b/pkg/transformers/vat_flux/config.go
@@ -1,12 +1,12 @@
package vat_flux
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetVatFluxConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetVatFluxConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.VatFluxLabel,
ContractAddresses: []string{constants.VatContractAddress()},
ContractAbi: constants.VatABI(),
diff --git a/pkg/transformers/vat_fold/config.go b/pkg/transformers/vat_fold/config.go
index f8e35c17..27fd3427 100644
--- a/pkg/transformers/vat_fold/config.go
+++ b/pkg/transformers/vat_fold/config.go
@@ -17,12 +17,12 @@
package vat_fold
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetVatFoldConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetVatFoldConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.VatFoldLabel,
ContractAddresses: []string{constants.VatContractAddress()},
ContractAbi: constants.VatABI(),
diff --git a/pkg/transformers/vat_grab/config.go b/pkg/transformers/vat_grab/config.go
index 89b8b309..ce653677 100644
--- a/pkg/transformers/vat_grab/config.go
+++ b/pkg/transformers/vat_grab/config.go
@@ -1,12 +1,12 @@
package vat_grab
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetVatGrabConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetVatGrabConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.VatGrabLabel,
ContractAddresses: []string{constants.VatContractAddress()},
ContractAbi: constants.VatABI(),
diff --git a/pkg/transformers/vat_heal/config.go b/pkg/transformers/vat_heal/config.go
index 4bc0831c..2e4ec56f 100644
--- a/pkg/transformers/vat_heal/config.go
+++ b/pkg/transformers/vat_heal/config.go
@@ -17,12 +17,12 @@
package vat_heal
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetVatHealConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetVatHealConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.VatHealLabel,
ContractAddresses: []string{constants.VatContractAddress()},
ContractAbi: constants.VatABI(),
diff --git a/pkg/transformers/vat_init/config.go b/pkg/transformers/vat_init/config.go
index 7d83c9d5..95a4a2f9 100644
--- a/pkg/transformers/vat_init/config.go
+++ b/pkg/transformers/vat_init/config.go
@@ -17,12 +17,12 @@
package vat_init
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetVatInitConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetVatInitConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.VatInitLabel,
ContractAddresses: []string{constants.VatContractAddress()},
ContractAbi: constants.VatABI(),
diff --git a/pkg/transformers/vat_move/config.go b/pkg/transformers/vat_move/config.go
index 6f8884d3..03c990bd 100644
--- a/pkg/transformers/vat_move/config.go
+++ b/pkg/transformers/vat_move/config.go
@@ -17,12 +17,12 @@
package vat_move
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetVatMoveConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetVatMoveConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.VatMoveLabel,
ContractAddresses: []string{constants.VatContractAddress()},
ContractAbi: constants.VatABI(),
diff --git a/pkg/transformers/vat_slip/config.go b/pkg/transformers/vat_slip/config.go
index db910f51..d095b8c1 100644
--- a/pkg/transformers/vat_slip/config.go
+++ b/pkg/transformers/vat_slip/config.go
@@ -1,12 +1,12 @@
package vat_slip
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetVatSlipConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetVatSlipConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.VatSlipLabel,
ContractAddresses: []string{constants.VatContractAddress()},
ContractAbi: constants.VatABI(),
diff --git a/pkg/transformers/vat_toll/config.go b/pkg/transformers/vat_toll/config.go
index 0003dc2b..998026d4 100644
--- a/pkg/transformers/vat_toll/config.go
+++ b/pkg/transformers/vat_toll/config.go
@@ -1,12 +1,12 @@
package vat_toll
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetVatTollConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetVatTollConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.VatTollLabel,
ContractAddresses: []string{constants.VatContractAddress()},
ContractAbi: constants.VatABI(),
diff --git a/pkg/transformers/vat_tune/config.go b/pkg/transformers/vat_tune/config.go
index 1a323258..cd3627a6 100644
--- a/pkg/transformers/vat_tune/config.go
+++ b/pkg/transformers/vat_tune/config.go
@@ -1,12 +1,12 @@
package vat_tune
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetVatTuneConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetVatTuneConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.VatTuneLabel,
ContractAddresses: []string{constants.VatContractAddress()},
ContractAbi: constants.VatABI(),
diff --git a/pkg/transformers/vow_flog/config.go b/pkg/transformers/vow_flog/config.go
index ca32ced2..5f46ec82 100644
--- a/pkg/transformers/vow_flog/config.go
+++ b/pkg/transformers/vow_flog/config.go
@@ -17,12 +17,12 @@
package vow_flog
import (
- "github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
+ shared_t "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants"
)
-func GetVowFlogConfig() shared.TransformerConfig {
- return shared.TransformerConfig{
+func GetVowFlogConfig() shared_t.TransformerConfig {
+ return shared_t.TransformerConfig{
TransformerName: constants.VowFlogLabel,
ContractAddresses: []string{constants.VowContractAddress()},
ContractAbi: constants.VowABI(),
diff --git a/plugins/README.md b/plugins/README.md
new file mode 100644
index 00000000..390eaeca
--- /dev/null
+++ b/plugins/README.md
@@ -0,0 +1,58 @@
+## Plugins
+
+This directory is for Exporter plugins (.go and .so files) generated by, output from, and linked to from the composeAndExecute command
+These plugins are generated using information provided in a .toml config file
+
+The config file requires, at a minimum, the below fields:
+
+```toml
+[database]
+ name = "vulcanize_public"
+ hostname = "localhost"
+ user = "vulcanize"
+ password = "vulcanize"
+ port = 5432
+
+[client]
+ ipcPath = "http://kovan0.vulcanize.io:8545"
+
+[exporter]
+ filePath = "$GOPATH/src/github.com/vulcanize/vulcanizedb/plugins/"
+ fileName = "exporter"
+ [exporter.transformers]
+ transformer1 = "github.com/path/to/transformer1"
+ transformer2 = "github.com/path/to/transformer2"
+ transformer3 = "github.com/path/to/transformer3"
+```
+
+In the above, the exporter.transformers are mappings of import aliases to their import paths
+If the individual transformers require additional configuration variables be sure to include them in the .toml file
+
+The general structure of a plugin .go file, and what we would see with the above config is below
+Note that `shared_transformer` is a reserved alias needed for the generic TransformerInitializer type:
+
+```go
+package main
+
+import (
+ shared_transformer "github.com/vulcanize/vulcanizedb/libraries/shared/transformer"
+ transformer1 "github.com/path/to/transformer1"
+ transformer2 "github.com/path/to/transformer2"
+ transformer3 "github.com/path/to/transformer3"
+)
+
+type exporter string
+
+var Exporter exporter
+
+func (e exporter) Export() []shared_transformer.TransformerInitializer {
+ return []shared_transformer.TransformerInitializer{
+ transformer1.TransformerInitializer,
+ transformer2.TransformerInitializer,
+ transformer3.TransformerInitializer,
+ }
+}
+```
+
+As such, to plug in an external transformer all we need to do is create a [package](https://github.com/vulcanize/maker-vulcanizedb/blob/compose_and_execute/pkg/autogen/test_helpers/bite/initializer.go) that exports a variable `TransformerInitializer` that is of type [TransformerInitializer](https://github.com/vulcanize/maker-vulcanizedb/blob/compose_and_execute/libraries/shared/transformer/transformer.go#L19)
+As long as the imported transformers abide by the required interfaces, we can execute over any arbitrary set of them
\ No newline at end of file
diff --git a/vendor/github.com/dave/jennifer/.gitignore b/vendor/github.com/dave/jennifer/.gitignore
new file mode 100644
index 00000000..f5730045
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/.gitignore
@@ -0,0 +1,30 @@
+*.iml
+
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+*.test
+*.prof
+
+.DS_Store
+.idea/
+coverage.out
diff --git a/vendor/github.com/dave/jennifer/.travis.yml b/vendor/github.com/dave/jennifer/.travis.yml
new file mode 100644
index 00000000..1b62d095
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/.travis.yml
@@ -0,0 +1,14 @@
+language: go
+go:
+ - 1.x
+notificaitons:
+ email:
+ recipients: dave@brophy.uk
+ on_failure: always
+install:
+ - go get -u github.com/dave/courtney
+ - go get -t -v ./...
+script:
+ - courtney -e
+after_success:
+ - bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/github.com/dave/jennifer/LICENSE b/vendor/github.com/dave/jennifer/LICENSE
new file mode 100644
index 00000000..17ab1ced
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 David Brophy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/dave/jennifer/README.md b/vendor/github.com/dave/jennifer/README.md
new file mode 100644
index 00000000..2d9060cd
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/README.md
@@ -0,0 +1,1052 @@
+[![Build Status](https://travis-ci.org/dave/jennifer.svg?branch=master)](https://travis-ci.org/dave/jennifer) [![Go Report Card](https://goreportcard.com/badge/github.com/dave/jennifer)](https://goreportcard.com/report/github.com/dave/jennifer) [![codecov](https://img.shields.io/badge/codecov-100%25-brightgreen.svg)](https://codecov.io/gh/dave/jennifer) ![stability-stable](https://img.shields.io/badge/stability-stable-brightgreen.svg) [![Sourcegraph](https://sourcegraph.com/github.com/dave/jennifer/jen/-/badge.svg)](https://sourcegraph.com/github.com/dave/jennifer?badge)
+
+# Jennifer
+Jennifer is a code generator for Go.
+
+```go
+package main
+
+import (
+ "fmt"
+
+ . "github.com/dave/jennifer/jen"
+)
+
+func main() {
+ f := NewFile("main")
+ f.Func().Id("main").Params().Block(
+ Qual("fmt", "Println").Call(Lit("Hello, world")),
+ )
+ fmt.Printf("%#v", f)
+}
+```
+Output:
+```go
+package main
+
+import "fmt"
+
+func main() {
+ fmt.Println("Hello, world")
+}
+```
+
+### Install
+```
+go get -u github.com/dave/jennifer/jen
+```
+
+### Need help?
+If you get stuck, have a question, would like a code review, or just want a
+chat: I'm happy to help! Feel free to open an issue, email me or mention @dave
+in your PR.
+
+### Examples
+Jennifer has a comprehensive suite of examples - see [godoc](https://godoc.org/github.com/dave/jennifer/jen#pkg-examples) for an index. Here's some examples of jennifer being used in the real-world:
+
+* [genjen](genjen/render.go) (which generates much of jennifer, using data in [data.go](genjen/data.go))
+* [zerogen](https://github.com/mrsinham/zerogen/blob/master/generator.go)
+* [go-contentful-generator](https://github.com/nicolai86/go-contentful-generator)
+
+### Rendering
+For testing, a File or Statement can be rendered with the fmt package
+using the %#v verb.
+
+```go
+c := Id("a").Call(Lit("b"))
+fmt.Printf("%#v", c)
+// Output:
+// a("b")
+```
+
+This is not recommended for use in production because any error will cause a
+panic. For production use, [File.Render](#render) or [File.Save](#save) are
+preferred.
+
+# Identifiers
+**Identifiers** [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+### Id
+Id renders an identifier.
+
+```go
+c := If(Id("i").Op("==").Id("j")).Block(
+ Return(Id("i")),
+)
+fmt.Printf("%#v", c)
+// Output:
+// if i == j {
+// return i
+// }
+```
+
+### Dot
+Dot renders a period followed by an identifier. Use for fields and selectors.
+
+```go
+c := Qual("a.b/c", "Foo").Call().Dot("Bar").Index(Lit(0)).Dot("Baz")
+fmt.Printf("%#v", c)
+// Output:
+// c.Foo().Bar[0].Baz
+```
+
+### Qual
+Qual renders a qualified identifier.
+
+```go
+c := Qual("encoding/gob", "NewEncoder").Call()
+fmt.Printf("%#v", c)
+// Output:
+// gob.NewEncoder()
+```
+
+Imports are automatically added when
+used with a File. If the path matches the local path, the package name is
+omitted. If package names conflict they are automatically renamed.
+
+```go
+f := NewFilePath("a.b/c")
+f.Func().Id("init").Params().Block(
+ Qual("a.b/c", "Foo").Call().Comment("Local package - name is omitted."),
+ Qual("d.e/f", "Bar").Call().Comment("Import is automatically added."),
+ Qual("g.h/f", "Baz").Call().Comment("Colliding package name is renamed."),
+)
+fmt.Printf("%#v", f)
+// Output:
+// package c
+//
+// import (
+// f "d.e/f"
+// f1 "g.h/f"
+// )
+//
+// func init() {
+// Foo() // Local package - name is omitted.
+// f.Bar() // Import is automatically added.
+// f1.Baz() // Colliding package name is renamed.
+// }
+```
+
+Note that
+it is not possible to reliably determine the package name given an arbitrary
+package path, so a sensible name is guessed from the path and added as an
+alias. The names of all standard library packages are known so these do not
+need to be aliased. If more control is needed of the aliases, see
+[File.ImportName](#importname) or [File.ImportAlias](#importalias).
+
+### List
+List renders a comma separated list. Use for multiple return functions.
+
+```go
+c := List(Id("a"), Err()).Op(":=").Id("b").Call()
+fmt.Printf("%#v", c)
+// Output:
+// a, err := b()
+```
+
+# Keywords
+[Identifiers](#identifiers) **Keywords** [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+Simple keywords, predeclared identifiers and built-in functions are self
+explanatory:
+
+| Construct | Name |
+| ---------------- | ---- |
+| Keywords | Break, Chan, Const, Continue, Default, Defer, Else, Fallthrough, Func, Go, Goto, Range, Select, Type, Var |
+| Functions | Append, Cap, Close, Complex, Copy, Delete, Imag, Len, Make, New, Panic, Print, Println, Real, Recover |
+| Types | Bool, Byte, Complex64, Complex128, Error, Float32, Float64, Int, Int8, Int16, Int32, Int64, Rune, String, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr |
+| Constants | True, False, Iota, Nil |
+| Helpers | Err |
+
+Built-in functions take a list of parameters and render them appropriately:
+
+```go
+c := Id("a").Op("=").Append(Id("a"), Id("b").Op("..."))
+fmt.Printf("%#v", c)
+// Output:
+// a = append(a, b...)
+```
+
+Special cases for [If, For](#if-for), [Interface, Struct](#interface-struct), [Switch, Case](#switch-select), [Return](#return) and [Map](#map) are explained below.
+
+# Operators
+[Identifiers](#identifiers) [Keywords](#keywords) **Operators** [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+Op renders the provided operator / token.
+
+```go
+c := Id("a").Op(":=").Id("b").Call()
+fmt.Printf("%#v", c)
+// Output:
+// a := b()
+```
+
+```go
+c := Id("a").Op("=").Op("*").Id("b")
+fmt.Printf("%#v", c)
+// Output:
+// a = *b
+```
+
+```go
+c := Id("a").Call(Id("b").Op("..."))
+fmt.Printf("%#v", c)
+// Output:
+// a(b...)
+```
+
+```go
+c := If(Parens(Id("a").Op("||").Id("b")).Op("&&").Id("c")).Block()
+fmt.Printf("%#v", c)
+// Output:
+// if (a || b) && c {
+// }
+```
+
+# Braces
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) **Braces** [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+Several methods render curly braces, summarized below:
+
+| Name | Prefix | Separator | Example |
+| ------------------------------ | ------------ | --------- | -------------------------------------|
+| [Block](#block) | | `\n` | `func a() { ... }` or `if a { ... }` |
+| [Interface](#interface-struct) | `interface` | `\n` | `interface { ... }` |
+| [Struct](#interface-struct) | `struct` | `\n` | `struct { ... }` |
+| [Values](#values) | | `,` | `[]int{1, 2}` or `A{B: "c"}` |
+
+### Block
+Block renders a statement list enclosed by curly braces. Use for code blocks.
+
+```go
+c := Func().Id("foo").Params().String().Block(
+ Id("a").Op("=").Id("b"),
+ Id("b").Op("++"),
+ Return(Id("b")),
+)
+fmt.Printf("%#v", c)
+// Output:
+// func foo() string {
+// a = b
+// b++
+// return b
+// }
+```
+
+```go
+c := If(Id("a").Op(">").Lit(10)).Block(
+ Id("a").Op("=").Id("a").Op("/").Lit(2),
+)
+fmt.Printf("%#v", c)
+// Output:
+// if a > 10 {
+// a = a / 2
+// }
+```
+
+A special case applies when used directly after Case or Default, where the braces are omitted. This allows use in switch and select statements. [See example](#switch-select).
+
+### Interface, Struct
+Interface and Struct render the keyword followed by a statement list enclosed
+by curly braces.
+
+```go
+c := Var().Id("a").Interface()
+fmt.Printf("%#v", c)
+// Output:
+// var a interface{}
+```
+
+```go
+c := Type().Id("a").Interface(
+ Id("b").Params().String(),
+)
+fmt.Printf("%#v", c)
+// Output:
+// type a interface {
+// b() string
+// }
+```
+
+```go
+c := Id("c").Op(":=").Make(Chan().Struct())
+fmt.Printf("%#v", c)
+// Output:
+// c := make(chan struct{})
+```
+
+```go
+c := Type().Id("foo").Struct(
+ List(Id("x"), Id("y")).Int(),
+ Id("u").Float32(),
+)
+fmt.Printf("%#v", c)
+// Output:
+// type foo struct {
+// x, y int
+// u float32
+// }
+```
+
+# Parentheses
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) **Parentheses** [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+Several methods output parenthesis, summarized below:
+
+| Name | Prefix | Separator | Example |
+| ----------------- | ------ | --------- | --------------------------------- |
+| [Call](#call) | | `,` | `fmt.Println(b, c)` |
+| [Params](#params) | | `,` | `func (a *A) Foo(i int) { ... }` |
+| [Defs](#defs) | | `\n` | `const ( ... )` |
+| [Parens](#parens) | | | `[]byte(s)` or `a / (b + c)` |
+| [Assert](#assert) | `.` | | `s, ok := i.(string)` |
+
+### Call
+Call renders a comma separated list enclosed by parenthesis. Use for function calls.
+
+```go
+c := Qual("fmt", "Printf").Call(
+ Lit("%#v: %T\n"),
+ Id("a"),
+ Id("b"),
+)
+fmt.Printf("%#v", c)
+// Output:
+// fmt.Printf("%#v: %T\n", a, b)
+```
+
+### Params
+Params renders a comma separated list enclosed by parenthesis. Use for function parameters and method receivers.
+
+```go
+c := Func().Params(
+ Id("a").Id("A"),
+).Id("foo").Params(
+ Id("b"),
+ Id("c").String(),
+).String().Block(
+ Return(Id("b").Op("+").Id("c")),
+)
+fmt.Printf("%#v", c)
+// Output:
+// func (a A) foo(b, c string) string {
+// return b + c
+// }
+```
+
+### Defs
+Defs renders a statement list enclosed in parenthesis. Use for definition lists.
+
+```go
+c := Const().Defs(
+ Id("a").Op("=").Lit("a"),
+ Id("b").Op("=").Lit("b"),
+)
+fmt.Printf("%#v", c)
+// Output:
+// const (
+// a = "a"
+// b = "b"
+// )
+```
+
+### Parens
+Parens renders a single item in parenthesis. Use for type conversion or to specify evaluation order.
+
+```go
+c := Id("b").Op(":=").Index().Byte().Parens(Id("s"))
+fmt.Printf("%#v", c)
+// Output:
+// b := []byte(s)
+```
+
+```go
+c := Id("a").Op("/").Parens(Id("b").Op("+").Id("c"))
+fmt.Printf("%#v", c)
+// Output:
+// a / (b + c)
+```
+
+### Assert
+Assert renders a period followed by a single item enclosed by parenthesis. Use for type assertions.
+
+```go
+c := List(Id("b"), Id("ok")).Op(":=").Id("a").Assert(Bool())
+fmt.Printf("%#v", c)
+// Output:
+// b, ok := a.(bool)
+```
+
+# Control flow
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) **Control flow** [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+### If, For
+If and For render the keyword followed by a semicolon separated list.
+
+```go
+c := If(
+ Err().Op(":=").Id("a").Call(),
+ Err().Op("!=").Nil(),
+).Block(
+ Return(Err()),
+)
+fmt.Printf("%#v", c)
+// Output:
+// if err := a(); err != nil {
+// return err
+// }
+```
+
+```go
+c := For(
+ Id("i").Op(":=").Lit(0),
+ Id("i").Op("<").Lit(10),
+ Id("i").Op("++"),
+).Block(
+ Qual("fmt", "Println").Call(Id("i")),
+)
+fmt.Printf("%#v", c)
+// Output:
+// for i := 0; i < 10; i++ {
+// fmt.Println(i)
+// }
+```
+
+### Switch, Select
+Switch, Select, Case and Block are used to build switch or select statements:
+
+```go
+c := Switch(Id("value").Dot("Kind").Call()).Block(
+ Case(Qual("reflect", "Float32"), Qual("reflect", "Float64")).Block(
+ Return(Lit("float")),
+ ),
+ Case(Qual("reflect", "Bool")).Block(
+ Return(Lit("bool")),
+ ),
+ Case(Qual("reflect", "Uintptr")).Block(
+ Fallthrough(),
+ ),
+ Default().Block(
+ Return(Lit("none")),
+ ),
+)
+fmt.Printf("%#v", c)
+// Output:
+// switch value.Kind() {
+// case reflect.Float32, reflect.Float64:
+// return "float"
+// case reflect.Bool:
+// return "bool"
+// case reflect.Uintptr:
+// fallthrough
+// default:
+// return "none"
+// }
+```
+
+### Return
+Return renders the keyword followed by a comma separated list.
+
+```go
+c := Return(Id("a"), Id("b"))
+fmt.Printf("%#v", c)
+// Output:
+// return a, b
+```
+
+# Collections
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) **Collections** [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+### Map
+Map renders the keyword followed by a single item enclosed by square brackets. Use for map definitions.
+
+```go
+c := Id("a").Op(":=").Map(String()).String().Values()
+fmt.Printf("%#v", c)
+// Output:
+// a := map[string]string{}
+```
+
+### Index
+Index renders a colon separated list enclosed by square brackets. Use for array / slice indexes and definitions.
+
+```go
+c := Var().Id("a").Index().String()
+fmt.Printf("%#v", c)
+// Output:
+// var a []string
+```
+
+```go
+c := Id("a").Op(":=").Id("b").Index(Lit(0), Lit(1))
+fmt.Printf("%#v", c)
+// Output:
+// a := b[0:1]
+```
+
+```go
+c := Id("a").Op(":=").Id("b").Index(Lit(1), Empty())
+fmt.Printf("%#v", c)
+// Output:
+// a := b[1:]
+```
+
+### Values
+Values renders a comma separated list enclosed by curly braces. Use for slice or composite literals.
+
+```go
+c := Index().String().Values(Lit("a"), Lit("b"))
+fmt.Printf("%#v", c)
+// Output:
+// []string{"a", "b"}
+```
+
+Dict renders as key/value pairs. Use with Values for map or composite
+literals.
+
+```go
+c := Map(String()).String().Values(Dict{
+ Lit("a"): Lit("b"),
+ Lit("c"): Lit("d"),
+})
+fmt.Printf("%#v", c)
+// Output:
+// map[string]string{
+// "a": "b",
+// "c": "d",
+// }
+```
+
+```go
+c := Op("&").Id("Person").Values(Dict{
+ Id("Age"): Lit(1),
+ Id("Name"): Lit("a"),
+})
+fmt.Printf("%#v", c)
+// Output:
+// &Person{
+// Age: 1,
+// Name: "a",
+// }
+```
+
+DictFunc executes a func(Dict) to generate the value.
+
+```go
+c := Id("a").Op(":=").Map(String()).String().Values(DictFunc(func(d Dict) {
+ d[Lit("a")] = Lit("b")
+ d[Lit("c")] = Lit("d")
+}))
+fmt.Printf("%#v", c)
+// Output:
+// a := map[string]string{
+// "a": "b",
+// "c": "d",
+// }
+```
+
+Note: the items are ordered by key when rendered to ensure repeatable code.
+
+# Literals
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) **Literals** [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+### Lit
+Lit renders a literal. Lit supports only built-in types (bool, string, int, complex128, float64,
+float32, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64).
+Passing any other type will panic.
+
+```go
+c := Id("a").Op(":=").Lit("a")
+fmt.Printf("%#v", c)
+// Output:
+// a := "a"
+```
+
+```go
+c := Id("a").Op(":=").Lit(1.5)
+fmt.Printf("%#v", c)
+// Output:
+// a := 1.5
+```
+
+LitFunc generates the value to render by executing the provided
+function.
+
+```go
+c := Id("a").Op(":=").LitFunc(func() interface{} { return 1 + 1 })
+fmt.Printf("%#v", c)
+// Output:
+// a := 2
+```
+
+For the default constant types (bool, int, float64, string, complex128), Lit
+will render the untyped constant.
+
+| Code | Output |
+| ------------- | ---------- |
+| `Lit(true)` | `true` |
+| `Lit(1)` | `1` |
+| `Lit(1.0)` | `1.0` |
+| `Lit("foo")` | `"foo"` |
+| `Lit(0 + 1i)` | `(0 + 1i)` |
+
+For all other built-in types (float32, int8, int16, int32, int64, uint, uint8,
+uint16, uint32, uint64, uintptr, complex64), Lit will also render the type.
+
+| Code | Output |
+| ------------------------ | ------------------- |
+| `Lit(float32(1))` | `float32(1)` |
+| `Lit(int16(1))` | `int16(1)` |
+| `Lit(uint8(0x1))` | `uint8(0x1)` |
+| `Lit(complex64(0 + 1i))` | `complex64(0 + 1i)` |
+
+The built-in alias types byte and rune need a special case. LitRune and LitByte
+render rune and byte literals.
+
+| Code | Output |
+| ------------------------ | ----------- |
+| `LitRune('x')` | `'x'` |
+| `LitByte(byte(0x1))` | `byte(0x1)` |
+
+# Comments
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) **Comments** [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+### Comment
+Comment adds a comment. If the provided string contains a newline, the
+comment is formatted in multiline style.
+
+```go
+f := NewFile("a")
+f.Comment("Foo returns the string \"foo\"")
+f.Func().Id("Foo").Params().String().Block(
+ Return(Lit("foo")).Comment("return the string foo"),
+)
+fmt.Printf("%#v", f)
+// Output:
+// package a
+//
+// // Foo returns the string "foo"
+// func Foo() string {
+// return "foo" // return the string foo
+// }
+```
+
+```go
+c := Comment("a\nb")
+fmt.Printf("%#v", c)
+// Output:
+// /*
+// a
+// b
+// */
+```
+
+If the comment string starts
+with "//" or "/*", the automatic formatting is disabled and the string is
+rendered directly.
+
+```go
+c := Id("foo").Call(Comment("/* inline */")).Comment("//no-space")
+fmt.Printf("%#v", c)
+// Output:
+// foo( /* inline */ ) //no-space
+```
+
+### Commentf
+Commentf adds a comment, using a format string and a list of parameters.
+
+```go
+name := "foo"
+val := "bar"
+c := Id(name).Op(":=").Lit(val).Commentf("%s is the string \"%s\"", name, val)
+fmt.Printf("%#v", c)
+// Output:
+// foo := "bar" // foo is the string "bar"
+```
+
+# Helpers
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) **Helpers** [Misc](#misc) [File](#file)
+
+### Func methods
+All constructs that accept a variadic list of items are paired with GroupFunc
+functions that accept a func(*Group). Use for embedding logic.
+
+```go
+c := Id("numbers").Op(":=").Index().Int().ValuesFunc(func(g *Group) {
+ for i := 0; i <= 5; i++ {
+ g.Lit(i)
+ }
+})
+fmt.Printf("%#v", c)
+// Output:
+// numbers := []int{0, 1, 2, 3, 4, 5}
+```
+
+```go
+increment := true
+name := "a"
+c := Func().Id("a").Params().BlockFunc(func(g *Group) {
+ g.Id(name).Op("=").Lit(1)
+ if increment {
+ g.Id(name).Op("++")
+ } else {
+ g.Id(name).Op("--")
+ }
+})
+fmt.Printf("%#v", c)
+// Output:
+// func a() {
+// a = 1
+// a++
+// }
+```
+
+### Add
+Add appends the provided items to the statement.
+
+```go
+ptr := Op("*")
+c := Id("a").Op("=").Add(ptr).Id("b")
+fmt.Printf("%#v", c)
+// Output:
+// a = *b
+```
+
+```go
+a := Id("a")
+i := Int()
+c := Var().Add(a, i)
+fmt.Printf("%#v", c)
+// Output:
+// var a int
+```
+
+### Do
+Do calls the provided function with the statement as a parameter. Use for
+embedding logic.
+
+```go
+f := func(name string, isMap bool) *Statement {
+ return Id(name).Op(":=").Do(func(s *Statement) {
+ if isMap {
+ s.Map(String()).String()
+ } else {
+ s.Index().String()
+ }
+ }).Values()
+}
+fmt.Printf("%#v\n%#v", f("a", true), f("b", false))
+// Output:
+// a := map[string]string{}
+// b := []string{}
+```
+
+# Misc
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) **Misc** [File](#file)
+
+### Tag
+Tag renders a struct tag
+
+```go
+c := Type().Id("foo").Struct(
+ Id("A").String().Tag(map[string]string{"json": "a"}),
+ Id("B").Int().Tag(map[string]string{"json": "b", "bar": "baz"}),
+)
+fmt.Printf("%#v", c)
+// Output:
+// type foo struct {
+// A string `json:"a"`
+// B int `bar:"baz" json:"b"`
+// }
+```
+
+Note: the items are ordered by key when rendered to ensure repeatable code.
+
+### Null
+Null adds a null item. Null items render nothing and are not followed by a
+separator in lists.
+
+In lists, nil will produce the same effect.
+
+```go
+c := Func().Id("foo").Params(
+ nil,
+ Id("s").String(),
+ Null(),
+ Id("i").Int(),
+).Block()
+fmt.Printf("%#v", c)
+// Output:
+// func foo(s string, i int) {}
+```
+
+### Empty
+Empty adds an empty item. Empty items render nothing but are followed by a
+separator in lists.
+
+```go
+c := Id("a").Op(":=").Id("b").Index(Lit(1), Empty())
+fmt.Printf("%#v", c)
+// Output:
+// a := b[1:]
+```
+
+### Line
+Line inserts a blank line.
+
+### Clone
+Be careful when passing *Statement. Consider the following...
+
+```go
+a := Id("a")
+c := Block(
+ a.Call(),
+ a.Call(),
+)
+fmt.Printf("%#v", c)
+// Output:
+// {
+// a()()
+// a()()
+// }
+```
+
+Id("a") returns a *Statement, which the Call() method appends to twice. To
+avoid this, use Clone. Clone makes a copy of the Statement, so further tokens can be appended
+without affecting the original.
+
+```go
+a := Id("a")
+c := Block(
+ a.Clone().Call(),
+ a.Clone().Call(),
+)
+fmt.Printf("%#v", c)
+// Output:
+// {
+// a()
+// a()
+// }
+```
+
+### Cgo
+The cgo "C" pseudo-package is a special case, and always renders without a package alias. The
+import can be added with `Qual`, `Anon` or by supplying a preamble. The preamble is added with
+`File.CgoPreamble` which has the same semantics as [Comment](#comments). If a preamble is provided,
+the import is separated, and preceded by the preamble.
+
+```go
+f := NewFile("a")
+f.CgoPreamble(`#include
+#include
+
+void myprint(char* s) {
+printf("%s\n", s);
+}
+`)
+f.Func().Id("init").Params().Block(
+ Id("cs").Op(":=").Qual("C", "CString").Call(Lit("Hello from stdio\n")),
+ Qual("C", "myprint").Call(Id("cs")),
+ Qual("C", "free").Call(Qual("unsafe", "Pointer").Parens(Id("cs"))),
+)
+fmt.Printf("%#v", f)
+// Output:
+// package a
+//
+// import "unsafe"
+//
+// /*
+// #include
+// #include
+//
+// void myprint(char* s) {
+// printf("%s\n", s);
+// }
+// */
+// import "C"
+//
+// func init() {
+// cs := C.CString("Hello from stdio\n")
+// C.myprint(cs)
+// C.free(unsafe.Pointer(cs))
+// }
+```
+
+# File
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) **File**
+
+File represents a single source file. Package imports are managed
+automaticaly by File.
+
+### NewFile
+NewFile Creates a new file, with the specified package name.
+
+### NewFilePath
+NewFilePath creates a new file while specifying the package path - the
+package name is inferred from the path.
+
+### NewFilePathName
+NewFilePathName creates a new file with the specified package path and name.
+
+```go
+f := NewFilePathName("a.b/c", "main")
+f.Func().Id("main").Params().Block(
+ Qual("a.b/c", "Foo").Call(),
+)
+fmt.Printf("%#v", f)
+// Output:
+// package main
+//
+// func main() {
+// Foo()
+// }
+```
+
+### Save
+Save renders the file and saves to the filename provided.
+
+### Render
+Render renders the file to the provided writer.
+
+```go
+f := NewFile("a")
+f.Func().Id("main").Params().Block()
+buf := &bytes.Buffer{}
+err := f.Render(buf)
+if err != nil {
+ fmt.Println(err.Error())
+} else {
+ fmt.Println(buf.String())
+}
+// Output:
+// package a
+//
+// func main() {}
+```
+
+### Anon
+Anon adds an anonymous import.
+
+```go
+f := NewFile("c")
+f.Anon("a")
+f.Func().Id("init").Params().Block()
+fmt.Printf("%#v", f)
+// Output:
+// package c
+//
+// import _ "a"
+//
+// func init() {}
+```
+
+### ImportName
+ImportName provides the package name for a path. If specified, the alias will be omitted from the
+import block. This is optional. If not specified, a sensible package name is used based on the path
+and this is added as an alias in the import block.
+
+```go
+f := NewFile("main")
+
+// package a should use name "a"
+f.ImportName("github.com/foo/a", "a")
+
+// package b is not used in the code so will not be included
+f.ImportName("github.com/foo/b", "b")
+
+f.Func().Id("main").Params().Block(
+ Qual("github.com/foo/a", "A").Call(),
+)
+fmt.Printf("%#v", f)
+
+// Output:
+// package main
+//
+// import "github.com/foo/a"
+//
+// func main() {
+// a.A()
+// }
+```
+
+### ImportNames
+ImportNames allows multiple names to be imported as a map. Use the [gennames](gennames) command to
+automatically generate a go file containing a map of a selection of package names.
+
+### ImportAlias
+ImportAlias provides the alias for a package path that should be used in the import block. A
+period can be used to force a dot-import.
+
+```go
+f := NewFile("main")
+
+// package a should be aliased to "b"
+f.ImportAlias("github.com/foo/a", "b")
+
+// package c is not used in the code so will not be included
+f.ImportAlias("github.com/foo/c", "c")
+
+f.Func().Id("main").Params().Block(
+ Qual("github.com/foo/a", "A").Call(),
+)
+fmt.Printf("%#v", f)
+
+// Output:
+// package main
+//
+// import b "github.com/foo/a"
+//
+// func main() {
+// b.A()
+// }
+```
+
+### Comments
+PackageComment adds a comment to the top of the file, above the package
+keyword.
+
+HeaderComment adds a comment to the top of the file, above any package
+comments. A blank line is rendered below the header comments, ensuring
+header comments are not included in the package doc.
+
+CanonicalPath adds a canonical import path annotation to the package clause.
+
+```go
+f := NewFile("c")
+f.CanonicalPath = "d.e/f"
+f.HeaderComment("Code generated by...")
+f.PackageComment("Package c implements...")
+f.Func().Id("init").Params().Block()
+fmt.Printf("%#v", f)
+// Output:
+// // Code generated by...
+//
+// // Package c implements...
+// package c // import "d.e/f"
+//
+// func init() {}
+```
+
+CgoPreamble adds a cgo preamble comment that is rendered directly before the "C" pseudo-package
+import.
+
+### PackagePrefix
+If you're worried about generated package aliases conflicting with local variable names, you
+can set a prefix here. Package foo becomes {prefix}_foo.
+
+```go
+f := NewFile("a")
+f.PackagePrefix = "pkg"
+f.Func().Id("main").Params().Block(
+ Qual("b.c/d", "E").Call(),
+)
+fmt.Printf("%#v", f)
+// Output:
+// package a
+//
+// import pkg_d "b.c/d"
+//
+// func main() {
+// pkg_d.E()
+// }
+```
diff --git a/vendor/github.com/dave/jennifer/README.md.tpl b/vendor/github.com/dave/jennifer/README.md.tpl
new file mode 100644
index 00000000..9000ca1d
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/README.md.tpl
@@ -0,0 +1,422 @@
+[![Build Status](https://travis-ci.org/dave/jennifer.svg?branch=master)](https://travis-ci.org/dave/jennifer) [![Go Report Card](https://goreportcard.com/badge/github.com/dave/jennifer)](https://goreportcard.com/report/github.com/dave/jennifer) [![codecov](https://img.shields.io/badge/codecov-100%25-brightgreen.svg)](https://codecov.io/gh/dave/jennifer) ![stability-stable](https://img.shields.io/badge/stability-stable-brightgreen.svg) [![Sourcegraph](https://sourcegraph.com/github.com/dave/jennifer/jen/-/badge.svg)](https://sourcegraph.com/github.com/dave/jennifer?badge)
+
+# Jennifer
+Jennifer is a code generator for Go.
+
+```go
+package main
+
+import (
+ "fmt"
+
+ . "github.com/dave/jennifer/jen"
+)
+
+func main() {{ "ExampleNewFile" | code }}
+```
+Output:
+```go
+{{ "ExampleNewFile" | output }}
+```
+
+### Install
+```
+go get -u github.com/dave/jennifer/jen
+```
+
+### Need help?
+If you get stuck, have a question, would like a code review, or just want a
+chat: I'm happy to help! Feel free to open an issue, email me or mention @dave
+in your PR.
+
+### Examples
+Jennifer has a comprehensive suite of examples - see [godoc](https://godoc.org/github.com/dave/jennifer/jen#pkg-examples) for an index. Here's some examples of jennifer being used in the real-world:
+
+* [genjen](genjen/render.go) (which generates much of jennifer, using data in [data.go](genjen/data.go))
+* [zerogen](https://github.com/mrsinham/zerogen/blob/master/generator.go)
+* [go-contentful-generator](https://github.com/nicolai86/go-contentful-generator)
+
+### Rendering
+For testing, a File or Statement can be rendered with the fmt package
+using the %#v verb.
+
+{{ "ExampleCall_fmt" | example }}
+
+This is not recommended for use in production because any error will cause a
+panic. For production use, [File.Render](#render) or [File.Save](#save) are
+preferred.
+
+# Identifiers
+**Identifiers** [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+### Id
+{{ "Id" | doc }}
+
+{{ "ExampleId" | example }}
+
+### Dot
+{{ "Dot" | doc }}
+
+{{ "ExampleDot" | example }}
+
+### Qual
+{{ "Qual[0]" | doc }}
+
+{{ "ExampleQual" | example }}
+
+{{ "Qual[1:4]" | doc }}
+
+{{ "ExampleQual_file" | example }}
+
+{{ "Qual[4:]" | doc }}
+
+### List
+{{ "List" | doc }}
+
+{{ "ExampleList" | example }}
+
+# Keywords
+[Identifiers](#identifiers) **Keywords** [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+Simple keywords, predeclared identifiers and built-in functions are self
+explanatory:
+
+| Construct | Name |
+| ---------------- | ---- |
+| Keywords | Break, Chan, Const, Continue, Default, Defer, Else, Fallthrough, Func, Go, Goto, Range, Select, Type, Var |
+| Functions | Append, Cap, Close, Complex, Copy, Delete, Imag, Len, Make, New, Panic, Print, Println, Real, Recover |
+| Types | Bool, Byte, Complex64, Complex128, Error, Float32, Float64, Int, Int8, Int16, Int32, Int64, Rune, String, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr |
+| Constants | True, False, Iota, Nil |
+| Helpers | Err |
+
+Built-in functions take a list of parameters and render them appropriately:
+
+{{ "ExampleAppend_more" | example }}
+
+Special cases for [If, For](#if-for), [Interface, Struct](#interface-struct), [Switch, Case](#switch-select), [Return](#return) and [Map](#map) are explained below.
+
+# Operators
+[Identifiers](#identifiers) [Keywords](#keywords) **Operators** [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+{{ "Op" | doc }}
+
+{{ "ExampleOp" | example }}
+
+{{ "ExampleOp_star" | example }}
+
+{{ "ExampleOp_variadic" | example }}
+
+{{ "ExampleOp_complex_conditions" | example }}
+
+# Braces
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) **Braces** [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+Several methods render curly braces, summarized below:
+
+| Name | Prefix | Separator | Example |
+| ------------------------------ | ------------ | --------- | -------------------------------------|
+| [Block](#block) | | `\n` | `func a() { ... }` or `if a { ... }` |
+| [Interface](#interface-struct) | `interface` | `\n` | `interface { ... }` |
+| [Struct](#interface-struct) | `struct` | `\n` | `struct { ... }` |
+| [Values](#values) | | `,` | `[]int{1, 2}` or `A{B: "c"}` |
+
+### Block
+{{ "Block[:2]" | doc }}
+
+{{ "ExampleBlock" | example }}
+
+{{ "ExampleBlock_if" | example }}
+
+{{ "Block[2:]" | doc }} [See example](#switch-select).
+
+### Interface, Struct
+Interface and Struct render the keyword followed by a statement list enclosed
+by curly braces.
+
+{{ "ExampleInterface_empty" | example }}
+
+{{ "ExampleInterface" | example }}
+
+{{ "ExampleStruct_empty" | example }}
+
+{{ "ExampleStruct" | example }}
+
+# Parentheses
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) **Parentheses** [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+Several methods output parenthesis, summarized below:
+
+| Name | Prefix | Separator | Example |
+| ----------------- | ------ | --------- | --------------------------------- |
+| [Call](#call) | | `,` | `fmt.Println(b, c)` |
+| [Params](#params) | | `,` | `func (a *A) Foo(i int) { ... }` |
+| [Defs](#defs) | | `\n` | `const ( ... )` |
+| [Parens](#parens) | | | `[]byte(s)` or `a / (b + c)` |
+| [Assert](#assert) | `.` | | `s, ok := i.(string)` |
+
+### Call
+{{ "Call" | doc }}
+
+{{ "ExampleCall" | example }}
+
+### Params
+{{ "Params" | doc }}
+
+{{ "ExampleParams" | example }}
+
+### Defs
+{{ "Defs" | doc }}
+
+{{ "ExampleDefs" | example }}
+
+### Parens
+{{ "Parens" | doc }}
+
+{{ "ExampleParens" | example }}
+
+{{ "ExampleParens_order" | example }}
+
+### Assert
+{{ "Assert" | doc }}
+
+{{ "ExampleAssert" | example }}
+
+# Control flow
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) **Control flow** [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+### If, For
+If and For render the keyword followed by a semicolon separated list.
+
+{{ "ExampleIf" | example }}
+
+{{ "ExampleFor" | example }}
+
+### Switch, Select
+Switch, Select, Case and Block are used to build switch or select statements:
+
+{{ "ExampleSwitch" | example }}
+
+### Return
+{{ "Return" | doc }}
+
+{{ "ExampleReturn" | example }}
+
+# Collections
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) **Collections** [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+### Map
+{{ "Map" | doc }}
+
+{{ "ExampleMap" | example }}
+
+### Index
+{{ "Index" | doc }}
+
+{{ "ExampleIndex" | example }}
+
+{{ "ExampleIndex_index" | example }}
+
+{{ "ExampleIndex_empty" | example }}
+
+### Values
+{{ "Values" | doc }}
+
+{{ "ExampleValues" | example }}
+
+{{ "Dict" | doc }}
+
+{{ "ExampleValues_dict_multiple" | example }}
+
+{{ "ExampleValues_dict_composite" | example }}
+
+{{ "DictFunc[0]" | doc }}
+
+{{ "ExampleDictFunc" | example }}
+
+Note: the items are ordered by key when rendered to ensure repeatable code.
+
+# Literals
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) **Literals** [Comments](#comments) [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+### Lit
+{{ "Lit" | doc }}
+
+{{ "ExampleLit" | example }}
+
+{{ "ExampleLit_float" | example }}
+
+{{ "LitFunc[1:2]" | doc }}
+
+{{ "ExampleLitFunc" | example }}
+
+For the default constant types (bool, int, float64, string, complex128), Lit
+will render the untyped constant.
+
+| Code | Output |
+| ------------- | ---------- |
+| `Lit(true)` | `true` |
+| `Lit(1)` | `1` |
+| `Lit(1.0)` | `1.0` |
+| `Lit("foo")` | `"foo"` |
+| `Lit(0 + 1i)` | `(0 + 1i)` |
+
+For all other built-in types (float32, int8, int16, int32, int64, uint, uint8,
+uint16, uint32, uint64, uintptr, complex64), Lit will also render the type.
+
+| Code | Output |
+| ------------------------ | ------------------- |
+| `Lit(float32(1))` | `float32(1)` |
+| `Lit(int16(1))` | `int16(1)` |
+| `Lit(uint8(0x1))` | `uint8(0x1)` |
+| `Lit(complex64(0 + 1i))` | `complex64(0 + 1i)` |
+
+The built-in alias types byte and rune need a special case. LitRune and LitByte
+render rune and byte literals.
+
+| Code | Output |
+| ------------------------ | ----------- |
+| `LitRune('x')` | `'x'` |
+| `LitByte(byte(0x1))` | `byte(0x1)` |
+
+# Comments
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) **Comments** [Helpers](#helpers) [Misc](#misc) [File](#file)
+
+### Comment
+{{ "Comment[:2]" | doc }}
+
+{{ "ExampleComment" | example }}
+
+{{ "ExampleComment_multiline" | example }}
+
+{{ "Comment[2:]" | doc }}
+
+{{ "ExampleComment_formatting_disabled" | example }}
+
+### Commentf
+{{ "Commentf[0]" | doc }}
+
+{{ "ExampleCommentf" | example }}
+
+# Helpers
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) **Helpers** [Misc](#misc) [File](#file)
+
+### Func methods
+All constructs that accept a variadic list of items are paired with GroupFunc
+functions that accept a func(*Group). Use for embedding logic.
+
+{{ "ExampleValuesFunc" | example }}
+
+{{ "ExampleBlockFunc" | example }}
+
+### Add
+{{ "Add" | doc }}
+
+{{ "ExampleAdd" | example }}
+
+{{ "ExampleAdd_var" | example }}
+
+### Do
+{{ "Do" | doc }}
+
+{{ "ExampleDo" | example }}
+
+# Misc
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) **Misc** [File](#file)
+
+### Tag
+{{ "Tag" | doc }}
+
+{{ "ExampleTag" | example }}
+
+Note: the items are ordered by key when rendered to ensure repeatable code.
+
+### Null
+{{ "Null" | doc }}
+
+In lists, nil will produce the same effect.
+
+{{ "ExampleNull_and_nil" | example }}
+
+### Empty
+{{ "Empty" | doc }}
+
+{{ "ExampleEmpty" | example }}
+
+### Line
+{{ "Line" | doc }}
+
+### Clone
+Be careful when passing *Statement. Consider the following...
+
+{{ "ExampleStatement_Clone_broken" | example }}
+
+Id("a") returns a *Statement, which the Call() method appends to twice. To
+avoid this, use Clone. {{ "Statement.Clone" | doc }}
+
+{{ "ExampleStatement_Clone_fixed" | example }}
+
+### Cgo
+The cgo "C" pseudo-package is a special case, and always renders without a package alias. The
+import can be added with `Qual`, `Anon` or by supplying a preamble. The preamble is added with
+`File.CgoPreamble` which has the same semantics as [Comment](#comments). If a preamble is provided,
+the import is separated, and preceded by the preamble.
+
+{{ "ExampleFile_CgoPreamble" | example }}
+
+# File
+[Identifiers](#identifiers) [Keywords](#keywords) [Operators](#operators) [Braces](#braces) [Parentheses](#parentheses) [Control flow](#control-flow) [Collections](#collections) [Literals](#literals) [Comments](#comments) [Helpers](#helpers) [Misc](#misc) **File**
+
+{{ "File" | doc }}
+
+### NewFile
+{{ "NewFile" | doc }}
+
+### NewFilePath
+{{ "NewFilePath" | doc }}
+
+### NewFilePathName
+{{ "NewFilePathName" | doc }}
+
+{{ "ExampleNewFilePathName" | example }}
+
+### Save
+{{ "File.Save" | doc }}
+
+### Render
+{{ "File.Render" | doc }}
+
+{{ "ExampleFile_Render" | example }}
+
+### Anon
+{{ "File.Anon" | doc }}
+
+{{ "ExampleFile_Anon" | example }}
+
+### ImportName
+{{ "File.ImportName" | doc }}
+
+{{ "ExampleFile_ImportName" | example }}
+
+### ImportNames
+{{ "File.ImportNames" | doc }}
+
+### ImportAlias
+{{ "File.ImportAlias" | doc }}
+
+{{ "ExampleFile_ImportAlias" | example }}
+
+### Comments
+{{ "File.PackageComment" | doc }}
+
+{{ "File.HeaderComment" | doc }}
+
+{{ "File.CanonicalPath" | doc }}
+
+{{ "ExampleFile_HeaderAndPackageComments" | example }}
+
+{{ "File.CgoPreamble" | doc }}
+
+### PackagePrefix
+{{ "File.PackagePrefix" | doc }}
+
+{{ "ExampleFile_PackagePrefix" | example }}
diff --git a/vendor/github.com/dave/jennifer/genjen/data.go b/vendor/github.com/dave/jennifer/genjen/data.go
new file mode 100644
index 00000000..ff8b39a7
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/genjen/data.go
@@ -0,0 +1,307 @@
+package main
+
+var keywords = []string{"break", "default", "func", "select", "chan", "else", "const", "fallthrough", "type", "continue", "var", "goto", "defer", "go", "range"}
+
+var identifiers = []string{"bool", "byte", "complex64", "complex128", "error", "float32", "float64", "int", "int8", "int16", "int32", "int64", "rune", "string", "uint", "uint8", "uint16", "uint32", "uint64", "uintptr", "true", "false", "iota", "nil", "err"}
+
+var groups = []struct {
+ name string // name of the function / method
+ comment string // comment appended to name
+ variadic bool // is the parameter variadic?
+ opening string // opening token
+ closing string // closing token
+ separator string // separator token
+ multi bool // items are always on multiple lines
+ parameters []string // parameter names
+ preventFunc bool // prevent the fooFunc function/method
+}{
+ {
+ name: "Parens",
+ comment: "renders a single item in parenthesis. Use for type conversion or to specify evaluation order.",
+ variadic: false,
+ opening: "(",
+ closing: ")",
+ separator: "",
+ parameters: []string{"item"},
+ },
+ {
+ name: "List",
+ comment: "renders a comma separated list. Use for multiple return functions.",
+ variadic: true,
+ opening: "",
+ closing: "",
+ separator: ",",
+ parameters: []string{"items"},
+ },
+ {
+ name: "Values",
+ comment: "renders a comma separated list enclosed by curly braces. Use for slice or composite literals.",
+ variadic: true,
+ opening: "{",
+ closing: "}",
+ separator: ",",
+ parameters: []string{"values"},
+ },
+ {
+ name: "Index",
+ comment: "renders a colon separated list enclosed by square brackets. Use for array / slice indexes and definitions.",
+ variadic: true,
+ opening: "[",
+ closing: "]",
+ separator: ":",
+ parameters: []string{"items"},
+ },
+ {
+ name: "Block",
+ comment: "renders a statement list enclosed by curly braces. Use for code blocks. A special case applies when used directly after Case or Default, where the braces are omitted. This allows use in switch and select statements.",
+ variadic: true,
+ opening: "{",
+ closing: "}",
+ multi: true,
+ parameters: []string{"statements"},
+ },
+ {
+ name: "Defs",
+ comment: "renders a statement list enclosed in parenthesis. Use for definition lists.",
+ variadic: true,
+ opening: "(",
+ closing: ")",
+ multi: true,
+ parameters: []string{"definitions"},
+ },
+ {
+ name: "Call",
+ comment: "renders a comma separated list enclosed by parenthesis. Use for function calls.",
+ variadic: true,
+ opening: "(",
+ closing: ")",
+ separator: ",",
+ parameters: []string{"params"},
+ },
+ {
+ name: "Params",
+ comment: "renders a comma separated list enclosed by parenthesis. Use for function parameters and method receivers.",
+ variadic: true,
+ opening: "(",
+ closing: ")",
+ separator: ",",
+ parameters: []string{"params"},
+ },
+ {
+ name: "Assert",
+ comment: "renders a period followed by a single item enclosed by parenthesis. Use for type assertions.",
+ variadic: false,
+ opening: ".(",
+ closing: ")",
+ separator: "",
+ parameters: []string{"typ"},
+ },
+ {
+ name: "Map",
+ comment: "renders the keyword followed by a single item enclosed by square brackets. Use for map definitions.",
+ variadic: false,
+ opening: "map[",
+ closing: "]",
+ separator: "",
+ parameters: []string{"typ"},
+ },
+ {
+ name: "If",
+ comment: "renders the keyword followed by a semicolon separated list.",
+ variadic: true,
+ opening: "if ",
+ closing: "",
+ separator: ";",
+ parameters: []string{"conditions"},
+ },
+ {
+ name: "Return",
+ comment: "renders the keyword followed by a comma separated list.",
+ variadic: true,
+ opening: "return ",
+ closing: "",
+ separator: ",",
+ parameters: []string{"results"},
+ },
+ {
+ name: "For",
+ comment: "renders the keyword followed by a semicolon separated list.",
+ variadic: true,
+ opening: "for ",
+ closing: "",
+ separator: ";",
+ parameters: []string{"conditions"},
+ },
+ {
+ name: "Switch",
+ comment: "renders the keyword followed by a semicolon separated list.",
+ variadic: true,
+ opening: "switch ",
+ closing: "",
+ separator: ";",
+ parameters: []string{"conditions"},
+ },
+ {
+ name: "Interface",
+ comment: "renders the keyword followed by a method list enclosed by curly braces.",
+ variadic: true,
+ opening: "interface{",
+ closing: "}",
+ multi: true,
+ parameters: []string{"methods"},
+ },
+ {
+ name: "Struct",
+ comment: "renders the keyword followed by a field list enclosed by curly braces.",
+ variadic: true,
+ opening: "struct{",
+ closing: "}",
+ multi: true,
+ parameters: []string{"fields"},
+ },
+ {
+ name: "Case",
+ comment: "renders the keyword followed by a comma separated list.",
+ variadic: true,
+ opening: "case ",
+ closing: ":",
+ separator: ",",
+ parameters: []string{"cases"},
+ },
+ {
+ name: "Append",
+ comment: "renders the append built-in function.",
+ variadic: true,
+ opening: "append(",
+ closing: ")",
+ separator: ",",
+ parameters: []string{"args"},
+ },
+ {
+ name: "Cap",
+ comment: "renders the cap built-in function.",
+ variadic: false,
+ opening: "cap(",
+ closing: ")",
+ separator: ",",
+ parameters: []string{"v"},
+ },
+ {
+ name: "Close",
+ comment: "renders the close built-in function.",
+ variadic: false,
+ opening: "close(",
+ closing: ")",
+ separator: ",",
+ parameters: []string{"c"},
+ },
+ {
+ name: "Complex",
+ comment: "renders the complex built-in function.",
+ variadic: false,
+ opening: "complex(",
+ closing: ")",
+ separator: ",",
+ parameters: []string{"r", "i"},
+ },
+ {
+ name: "Copy",
+ comment: "renders the copy built-in function.",
+ variadic: false,
+ opening: "copy(",
+ closing: ")",
+ separator: ",",
+ parameters: []string{"dst", "src"},
+ },
+ {
+ name: "Delete",
+ comment: "renders the delete built-in function.",
+ variadic: false,
+ opening: "delete(",
+ closing: ")",
+ separator: ",",
+ parameters: []string{"m", "key"},
+ },
+ {
+ name: "Imag",
+ comment: "renders the imag built-in function.",
+ variadic: false,
+ opening: "imag(",
+ closing: ")",
+ separator: ",",
+ parameters: []string{"c"},
+ },
+ {
+ name: "Len",
+ comment: "renders the len built-in function.",
+ variadic: false,
+ opening: "len(",
+ closing: ")",
+ separator: ",",
+ parameters: []string{"v"},
+ },
+ {
+ name: "Make",
+ comment: "renders the make built-in function. The final parameter of the make function is optional, so it is represented by a variadic parameter list.",
+ variadic: true,
+ opening: "make(",
+ closing: ")",
+ separator: ",",
+ parameters: []string{"args"},
+ preventFunc: true, // the underlying function is not variadic, so we prevent the MakeFunc variation
+ },
+ {
+ name: "New",
+ comment: "renders the new built-in function.",
+ variadic: false,
+ opening: "new(",
+ closing: ")",
+ separator: ",",
+ parameters: []string{"typ"},
+ },
+ {
+ name: "Panic",
+ comment: "renders the panic built-in function.",
+ variadic: false,
+ opening: "panic(",
+ closing: ")",
+ separator: ",",
+ parameters: []string{"v"},
+ },
+ {
+ name: "Print",
+ comment: "renders the print built-in function.",
+ variadic: true,
+ opening: "print(",
+ closing: ")",
+ separator: ",",
+ parameters: []string{"args"},
+ },
+ {
+ name: "Println",
+ comment: "renders the println built-in function.",
+ variadic: true,
+ opening: "println(",
+ closing: ")",
+ separator: ",",
+ parameters: []string{"args"},
+ },
+ {
+ name: "Real",
+ comment: "renders the real built-in function.",
+ variadic: false,
+ opening: "real(",
+ closing: ")",
+ separator: ",",
+ parameters: []string{"c"},
+ },
+ {
+ name: "Recover",
+ comment: "renders the recover built-in function.",
+ variadic: false,
+ opening: "recover(",
+ closing: ")",
+ separator: ",",
+ parameters: []string{},
+ },
+}
diff --git a/vendor/github.com/dave/jennifer/genjen/main.go b/vendor/github.com/dave/jennifer/genjen/main.go
new file mode 100644
index 00000000..ff73434c
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/genjen/main.go
@@ -0,0 +1,17 @@
+package main
+
+import (
+ "bytes"
+ "io/ioutil"
+)
+
+func main() {
+ // notest
+ buf := &bytes.Buffer{}
+ if err := render(buf); err != nil {
+ panic(err)
+ }
+ if err := ioutil.WriteFile("./jen/generated.go", buf.Bytes(), 0644); err != nil {
+ panic(err)
+ }
+}
diff --git a/vendor/github.com/dave/jennifer/genjen/render.go b/vendor/github.com/dave/jennifer/genjen/render.go
new file mode 100644
index 00000000..3ab0e93a
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/genjen/render.go
@@ -0,0 +1,260 @@
+package main
+
+import (
+ "io"
+ "strings"
+
+ . "github.com/dave/jennifer/jen"
+)
+
+func render(w io.Writer) error {
+ file := NewFile("jen")
+
+ file.HeaderComment("This file is generated - do not edit.")
+ file.Line()
+
+ for _, b := range groups {
+ b := b // b used in closures
+ comment := Commentf("%s %s", b.name, b.comment)
+
+ if b.variadic && len(b.parameters) > 1 {
+ panic("should not have variadic function with multiple params")
+ }
+
+ var variadic Code
+ if b.variadic {
+ variadic = Op("...")
+ }
+ var funcParams []Code
+ var callParams []Code
+ for _, name := range b.parameters {
+ funcParams = append(funcParams, Id(name).Add(variadic).Id("Code"))
+ callParams = append(callParams, Id(name).Add(variadic))
+ }
+
+ addFunctionAndGroupMethod(
+ file,
+ b.name,
+ comment,
+ funcParams,
+ callParams,
+ false,
+ )
+
+ /*
+ //
+ func (s *Statement) () *Statement {
+ g := &Group{
+ items: []Code{}|,
+ name: "",
+ open: "",
+ close: "",
+ separator: "",
+ multi: ,
+ }
+ *s = append(*s, g)
+ return s
+ }
+ */
+ file.Add(comment)
+ file.Func().Params(
+ Id("s").Op("*").Id("Statement"),
+ ).Id(b.name).Params(
+ funcParams...,
+ ).Op("*").Id("Statement").Block(
+ Id("g").Op(":=").Op("&").Id("Group").Values(Dict{
+ Id("items"): Do(func(s *Statement) {
+ if b.variadic {
+ s.Id(b.parameters[0])
+ } else {
+ s.Index().Id("Code").ValuesFunc(func(g *Group) {
+ for _, name := range b.parameters {
+ g.Id(name)
+ }
+ })
+ }
+ }),
+ Id("name"): Lit(strings.ToLower(b.name)),
+ Id("open"): Lit(b.opening),
+ Id("close"): Lit(b.closing),
+ Id("separator"): Lit(b.separator),
+ Id("multi"): Lit(b.multi),
+ }),
+ Op("*").Id("s").Op("=").Append(Op("*").Id("s"), Id("g")),
+ Return(Id("s")),
+ )
+
+ if b.variadic && !b.preventFunc {
+
+ funcName := b.name + "Func"
+ funcComment := Commentf("%sFunc %s", b.name, b.comment)
+ funcFuncParams := []Code{Id("f").Func().Params(Op("*").Id("Group"))}
+ funcCallParams := []Code{Id("f")}
+
+ addFunctionAndGroupMethod(
+ file,
+ funcName,
+ funcComment,
+ funcFuncParams,
+ funcCallParams,
+ false,
+ )
+
+ /*
+ //
+ func (s *Statement) (f func(*Group)) *Statement {
+ g := &Group{
+ name: "",
+ open: "",
+ close: "",
+ separator: "",
+ multi: ,
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+ }
+ */
+ file.Add(funcComment)
+ file.Func().Params(
+ Id("s").Op("*").Id("Statement"),
+ ).Id(funcName).Params(
+ funcFuncParams...,
+ ).Op("*").Id("Statement").Block(
+ Id("g").Op(":=").Op("&").Id("Group").Values(Dict{
+ Id("name"): Lit(strings.ToLower(b.name)),
+ Id("open"): Lit(b.opening),
+ Id("close"): Lit(b.closing),
+ Id("separator"): Lit(b.separator),
+ Id("multi"): Lit(b.multi),
+ }),
+ Id("f").Call(Id("g")),
+ Op("*").Id("s").Op("=").Append(Op("*").Id("s"), Id("g")),
+ Return(Id("s")),
+ )
+ }
+ }
+
+ type tkn struct {
+ token string
+ name string
+ tokenType string
+ tokenDesc string
+ }
+ tokens := []tkn{}
+ for _, v := range identifiers {
+ tokens = append(tokens, tkn{
+ token: v,
+ name: strings.ToUpper(v[:1]) + v[1:],
+ tokenType: "identifierToken",
+ tokenDesc: "identifier",
+ })
+ }
+ for _, v := range keywords {
+ tokens = append(tokens, tkn{
+ token: v,
+ name: strings.ToUpper(v[:1]) + v[1:],
+ tokenType: "keywordToken",
+ tokenDesc: "keyword",
+ })
+ }
+
+ for i, t := range tokens {
+ t := t // used in closures
+ comment := Commentf(
+ "%s renders the %s %s.",
+ t.name,
+ t.token,
+ t.tokenDesc,
+ )
+ addFunctionAndGroupMethod(
+ file,
+ t.name,
+ comment,
+ nil,
+ nil,
+ i != 0, // only enforce test coverage on one item
+ )
+
+ /*
+ //
+ func (s *Statement) () *Statement {
+ t := token{
+ typ: ,
+ content: "",
+ }
+ *s = append(*s, t)
+ return s
+ }
+ */
+ file.Add(comment)
+ file.Func().Params(
+ Id("s").Op("*").Id("Statement"),
+ ).Id(t.name).Params().Op("*").Id("Statement").Block(
+ Do(func(s *Statement) {
+ if i != 0 {
+ // only enforce test coverage on one item
+ s.Comment("notest")
+ }
+ }),
+ Id("t").Op(":=").Id("token").Values(Dict{
+ Id("typ"): Id(t.tokenType),
+ Id("content"): Lit(t.token),
+ }),
+ Op("*").Id("s").Op("=").Append(Op("*").Id("s"), Id("t")),
+ Return(Id("s")),
+ )
+ }
+
+ return file.Render(w)
+}
+
+// For each method on *Statement, this generates a package level
+// function and a method on *Group, both with the same name.
+func addFunctionAndGroupMethod(
+ file *File,
+ name string,
+ comment *Statement,
+ funcParams []Code,
+ callParams []Code,
+ notest bool,
+) {
+ /*
+ //
+ func () *Statement {
+ return newStatement().()
+ }
+ */
+ file.Add(comment)
+ file.Func().Id(name).Params(funcParams...).Op("*").Id("Statement").Block(
+ Do(func(s *Statement) {
+ if notest {
+ // only enforce test coverage on one item
+ s.Comment("notest")
+ }
+ }),
+ Return(Id("newStatement").Call().Dot(name).Call(callParams...)),
+ )
+ /*
+ //
+ func (g *Group) () *Statement {
+ s := ()
+ g.items = append(g.items, s)
+ return s
+ }
+ */
+ file.Add(comment)
+ file.Func().Params(
+ Id("g").Op("*").Id("Group"),
+ ).Id(name).Params(funcParams...).Op("*").Id("Statement").Block(
+ Do(func(s *Statement) {
+ if notest {
+ // only enforce test coverage on one item
+ s.Comment("notest")
+ }
+ }),
+ Id("s").Op(":=").Id(name).Params(callParams...),
+ Id("g").Dot("items").Op("=").Append(Id("g").Dot("items"), Id("s")),
+ Return(Id("s")),
+ )
+}
diff --git a/vendor/github.com/dave/jennifer/genjen/render_test.go b/vendor/github.com/dave/jennifer/genjen/render_test.go
new file mode 100644
index 00000000..2b549d91
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/genjen/render_test.go
@@ -0,0 +1,35 @@
+package main
+
+import (
+ "io/ioutil"
+ "regexp"
+ "testing"
+
+ "bytes"
+)
+
+func TestRender(t *testing.T) {
+
+ buf := &bytes.Buffer{}
+ if err := render(buf); err != nil {
+ t.Fatal(err.Error())
+ }
+ generatedString := buf.String()
+
+ existingFilePath := "../jen/generated.go"
+ existingBytes, err := ioutil.ReadFile(existingFilePath)
+ if err != nil {
+ t.Fatal(err.Error())
+ }
+ existingString := string(existingBytes)
+
+ // The "goimports" tool will often re-order the imports, so this is a
+ // kludge to remove it before comparing. This is not ideal!
+ importsRegex := regexp.MustCompile(`(?ms:\nimport \(\n.*\n\)\n)`)
+ generatedString = importsRegex.ReplaceAllString(generatedString, "-")
+ existingString = importsRegex.ReplaceAllString(existingString, "-")
+
+ if generatedString != existingString {
+ t.Fatalf("Generated code is not what is present:\n%s", generatedString)
+ }
+}
diff --git a/vendor/github.com/dave/jennifer/gennames/README.md b/vendor/github.com/dave/jennifer/gennames/README.md
new file mode 100644
index 00000000..ef60cfe0
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/gennames/README.md
@@ -0,0 +1,52 @@
+# gennames
+For large projects, it may be useful to generate an index of package names for commonly used packages.
+The index of names can be added to each generated file using `File.ImportNames`. The `gennames` command
+is used internally to generate the list of standard library package names.
+
+### Usage
+
+```
+Usage of gennames:
+ -filter string
+ Regex to filter paths (operates on full path including vendor directory) (default ".*")
+ -name string
+ Name of the variable to define (default "PackageNames")
+ -novendor
+ Exclude packages in vendor directories
+ -output string
+ Output filename to write (default "./package-names.go")
+ -package string
+ Package name in generated file (default "main")
+ -path string
+ Path to pass to go list command (default "all")
+ -standard
+ Use standard library packages
+```
+
+### Path
+Supply a `path` to pass to the `go list` command. You may use the wildcard `/...` to recursively return
+packages, but it's worth remembering that vendored packages are not returned by this method unless the
+path itself is a vendored path. Use `all` to return all packages in your `GOPATH` (including vendored
+packages), however remember this may take some time for a large `GOPATH`.
+
+### Filter
+Supply a regex `filter` to limit the packages that are returned by the `go list` command. The filter
+operates on the full vendored package path (e.g. `github.com/foo/bar/vendor/github.com/baz/qux`), however
+the package path added to the index is unvendored (e.g. `github.com/baz/qux`).
+
+### Examples
+
+```
+gennames -filter "foo|bar"
+```
+
+Create a file named `package-names.go` with `package main` listing the names of all packages with paths
+containing `foo` or `bar`.
+
+```
+gennames -output "foo/names.go" -package "foo" -path "github.com/foo/bar/vendor/..."
+```
+
+Create a file named `foo/names.go` with `package foo` listing the names of all packages that are vendored
+inside `github.com/foo/bar`.
+
diff --git a/vendor/github.com/dave/jennifer/gennames/hints.go b/vendor/github.com/dave/jennifer/gennames/hints.go
new file mode 100644
index 00000000..51288f1e
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/gennames/hints.go
@@ -0,0 +1,141 @@
+package main
+
+import (
+ "fmt"
+ "go/build"
+ "io"
+ "os/exec"
+ "strings"
+
+ "regexp"
+
+ "path/filepath"
+
+ . "github.com/dave/jennifer/jen"
+)
+
+func hints(w io.Writer, pkg, name, goListPath, filter string, standard, novendor bool) error {
+
+ // notest
+
+ file := NewFile(pkg)
+
+ file.HeaderComment("This file is generated - do not edit.")
+ file.Line()
+
+ packages, err := getPackages(goListPath, filter, standard, novendor)
+ if err != nil {
+ return err
+ }
+ /*
+ // contains package name hints
+ var = map[string]string{
+ ...
+ }
+ */
+ file.Commentf("%s contains package name hints", name)
+ file.Var().Id(name).Op("=").Map(String()).String().Values(DictFunc(func(d Dict) {
+ for path, name := range packages {
+ d[Lit(path)] = Lit(name)
+ }
+ }))
+
+ return file.Render(w)
+}
+
+func getPackages(goListPath, filter string, standard, novendor bool) (map[string]string, error) {
+
+ // notest
+
+ r, err := regexp.Compile(filter)
+ if err != nil {
+ return nil, err
+ }
+
+ cmd := exec.Command("go", "list", "-e", "-f", "{{ .Standard }} {{ .ImportPath }} {{ .Name }}", goListPath)
+ cmd.Env = []string{
+ fmt.Sprintf("GOPATH=%s", build.Default.GOPATH),
+ fmt.Sprintf("GOROOT=%s", build.Default.GOROOT),
+ }
+ if standard {
+ cmd.Dir = filepath.Join(build.Default.GOROOT, "src")
+ } else {
+ cmd.Dir = filepath.Join(build.Default.GOPATH, "src")
+ }
+ b, err := cmd.Output()
+ if err != nil {
+ if x, ok := err.(*exec.ExitError); ok {
+ return nil, fmt.Errorf("go list command returned an error - %s: %s", err.Error(), string(x.Stderr))
+ }
+ return nil, fmt.Errorf("go list command returned an error: %s", err.Error())
+ }
+ all := strings.Split(strings.TrimSpace(string(b)), "\n")
+
+ packages := map[string]string{}
+ for _, j := range all {
+
+ parts := strings.Split(j, " ")
+
+ isStandard := parts[0] == "true"
+ if isStandard != standard {
+ continue
+ }
+
+ path := parts[1]
+ name := parts[2]
+
+ if novendor && hasVendor(path) {
+ continue
+ }
+
+ if name == "main" {
+ continue
+ }
+
+ if !r.MatchString(path) {
+ continue
+ }
+
+ path = unvendorPath(path)
+
+ if packages[path] != "" {
+ continue
+ }
+
+ packages[path] = name
+ }
+ return packages, nil
+}
+
+func unvendorPath(path string) string {
+ // notest
+ i, ok := findVendor(path)
+ if !ok {
+ return path
+ }
+ return path[i+len("vendor/"):]
+}
+
+// FindVendor looks for the last non-terminating "vendor" path element in the given import path.
+// If there isn't one, FindVendor returns ok=false.
+// Otherwise, FindVendor returns ok=true and the index of the "vendor".
+// Copied from cmd/go/internal/load
+func findVendor(path string) (index int, ok bool) {
+ // notest
+ // Two cases, depending on internal at start of string or not.
+ // The order matters: we must return the index of the final element,
+ // because the final one is where the effective import path starts.
+ switch {
+ case strings.Contains(path, "/vendor/"):
+ return strings.LastIndex(path, "/vendor/") + 1, true
+ case strings.HasPrefix(path, "vendor/"):
+ return 0, true
+ }
+ return 0, false
+}
+
+func hasVendor(path string) bool {
+ // notest
+ _, v := findVendor(path)
+ return v
+}
diff --git a/vendor/github.com/dave/jennifer/gennames/main.go b/vendor/github.com/dave/jennifer/gennames/main.go
new file mode 100644
index 00000000..1ff8e51a
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/gennames/main.go
@@ -0,0 +1,29 @@
+package main
+
+import (
+ "bytes"
+ "flag"
+ "io/ioutil"
+ "log"
+)
+
+func main() {
+ // notest
+
+ var out = flag.String("output", "./package-names.go", "Output filename to write")
+ var pkg = flag.String("package", "main", "Package name in generated file")
+ var name = flag.String("name", "PackageNames", "Name of the variable to define")
+ var filter = flag.String("filter", ".*", "Regex to filter paths (operates on full path including vendor directory)")
+ var standard = flag.Bool("standard", false, "Use standard library packages")
+ var novendor = flag.Bool("novendor", false, "Exclude packages in vendor directories")
+ var goListPath = flag.String("path", "all", "Path to pass to go list command")
+ flag.Parse()
+
+ buf := &bytes.Buffer{}
+ if err := hints(buf, *pkg, *name, *goListPath, *filter, *standard, *novendor); err != nil {
+ log.Fatal(err.Error())
+ }
+ if err := ioutil.WriteFile(*out, buf.Bytes(), 0644); err != nil {
+ log.Fatal(err.Error())
+ }
+}
diff --git a/vendor/github.com/dave/jennifer/jen/add.go b/vendor/github.com/dave/jennifer/jen/add.go
new file mode 100644
index 00000000..2efb3f6d
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/add.go
@@ -0,0 +1,19 @@
+package jen
+
+// Add appends the provided items to the statement.
+func Add(code ...Code) *Statement {
+ return newStatement().Add(code...)
+}
+
+// Add appends the provided items to the statement.
+func (g *Group) Add(code ...Code) *Statement {
+ s := Add(code...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Add appends the provided items to the statement.
+func (s *Statement) Add(code ...Code) *Statement {
+ *s = append(*s, code...)
+ return s
+}
diff --git a/vendor/github.com/dave/jennifer/jen/comments.go b/vendor/github.com/dave/jennifer/jen/comments.go
new file mode 100644
index 00000000..886e885b
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/comments.go
@@ -0,0 +1,108 @@
+package jen
+
+import (
+ "fmt"
+ "io"
+ "strings"
+)
+
+// Comment adds a comment. If the provided string contains a newline, the
+// comment is formatted in multiline style. If the comment string starts
+// with "//" or "/*", the automatic formatting is disabled and the string is
+// rendered directly.
+func Comment(str string) *Statement {
+ return newStatement().Comment(str)
+}
+
+// Comment adds a comment. If the provided string contains a newline, the
+// comment is formatted in multiline style. If the comment string starts
+// with "//" or "/*", the automatic formatting is disabled and the string is
+// rendered directly.
+func (g *Group) Comment(str string) *Statement {
+ s := Comment(str)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Comment adds a comment. If the provided string contains a newline, the
+// comment is formatted in multiline style. If the comment string starts
+// with "//" or "/*", the automatic formatting is disabled and the string is
+// rendered directly.
+func (s *Statement) Comment(str string) *Statement {
+ c := comment{
+ comment: str,
+ }
+ *s = append(*s, c)
+ return s
+}
+
+// Commentf adds a comment, using a format string and a list of parameters. If
+// the provided string contains a newline, the comment is formatted in
+// multiline style. If the comment string starts with "//" or "/*", the
+// automatic formatting is disabled and the string is rendered directly.
+func Commentf(format string, a ...interface{}) *Statement {
+ return newStatement().Commentf(format, a...)
+}
+
+// Commentf adds a comment, using a format string and a list of parameters. If
+// the provided string contains a newline, the comment is formatted in
+// multiline style. If the comment string starts with "//" or "/*", the
+// automatic formatting is disabled and the string is rendered directly.
+func (g *Group) Commentf(format string, a ...interface{}) *Statement {
+ s := Commentf(format, a...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Commentf adds a comment, using a format string and a list of parameters. If
+// the provided string contains a newline, the comment is formatted in
+// multiline style. If the comment string starts with "//" or "/*", the
+// automatic formatting is disabled and the string is rendered directly.
+func (s *Statement) Commentf(format string, a ...interface{}) *Statement {
+ c := comment{
+ comment: fmt.Sprintf(format, a...),
+ }
+ *s = append(*s, c)
+ return s
+}
+
+type comment struct {
+ comment string
+}
+
+func (c comment) isNull(f *File) bool {
+ return false
+}
+
+func (c comment) render(f *File, w io.Writer, s *Statement) error {
+ if strings.HasPrefix(c.comment, "//") || strings.HasPrefix(c.comment, "/*") {
+ // automatic formatting disabled.
+ if _, err := w.Write([]byte(c.comment)); err != nil {
+ return err
+ }
+ return nil
+ }
+ if strings.Contains(c.comment, "\n") {
+ if _, err := w.Write([]byte("/*\n")); err != nil {
+ return err
+ }
+ } else {
+ if _, err := w.Write([]byte("// ")); err != nil {
+ return err
+ }
+ }
+ if _, err := w.Write([]byte(c.comment)); err != nil {
+ return err
+ }
+ if strings.Contains(c.comment, "\n") {
+ if !strings.HasSuffix(c.comment, "\n") {
+ if _, err := w.Write([]byte("\n")); err != nil {
+ return err
+ }
+ }
+ if _, err := w.Write([]byte("*/")); err != nil {
+ return err
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/dave/jennifer/jen/custom.go b/vendor/github.com/dave/jennifer/jen/custom.go
new file mode 100644
index 00000000..4966a070
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/custom.go
@@ -0,0 +1,61 @@
+package jen
+
+// Options specifies options for the Custom method
+type Options struct {
+ Open string
+ Close string
+ Separator string
+ Multi bool
+}
+
+// Custom renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator.
+func Custom(options Options, statements ...Code) *Statement {
+ return newStatement().Custom(options, statements...)
+}
+
+// Custom renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator.
+func (g *Group) Custom(options Options, statements ...Code) *Statement {
+ s := Custom(options, statements...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Custom renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator.
+func (s *Statement) Custom(options Options, statements ...Code) *Statement {
+ g := &Group{
+ close: options.Close,
+ items: statements,
+ multi: options.Multi,
+ name: "custom",
+ open: options.Open,
+ separator: options.Separator,
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// CustomFunc renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator.
+func CustomFunc(options Options, f func(*Group)) *Statement {
+ return newStatement().CustomFunc(options, f)
+}
+
+// CustomFunc renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator.
+func (g *Group) CustomFunc(options Options, f func(*Group)) *Statement {
+ s := CustomFunc(options, f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// CustomFunc renders a customized statement list. Pass in options to specify multi-line, and tokens for open, close, separator.
+func (s *Statement) CustomFunc(options Options, f func(*Group)) *Statement {
+ g := &Group{
+ close: options.Close,
+ multi: options.Multi,
+ name: "custom",
+ open: options.Open,
+ separator: options.Separator,
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
diff --git a/vendor/github.com/dave/jennifer/jen/dict.go b/vendor/github.com/dave/jennifer/jen/dict.go
new file mode 100644
index 00000000..260cf928
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/dict.go
@@ -0,0 +1,81 @@
+package jen
+
+import (
+ "bytes"
+ "io"
+ "sort"
+)
+
+// Dict renders as key/value pairs. Use with Values for map or composite
+// literals.
+type Dict map[Code]Code
+
+// DictFunc executes a func(Dict) to generate the value. Use with Values for
+// map or composite literals.
+func DictFunc(f func(Dict)) Dict {
+ d := Dict{}
+ f(d)
+ return d
+}
+
+func (d Dict) render(f *File, w io.Writer, s *Statement) error {
+ first := true
+ // must order keys to ensure repeatable source
+ type kv struct {
+ k Code
+ v Code
+ }
+ lookup := map[string]kv{}
+ keys := []string{}
+ for k, v := range d {
+ if k.isNull(f) || v.isNull(f) {
+ continue
+ }
+ buf := &bytes.Buffer{}
+ if err := k.render(f, buf, nil); err != nil {
+ return err
+ }
+ keys = append(keys, buf.String())
+ lookup[buf.String()] = kv{k: k, v: v}
+ }
+ sort.Strings(keys)
+ for _, key := range keys {
+ k := lookup[key].k
+ v := lookup[key].v
+ if first && len(keys) > 1 {
+ if _, err := w.Write([]byte("\n")); err != nil {
+ return err
+ }
+ first = false
+ }
+ if err := k.render(f, w, nil); err != nil {
+ return err
+ }
+ if _, err := w.Write([]byte(":")); err != nil {
+ return err
+ }
+ if err := v.render(f, w, nil); err != nil {
+ return err
+ }
+ if len(keys) > 1 {
+ if _, err := w.Write([]byte(",\n")); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+func (d Dict) isNull(f *File) bool {
+ if d == nil || len(d) == 0 {
+ return true
+ }
+ for k, v := range d {
+ if !k.isNull(f) && !v.isNull(f) {
+ // if any of the key/value pairs are both not null, the Dict is not
+ // null
+ return false
+ }
+ }
+ return true
+}
diff --git a/vendor/github.com/dave/jennifer/jen/do.go b/vendor/github.com/dave/jennifer/jen/do.go
new file mode 100644
index 00000000..c1bceab5
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/do.go
@@ -0,0 +1,22 @@
+package jen
+
+// Do calls the provided function with the statement as a parameter. Use for
+// embedding logic.
+func Do(f func(*Statement)) *Statement {
+ return newStatement().Do(f)
+}
+
+// Do calls the provided function with the statement as a parameter. Use for
+// embedding logic.
+func (g *Group) Do(f func(*Statement)) *Statement {
+ s := Do(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Do calls the provided function with the statement as a parameter. Use for
+// embedding logic.
+func (s *Statement) Do(f func(*Statement)) *Statement {
+ f(s)
+ return s
+}
diff --git a/vendor/github.com/dave/jennifer/jen/examples_test.go b/vendor/github.com/dave/jennifer/jen/examples_test.go
new file mode 100644
index 00000000..d6316b5f
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/examples_test.go
@@ -0,0 +1,1610 @@
+package jen_test
+
+import (
+ "fmt"
+
+ "bytes"
+
+ . "github.com/dave/jennifer/jen"
+)
+
+func ExampleCaseBug() {
+ c := Switch(Id("a")).Block(
+ Case(Lit(1)).Block(
+ Var().Id("i").Int(),
+ Var().Id("j").Int(),
+ ),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // switch a {
+ // case 1:
+ // var i int
+ // var j int
+ // }
+}
+
+func ExampleCustom() {
+ multiLineCall := Options{
+ Close: ")",
+ Multi: true,
+ Open: "(",
+ Separator: ",",
+ }
+ c := Id("foo").Custom(multiLineCall, Lit("a"), Lit("b"), Lit("c"))
+ fmt.Printf("%#v", c)
+ // Output:
+ // foo(
+ // "a",
+ // "b",
+ // "c",
+ // )
+}
+
+func ExampleCustomFunc() {
+ multiLineCall := Options{
+ Close: ")",
+ Multi: true,
+ Open: "(",
+ Separator: ",",
+ }
+ c := Id("foo").CustomFunc(multiLineCall, func(g *Group) {
+ g.Lit("a")
+ g.Lit("b")
+ g.Lit("c")
+ })
+ fmt.Printf("%#v", c)
+ // Output:
+ // foo(
+ // "a",
+ // "b",
+ // "c",
+ // )
+}
+
+func ExampleFile_ImportName_conflict() {
+ f := NewFile("main")
+
+ // We provide a hint that package foo/a should use name "a", but because package bar/a already
+ // registers the required name, foo/a is aliased.
+ f.ImportName("github.com/foo/a", "a")
+
+ f.Func().Id("main").Params().Block(
+ Qual("github.com/bar/a", "Bar").Call(),
+ Qual("github.com/foo/a", "Foo").Call(),
+ )
+ fmt.Printf("%#v", f)
+
+ // Output:
+ // package main
+ //
+ // import (
+ // a "github.com/bar/a"
+ // a1 "github.com/foo/a"
+ // )
+ //
+ // func main() {
+ // a.Bar()
+ // a1.Foo()
+ // }
+}
+
+func ExampleFile_ImportAlias_conflict() {
+ f := NewFile("main")
+
+ // We provide a hint that package foo/a should use alias "b", but because package bar/b already
+ // registers the required name, foo/a is aliased using the requested alias as a base.
+ f.ImportName("github.com/foo/a", "b")
+
+ f.Func().Id("main").Params().Block(
+ Qual("github.com/bar/b", "Bar").Call(),
+ Qual("github.com/foo/a", "Foo").Call(),
+ )
+ fmt.Printf("%#v", f)
+
+ // Output:
+ // package main
+ //
+ // import (
+ // b "github.com/bar/b"
+ // b1 "github.com/foo/a"
+ // )
+ //
+ // func main() {
+ // b.Bar()
+ // b1.Foo()
+ // }
+}
+
+func ExampleFile_ImportName() {
+ f := NewFile("main")
+
+ // package a should use name "a"
+ f.ImportName("github.com/foo/a", "a")
+
+ // package b is not used in the code so will not be included
+ f.ImportName("github.com/foo/b", "b")
+
+ f.Func().Id("main").Params().Block(
+ Qual("github.com/foo/a", "A").Call(),
+ )
+ fmt.Printf("%#v", f)
+
+ // Output:
+ // package main
+ //
+ // import "github.com/foo/a"
+ //
+ // func main() {
+ // a.A()
+ // }
+}
+
+func ExampleFile_ImportNames() {
+
+ // package a should use name "a", package b is not used in the code so will not be included
+ names := map[string]string{
+ "github.com/foo/a": "a",
+ "github.com/foo/b": "b",
+ }
+
+ f := NewFile("main")
+ f.ImportNames(names)
+ f.Func().Id("main").Params().Block(
+ Qual("github.com/foo/a", "A").Call(),
+ )
+ fmt.Printf("%#v", f)
+
+ // Output:
+ // package main
+ //
+ // import "github.com/foo/a"
+ //
+ // func main() {
+ // a.A()
+ // }
+}
+
+func ExampleFile_ImportAlias() {
+ f := NewFile("main")
+
+ // package a should be aliased to "b"
+ f.ImportAlias("github.com/foo/a", "b")
+
+ // package c is not used in the code so will not be included
+ f.ImportAlias("github.com/foo/c", "c")
+
+ f.Func().Id("main").Params().Block(
+ Qual("github.com/foo/a", "A").Call(),
+ )
+ fmt.Printf("%#v", f)
+
+ // Output:
+ // package main
+ //
+ // import b "github.com/foo/a"
+ //
+ // func main() {
+ // b.A()
+ // }
+}
+
+func ExampleFile_ImportAliasDot() {
+ f := NewFile("main")
+
+ // package a should be a dot-import
+ f.ImportAlias("github.com/foo/a", ".")
+
+ // package b should be a dot-import
+ f.ImportAlias("github.com/foo/b", ".")
+
+ // package c is not used in the code so will not be included
+ f.ImportAlias("github.com/foo/c", ".")
+
+ f.Func().Id("main").Params().Block(
+ Qual("github.com/foo/a", "A").Call(),
+ Qual("github.com/foo/b", "B").Call(),
+ )
+ fmt.Printf("%#v", f)
+
+ // Output:
+ // package main
+ //
+ // import (
+ // . "github.com/foo/a"
+ // . "github.com/foo/b"
+ // )
+ //
+ // func main() {
+ // A()
+ // B()
+ // }
+}
+
+func ExampleFile_CgoPreamble() {
+ f := NewFile("a")
+ f.CgoPreamble(`#include
+#include
+
+void myprint(char* s) {
+ printf("%s\n", s);
+}
+`)
+ f.Func().Id("init").Params().Block(
+ Id("cs").Op(":=").Qual("C", "CString").Call(Lit("Hello from stdio\n")),
+ Qual("C", "myprint").Call(Id("cs")),
+ Qual("C", "free").Call(Qual("unsafe", "Pointer").Parens(Id("cs"))),
+ )
+ fmt.Printf("%#v", f)
+ // Output:
+ // package a
+ //
+ // import "unsafe"
+ //
+ // /*
+ // #include
+ // #include
+ //
+ // void myprint(char* s) {
+ // printf("%s\n", s);
+ // }
+ // */
+ // import "C"
+ //
+ // func init() {
+ // cs := C.CString("Hello from stdio\n")
+ // C.myprint(cs)
+ // C.free(unsafe.Pointer(cs))
+ // }
+}
+
+func ExampleFile_CgoPreamble_anon() {
+ f := NewFile("a")
+ f.CgoPreamble(`#include `)
+ f.Func().Id("init").Params().Block(
+ Qual("foo.bar/a", "A"),
+ Qual("foo.bar/b", "B"),
+ )
+ fmt.Printf("%#v", f)
+ // Output:
+ // package a
+ //
+ // import (
+ // a "foo.bar/a"
+ // b "foo.bar/b"
+ // )
+ //
+ // // #include
+ // import "C"
+ //
+ // func init() {
+ // a.A
+ // b.B
+ // }
+}
+
+func ExampleFile_CgoPreamble_no_preamble() {
+ f := NewFile("a")
+ f.Func().Id("init").Params().Block(
+ Qual("C", "Foo").Call(),
+ Qual("fmt", "Print").Call(),
+ )
+ fmt.Printf("%#v", f)
+ // Output:
+ // package a
+ //
+ // import (
+ // "C"
+ // "fmt"
+ // )
+ //
+ // func init() {
+ // C.Foo()
+ // fmt.Print()
+ // }
+}
+
+func ExampleFile_CgoPreamble_no_preamble_single() {
+ f := NewFile("a")
+ f.Func().Id("init").Params().Block(
+ Qual("C", "Foo").Call(),
+ )
+ fmt.Printf("%#v", f)
+ // Output:
+ // package a
+ //
+ // import "C"
+ //
+ // func init() {
+ // C.Foo()
+ // }
+}
+
+func ExampleFile_CgoPreamble_no_preamble_single_anon() {
+ f := NewFile("a")
+ f.Anon("C")
+ f.Func().Id("init").Params().Block()
+ fmt.Printf("%#v", f)
+ // Output:
+ // package a
+ //
+ // import "C"
+ //
+ // func init() {}
+}
+
+func ExampleFile_CgoPreamble_no_preamble_anon() {
+ f := NewFile("a")
+ f.Anon("C")
+ f.Func().Id("init").Params().Block(
+ Qual("fmt", "Print").Call(),
+ )
+ fmt.Printf("%#v", f)
+ // Output:
+ // package a
+ //
+ // import (
+ // "C"
+ // "fmt"
+ // )
+ //
+ // func init() {
+ // fmt.Print()
+ // }
+}
+
+func ExampleOp_complex_conditions() {
+ c := If(Parens(Id("a").Op("||").Id("b")).Op("&&").Id("c")).Block()
+ fmt.Printf("%#v", c)
+ // Output:
+ // if (a || b) && c {
+ // }
+}
+
+func ExampleLit_bool_true() {
+ c := Lit(true)
+ fmt.Printf("%#v", c)
+ // Output:
+ // true
+}
+
+func ExampleLit_bool_false() {
+ c := Lit(false)
+ fmt.Printf("%#v", c)
+ // Output:
+ // false
+}
+
+func ExampleLit_byte() {
+ // Lit can't tell the difference between byte and uint8. Use LitByte to
+ // render byte literals.
+ c := Lit(byte(0x1))
+ fmt.Printf("%#v", c)
+ // Output:
+ // uint8(0x1)
+}
+
+func ExampleLit_complex64() {
+ c := Lit(complex64(0 + 0i))
+ fmt.Printf("%#v", c)
+ // Output:
+ // complex64(0 + 0i)
+}
+
+func ExampleLit_complex128() {
+ c := Lit(0 + 0i)
+ fmt.Printf("%#v", c)
+ // Output:
+ // (0 + 0i)
+}
+
+func ExampleLit_float32() {
+ c := Lit(float32(1))
+ fmt.Printf("%#v", c)
+ // Output:
+ // float32(1)
+}
+
+func ExampleLit_float64_one_point_zero() {
+ c := Lit(1.0)
+ fmt.Printf("%#v", c)
+ // Output:
+ // 1.0
+}
+
+func ExampleLit_float64_zero() {
+ c := Lit(0.0)
+ fmt.Printf("%#v", c)
+ // Output:
+ // 0.0
+}
+
+func ExampleLit_float64_negative() {
+ c := Lit(-0.1)
+ fmt.Printf("%#v", c)
+ // Output:
+ // -0.1
+}
+
+func ExampleLit_float64_negative_whole() {
+ c := Lit(-1.0)
+ fmt.Printf("%#v", c)
+ // Output:
+ // -1.0
+}
+
+func ExampleLit_int() {
+ c := Lit(1)
+ fmt.Printf("%#v", c)
+ // Output:
+ // 1
+}
+
+func ExampleLit_int8() {
+ c := Lit(int8(1))
+ fmt.Printf("%#v", c)
+ // Output:
+ // int8(1)
+}
+
+func ExampleLit_int16() {
+ c := Lit(int16(1))
+ fmt.Printf("%#v", c)
+ // Output:
+ // int16(1)
+}
+
+func ExampleLit_int32() {
+ c := Lit(int32(1))
+ fmt.Printf("%#v", c)
+ // Output:
+ // int32(1)
+}
+
+func ExampleLit_int64() {
+ c := Lit(int64(1))
+ fmt.Printf("%#v", c)
+ // Output:
+ // int64(1)
+}
+
+func ExampleLit_uint() {
+ c := Lit(uint(0x1))
+ fmt.Printf("%#v", c)
+ // Output:
+ // uint(0x1)
+}
+
+func ExampleLit_uint8() {
+ c := Lit(uint8(0x1))
+ fmt.Printf("%#v", c)
+ // Output:
+ // uint8(0x1)
+}
+
+func ExampleLit_uint16() {
+ c := Lit(uint16(0x1))
+ fmt.Printf("%#v", c)
+ // Output:
+ // uint16(0x1)
+}
+
+func ExampleLit_uint32() {
+ c := Lit(uint32(0x1))
+ fmt.Printf("%#v", c)
+ // Output:
+ // uint32(0x1)
+}
+
+func ExampleLit_uint64() {
+ c := Lit(uint64(0x1))
+ fmt.Printf("%#v", c)
+ // Output:
+ // uint64(0x1)
+}
+
+func ExampleLit_uintptr() {
+ c := Lit(uintptr(0x1))
+ fmt.Printf("%#v", c)
+ // Output:
+ // uintptr(0x1)
+}
+
+func ExampleLit_rune() {
+ // Lit can't tell the difference between rune and int32. Use LitRune to
+ // render rune literals.
+ c := Lit('x')
+ fmt.Printf("%#v", c)
+ // Output:
+ // int32(120)
+}
+
+func ExampleLitRune() {
+ c := LitRune('x')
+ fmt.Printf("%#v", c)
+ // Output:
+ // 'x'
+}
+
+func ExampleLitRuneFunc() {
+ c := LitRuneFunc(func() rune {
+ return '\t'
+ })
+ fmt.Printf("%#v", c)
+ // Output:
+ // '\t'
+}
+
+func ExampleLitByte() {
+ c := LitByte(byte(1))
+ fmt.Printf("%#v", c)
+ // Output:
+ // byte(0x1)
+}
+
+func ExampleLitByteFunc() {
+ c := LitByteFunc(func() byte {
+ return byte(2)
+ })
+ fmt.Printf("%#v", c)
+ // Output:
+ // byte(0x2)
+}
+
+func ExampleLit_string() {
+ c := Lit("foo")
+ fmt.Printf("%#v", c)
+ // Output:
+ // "foo"
+}
+
+func ExampleValues_dict_single() {
+ c := Map(String()).String().Values(Dict{
+ Lit("a"): Lit("b"),
+ })
+ fmt.Printf("%#v", c)
+ // Output:
+ // map[string]string{"a": "b"}
+}
+
+func ExampleValues_dict_multiple() {
+ c := Map(String()).String().Values(Dict{
+ Lit("a"): Lit("b"),
+ Lit("c"): Lit("d"),
+ })
+ fmt.Printf("%#v", c)
+ // Output:
+ // map[string]string{
+ // "a": "b",
+ // "c": "d",
+ // }
+}
+
+func ExampleValues_dict_composite() {
+ c := Op("&").Id("Person").Values(Dict{
+ Id("Age"): Lit(1),
+ Id("Name"): Lit("a"),
+ })
+ fmt.Printf("%#v", c)
+ // Output:
+ // &Person{
+ // Age: 1,
+ // Name: "a",
+ // }
+}
+
+func ExampleAdd() {
+ ptr := Op("*")
+ c := Id("a").Op("=").Add(ptr).Id("b")
+ fmt.Printf("%#v", c)
+ // Output:
+ // a = *b
+}
+
+func ExampleAdd_var() {
+ a := Id("a")
+ i := Int()
+ c := Var().Add(a, i)
+ fmt.Printf("%#v", c)
+ // Output:
+ // var a int
+}
+
+func ExampleAppend() {
+ c := Append(Id("a"), Id("b"))
+ fmt.Printf("%#v", c)
+ // Output:
+ // append(a, b)
+}
+
+func ExampleAppend_more() {
+ c := Id("a").Op("=").Append(Id("a"), Id("b").Op("..."))
+ fmt.Printf("%#v", c)
+ // Output:
+ // a = append(a, b...)
+}
+
+func ExampleAssert() {
+ c := List(Id("b"), Id("ok")).Op(":=").Id("a").Assert(Bool())
+ fmt.Printf("%#v", c)
+ // Output:
+ // b, ok := a.(bool)
+}
+
+func ExampleBlock() {
+ c := Func().Id("foo").Params().String().Block(
+ Id("a").Op("=").Id("b"),
+ Id("b").Op("++"),
+ Return(Id("b")),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // func foo() string {
+ // a = b
+ // b++
+ // return b
+ // }
+}
+
+func ExampleBlock_if() {
+ c := If(Id("a").Op(">").Lit(10)).Block(
+ Id("a").Op("=").Id("a").Op("/").Lit(2),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // if a > 10 {
+ // a = a / 2
+ // }
+}
+
+func ExampleValuesFunc() {
+ c := Id("numbers").Op(":=").Index().Int().ValuesFunc(func(g *Group) {
+ for i := 0; i <= 5; i++ {
+ g.Lit(i)
+ }
+ })
+ fmt.Printf("%#v", c)
+ // Output:
+ // numbers := []int{0, 1, 2, 3, 4, 5}
+}
+
+func ExampleBlockFunc() {
+ increment := true
+ name := "a"
+ c := Func().Id("a").Params().BlockFunc(func(g *Group) {
+ g.Id(name).Op("=").Lit(1)
+ if increment {
+ g.Id(name).Op("++")
+ } else {
+ g.Id(name).Op("--")
+ }
+ })
+ fmt.Printf("%#v", c)
+ // Output:
+ // func a() {
+ // a = 1
+ // a++
+ // }
+}
+
+func ExampleBool() {
+ c := Var().Id("b").Bool()
+ fmt.Printf("%#v", c)
+ // Output:
+ // var b bool
+}
+
+func ExampleBreak() {
+ c := For(
+ Id("i").Op(":=").Lit(0),
+ Id("i").Op("<").Lit(10),
+ Id("i").Op("++"),
+ ).Block(
+ If(Id("i").Op(">").Lit(5)).Block(
+ Break(),
+ ),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // for i := 0; i < 10; i++ {
+ // if i > 5 {
+ // break
+ // }
+ // }
+}
+
+func ExampleByte() {
+ c := Id("b").Op(":=").Id("a").Assert(Byte())
+ fmt.Printf("%#v", c)
+ // Output:
+ // b := a.(byte)
+}
+
+func ExampleCall() {
+ c := Qual("fmt", "Printf").Call(
+ Lit("%#v: %T\n"),
+ Id("a"),
+ Id("b"),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // fmt.Printf("%#v: %T\n", a, b)
+}
+
+func ExampleCall_fmt() {
+ c := Id("a").Call(Lit("b"))
+ fmt.Printf("%#v", c)
+ // Output:
+ // a("b")
+}
+
+func ExampleCallFunc() {
+ f := func(name string, second string) {
+ c := Id("foo").CallFunc(func(g *Group) {
+ g.Id(name)
+ if second != "" {
+ g.Lit(second)
+ }
+ })
+ fmt.Printf("%#v\n", c)
+ }
+ f("a", "b")
+ f("c", "")
+ // Output:
+ // foo(a, "b")
+ // foo(c)
+}
+
+func ExampleCap() {
+ c := Id("i").Op(":=").Cap(Id("v"))
+ fmt.Printf("%#v", c)
+ // Output:
+ // i := cap(v)
+}
+
+func ExampleCase() {
+ c := Switch(Id("person")).Block(
+ Case(Id("John"), Id("Peter")).Block(
+ Return(Lit("male")),
+ ),
+ Case(Id("Gill")).Block(
+ Return(Lit("female")),
+ ),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // switch person {
+ // case John, Peter:
+ // return "male"
+ // case Gill:
+ // return "female"
+ // }
+}
+
+func ExampleBlock_case() {
+ c := Select().Block(
+ Case(Op("<-").Id("done")).Block(
+ Return(Nil()),
+ ),
+ Case(List(Err(), Id("open")).Op(":=").Op("<-").Id("fail")).Block(
+ If(Op("!").Id("open")).Block(
+ Return(Err()),
+ ),
+ ),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // select {
+ // case <-done:
+ // return nil
+ // case err, open := <-fail:
+ // if !open {
+ // return err
+ // }
+ // }
+}
+
+func ExampleBlockFunc_case() {
+ preventExitOnError := true
+ c := Select().Block(
+ Case(Op("<-").Id("done")).Block(
+ Return(Nil()),
+ ),
+ Case(Err().Op(":=").Op("<-").Id("fail")).BlockFunc(func(g *Group) {
+ if !preventExitOnError {
+ g.Return(Err())
+ } else {
+ g.Qual("fmt", "Println").Call(Err())
+ }
+ }),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // select {
+ // case <-done:
+ // return nil
+ // case err := <-fail:
+ // fmt.Println(err)
+ // }
+}
+
+func ExampleCaseFunc() {
+ samIsMale := false
+ c := Switch(Id("person")).Block(
+ CaseFunc(func(g *Group) {
+ g.Id("John")
+ g.Id("Peter")
+ if samIsMale {
+ g.Id("Sam")
+ }
+ }).Block(
+ Return(Lit("male")),
+ ),
+ CaseFunc(func(g *Group) {
+ g.Id("Gill")
+ if !samIsMale {
+ g.Id("Sam")
+ }
+ }).Block(
+ Return(Lit("female")),
+ ),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // switch person {
+ // case John, Peter:
+ // return "male"
+ // case Gill, Sam:
+ // return "female"
+ // }
+}
+
+func ExampleChan() {
+ c := Func().Id("init").Params().Block(
+ Id("c").Op(":=").Make(Chan().Qual("os", "Signal"), Lit(1)),
+ Qual("os/signal", "Notify").Call(Id("c"), Qual("os", "Interrupt")),
+ Qual("os/signal", "Notify").Call(Id("c"), Qual("syscall", "SIGTERM")),
+ Go().Func().Params().Block(
+ Op("<-").Id("c"),
+ Id("cancel").Call(),
+ ).Call(),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // func init() {
+ // c := make(chan os.Signal, 1)
+ // signal.Notify(c, os.Interrupt)
+ // signal.Notify(c, syscall.SIGTERM)
+ // go func() {
+ // <-c
+ // cancel()
+ // }()
+ // }
+}
+
+func ExampleClose() {
+ c := Block(
+ Id("ch").Op(":=").Make(Chan().Struct()),
+ Go().Func().Params().Block(
+ Op("<-").Id("ch"),
+ Qual("fmt", "Println").Call(Lit("done.")),
+ ).Call(),
+ Close(Id("ch")),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // {
+ // ch := make(chan struct{})
+ // go func() {
+ // <-ch
+ // fmt.Println("done.")
+ // }()
+ // close(ch)
+ // }
+}
+
+func ExampleComment() {
+ f := NewFile("a")
+ f.Comment("Foo returns the string \"foo\"")
+ f.Func().Id("Foo").Params().String().Block(
+ Return(Lit("foo")).Comment("return the string foo"),
+ )
+ fmt.Printf("%#v", f)
+ // Output:
+ // package a
+ //
+ // // Foo returns the string "foo"
+ // func Foo() string {
+ // return "foo" // return the string foo
+ // }
+}
+
+func ExampleComment_multiline() {
+ c := Comment("a\nb")
+ fmt.Printf("%#v", c)
+ // Output:
+ // /*
+ // a
+ // b
+ // */
+}
+
+func ExampleComment_formatting_disabled() {
+ c := Id("foo").Call(Comment("/* inline */")).Comment("//no-space")
+ fmt.Printf("%#v", c)
+ // Output:
+ // foo( /* inline */ ) //no-space
+}
+
+func ExampleCommentf() {
+ name := "foo"
+ val := "bar"
+ c := Id(name).Op(":=").Lit(val).Commentf("%s is the string \"%s\"", name, val)
+ fmt.Printf("%#v", c)
+ // Output:
+ // foo := "bar" // foo is the string "bar"
+}
+
+func ExampleComplex() {
+ c := Func().Id("main").Params().Block(
+ Id("c1").Op(":=").Lit(1+3.75i),
+ Id("c2").Op(":=").Complex(Lit(1), Lit(3.75)),
+ Qual("fmt", "Println").Call(Id("c1").Op("==").Id("c2")),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // func main() {
+ // c1 := (1 + 3.75i)
+ // c2 := complex(1, 3.75)
+ // fmt.Println(c1 == c2)
+ // }
+}
+
+func ExampleComplex128() {
+ c := Func().Id("main").Params().Block(
+ Var().Id("c").Complex128(),
+ Id("c").Op("=").Lit(1+2i),
+ Qual("fmt", "Println").Call(Id("c")),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // func main() {
+ // var c complex128
+ // c = (1 + 2i)
+ // fmt.Println(c)
+ // }
+}
+
+func ExampleComplex64() {
+ c := Func().Id("main").Params().Block(
+ Var().Id("c64").Complex64(),
+ Id("c64").Op("=").Complex(Lit(5), Float32().Parens(Lit(2))),
+ Qual("fmt", "Printf").Call(Lit("%T\n"), Id("c64")),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // func main() {
+ // var c64 complex64
+ // c64 = complex(5, float32(2))
+ // fmt.Printf("%T\n", c64)
+ // }
+}
+
+func ExampleParams() {
+ c := Func().Params(
+ Id("a").Id("A"),
+ ).Id("foo").Params(
+ Id("b"),
+ Id("c").String(),
+ ).String().Block(
+ Return(Id("b").Op("+").Id("c")),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // func (a A) foo(b, c string) string {
+ // return b + c
+ // }
+}
+
+func ExampleIndex() {
+ c := Var().Id("a").Index().String()
+ fmt.Printf("%#v", c)
+ // Output:
+ // var a []string
+}
+
+func ExampleIndex_index() {
+ c := Id("a").Op(":=").Id("b").Index(Lit(0), Lit(1))
+ fmt.Printf("%#v", c)
+ // Output:
+ // a := b[0:1]
+}
+
+func ExampleIndex_empty() {
+ c := Id("a").Op(":=").Id("b").Index(Lit(1), Empty())
+ fmt.Printf("%#v", c)
+ // Output:
+ // a := b[1:]
+}
+
+func ExampleOp() {
+ c := Id("a").Op(":=").Id("b").Call()
+ fmt.Printf("%#v", c)
+ // Output:
+ // a := b()
+}
+
+func ExampleOp_star() {
+ c := Id("a").Op("=").Op("*").Id("b")
+ fmt.Printf("%#v", c)
+ // Output:
+ // a = *b
+}
+
+func ExampleOp_variadic() {
+ c := Id("a").Call(Id("b").Op("..."))
+ fmt.Printf("%#v", c)
+ // Output:
+ // a(b...)
+}
+
+func ExampleNewFilePath() {
+ f := NewFilePath("a.b/c")
+ f.Func().Id("init").Params().Block(
+ Qual("a.b/c", "Foo").Call().Comment("Local package - alias is omitted."),
+ Qual("d.e/f", "Bar").Call().Comment("Import is automatically added."),
+ Qual("g.h/f", "Baz").Call().Comment("Colliding package name is automatically renamed."),
+ )
+ fmt.Printf("%#v", f)
+ // Output:
+ // package c
+ //
+ // import (
+ // f "d.e/f"
+ // f1 "g.h/f"
+ // )
+ //
+ // func init() {
+ // Foo() // Local package - alias is omitted.
+ // f.Bar() // Import is automatically added.
+ // f1.Baz() // Colliding package name is automatically renamed.
+ // }
+}
+
+func ExampleStruct_empty() {
+ c := Id("c").Op(":=").Make(Chan().Struct())
+ fmt.Printf("%#v", c)
+ // Output:
+ // c := make(chan struct{})
+}
+
+func ExampleStruct() {
+ c := Type().Id("foo").Struct(
+ List(Id("x"), Id("y")).Int(),
+ Id("u").Float32(),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // type foo struct {
+ // x, y int
+ // u float32
+ // }
+}
+
+func ExampleDefer() {
+ c := Defer().Id("foo").Call()
+ fmt.Printf("%#v", c)
+ // Output:
+ // defer foo()
+}
+
+func ExampleGoto() {
+ c := Goto().Id("Outer")
+ fmt.Printf("%#v", c)
+ // Output:
+ // goto Outer
+}
+
+func ExampleStatement_Clone_broken() {
+ a := Id("a")
+ c := Block(
+ a.Call(),
+ a.Call(),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // {
+ // a()()
+ // a()()
+ // }
+}
+
+func ExampleStatement_Clone_fixed() {
+ a := Id("a")
+ c := Block(
+ a.Clone().Call(),
+ a.Clone().Call(),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // {
+ // a()
+ // a()
+ // }
+}
+
+func ExampleFile_Render() {
+ f := NewFile("a")
+ f.Func().Id("main").Params().Block()
+ buf := &bytes.Buffer{}
+ err := f.Render(buf)
+ if err != nil {
+ fmt.Println(err.Error())
+ } else {
+ fmt.Println(buf.String())
+ }
+ // Output:
+ // package a
+ //
+ // func main() {}
+}
+
+func ExampleLit() {
+ c := Id("a").Op(":=").Lit("a")
+ fmt.Printf("%#v", c)
+ // Output:
+ // a := "a"
+}
+
+func ExampleLit_float() {
+ c := Id("a").Op(":=").Lit(1.5)
+ fmt.Printf("%#v", c)
+ // Output:
+ // a := 1.5
+}
+
+func ExampleLitFunc() {
+ c := Id("a").Op(":=").LitFunc(func() interface{} { return 1 + 1 })
+ fmt.Printf("%#v", c)
+ // Output:
+ // a := 2
+}
+
+func ExampleDot() {
+ c := Qual("a.b/c", "Foo").Call().Dot("Bar").Index(Lit(0)).Dot("Baz")
+ fmt.Printf("%#v", c)
+ // Output:
+ // c.Foo().Bar[0].Baz
+}
+
+func ExampleList() {
+ c := List(Id("a"), Err()).Op(":=").Id("b").Call()
+ fmt.Printf("%#v", c)
+ // Output:
+ // a, err := b()
+}
+
+func ExampleQual() {
+ c := Qual("encoding/gob", "NewEncoder").Call()
+ fmt.Printf("%#v", c)
+ // Output:
+ // gob.NewEncoder()
+}
+
+func ExampleQual_file() {
+ f := NewFilePath("a.b/c")
+ f.Func().Id("init").Params().Block(
+ Qual("a.b/c", "Foo").Call().Comment("Local package - name is omitted."),
+ Qual("d.e/f", "Bar").Call().Comment("Import is automatically added."),
+ Qual("g.h/f", "Baz").Call().Comment("Colliding package name is renamed."),
+ )
+ fmt.Printf("%#v", f)
+ // Output:
+ // package c
+ //
+ // import (
+ // f "d.e/f"
+ // f1 "g.h/f"
+ // )
+ //
+ // func init() {
+ // Foo() // Local package - name is omitted.
+ // f.Bar() // Import is automatically added.
+ // f1.Baz() // Colliding package name is renamed.
+ // }
+}
+
+func ExampleQual_local() {
+ f := NewFilePath("a.b/c")
+ f.Func().Id("main").Params().Block(
+ Qual("a.b/c", "D").Call(),
+ )
+ fmt.Printf("%#v", f)
+ // Output:
+ // package c
+ //
+ // func main() {
+ // D()
+ // }
+}
+
+func ExampleId() {
+ c := If(Id("i").Op("==").Id("j")).Block(
+ Return(Id("i")),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // if i == j {
+ // return i
+ // }
+}
+
+func ExampleErr() {
+ c := If(
+ Err().Op(":=").Id("foo").Call(),
+ Err().Op("!=").Nil(),
+ ).Block(
+ Return(Err()),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // if err := foo(); err != nil {
+ // return err
+ // }
+}
+
+func ExampleSwitch() {
+ c := Switch(Id("value").Dot("Kind").Call()).Block(
+ Case(Qual("reflect", "Float32"), Qual("reflect", "Float64")).Block(
+ Return(Lit("float")),
+ ),
+ Case(Qual("reflect", "Bool")).Block(
+ Return(Lit("bool")),
+ ),
+ Case(Qual("reflect", "Uintptr")).Block(
+ Fallthrough(),
+ ),
+ Default().Block(
+ Return(Lit("none")),
+ ),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // switch value.Kind() {
+ // case reflect.Float32, reflect.Float64:
+ // return "float"
+ // case reflect.Bool:
+ // return "bool"
+ // case reflect.Uintptr:
+ // fallthrough
+ // default:
+ // return "none"
+ // }
+}
+
+func ExampleTag() {
+ c := Type().Id("foo").Struct(
+ Id("A").String().Tag(map[string]string{"json": "a"}),
+ Id("B").Int().Tag(map[string]string{"json": "b", "bar": "baz"}),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // type foo struct {
+ // A string `json:"a"`
+ // B int `bar:"baz" json:"b"`
+ // }
+}
+
+func ExampleNull_and_nil() {
+ c := Func().Id("foo").Params(
+ nil,
+ Id("s").String(),
+ Null(),
+ Id("i").Int(),
+ ).Block()
+ fmt.Printf("%#v", c)
+ // Output:
+ // func foo(s string, i int) {}
+}
+
+func ExampleNull_index() {
+ c := Id("a").Op(":=").Id("b").Index(Lit(1), Null())
+ fmt.Printf("%#v", c)
+ // Output:
+ // a := b[1]
+}
+
+func ExampleEmpty() {
+ c := Id("a").Op(":=").Id("b").Index(Lit(1), Empty())
+ fmt.Printf("%#v", c)
+ // Output:
+ // a := b[1:]
+}
+
+func ExampleBlock_complex() {
+ collection := func(name string, key Code, value Code) *Statement {
+ if key == nil {
+ // slice
+ return Var().Id(name).Index().Add(value)
+ } else {
+ // map
+ return Var().Id(name).Map(key).Add(value)
+ }
+ }
+ c := Func().Id("main").Params().Block(
+ collection("foo", nil, String()),
+ collection("bar", String(), Int()),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // func main() {
+ // var foo []string
+ // var bar map[string]int
+ // }
+}
+
+func ExampleFunc_declaration() {
+ c := Func().Id("a").Params().Block()
+ fmt.Printf("%#v", c)
+ // Output:
+ // func a() {}
+}
+
+func ExampleFunc_literal() {
+ c := Id("a").Op(":=").Func().Params().Block()
+ fmt.Printf("%#v", c)
+ // Output:
+ // a := func() {}
+}
+
+func ExampleInterface() {
+ c := Type().Id("a").Interface(
+ Id("b").Params().String(),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // type a interface {
+ // b() string
+ // }
+}
+
+func ExampleInterface_empty() {
+ c := Var().Id("a").Interface()
+ fmt.Printf("%#v", c)
+ // Output:
+ // var a interface{}
+}
+
+func ExampleParens() {
+ c := Id("b").Op(":=").Index().Byte().Parens(Id("s"))
+ fmt.Printf("%#v", c)
+ // Output:
+ // b := []byte(s)
+}
+
+func ExampleParens_order() {
+ c := Id("a").Op("/").Parens(Id("b").Op("+").Id("c"))
+ fmt.Printf("%#v", c)
+ // Output:
+ // a / (b + c)
+}
+
+func ExampleValues() {
+ c := Index().String().Values(Lit("a"), Lit("b"))
+ fmt.Printf("%#v", c)
+ // Output:
+ // []string{"a", "b"}
+}
+
+func ExampleDo() {
+ f := func(name string, isMap bool) *Statement {
+ return Id(name).Op(":=").Do(func(s *Statement) {
+ if isMap {
+ s.Map(String()).String()
+ } else {
+ s.Index().String()
+ }
+ }).Values()
+ }
+ fmt.Printf("%#v\n%#v", f("a", true), f("b", false))
+ // Output:
+ // a := map[string]string{}
+ // b := []string{}
+}
+
+func ExampleReturn() {
+ c := Return(Id("a"), Id("b"))
+ fmt.Printf("%#v", c)
+ // Output:
+ // return a, b
+}
+
+func ExampleMap() {
+ c := Id("a").Op(":=").Map(String()).String().Values()
+ fmt.Printf("%#v", c)
+ // Output:
+ // a := map[string]string{}
+}
+
+func ExampleDict() {
+ c := Id("a").Op(":=").Map(String()).String().Values(Dict{
+ Lit("a"): Lit("b"),
+ Lit("c"): Lit("d"),
+ })
+ fmt.Printf("%#v", c)
+ // Output:
+ // a := map[string]string{
+ // "a": "b",
+ // "c": "d",
+ // }
+}
+
+func ExampleDict_nil() {
+ c := Id("a").Op(":=").Map(String()).String().Values()
+ fmt.Printf("%#v", c)
+ // Output:
+ // a := map[string]string{}
+}
+
+func ExampleDictFunc() {
+ c := Id("a").Op(":=").Map(String()).String().Values(DictFunc(func(d Dict) {
+ d[Lit("a")] = Lit("b")
+ d[Lit("c")] = Lit("d")
+ }))
+ fmt.Printf("%#v", c)
+ // Output:
+ // a := map[string]string{
+ // "a": "b",
+ // "c": "d",
+ // }
+}
+
+func ExampleDefs() {
+ c := Const().Defs(
+ Id("a").Op("=").Lit("a"),
+ Id("b").Op("=").Lit("b"),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // const (
+ // a = "a"
+ // b = "b"
+ // )
+}
+
+func ExampleIf() {
+ c := If(
+ Err().Op(":=").Id("a").Call(),
+ Err().Op("!=").Nil(),
+ ).Block(
+ Return(Err()),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // if err := a(); err != nil {
+ // return err
+ // }
+}
+
+func ExampleId_local() {
+ c := Id("a").Op(":=").Lit(1)
+ fmt.Printf("%#v", c)
+ // Output:
+ // a := 1
+}
+
+func ExampleId_select() {
+ c := Id("a").Dot("b").Dot("c").Call()
+ fmt.Printf("%#v", c)
+ // Output:
+ // a.b.c()
+}
+
+func ExampleId_remote() {
+ f := NewFile("main")
+ f.Func().Id("main").Params().Block(
+ Qual("fmt", "Println").Call(
+ Lit("Hello, world"),
+ ),
+ )
+ fmt.Printf("%#v", f)
+ // Output:
+ // package main
+ //
+ // import "fmt"
+ //
+ // func main() {
+ // fmt.Println("Hello, world")
+ // }
+}
+
+func ExampleFor() {
+ c := For(
+ Id("i").Op(":=").Lit(0),
+ Id("i").Op("<").Lit(10),
+ Id("i").Op("++"),
+ ).Block(
+ Qual("fmt", "Println").Call(Id("i")),
+ )
+ fmt.Printf("%#v", c)
+ // Output:
+ // for i := 0; i < 10; i++ {
+ // fmt.Println(i)
+ // }
+}
+
+func ExampleNewFile() {
+ f := NewFile("main")
+ f.Func().Id("main").Params().Block(
+ Qual("fmt", "Println").Call(Lit("Hello, world")),
+ )
+ fmt.Printf("%#v", f)
+ // Output:
+ // package main
+ //
+ // import "fmt"
+ //
+ // func main() {
+ // fmt.Println("Hello, world")
+ // }
+}
+
+func ExampleNewFilePathName() {
+ f := NewFilePathName("a.b/c", "main")
+ f.Func().Id("main").Params().Block(
+ Qual("a.b/c", "Foo").Call(),
+ )
+ fmt.Printf("%#v", f)
+ // Output:
+ // package main
+ //
+ // func main() {
+ // Foo()
+ // }
+}
+
+func ExampleFile_HeaderAndPackageComments() {
+ f := NewFile("c")
+ f.CanonicalPath = "d.e/f"
+ f.HeaderComment("Code generated by...")
+ f.PackageComment("Package c implements...")
+ f.Func().Id("init").Params().Block()
+ fmt.Printf("%#v", f)
+ // Output:
+ // // Code generated by...
+ //
+ // // Package c implements...
+ // package c // import "d.e/f"
+ //
+ // func init() {}
+}
+
+func ExampleFile_Anon() {
+ f := NewFile("c")
+ f.Anon("a")
+ f.Func().Id("init").Params().Block()
+ fmt.Printf("%#v", f)
+ // Output:
+ // package c
+ //
+ // import _ "a"
+ //
+ // func init() {}
+}
+
+func ExampleFile_PackagePrefix() {
+ f := NewFile("a")
+ f.PackagePrefix = "pkg"
+ f.Func().Id("main").Params().Block(
+ Qual("b.c/d", "E").Call(),
+ )
+ fmt.Printf("%#v", f)
+ // Output:
+ // package a
+ //
+ // import pkg_d "b.c/d"
+ //
+ // func main() {
+ // pkg_d.E()
+ // }
+}
diff --git a/vendor/github.com/dave/jennifer/jen/file.go b/vendor/github.com/dave/jennifer/jen/file.go
new file mode 100644
index 00000000..1ce442b9
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/file.go
@@ -0,0 +1,262 @@
+package jen
+
+import (
+ "bytes"
+ "fmt"
+ "regexp"
+ "strings"
+)
+
+// NewFile Creates a new file, with the specified package name.
+func NewFile(packageName string) *File {
+ return &File{
+ Group: &Group{
+ multi: true,
+ },
+ name: packageName,
+ imports: map[string]importdef{},
+ hints: map[string]importdef{},
+ }
+}
+
+// NewFilePath creates a new file while specifying the package path - the
+// package name is inferred from the path.
+func NewFilePath(packagePath string) *File {
+ return &File{
+ Group: &Group{
+ multi: true,
+ },
+ name: guessAlias(packagePath),
+ path: packagePath,
+ imports: map[string]importdef{},
+ hints: map[string]importdef{},
+ }
+}
+
+// NewFilePathName creates a new file with the specified package path and name.
+func NewFilePathName(packagePath, packageName string) *File {
+ return &File{
+ Group: &Group{
+ multi: true,
+ },
+ name: packageName,
+ path: packagePath,
+ imports: map[string]importdef{},
+ hints: map[string]importdef{},
+ }
+}
+
+// File represents a single source file. Package imports are managed
+// automaticaly by File.
+type File struct {
+ *Group
+ name string
+ path string
+ imports map[string]importdef
+ hints map[string]importdef
+ comments []string
+ headers []string
+ cgoPreamble []string
+ // If you're worried about generated package aliases conflicting with local variable names, you
+ // can set a prefix here. Package foo becomes {prefix}_foo.
+ PackagePrefix string
+ // CanonicalPath adds a canonical import path annotation to the package clause.
+ CanonicalPath string
+}
+
+// importdef is used to differentiate packages where we know the package name from packages where the
+// import is aliased. If alias == false, then name is the actual package name, and the import will be
+// rendered without an alias. If used == false, the import has not been used in code yet and should be
+// excluded from the import block.
+type importdef struct {
+ name string
+ alias bool
+}
+
+// HeaderComment adds a comment to the top of the file, above any package
+// comments. A blank line is rendered below the header comments, ensuring
+// header comments are not included in the package doc.
+func (f *File) HeaderComment(comment string) {
+ f.headers = append(f.headers, comment)
+}
+
+// PackageComment adds a comment to the top of the file, above the package
+// keyword.
+func (f *File) PackageComment(comment string) {
+ f.comments = append(f.comments, comment)
+}
+
+// CgoPreamble adds a cgo preamble comment that is rendered directly before the "C" pseudo-package
+// import.
+func (f *File) CgoPreamble(comment string) {
+ f.cgoPreamble = append(f.cgoPreamble, comment)
+}
+
+// Anon adds an anonymous import.
+func (f *File) Anon(paths ...string) {
+ for _, p := range paths {
+ f.imports[p] = importdef{name: "_", alias: true}
+ }
+}
+
+// ImportName provides the package name for a path. If specified, the alias will be omitted from the
+// import block. This is optional. If not specified, a sensible package name is used based on the path
+// and this is added as an alias in the import block.
+func (f *File) ImportName(path, name string) {
+ f.hints[path] = importdef{name: name, alias: false}
+}
+
+// ImportNames allows multiple names to be imported as a map. Use the [gennames](gennames) command to
+// automatically generate a go file containing a map of a selection of package names.
+func (f *File) ImportNames(names map[string]string) {
+ for path, name := range names {
+ f.hints[path] = importdef{name: name, alias: false}
+ }
+}
+
+// ImportAlias provides the alias for a package path that should be used in the import block. A
+// period can be used to force a dot-import.
+func (f *File) ImportAlias(path, alias string) {
+ f.hints[path] = importdef{name: alias, alias: true}
+}
+
+func (f *File) isLocal(path string) bool {
+ return f.path == path
+}
+
+var reserved = []string{
+ /* keywords */
+ "break", "default", "func", "interface", "select", "case", "defer", "go", "map", "struct", "chan", "else", "goto", "package", "switch", "const", "fallthrough", "if", "range", "type", "continue", "for", "import", "return", "var",
+ /* predeclared */
+ "bool", "byte", "complex64", "complex128", "error", "float32", "float64", "int", "int8", "int16", "int32", "int64", "rune", "string", "uint", "uint8", "uint16", "uint32", "uint64", "uintptr", "true", "false", "iota", "nil", "append", "cap", "close", "complex", "copy", "delete", "imag", "len", "make", "new", "panic", "print", "println", "real", "recover",
+ /* common variables */
+ "err",
+}
+
+func isReservedWord(alias string) bool {
+ for _, name := range reserved {
+ if alias == name {
+ return true
+ }
+ }
+ return false
+}
+
+func (f *File) isValidAlias(alias string) bool {
+ // multiple dot-imports are ok
+ if alias == "." {
+ return true
+ }
+ // the import alias is invalid if it's a reserved word
+ if isReservedWord(alias) {
+ return false
+ }
+ // the import alias is invalid if it's already been registered
+ for _, v := range f.imports {
+ if alias == v.name {
+ return false
+ }
+ }
+ return true
+}
+
+func (f *File) isDotImport(path string) bool {
+ if id, ok := f.hints[path]; ok {
+ return id.name == "." && id.alias
+ }
+ return false
+}
+
+func (f *File) register(path string) string {
+ if f.isLocal(path) {
+ // notest
+ // should never get here becasue in Qual the packageToken will be null,
+ // so render will never be called.
+ return ""
+ }
+
+ // if the path has been registered previously, simply return the name
+ def := f.imports[path]
+ if def.name != "" && def.name != "_" {
+ return def.name
+ }
+
+ // special case for "C" pseudo-package
+ if path == "C" {
+ f.imports["C"] = importdef{name: "C", alias: false}
+ return "C"
+ }
+
+ var name string
+ var alias bool
+
+ if hint := f.hints[path]; hint.name != "" {
+ // look up the path in the list of provided package names and aliases by ImportName / ImportAlias
+ name = hint.name
+ alias = hint.alias
+ } else if standardLibraryHints[path] != "" {
+ // look up the path in the list of standard library packages
+ name = standardLibraryHints[path]
+ alias = false
+ } else {
+ // if a hint is not found for the package, guess the alias from the package path
+ name = guessAlias(path)
+ alias = true
+ }
+
+ // If the name is invalid or has been registered already, make it unique by appending a number
+ unique := name
+ i := 0
+ for !f.isValidAlias(unique) {
+ i++
+ unique = fmt.Sprintf("%s%d", name, i)
+ }
+
+ // If we've changed the name to make it unique, it should definitely be an alias
+ if unique != name {
+ alias = true
+ }
+
+ // Only add a prefix if the name is an alias
+ if f.PackagePrefix != "" && alias {
+ unique = f.PackagePrefix + "_" + unique
+ }
+
+ // Register the eventual name
+ f.imports[path] = importdef{name: unique, alias: alias}
+
+ return unique
+}
+
+// GoString renders the File for testing. Any error will cause a panic.
+func (f *File) GoString() string {
+ buf := &bytes.Buffer{}
+ if err := f.Render(buf); err != nil {
+ panic(err)
+ }
+ return buf.String()
+}
+
+func guessAlias(path string) string {
+ alias := path
+
+ if strings.HasSuffix(alias, "/") {
+ // training slashes are usually tolerated, so we can get rid of one if
+ // it exists
+ alias = alias[:len(alias)-1]
+ }
+
+ if strings.Contains(alias, "/") {
+ // if the path contains a "/", use the last part
+ alias = alias[strings.LastIndex(alias, "/")+1:]
+ }
+
+ // alias should be lower case
+ alias = strings.ToLower(alias)
+
+ // alias should now only contain alphanumerics
+ importsRegex := regexp.MustCompile(`[^a-z0-9]`)
+ alias = importsRegex.ReplaceAllString(alias, "")
+
+ return alias
+}
diff --git a/vendor/github.com/dave/jennifer/jen/file_test.go b/vendor/github.com/dave/jennifer/jen/file_test.go
new file mode 100644
index 00000000..798faf63
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/file_test.go
@@ -0,0 +1,48 @@
+package jen
+
+import (
+ "fmt"
+ "testing"
+)
+
+func TestGuessAlias(t *testing.T) {
+
+ data := map[string]string{
+ "A": "a",
+ "a": "a",
+ "a$": "a",
+ "a/b": "b",
+ "a/b/c": "c",
+ "a/b/c-d": "cd",
+ "a/b/c-d/": "cd",
+ "a.b": "ab",
+ "a/b.c": "bc",
+ "a/b-c.d": "bcd",
+ "a/bb-ccc.dddd": "bbcccdddd",
+ "a/foo-go": "foogo",
+ }
+ for path, expected := range data {
+ if guessAlias(path) != expected {
+ fmt.Printf("guessAlias test failed %s should return %s but got %s\n", path, expected, guessAlias(path))
+ t.Fail()
+ }
+ }
+}
+
+func TestValidAlias(t *testing.T) {
+ data := map[string]bool{
+ "a": true, // ok
+ "b": false, // already registered
+ "go": false, // keyword
+ "int": false, // predeclared
+ "err": false, // common name
+ }
+ f := NewFile("test")
+ f.register("b")
+ for alias, expected := range data {
+ if f.isValidAlias(alias) != expected {
+ fmt.Printf("isValidAlias test failed %s should return %t but got %t\n", alias, expected, f.isValidAlias(alias))
+ t.Fail()
+ }
+ }
+}
diff --git a/vendor/github.com/dave/jennifer/jen/generated.go b/vendor/github.com/dave/jennifer/jen/generated.go
new file mode 100644
index 00000000..3983cf97
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/generated.go
@@ -0,0 +1,2274 @@
+// This file is generated - do not edit.
+
+package jen
+
+// Parens renders a single item in parenthesis. Use for type conversion or to specify evaluation order.
+func Parens(item Code) *Statement {
+ return newStatement().Parens(item)
+}
+
+// Parens renders a single item in parenthesis. Use for type conversion or to specify evaluation order.
+func (g *Group) Parens(item Code) *Statement {
+ s := Parens(item)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Parens renders a single item in parenthesis. Use for type conversion or to specify evaluation order.
+func (s *Statement) Parens(item Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: []Code{item},
+ multi: false,
+ name: "parens",
+ open: "(",
+ separator: "",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// List renders a comma separated list. Use for multiple return functions.
+func List(items ...Code) *Statement {
+ return newStatement().List(items...)
+}
+
+// List renders a comma separated list. Use for multiple return functions.
+func (g *Group) List(items ...Code) *Statement {
+ s := List(items...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// List renders a comma separated list. Use for multiple return functions.
+func (s *Statement) List(items ...Code) *Statement {
+ g := &Group{
+ close: "",
+ items: items,
+ multi: false,
+ name: "list",
+ open: "",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// ListFunc renders a comma separated list. Use for multiple return functions.
+func ListFunc(f func(*Group)) *Statement {
+ return newStatement().ListFunc(f)
+}
+
+// ListFunc renders a comma separated list. Use for multiple return functions.
+func (g *Group) ListFunc(f func(*Group)) *Statement {
+ s := ListFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// ListFunc renders a comma separated list. Use for multiple return functions.
+func (s *Statement) ListFunc(f func(*Group)) *Statement {
+ g := &Group{
+ close: "",
+ multi: false,
+ name: "list",
+ open: "",
+ separator: ",",
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
+
+// Values renders a comma separated list enclosed by curly braces. Use for slice or composite literals.
+func Values(values ...Code) *Statement {
+ return newStatement().Values(values...)
+}
+
+// Values renders a comma separated list enclosed by curly braces. Use for slice or composite literals.
+func (g *Group) Values(values ...Code) *Statement {
+ s := Values(values...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Values renders a comma separated list enclosed by curly braces. Use for slice or composite literals.
+func (s *Statement) Values(values ...Code) *Statement {
+ g := &Group{
+ close: "}",
+ items: values,
+ multi: false,
+ name: "values",
+ open: "{",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// ValuesFunc renders a comma separated list enclosed by curly braces. Use for slice or composite literals.
+func ValuesFunc(f func(*Group)) *Statement {
+ return newStatement().ValuesFunc(f)
+}
+
+// ValuesFunc renders a comma separated list enclosed by curly braces. Use for slice or composite literals.
+func (g *Group) ValuesFunc(f func(*Group)) *Statement {
+ s := ValuesFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// ValuesFunc renders a comma separated list enclosed by curly braces. Use for slice or composite literals.
+func (s *Statement) ValuesFunc(f func(*Group)) *Statement {
+ g := &Group{
+ close: "}",
+ multi: false,
+ name: "values",
+ open: "{",
+ separator: ",",
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
+
+// Index renders a colon separated list enclosed by square brackets. Use for array / slice indexes and definitions.
+func Index(items ...Code) *Statement {
+ return newStatement().Index(items...)
+}
+
+// Index renders a colon separated list enclosed by square brackets. Use for array / slice indexes and definitions.
+func (g *Group) Index(items ...Code) *Statement {
+ s := Index(items...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Index renders a colon separated list enclosed by square brackets. Use for array / slice indexes and definitions.
+func (s *Statement) Index(items ...Code) *Statement {
+ g := &Group{
+ close: "]",
+ items: items,
+ multi: false,
+ name: "index",
+ open: "[",
+ separator: ":",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// IndexFunc renders a colon separated list enclosed by square brackets. Use for array / slice indexes and definitions.
+func IndexFunc(f func(*Group)) *Statement {
+ return newStatement().IndexFunc(f)
+}
+
+// IndexFunc renders a colon separated list enclosed by square brackets. Use for array / slice indexes and definitions.
+func (g *Group) IndexFunc(f func(*Group)) *Statement {
+ s := IndexFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// IndexFunc renders a colon separated list enclosed by square brackets. Use for array / slice indexes and definitions.
+func (s *Statement) IndexFunc(f func(*Group)) *Statement {
+ g := &Group{
+ close: "]",
+ multi: false,
+ name: "index",
+ open: "[",
+ separator: ":",
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
+
+// Block renders a statement list enclosed by curly braces. Use for code blocks. A special case applies when used directly after Case or Default, where the braces are omitted. This allows use in switch and select statements.
+func Block(statements ...Code) *Statement {
+ return newStatement().Block(statements...)
+}
+
+// Block renders a statement list enclosed by curly braces. Use for code blocks. A special case applies when used directly after Case or Default, where the braces are omitted. This allows use in switch and select statements.
+func (g *Group) Block(statements ...Code) *Statement {
+ s := Block(statements...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Block renders a statement list enclosed by curly braces. Use for code blocks. A special case applies when used directly after Case or Default, where the braces are omitted. This allows use in switch and select statements.
+func (s *Statement) Block(statements ...Code) *Statement {
+ g := &Group{
+ close: "}",
+ items: statements,
+ multi: true,
+ name: "block",
+ open: "{",
+ separator: "",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// BlockFunc renders a statement list enclosed by curly braces. Use for code blocks. A special case applies when used directly after Case or Default, where the braces are omitted. This allows use in switch and select statements.
+func BlockFunc(f func(*Group)) *Statement {
+ return newStatement().BlockFunc(f)
+}
+
+// BlockFunc renders a statement list enclosed by curly braces. Use for code blocks. A special case applies when used directly after Case or Default, where the braces are omitted. This allows use in switch and select statements.
+func (g *Group) BlockFunc(f func(*Group)) *Statement {
+ s := BlockFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// BlockFunc renders a statement list enclosed by curly braces. Use for code blocks. A special case applies when used directly after Case or Default, where the braces are omitted. This allows use in switch and select statements.
+func (s *Statement) BlockFunc(f func(*Group)) *Statement {
+ g := &Group{
+ close: "}",
+ multi: true,
+ name: "block",
+ open: "{",
+ separator: "",
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
+
+// Defs renders a statement list enclosed in parenthesis. Use for definition lists.
+func Defs(definitions ...Code) *Statement {
+ return newStatement().Defs(definitions...)
+}
+
+// Defs renders a statement list enclosed in parenthesis. Use for definition lists.
+func (g *Group) Defs(definitions ...Code) *Statement {
+ s := Defs(definitions...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Defs renders a statement list enclosed in parenthesis. Use for definition lists.
+func (s *Statement) Defs(definitions ...Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: definitions,
+ multi: true,
+ name: "defs",
+ open: "(",
+ separator: "",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// DefsFunc renders a statement list enclosed in parenthesis. Use for definition lists.
+func DefsFunc(f func(*Group)) *Statement {
+ return newStatement().DefsFunc(f)
+}
+
+// DefsFunc renders a statement list enclosed in parenthesis. Use for definition lists.
+func (g *Group) DefsFunc(f func(*Group)) *Statement {
+ s := DefsFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// DefsFunc renders a statement list enclosed in parenthesis. Use for definition lists.
+func (s *Statement) DefsFunc(f func(*Group)) *Statement {
+ g := &Group{
+ close: ")",
+ multi: true,
+ name: "defs",
+ open: "(",
+ separator: "",
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
+
+// Call renders a comma separated list enclosed by parenthesis. Use for function calls.
+func Call(params ...Code) *Statement {
+ return newStatement().Call(params...)
+}
+
+// Call renders a comma separated list enclosed by parenthesis. Use for function calls.
+func (g *Group) Call(params ...Code) *Statement {
+ s := Call(params...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Call renders a comma separated list enclosed by parenthesis. Use for function calls.
+func (s *Statement) Call(params ...Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: params,
+ multi: false,
+ name: "call",
+ open: "(",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// CallFunc renders a comma separated list enclosed by parenthesis. Use for function calls.
+func CallFunc(f func(*Group)) *Statement {
+ return newStatement().CallFunc(f)
+}
+
+// CallFunc renders a comma separated list enclosed by parenthesis. Use for function calls.
+func (g *Group) CallFunc(f func(*Group)) *Statement {
+ s := CallFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// CallFunc renders a comma separated list enclosed by parenthesis. Use for function calls.
+func (s *Statement) CallFunc(f func(*Group)) *Statement {
+ g := &Group{
+ close: ")",
+ multi: false,
+ name: "call",
+ open: "(",
+ separator: ",",
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
+
+// Params renders a comma separated list enclosed by parenthesis. Use for function parameters and method receivers.
+func Params(params ...Code) *Statement {
+ return newStatement().Params(params...)
+}
+
+// Params renders a comma separated list enclosed by parenthesis. Use for function parameters and method receivers.
+func (g *Group) Params(params ...Code) *Statement {
+ s := Params(params...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Params renders a comma separated list enclosed by parenthesis. Use for function parameters and method receivers.
+func (s *Statement) Params(params ...Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: params,
+ multi: false,
+ name: "params",
+ open: "(",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// ParamsFunc renders a comma separated list enclosed by parenthesis. Use for function parameters and method receivers.
+func ParamsFunc(f func(*Group)) *Statement {
+ return newStatement().ParamsFunc(f)
+}
+
+// ParamsFunc renders a comma separated list enclosed by parenthesis. Use for function parameters and method receivers.
+func (g *Group) ParamsFunc(f func(*Group)) *Statement {
+ s := ParamsFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// ParamsFunc renders a comma separated list enclosed by parenthesis. Use for function parameters and method receivers.
+func (s *Statement) ParamsFunc(f func(*Group)) *Statement {
+ g := &Group{
+ close: ")",
+ multi: false,
+ name: "params",
+ open: "(",
+ separator: ",",
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
+
+// Assert renders a period followed by a single item enclosed by parenthesis. Use for type assertions.
+func Assert(typ Code) *Statement {
+ return newStatement().Assert(typ)
+}
+
+// Assert renders a period followed by a single item enclosed by parenthesis. Use for type assertions.
+func (g *Group) Assert(typ Code) *Statement {
+ s := Assert(typ)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Assert renders a period followed by a single item enclosed by parenthesis. Use for type assertions.
+func (s *Statement) Assert(typ Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: []Code{typ},
+ multi: false,
+ name: "assert",
+ open: ".(",
+ separator: "",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// Map renders the keyword followed by a single item enclosed by square brackets. Use for map definitions.
+func Map(typ Code) *Statement {
+ return newStatement().Map(typ)
+}
+
+// Map renders the keyword followed by a single item enclosed by square brackets. Use for map definitions.
+func (g *Group) Map(typ Code) *Statement {
+ s := Map(typ)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Map renders the keyword followed by a single item enclosed by square brackets. Use for map definitions.
+func (s *Statement) Map(typ Code) *Statement {
+ g := &Group{
+ close: "]",
+ items: []Code{typ},
+ multi: false,
+ name: "map",
+ open: "map[",
+ separator: "",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// If renders the keyword followed by a semicolon separated list.
+func If(conditions ...Code) *Statement {
+ return newStatement().If(conditions...)
+}
+
+// If renders the keyword followed by a semicolon separated list.
+func (g *Group) If(conditions ...Code) *Statement {
+ s := If(conditions...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// If renders the keyword followed by a semicolon separated list.
+func (s *Statement) If(conditions ...Code) *Statement {
+ g := &Group{
+ close: "",
+ items: conditions,
+ multi: false,
+ name: "if",
+ open: "if ",
+ separator: ";",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// IfFunc renders the keyword followed by a semicolon separated list.
+func IfFunc(f func(*Group)) *Statement {
+ return newStatement().IfFunc(f)
+}
+
+// IfFunc renders the keyword followed by a semicolon separated list.
+func (g *Group) IfFunc(f func(*Group)) *Statement {
+ s := IfFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// IfFunc renders the keyword followed by a semicolon separated list.
+func (s *Statement) IfFunc(f func(*Group)) *Statement {
+ g := &Group{
+ close: "",
+ multi: false,
+ name: "if",
+ open: "if ",
+ separator: ";",
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
+
+// Return renders the keyword followed by a comma separated list.
+func Return(results ...Code) *Statement {
+ return newStatement().Return(results...)
+}
+
+// Return renders the keyword followed by a comma separated list.
+func (g *Group) Return(results ...Code) *Statement {
+ s := Return(results...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Return renders the keyword followed by a comma separated list.
+func (s *Statement) Return(results ...Code) *Statement {
+ g := &Group{
+ close: "",
+ items: results,
+ multi: false,
+ name: "return",
+ open: "return ",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// ReturnFunc renders the keyword followed by a comma separated list.
+func ReturnFunc(f func(*Group)) *Statement {
+ return newStatement().ReturnFunc(f)
+}
+
+// ReturnFunc renders the keyword followed by a comma separated list.
+func (g *Group) ReturnFunc(f func(*Group)) *Statement {
+ s := ReturnFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// ReturnFunc renders the keyword followed by a comma separated list.
+func (s *Statement) ReturnFunc(f func(*Group)) *Statement {
+ g := &Group{
+ close: "",
+ multi: false,
+ name: "return",
+ open: "return ",
+ separator: ",",
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
+
+// For renders the keyword followed by a semicolon separated list.
+func For(conditions ...Code) *Statement {
+ return newStatement().For(conditions...)
+}
+
+// For renders the keyword followed by a semicolon separated list.
+func (g *Group) For(conditions ...Code) *Statement {
+ s := For(conditions...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// For renders the keyword followed by a semicolon separated list.
+func (s *Statement) For(conditions ...Code) *Statement {
+ g := &Group{
+ close: "",
+ items: conditions,
+ multi: false,
+ name: "for",
+ open: "for ",
+ separator: ";",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// ForFunc renders the keyword followed by a semicolon separated list.
+func ForFunc(f func(*Group)) *Statement {
+ return newStatement().ForFunc(f)
+}
+
+// ForFunc renders the keyword followed by a semicolon separated list.
+func (g *Group) ForFunc(f func(*Group)) *Statement {
+ s := ForFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// ForFunc renders the keyword followed by a semicolon separated list.
+func (s *Statement) ForFunc(f func(*Group)) *Statement {
+ g := &Group{
+ close: "",
+ multi: false,
+ name: "for",
+ open: "for ",
+ separator: ";",
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
+
+// Switch renders the keyword followed by a semicolon separated list.
+func Switch(conditions ...Code) *Statement {
+ return newStatement().Switch(conditions...)
+}
+
+// Switch renders the keyword followed by a semicolon separated list.
+func (g *Group) Switch(conditions ...Code) *Statement {
+ s := Switch(conditions...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Switch renders the keyword followed by a semicolon separated list.
+func (s *Statement) Switch(conditions ...Code) *Statement {
+ g := &Group{
+ close: "",
+ items: conditions,
+ multi: false,
+ name: "switch",
+ open: "switch ",
+ separator: ";",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// SwitchFunc renders the keyword followed by a semicolon separated list.
+func SwitchFunc(f func(*Group)) *Statement {
+ return newStatement().SwitchFunc(f)
+}
+
+// SwitchFunc renders the keyword followed by a semicolon separated list.
+func (g *Group) SwitchFunc(f func(*Group)) *Statement {
+ s := SwitchFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// SwitchFunc renders the keyword followed by a semicolon separated list.
+func (s *Statement) SwitchFunc(f func(*Group)) *Statement {
+ g := &Group{
+ close: "",
+ multi: false,
+ name: "switch",
+ open: "switch ",
+ separator: ";",
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
+
+// Interface renders the keyword followed by a method list enclosed by curly braces.
+func Interface(methods ...Code) *Statement {
+ return newStatement().Interface(methods...)
+}
+
+// Interface renders the keyword followed by a method list enclosed by curly braces.
+func (g *Group) Interface(methods ...Code) *Statement {
+ s := Interface(methods...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Interface renders the keyword followed by a method list enclosed by curly braces.
+func (s *Statement) Interface(methods ...Code) *Statement {
+ g := &Group{
+ close: "}",
+ items: methods,
+ multi: true,
+ name: "interface",
+ open: "interface{",
+ separator: "",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// InterfaceFunc renders the keyword followed by a method list enclosed by curly braces.
+func InterfaceFunc(f func(*Group)) *Statement {
+ return newStatement().InterfaceFunc(f)
+}
+
+// InterfaceFunc renders the keyword followed by a method list enclosed by curly braces.
+func (g *Group) InterfaceFunc(f func(*Group)) *Statement {
+ s := InterfaceFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// InterfaceFunc renders the keyword followed by a method list enclosed by curly braces.
+func (s *Statement) InterfaceFunc(f func(*Group)) *Statement {
+ g := &Group{
+ close: "}",
+ multi: true,
+ name: "interface",
+ open: "interface{",
+ separator: "",
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
+
+// Struct renders the keyword followed by a field list enclosed by curly braces.
+func Struct(fields ...Code) *Statement {
+ return newStatement().Struct(fields...)
+}
+
+// Struct renders the keyword followed by a field list enclosed by curly braces.
+func (g *Group) Struct(fields ...Code) *Statement {
+ s := Struct(fields...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Struct renders the keyword followed by a field list enclosed by curly braces.
+func (s *Statement) Struct(fields ...Code) *Statement {
+ g := &Group{
+ close: "}",
+ items: fields,
+ multi: true,
+ name: "struct",
+ open: "struct{",
+ separator: "",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// StructFunc renders the keyword followed by a field list enclosed by curly braces.
+func StructFunc(f func(*Group)) *Statement {
+ return newStatement().StructFunc(f)
+}
+
+// StructFunc renders the keyword followed by a field list enclosed by curly braces.
+func (g *Group) StructFunc(f func(*Group)) *Statement {
+ s := StructFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// StructFunc renders the keyword followed by a field list enclosed by curly braces.
+func (s *Statement) StructFunc(f func(*Group)) *Statement {
+ g := &Group{
+ close: "}",
+ multi: true,
+ name: "struct",
+ open: "struct{",
+ separator: "",
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
+
+// Case renders the keyword followed by a comma separated list.
+func Case(cases ...Code) *Statement {
+ return newStatement().Case(cases...)
+}
+
+// Case renders the keyword followed by a comma separated list.
+func (g *Group) Case(cases ...Code) *Statement {
+ s := Case(cases...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Case renders the keyword followed by a comma separated list.
+func (s *Statement) Case(cases ...Code) *Statement {
+ g := &Group{
+ close: ":",
+ items: cases,
+ multi: false,
+ name: "case",
+ open: "case ",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// CaseFunc renders the keyword followed by a comma separated list.
+func CaseFunc(f func(*Group)) *Statement {
+ return newStatement().CaseFunc(f)
+}
+
+// CaseFunc renders the keyword followed by a comma separated list.
+func (g *Group) CaseFunc(f func(*Group)) *Statement {
+ s := CaseFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// CaseFunc renders the keyword followed by a comma separated list.
+func (s *Statement) CaseFunc(f func(*Group)) *Statement {
+ g := &Group{
+ close: ":",
+ multi: false,
+ name: "case",
+ open: "case ",
+ separator: ",",
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
+
+// Append renders the append built-in function.
+func Append(args ...Code) *Statement {
+ return newStatement().Append(args...)
+}
+
+// Append renders the append built-in function.
+func (g *Group) Append(args ...Code) *Statement {
+ s := Append(args...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Append renders the append built-in function.
+func (s *Statement) Append(args ...Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: args,
+ multi: false,
+ name: "append",
+ open: "append(",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// AppendFunc renders the append built-in function.
+func AppendFunc(f func(*Group)) *Statement {
+ return newStatement().AppendFunc(f)
+}
+
+// AppendFunc renders the append built-in function.
+func (g *Group) AppendFunc(f func(*Group)) *Statement {
+ s := AppendFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// AppendFunc renders the append built-in function.
+func (s *Statement) AppendFunc(f func(*Group)) *Statement {
+ g := &Group{
+ close: ")",
+ multi: false,
+ name: "append",
+ open: "append(",
+ separator: ",",
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
+
+// Cap renders the cap built-in function.
+func Cap(v Code) *Statement {
+ return newStatement().Cap(v)
+}
+
+// Cap renders the cap built-in function.
+func (g *Group) Cap(v Code) *Statement {
+ s := Cap(v)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Cap renders the cap built-in function.
+func (s *Statement) Cap(v Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: []Code{v},
+ multi: false,
+ name: "cap",
+ open: "cap(",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// Close renders the close built-in function.
+func Close(c Code) *Statement {
+ return newStatement().Close(c)
+}
+
+// Close renders the close built-in function.
+func (g *Group) Close(c Code) *Statement {
+ s := Close(c)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Close renders the close built-in function.
+func (s *Statement) Close(c Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: []Code{c},
+ multi: false,
+ name: "close",
+ open: "close(",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// Complex renders the complex built-in function.
+func Complex(r Code, i Code) *Statement {
+ return newStatement().Complex(r, i)
+}
+
+// Complex renders the complex built-in function.
+func (g *Group) Complex(r Code, i Code) *Statement {
+ s := Complex(r, i)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Complex renders the complex built-in function.
+func (s *Statement) Complex(r Code, i Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: []Code{r, i},
+ multi: false,
+ name: "complex",
+ open: "complex(",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// Copy renders the copy built-in function.
+func Copy(dst Code, src Code) *Statement {
+ return newStatement().Copy(dst, src)
+}
+
+// Copy renders the copy built-in function.
+func (g *Group) Copy(dst Code, src Code) *Statement {
+ s := Copy(dst, src)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Copy renders the copy built-in function.
+func (s *Statement) Copy(dst Code, src Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: []Code{dst, src},
+ multi: false,
+ name: "copy",
+ open: "copy(",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// Delete renders the delete built-in function.
+func Delete(m Code, key Code) *Statement {
+ return newStatement().Delete(m, key)
+}
+
+// Delete renders the delete built-in function.
+func (g *Group) Delete(m Code, key Code) *Statement {
+ s := Delete(m, key)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Delete renders the delete built-in function.
+func (s *Statement) Delete(m Code, key Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: []Code{m, key},
+ multi: false,
+ name: "delete",
+ open: "delete(",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// Imag renders the imag built-in function.
+func Imag(c Code) *Statement {
+ return newStatement().Imag(c)
+}
+
+// Imag renders the imag built-in function.
+func (g *Group) Imag(c Code) *Statement {
+ s := Imag(c)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Imag renders the imag built-in function.
+func (s *Statement) Imag(c Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: []Code{c},
+ multi: false,
+ name: "imag",
+ open: "imag(",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// Len renders the len built-in function.
+func Len(v Code) *Statement {
+ return newStatement().Len(v)
+}
+
+// Len renders the len built-in function.
+func (g *Group) Len(v Code) *Statement {
+ s := Len(v)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Len renders the len built-in function.
+func (s *Statement) Len(v Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: []Code{v},
+ multi: false,
+ name: "len",
+ open: "len(",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// Make renders the make built-in function. The final parameter of the make function is optional, so it is represented by a variadic parameter list.
+func Make(args ...Code) *Statement {
+ return newStatement().Make(args...)
+}
+
+// Make renders the make built-in function. The final parameter of the make function is optional, so it is represented by a variadic parameter list.
+func (g *Group) Make(args ...Code) *Statement {
+ s := Make(args...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Make renders the make built-in function. The final parameter of the make function is optional, so it is represented by a variadic parameter list.
+func (s *Statement) Make(args ...Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: args,
+ multi: false,
+ name: "make",
+ open: "make(",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// New renders the new built-in function.
+func New(typ Code) *Statement {
+ return newStatement().New(typ)
+}
+
+// New renders the new built-in function.
+func (g *Group) New(typ Code) *Statement {
+ s := New(typ)
+ g.items = append(g.items, s)
+ return s
+}
+
+// New renders the new built-in function.
+func (s *Statement) New(typ Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: []Code{typ},
+ multi: false,
+ name: "new",
+ open: "new(",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// Panic renders the panic built-in function.
+func Panic(v Code) *Statement {
+ return newStatement().Panic(v)
+}
+
+// Panic renders the panic built-in function.
+func (g *Group) Panic(v Code) *Statement {
+ s := Panic(v)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Panic renders the panic built-in function.
+func (s *Statement) Panic(v Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: []Code{v},
+ multi: false,
+ name: "panic",
+ open: "panic(",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// Print renders the print built-in function.
+func Print(args ...Code) *Statement {
+ return newStatement().Print(args...)
+}
+
+// Print renders the print built-in function.
+func (g *Group) Print(args ...Code) *Statement {
+ s := Print(args...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Print renders the print built-in function.
+func (s *Statement) Print(args ...Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: args,
+ multi: false,
+ name: "print",
+ open: "print(",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// PrintFunc renders the print built-in function.
+func PrintFunc(f func(*Group)) *Statement {
+ return newStatement().PrintFunc(f)
+}
+
+// PrintFunc renders the print built-in function.
+func (g *Group) PrintFunc(f func(*Group)) *Statement {
+ s := PrintFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// PrintFunc renders the print built-in function.
+func (s *Statement) PrintFunc(f func(*Group)) *Statement {
+ g := &Group{
+ close: ")",
+ multi: false,
+ name: "print",
+ open: "print(",
+ separator: ",",
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
+
+// Println renders the println built-in function.
+func Println(args ...Code) *Statement {
+ return newStatement().Println(args...)
+}
+
+// Println renders the println built-in function.
+func (g *Group) Println(args ...Code) *Statement {
+ s := Println(args...)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Println renders the println built-in function.
+func (s *Statement) Println(args ...Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: args,
+ multi: false,
+ name: "println",
+ open: "println(",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// PrintlnFunc renders the println built-in function.
+func PrintlnFunc(f func(*Group)) *Statement {
+ return newStatement().PrintlnFunc(f)
+}
+
+// PrintlnFunc renders the println built-in function.
+func (g *Group) PrintlnFunc(f func(*Group)) *Statement {
+ s := PrintlnFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// PrintlnFunc renders the println built-in function.
+func (s *Statement) PrintlnFunc(f func(*Group)) *Statement {
+ g := &Group{
+ close: ")",
+ multi: false,
+ name: "println",
+ open: "println(",
+ separator: ",",
+ }
+ f(g)
+ *s = append(*s, g)
+ return s
+}
+
+// Real renders the real built-in function.
+func Real(c Code) *Statement {
+ return newStatement().Real(c)
+}
+
+// Real renders the real built-in function.
+func (g *Group) Real(c Code) *Statement {
+ s := Real(c)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Real renders the real built-in function.
+func (s *Statement) Real(c Code) *Statement {
+ g := &Group{
+ close: ")",
+ items: []Code{c},
+ multi: false,
+ name: "real",
+ open: "real(",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// Recover renders the recover built-in function.
+func Recover() *Statement {
+ return newStatement().Recover()
+}
+
+// Recover renders the recover built-in function.
+func (g *Group) Recover() *Statement {
+ s := Recover()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Recover renders the recover built-in function.
+func (s *Statement) Recover() *Statement {
+ g := &Group{
+ close: ")",
+ items: []Code{},
+ multi: false,
+ name: "recover",
+ open: "recover(",
+ separator: ",",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// Bool renders the bool identifier.
+func Bool() *Statement {
+ return newStatement().Bool()
+}
+
+// Bool renders the bool identifier.
+func (g *Group) Bool() *Statement {
+ s := Bool()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Bool renders the bool identifier.
+func (s *Statement) Bool() *Statement {
+ t := token{
+ content: "bool",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Byte renders the byte identifier.
+func Byte() *Statement {
+ // notest
+ return newStatement().Byte()
+}
+
+// Byte renders the byte identifier.
+func (g *Group) Byte() *Statement {
+ // notest
+ s := Byte()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Byte renders the byte identifier.
+func (s *Statement) Byte() *Statement {
+ // notest
+ t := token{
+ content: "byte",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Complex64 renders the complex64 identifier.
+func Complex64() *Statement {
+ // notest
+ return newStatement().Complex64()
+}
+
+// Complex64 renders the complex64 identifier.
+func (g *Group) Complex64() *Statement {
+ // notest
+ s := Complex64()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Complex64 renders the complex64 identifier.
+func (s *Statement) Complex64() *Statement {
+ // notest
+ t := token{
+ content: "complex64",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Complex128 renders the complex128 identifier.
+func Complex128() *Statement {
+ // notest
+ return newStatement().Complex128()
+}
+
+// Complex128 renders the complex128 identifier.
+func (g *Group) Complex128() *Statement {
+ // notest
+ s := Complex128()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Complex128 renders the complex128 identifier.
+func (s *Statement) Complex128() *Statement {
+ // notest
+ t := token{
+ content: "complex128",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Error renders the error identifier.
+func Error() *Statement {
+ // notest
+ return newStatement().Error()
+}
+
+// Error renders the error identifier.
+func (g *Group) Error() *Statement {
+ // notest
+ s := Error()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Error renders the error identifier.
+func (s *Statement) Error() *Statement {
+ // notest
+ t := token{
+ content: "error",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Float32 renders the float32 identifier.
+func Float32() *Statement {
+ // notest
+ return newStatement().Float32()
+}
+
+// Float32 renders the float32 identifier.
+func (g *Group) Float32() *Statement {
+ // notest
+ s := Float32()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Float32 renders the float32 identifier.
+func (s *Statement) Float32() *Statement {
+ // notest
+ t := token{
+ content: "float32",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Float64 renders the float64 identifier.
+func Float64() *Statement {
+ // notest
+ return newStatement().Float64()
+}
+
+// Float64 renders the float64 identifier.
+func (g *Group) Float64() *Statement {
+ // notest
+ s := Float64()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Float64 renders the float64 identifier.
+func (s *Statement) Float64() *Statement {
+ // notest
+ t := token{
+ content: "float64",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Int renders the int identifier.
+func Int() *Statement {
+ // notest
+ return newStatement().Int()
+}
+
+// Int renders the int identifier.
+func (g *Group) Int() *Statement {
+ // notest
+ s := Int()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Int renders the int identifier.
+func (s *Statement) Int() *Statement {
+ // notest
+ t := token{
+ content: "int",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Int8 renders the int8 identifier.
+func Int8() *Statement {
+ // notest
+ return newStatement().Int8()
+}
+
+// Int8 renders the int8 identifier.
+func (g *Group) Int8() *Statement {
+ // notest
+ s := Int8()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Int8 renders the int8 identifier.
+func (s *Statement) Int8() *Statement {
+ // notest
+ t := token{
+ content: "int8",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Int16 renders the int16 identifier.
+func Int16() *Statement {
+ // notest
+ return newStatement().Int16()
+}
+
+// Int16 renders the int16 identifier.
+func (g *Group) Int16() *Statement {
+ // notest
+ s := Int16()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Int16 renders the int16 identifier.
+func (s *Statement) Int16() *Statement {
+ // notest
+ t := token{
+ content: "int16",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Int32 renders the int32 identifier.
+func Int32() *Statement {
+ // notest
+ return newStatement().Int32()
+}
+
+// Int32 renders the int32 identifier.
+func (g *Group) Int32() *Statement {
+ // notest
+ s := Int32()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Int32 renders the int32 identifier.
+func (s *Statement) Int32() *Statement {
+ // notest
+ t := token{
+ content: "int32",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Int64 renders the int64 identifier.
+func Int64() *Statement {
+ // notest
+ return newStatement().Int64()
+}
+
+// Int64 renders the int64 identifier.
+func (g *Group) Int64() *Statement {
+ // notest
+ s := Int64()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Int64 renders the int64 identifier.
+func (s *Statement) Int64() *Statement {
+ // notest
+ t := token{
+ content: "int64",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Rune renders the rune identifier.
+func Rune() *Statement {
+ // notest
+ return newStatement().Rune()
+}
+
+// Rune renders the rune identifier.
+func (g *Group) Rune() *Statement {
+ // notest
+ s := Rune()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Rune renders the rune identifier.
+func (s *Statement) Rune() *Statement {
+ // notest
+ t := token{
+ content: "rune",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// String renders the string identifier.
+func String() *Statement {
+ // notest
+ return newStatement().String()
+}
+
+// String renders the string identifier.
+func (g *Group) String() *Statement {
+ // notest
+ s := String()
+ g.items = append(g.items, s)
+ return s
+}
+
+// String renders the string identifier.
+func (s *Statement) String() *Statement {
+ // notest
+ t := token{
+ content: "string",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Uint renders the uint identifier.
+func Uint() *Statement {
+ // notest
+ return newStatement().Uint()
+}
+
+// Uint renders the uint identifier.
+func (g *Group) Uint() *Statement {
+ // notest
+ s := Uint()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Uint renders the uint identifier.
+func (s *Statement) Uint() *Statement {
+ // notest
+ t := token{
+ content: "uint",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Uint8 renders the uint8 identifier.
+func Uint8() *Statement {
+ // notest
+ return newStatement().Uint8()
+}
+
+// Uint8 renders the uint8 identifier.
+func (g *Group) Uint8() *Statement {
+ // notest
+ s := Uint8()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Uint8 renders the uint8 identifier.
+func (s *Statement) Uint8() *Statement {
+ // notest
+ t := token{
+ content: "uint8",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Uint16 renders the uint16 identifier.
+func Uint16() *Statement {
+ // notest
+ return newStatement().Uint16()
+}
+
+// Uint16 renders the uint16 identifier.
+func (g *Group) Uint16() *Statement {
+ // notest
+ s := Uint16()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Uint16 renders the uint16 identifier.
+func (s *Statement) Uint16() *Statement {
+ // notest
+ t := token{
+ content: "uint16",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Uint32 renders the uint32 identifier.
+func Uint32() *Statement {
+ // notest
+ return newStatement().Uint32()
+}
+
+// Uint32 renders the uint32 identifier.
+func (g *Group) Uint32() *Statement {
+ // notest
+ s := Uint32()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Uint32 renders the uint32 identifier.
+func (s *Statement) Uint32() *Statement {
+ // notest
+ t := token{
+ content: "uint32",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Uint64 renders the uint64 identifier.
+func Uint64() *Statement {
+ // notest
+ return newStatement().Uint64()
+}
+
+// Uint64 renders the uint64 identifier.
+func (g *Group) Uint64() *Statement {
+ // notest
+ s := Uint64()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Uint64 renders the uint64 identifier.
+func (s *Statement) Uint64() *Statement {
+ // notest
+ t := token{
+ content: "uint64",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Uintptr renders the uintptr identifier.
+func Uintptr() *Statement {
+ // notest
+ return newStatement().Uintptr()
+}
+
+// Uintptr renders the uintptr identifier.
+func (g *Group) Uintptr() *Statement {
+ // notest
+ s := Uintptr()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Uintptr renders the uintptr identifier.
+func (s *Statement) Uintptr() *Statement {
+ // notest
+ t := token{
+ content: "uintptr",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// True renders the true identifier.
+func True() *Statement {
+ // notest
+ return newStatement().True()
+}
+
+// True renders the true identifier.
+func (g *Group) True() *Statement {
+ // notest
+ s := True()
+ g.items = append(g.items, s)
+ return s
+}
+
+// True renders the true identifier.
+func (s *Statement) True() *Statement {
+ // notest
+ t := token{
+ content: "true",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// False renders the false identifier.
+func False() *Statement {
+ // notest
+ return newStatement().False()
+}
+
+// False renders the false identifier.
+func (g *Group) False() *Statement {
+ // notest
+ s := False()
+ g.items = append(g.items, s)
+ return s
+}
+
+// False renders the false identifier.
+func (s *Statement) False() *Statement {
+ // notest
+ t := token{
+ content: "false",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Iota renders the iota identifier.
+func Iota() *Statement {
+ // notest
+ return newStatement().Iota()
+}
+
+// Iota renders the iota identifier.
+func (g *Group) Iota() *Statement {
+ // notest
+ s := Iota()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Iota renders the iota identifier.
+func (s *Statement) Iota() *Statement {
+ // notest
+ t := token{
+ content: "iota",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Nil renders the nil identifier.
+func Nil() *Statement {
+ // notest
+ return newStatement().Nil()
+}
+
+// Nil renders the nil identifier.
+func (g *Group) Nil() *Statement {
+ // notest
+ s := Nil()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Nil renders the nil identifier.
+func (s *Statement) Nil() *Statement {
+ // notest
+ t := token{
+ content: "nil",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Err renders the err identifier.
+func Err() *Statement {
+ // notest
+ return newStatement().Err()
+}
+
+// Err renders the err identifier.
+func (g *Group) Err() *Statement {
+ // notest
+ s := Err()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Err renders the err identifier.
+func (s *Statement) Err() *Statement {
+ // notest
+ t := token{
+ content: "err",
+ typ: identifierToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Break renders the break keyword.
+func Break() *Statement {
+ // notest
+ return newStatement().Break()
+}
+
+// Break renders the break keyword.
+func (g *Group) Break() *Statement {
+ // notest
+ s := Break()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Break renders the break keyword.
+func (s *Statement) Break() *Statement {
+ // notest
+ t := token{
+ content: "break",
+ typ: keywordToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Default renders the default keyword.
+func Default() *Statement {
+ // notest
+ return newStatement().Default()
+}
+
+// Default renders the default keyword.
+func (g *Group) Default() *Statement {
+ // notest
+ s := Default()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Default renders the default keyword.
+func (s *Statement) Default() *Statement {
+ // notest
+ t := token{
+ content: "default",
+ typ: keywordToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Func renders the func keyword.
+func Func() *Statement {
+ // notest
+ return newStatement().Func()
+}
+
+// Func renders the func keyword.
+func (g *Group) Func() *Statement {
+ // notest
+ s := Func()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Func renders the func keyword.
+func (s *Statement) Func() *Statement {
+ // notest
+ t := token{
+ content: "func",
+ typ: keywordToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Select renders the select keyword.
+func Select() *Statement {
+ // notest
+ return newStatement().Select()
+}
+
+// Select renders the select keyword.
+func (g *Group) Select() *Statement {
+ // notest
+ s := Select()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Select renders the select keyword.
+func (s *Statement) Select() *Statement {
+ // notest
+ t := token{
+ content: "select",
+ typ: keywordToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Chan renders the chan keyword.
+func Chan() *Statement {
+ // notest
+ return newStatement().Chan()
+}
+
+// Chan renders the chan keyword.
+func (g *Group) Chan() *Statement {
+ // notest
+ s := Chan()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Chan renders the chan keyword.
+func (s *Statement) Chan() *Statement {
+ // notest
+ t := token{
+ content: "chan",
+ typ: keywordToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Else renders the else keyword.
+func Else() *Statement {
+ // notest
+ return newStatement().Else()
+}
+
+// Else renders the else keyword.
+func (g *Group) Else() *Statement {
+ // notest
+ s := Else()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Else renders the else keyword.
+func (s *Statement) Else() *Statement {
+ // notest
+ t := token{
+ content: "else",
+ typ: keywordToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Const renders the const keyword.
+func Const() *Statement {
+ // notest
+ return newStatement().Const()
+}
+
+// Const renders the const keyword.
+func (g *Group) Const() *Statement {
+ // notest
+ s := Const()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Const renders the const keyword.
+func (s *Statement) Const() *Statement {
+ // notest
+ t := token{
+ content: "const",
+ typ: keywordToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Fallthrough renders the fallthrough keyword.
+func Fallthrough() *Statement {
+ // notest
+ return newStatement().Fallthrough()
+}
+
+// Fallthrough renders the fallthrough keyword.
+func (g *Group) Fallthrough() *Statement {
+ // notest
+ s := Fallthrough()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Fallthrough renders the fallthrough keyword.
+func (s *Statement) Fallthrough() *Statement {
+ // notest
+ t := token{
+ content: "fallthrough",
+ typ: keywordToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Type renders the type keyword.
+func Type() *Statement {
+ // notest
+ return newStatement().Type()
+}
+
+// Type renders the type keyword.
+func (g *Group) Type() *Statement {
+ // notest
+ s := Type()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Type renders the type keyword.
+func (s *Statement) Type() *Statement {
+ // notest
+ t := token{
+ content: "type",
+ typ: keywordToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Continue renders the continue keyword.
+func Continue() *Statement {
+ // notest
+ return newStatement().Continue()
+}
+
+// Continue renders the continue keyword.
+func (g *Group) Continue() *Statement {
+ // notest
+ s := Continue()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Continue renders the continue keyword.
+func (s *Statement) Continue() *Statement {
+ // notest
+ t := token{
+ content: "continue",
+ typ: keywordToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Var renders the var keyword.
+func Var() *Statement {
+ // notest
+ return newStatement().Var()
+}
+
+// Var renders the var keyword.
+func (g *Group) Var() *Statement {
+ // notest
+ s := Var()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Var renders the var keyword.
+func (s *Statement) Var() *Statement {
+ // notest
+ t := token{
+ content: "var",
+ typ: keywordToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Goto renders the goto keyword.
+func Goto() *Statement {
+ // notest
+ return newStatement().Goto()
+}
+
+// Goto renders the goto keyword.
+func (g *Group) Goto() *Statement {
+ // notest
+ s := Goto()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Goto renders the goto keyword.
+func (s *Statement) Goto() *Statement {
+ // notest
+ t := token{
+ content: "goto",
+ typ: keywordToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Defer renders the defer keyword.
+func Defer() *Statement {
+ // notest
+ return newStatement().Defer()
+}
+
+// Defer renders the defer keyword.
+func (g *Group) Defer() *Statement {
+ // notest
+ s := Defer()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Defer renders the defer keyword.
+func (s *Statement) Defer() *Statement {
+ // notest
+ t := token{
+ content: "defer",
+ typ: keywordToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Go renders the go keyword.
+func Go() *Statement {
+ // notest
+ return newStatement().Go()
+}
+
+// Go renders the go keyword.
+func (g *Group) Go() *Statement {
+ // notest
+ s := Go()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Go renders the go keyword.
+func (s *Statement) Go() *Statement {
+ // notest
+ t := token{
+ content: "go",
+ typ: keywordToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Range renders the range keyword.
+func Range() *Statement {
+ // notest
+ return newStatement().Range()
+}
+
+// Range renders the range keyword.
+func (g *Group) Range() *Statement {
+ // notest
+ s := Range()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Range renders the range keyword.
+func (s *Statement) Range() *Statement {
+ // notest
+ t := token{
+ content: "range",
+ typ: keywordToken,
+ }
+ *s = append(*s, t)
+ return s
+}
diff --git a/vendor/github.com/dave/jennifer/jen/generated_test.go b/vendor/github.com/dave/jennifer/jen/generated_test.go
new file mode 100644
index 00000000..fce14c70
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/generated_test.go
@@ -0,0 +1,808 @@
+package jen_test
+
+import (
+ "testing"
+
+ . "github.com/dave/jennifer/jen"
+)
+
+var gencases = []tc{
+ {
+ desc: `bool group`,
+ code: BlockFunc(func(g *Group) {
+ g.Bool()
+ }),
+ expect: `{
+ bool
+ }`,
+ },
+ {
+ desc: `recover func`,
+ code: Recover(),
+ expect: `recover()`,
+ },
+ {
+ desc: `recover statement`,
+ code: Null().Recover(),
+ expect: `recover()`,
+ },
+ {
+ desc: `recover group`,
+ code: BlockFunc(func(g *Group) {
+ g.Recover()
+ }),
+ expect: `{
+ recover()
+ }`,
+ },
+ {
+ desc: `real func`,
+ code: Real(Id("a")),
+ expect: `real(a)`,
+ },
+ {
+ desc: `real statement`,
+ code: Null().Real(Id("a")),
+ expect: `real(a)`,
+ },
+ {
+ desc: `real group`,
+ code: BlockFunc(func(g *Group) {
+ g.Real(Id("a"))
+ }),
+ expect: `{
+ real(a)
+ }`,
+ },
+ {
+ desc: `printlnfunc func`,
+ code: PrintlnFunc(func(g *Group) { g.Id("a") }),
+ expect: `println(a)`,
+ },
+ {
+ desc: `printlnfunc statement`,
+ code: Null().PrintlnFunc(func(g *Group) { g.Id("a") }),
+ expect: `println(a)`,
+ },
+ {
+ desc: `printlnfunc group`,
+ code: BlockFunc(func(bg *Group) {
+ bg.PrintlnFunc(func(pg *Group) { pg.Id("a") })
+ }),
+ expect: `{
+ println(a)
+ }`,
+ },
+ {
+ desc: `println func`,
+ code: Println(Id("a")),
+ expect: `println(a)`,
+ },
+ {
+ desc: `println statement`,
+ code: Null().Println(Id("a")),
+ expect: `println(a)`,
+ },
+ {
+ desc: `println group`,
+ code: BlockFunc(func(g *Group) {
+ g.Println(Id("a"))
+ }),
+ expect: `{
+ println(a)
+ }`,
+ },
+ {
+ desc: `printfunc func`,
+ code: PrintFunc(func(g *Group) { g.Id("a") }),
+ expect: `print(a)`,
+ },
+ {
+ desc: `printfunc statement`,
+ code: Null().PrintFunc(func(g *Group) { g.Id("a") }),
+ expect: `print(a)`,
+ },
+ {
+ desc: `printfunc group`,
+ code: BlockFunc(func(bg *Group) {
+ bg.PrintFunc(func(pg *Group) { pg.Id("a") })
+ }),
+ expect: `{
+ print(a)
+ }`,
+ },
+ {
+ desc: `print func`,
+ code: Print(Id("a")),
+ expect: `print(a)`,
+ },
+ {
+ desc: `print statement`,
+ code: Null().Print(Id("a")),
+ expect: `print(a)`,
+ },
+ {
+ desc: `print group`,
+ code: BlockFunc(func(g *Group) {
+ g.Print(Id("a"))
+ }),
+ expect: `{
+ print(a)
+ }`,
+ },
+ {
+ desc: `panic func`,
+ code: Panic(Id("a")),
+ expect: `panic(a)`,
+ },
+ {
+ desc: `panic statement`,
+ code: Null().Panic(Id("a")),
+ expect: `panic(a)`,
+ },
+ {
+ desc: `panic group`,
+ code: BlockFunc(func(g *Group) {
+ g.Panic(Id("a"))
+ }),
+ expect: `{
+ panic(a)
+ }`,
+ },
+ {
+ desc: `new func`,
+ code: New(Id("a")),
+ expect: `new(a)`,
+ },
+ {
+ desc: `new statement`,
+ code: Id("a").Op(":=").New(Id("a")),
+ expect: `a := new(a)`,
+ },
+ {
+ desc: `new group`,
+ code: BlockFunc(func(g *Group) {
+ g.New(Id("a"))
+ }),
+ expect: `{
+ new(a)
+ }`,
+ },
+ {
+ desc: `make func`,
+ code: Make(Id("a")),
+ expect: `make(a)`,
+ },
+ {
+ desc: `make statement`,
+ code: Id("a").Op(":=").Make(Id("a")),
+ expect: `a := make(a)`,
+ },
+ {
+ desc: `make group`,
+ code: BlockFunc(func(g *Group) {
+ g.Make(Id("a"))
+ }),
+ expect: `{
+ make(a)
+ }`,
+ },
+ {
+ desc: `len func`,
+ code: Len(Id("a")),
+ expect: `len(a)`,
+ },
+ {
+ desc: `len statement`,
+ code: Id("a").Op(":=").Len(Id("a")),
+ expect: `a := len(a)`,
+ },
+ {
+ desc: `len group`,
+ code: BlockFunc(func(g *Group) {
+ g.Len(Id("a"))
+ }),
+ expect: `{
+ len(a)
+ }`,
+ },
+ {
+ desc: `imag func`,
+ code: Imag(Id("a")),
+ expect: `imag(a)`,
+ },
+ {
+ desc: `imag statement`,
+ code: Id("a").Op(":=").Imag(Id("a")),
+ expect: `a := imag(a)`,
+ },
+ {
+ desc: `imag group`,
+ code: BlockFunc(func(g *Group) {
+ g.Imag(Id("a"))
+ }),
+ expect: `{
+ imag(a)
+ }`,
+ },
+ {
+ desc: `delete func`,
+ code: Delete(Id("a"), Id("b")),
+ expect: `delete(a, b)`,
+ },
+ {
+ desc: `delete statement`,
+ code: Null().Delete(Id("a"), Id("b")),
+ expect: `delete(a, b)`,
+ },
+ {
+ desc: `delete group`,
+ code: BlockFunc(func(g *Group) {
+ g.Delete(Id("a"), Id("b"))
+ }),
+ expect: `{
+ delete(a, b)
+ }`,
+ },
+ {
+ desc: `copy func`,
+ code: Copy(Id("a"), Id("b")),
+ expect: `copy(a, b)`,
+ },
+ {
+ desc: `copy statement`,
+ code: Id("a").Op(":=").Copy(Id("a"), Id("b")),
+ expect: `a := copy(a, b)`,
+ },
+ {
+ desc: `copy group`,
+ code: BlockFunc(func(g *Group) {
+ g.Copy(Id("a"), Id("b"))
+ }),
+ expect: `{
+ copy(a, b)
+ }`,
+ },
+ {
+ desc: `complex func`,
+ code: Complex(Id("a"), Id("b")),
+ expect: `complex(a, b)`,
+ },
+ {
+ desc: `complex statement`,
+ code: Id("a").Op(":=").Complex(Id("a"), Id("b")),
+ expect: `a := complex(a, b)`,
+ },
+ {
+ desc: `complex group`,
+ code: BlockFunc(func(g *Group) {
+ g.Complex(Id("a"), Id("b"))
+ }),
+ expect: `{
+ complex(a, b)
+ }`,
+ },
+ {
+ desc: `close group`,
+ code: BlockFunc(func(g *Group) { g.Close(Id("a")) }),
+ expect: `{
+ close(a)
+ }`,
+ },
+ {
+ desc: `cap func`,
+ code: Cap(Id("a")),
+ expect: `cap(a)`,
+ },
+ {
+ desc: `cap statement`,
+ code: Id("a").Op(":=").Cap(Id("b")),
+ expect: `a := cap(b)`,
+ },
+ {
+ desc: `cap group`,
+ code: BlockFunc(func(g *Group) {
+ g.Cap(Id("a"))
+ }),
+ expect: `{
+ cap(a)
+ }`,
+ },
+ {
+ desc: `append group`,
+ code: BlockFunc(func(g *Group) {
+ g.Append(Id("a"))
+ }),
+ expect: `{
+ append(a)
+ }`,
+ },
+ {
+ desc: `appendfunc statement`,
+ code: Id("a").Op("=").AppendFunc(func(ag *Group) { ag.Id("a") }),
+ expect: `a = append(a)`,
+ },
+ {
+ desc: `appendfunc func`,
+ code: AppendFunc(func(ag *Group) { ag.Id("a") }),
+ expect: `append(a)`,
+ },
+ {
+ desc: `appendfunc group`,
+ code: BlockFunc(func(bg *Group) {
+ bg.AppendFunc(func(ag *Group) { ag.Id("a") })
+ }),
+ expect: `{
+ append(a)
+ }`,
+ },
+ {
+ desc: `casefunc group`,
+ code: Switch().BlockFunc(func(g *Group) {
+ g.CaseFunc(func(g *Group) { g.Id("a") }).Block()
+ }),
+ expect: `switch {
+ case a:
+ }`,
+ },
+ {
+ desc: `case group`,
+ code: Switch().BlockFunc(func(g *Group) {
+ g.Case(Id("a")).Block()
+ }),
+ expect: `switch {
+ case a:
+ }`,
+ },
+ {
+ desc: `structfunc statement`,
+ code: Id("a").Op(":=").StructFunc(func(g *Group) {}).Values(),
+ expect: `a := struct{}{}`,
+ },
+ {
+ desc: `structfunc group`,
+ // Don't do this! ListFunc used to kludge Group.Struct usage
+ // without syntax error.
+ code: Id("a").Op(":=").ListFunc(func(g *Group) { g.StructFunc(func(g *Group) {}) }).Values(),
+ expect: `a := struct{}{}`,
+ },
+ {
+ desc: `structfunc func`,
+ code: Id("a").Op(":=").Add(StructFunc(func(g *Group) {})).Values(),
+ expect: `a := struct{}{}`,
+ },
+ {
+ desc: `struct group`,
+ // Don't do this! ListFunc used to kludge Group.Struct usage
+ // without syntax error.
+ code: Id("a").Op(":=").ListFunc(func(g *Group) { g.Struct() }).Values(),
+ expect: `a := struct{}{}`,
+ },
+ {
+ desc: `struct func`,
+ code: Id("a").Op(":=").Add(Struct()).Values(),
+ expect: `a := struct{}{}`,
+ },
+ {
+ desc: `interfacefunc func`,
+ code: Id("a").Assert(InterfaceFunc(func(g *Group) {
+ g.Id("a").Call().Int()
+ g.Id("b").Call().Int()
+ })),
+ expect: `a.(interface{
+ a() int
+ b() int
+ })`,
+ },
+ {
+ desc: `interfacefunc statement`,
+ code: Id("a").Assert(Null().InterfaceFunc(func(g *Group) {
+ g.Id("a").Call().Int()
+ g.Id("b").Call().Int()
+ })),
+ expect: `a.(interface{
+ a() int
+ b() int
+ })`,
+ },
+ {
+ desc: `interfacefunc group`,
+ // Don't do this! ListFunc used to kludge Group.InterfaceFunc usage
+ // without syntax error.
+ code: Id("a").Assert(ListFunc(func(lg *Group) {
+ lg.InterfaceFunc(func(ig *Group) {
+ ig.Id("a").Call().Int()
+ ig.Id("b").Call().Int()
+ })
+ })),
+ expect: `a.(interface{
+ a() int
+ b() int
+ })`,
+ },
+ {
+ desc: `interface func`,
+ code: Interface().Parens(Id("a")),
+ expect: `interface{}(a)`,
+ },
+ {
+ desc: `interface group`,
+ code: BlockFunc(func(g *Group) {
+ g.Interface().Parens(Id("a"))
+ }),
+ expect: `{
+ interface{}(a)
+ }`,
+ },
+ {
+ desc: `interface statement`,
+ code: Null().Interface().Parens(Id("a")),
+ expect: `interface{}(a)`,
+ },
+ {
+ desc: `switchfunc func`,
+ code: SwitchFunc(func(rg *Group) {
+ rg.Id("a")
+ }).Block(),
+ expect: `switch a {}`,
+ },
+ {
+ desc: `switchfunc statement`,
+ code: Null().SwitchFunc(func(rg *Group) {
+ rg.Id("a")
+ }).Block(),
+ expect: `switch a {
+ }`,
+ },
+ {
+ desc: `switchfunc group`,
+ code: BlockFunc(func(bg *Group) {
+ bg.SwitchFunc(func(rg *Group) {
+ rg.Id("a")
+ }).Block()
+ }),
+ expect: `{
+ switch a {
+ }
+ }`,
+ },
+ {
+ desc: `switch group`,
+ code: BlockFunc(func(bg *Group) {
+ bg.Switch().Block()
+ }),
+ expect: `{
+ switch {
+ }
+ }`,
+ },
+ {
+ desc: `forfunc func`,
+ code: ForFunc(func(rg *Group) {
+ rg.Id("a")
+ }).Block(),
+ expect: `for a {}`,
+ },
+ {
+ desc: `forfunc statement`,
+ code: Null().ForFunc(func(rg *Group) {
+ rg.Id("a")
+ }).Block(),
+ expect: `for a {
+ }`,
+ },
+ {
+ desc: `forfunc group`,
+ code: BlockFunc(func(bg *Group) {
+ bg.ForFunc(func(rg *Group) {
+ rg.Id("a")
+ }).Block()
+ }),
+ expect: `{
+ for a {
+ }
+ }`,
+ },
+ {
+ desc: `for group`,
+ code: BlockFunc(func(g *Group) {
+ g.For(Id("a")).Block()
+ }),
+ expect: `{
+ for a {}
+ }`,
+ },
+ {
+ desc: `returnfunc func`,
+ code: ReturnFunc(func(rg *Group) {
+ rg.Lit(1)
+ rg.Lit(2)
+ }),
+ expect: `return 1, 2`,
+ },
+ {
+ desc: `returnfunc statement`,
+ code: Empty().ReturnFunc(func(rg *Group) {
+ rg.Lit(1)
+ rg.Lit(2)
+ }),
+ expect: `return 1, 2`,
+ },
+ {
+ desc: `returnfunc group`,
+ code: BlockFunc(func(bg *Group) {
+ bg.ReturnFunc(func(rg *Group) {
+ rg.Lit(1)
+ rg.Lit(2)
+ })
+ }),
+ expect: `{
+ return 1, 2
+ }`,
+ },
+ {
+ desc: `return group`,
+ code: BlockFunc(func(g *Group) {
+ g.Return()
+ }),
+ expect: `{
+ return
+ }`,
+ },
+ {
+ desc: `iffunc group`,
+ code: BlockFunc(func(bg *Group) {
+ bg.IfFunc(func(ig *Group) {
+ ig.Id("a")
+ }).Block()
+ }),
+ expect: `{
+ if a {}
+ }`,
+ },
+ {
+ desc: `iffunc func`,
+ code: IfFunc(func(ig *Group) {
+ ig.Id("a")
+ }).Block(),
+ expect: `if a {}`,
+ },
+ {
+ desc: `iffunc statement`,
+ code: Null().IfFunc(func(ig *Group) {
+ ig.Id("a")
+ }).Block(),
+ expect: `if a {}`,
+ },
+ {
+ desc: `if group`,
+ code: BlockFunc(func(g *Group) { g.If(Id("a")).Block() }),
+ expect: `{
+ if a {}
+ }`,
+ },
+ {
+ desc: `map group`,
+ code: BlockFunc(func(g *Group) { g.Map(Int()).Int().Values(Dict{Lit(1): Lit(1)}) }),
+ expect: `{
+ map[int]int{1:1}
+ }`,
+ },
+ {
+ desc: `assert group`,
+ // Don't do this! ListFunc used to kludge Group.Assert usage without
+ // syntax error.
+ code: Id("a").ListFunc(func(g *Group) { g.Assert(Id("b")) }),
+ expect: `a.(b)`,
+ },
+ {
+ desc: `assert func`,
+ code: Id("a").Add(Assert(Id("b"))),
+ expect: `a.(b)`,
+ },
+ {
+ desc: `paramsfunc group`,
+ // Don't do this! ListFunc used to kludge Group.ParamsFunc usage without
+ // syntax error.
+ code: Id("a").ListFunc(func(lg *Group) { lg.ParamsFunc(func(cg *Group) { cg.Lit(1) }) }),
+ expect: `a(1)`,
+ },
+ {
+ desc: `paramsfunc func`,
+ code: Id("a").Add(ParamsFunc(func(g *Group) { g.Lit(1) })),
+ expect: `a(1)`,
+ },
+ {
+ desc: `paramsfunc statement`,
+ code: Id("a").ParamsFunc(func(g *Group) { g.Lit(1) }),
+ expect: `a(1)`,
+ },
+ {
+ desc: `params group`,
+ // Don't do this! ListFunc used to kludge Group.Params usage without
+ // syntax error.
+ code: Id("a").ListFunc(func(g *Group) { g.Params(Lit(1)) }),
+ expect: `a(1)`,
+ },
+ {
+ desc: `params func`,
+ code: Id("a").Add(Params(Lit(1))),
+ expect: `a(1)`,
+ },
+ {
+ desc: `callfunc group`,
+ // Don't do this! ListFunc used to kludge Group.CallFunc usage without
+ // syntax error.
+ code: Id("a").ListFunc(func(lg *Group) { lg.CallFunc(func(cg *Group) { cg.Lit(1) }) }),
+ expect: `a(1)`,
+ },
+ {
+ desc: `callfunc func`,
+ code: Id("a").Add(CallFunc(func(g *Group) { g.Lit(1) })),
+ expect: `a(1)`,
+ },
+ {
+ desc: `call group`,
+ // Don't do this! ListFunc used to kludge Group.Call usage without
+ // syntax error.
+ code: Id("a").ListFunc(func(g *Group) { g.Call(Lit(1)) }),
+ expect: `a(1)`,
+ },
+ {
+ desc: `call func`,
+ code: Id("a").Add(Call(Lit(1))),
+ expect: `a(1)`,
+ },
+ {
+ desc: `defsfunc statement`,
+ code: Const().DefsFunc(func(g *Group) { g.Id("a").Op("=").Lit(1) }),
+ expect: `const (
+ a = 1
+ )`,
+ },
+ {
+ desc: `defsfunc func`,
+ code: Const().Add(DefsFunc(func(g *Group) { g.Id("a").Op("=").Lit(1) })),
+ expect: `const (
+ a = 1
+ )`,
+ },
+ {
+ desc: `defsfunc group`,
+ // Don't do this! ListFunc used to kludge Group.DefsFunc usage without
+ // syntax error.
+ code: Const().ListFunc(func(lg *Group) { lg.DefsFunc(func(dg *Group) { dg.Id("a").Op("=").Lit(1) }) }),
+ expect: `const (
+ a = 1
+ )`,
+ },
+ {
+ desc: `defs group`,
+ // Don't do this! ListFunc used to kludge Group.Defs usage without
+ // syntax error.
+ code: Const().ListFunc(func(g *Group) { g.Defs(Id("a").Op("=").Lit(1)) }),
+ expect: `const (
+ a = 1
+ )`,
+ },
+ {
+ desc: `defs func`,
+ code: Const().Add(Defs(Id("a").Op("=").Lit(1))),
+ expect: `const (
+ a = 1
+ )`,
+ },
+ {
+ desc: `blockfunc group`,
+ code: BlockFunc(func(g *Group) { g.BlockFunc(func(g *Group) {}) }),
+ expect: `{{}}`,
+ },
+ {
+ desc: `block group`,
+ code: BlockFunc(func(g *Group) { g.Block() }),
+ expect: `{{}}`,
+ },
+ {
+ desc: `indexfunc group`,
+ code: BlockFunc(func(g *Group) { g.IndexFunc(func(g *Group) { g.Lit(1) }).Int().Values(Lit(1)) }),
+ expect: `{[1]int{1}}`,
+ },
+ {
+ desc: `indexfunc statement`,
+ code: Id("a").IndexFunc(func(g *Group) { g.Lit(1) }),
+ expect: `a[1]`,
+ },
+ {
+ desc: `indexfunc func`,
+ code: Id("a").Add(IndexFunc(func(g *Group) { g.Lit(1) })),
+ expect: `a[1]`,
+ },
+ {
+ desc: `index group`,
+ code: BlockFunc(func(g *Group) { g.Index(Lit(1)).Int().Values(Lit(1)) }),
+ expect: `{[1]int{1}}`,
+ },
+ {
+ desc: `index func`,
+ code: Id("a").Add(Index(Lit(1))),
+ expect: `a[1]`,
+ },
+ {
+ desc: `valuesfunc func`,
+ code: ValuesFunc(func(vg *Group) {
+ vg.Lit(1)
+ }),
+ expect: `{1}`,
+ },
+ {
+ desc: `valuesfunc group`,
+ code: BlockFunc(func(bg *Group) {
+ bg.ValuesFunc(func(vg *Group) {
+ vg.Lit(1)
+ })
+ }),
+ expect: `{
+ {1}
+ }`,
+ },
+ {
+ desc: `values group`,
+ code: BlockFunc(func(g *Group) {
+ g.Values(Lit(1))
+ }),
+ expect: `{
+ {1}
+ }`,
+ },
+ {
+ desc: `listfunc statement`,
+ code: Add(Null()).ListFunc(func(lg *Group) {
+ lg.Id("a")
+ lg.Id("b")
+ }).Op("=").Id("c"),
+ expect: `a, b = c`,
+ },
+ {
+ desc: `listfunc func`,
+ code: ListFunc(func(lg *Group) {
+ lg.Id("a")
+ lg.Id("b")
+ }).Op("=").Id("c"),
+ expect: `a, b = c`,
+ },
+ {
+ desc: `listfunc group`,
+ code: BlockFunc(func(bg *Group) {
+ bg.ListFunc(func(lg *Group) {
+ lg.Id("a")
+ lg.Id("b")
+ }).Op("=").Id("c")
+ }),
+ expect: `{
+ a, b = c
+ }`,
+ },
+ {
+ desc: `list group`,
+ code: BlockFunc(func(g *Group) { g.List(Id("a"), Id("b")).Op("=").Id("c") }),
+ expect: `{
+ a, b = c
+ }`,
+ },
+ {
+ desc: `parens func`,
+ code: Parens(Lit(1)),
+ expect: `(1)`,
+ },
+ {
+ desc: `parens group`,
+ code: BlockFunc(func(g *Group) { g.Parens(Lit(1)) }),
+ expect: `{
+ (1)
+ }`,
+ },
+}
+
+func TestGen(t *testing.T) {
+ caseTester(t, gencases)
+}
diff --git a/vendor/github.com/dave/jennifer/jen/group.go b/vendor/github.com/dave/jennifer/jen/group.go
new file mode 100644
index 00000000..0b85c901
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/group.go
@@ -0,0 +1,147 @@
+package jen
+
+import (
+ "bytes"
+ "fmt"
+ "go/format"
+ "io"
+)
+
+// Group represents a list of Code items, separated by tokens with an optional
+// open and close token.
+type Group struct {
+ name string
+ items []Code
+ open string
+ close string
+ separator string
+ multi bool
+}
+
+func (g *Group) isNull(f *File) bool {
+ if g == nil {
+ return true
+ }
+ if g.open != "" || g.close != "" {
+ return false
+ }
+ for _, c := range g.items {
+ if !c.isNull(f) {
+ return false
+ }
+ }
+ return true
+}
+
+func (g *Group) render(f *File, w io.Writer, s *Statement) error {
+ if g.name == "block" && s != nil {
+ // Special CaseBlock format for then the previous item in the statement
+ // is a Case group or the default keyword.
+ prev := s.previous(g)
+ grp, isGrp := prev.(*Group)
+ tkn, isTkn := prev.(token)
+ if isGrp && grp.name == "case" || isTkn && tkn.content == "default" {
+ g.open = ""
+ g.close = ""
+ }
+ }
+ if g.open != "" {
+ if _, err := w.Write([]byte(g.open)); err != nil {
+ return err
+ }
+ }
+ isNull, err := g.renderItems(f, w)
+ if err != nil {
+ return err
+ }
+ if !isNull && g.multi && g.close != "" {
+ // For multi-line blocks with a closing token, we insert a new line after the last item (but
+ // not if all items were null). This is to ensure that if the statement finishes with a comment,
+ // the closing token is not commented out.
+ s := "\n"
+ if g.separator == "," {
+ // We also insert add trailing comma if the separator was ",".
+ s = ",\n"
+ }
+ if _, err := w.Write([]byte(s)); err != nil {
+ return err
+ }
+ }
+ if g.close != "" {
+ if _, err := w.Write([]byte(g.close)); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (g *Group) renderItems(f *File, w io.Writer) (isNull bool, err error) {
+ first := true
+ for _, code := range g.items {
+ if pt, ok := code.(token); ok && pt.typ == packageToken {
+ // Special case for package tokens in Qual groups - for dot-imports, the package token
+ // will be null, so will not render and will not be registered in the imports block.
+ // This ensures all packageTokens that are rendered are registered.
+ f.register(pt.content.(string))
+ }
+ if code == nil || code.isNull(f) {
+ // Null() token produces no output but also
+ // no separator. Empty() token products no
+ // output but adds a separator.
+ continue
+ }
+ if g.name == "values" {
+ if _, ok := code.(Dict); ok && len(g.items) > 1 {
+ panic("Error in Values: if Dict is used, must be one item only")
+ }
+ }
+ if !first && g.separator != "" {
+ // The separator token is added before each non-null item, but not before the first item.
+ if _, err := w.Write([]byte(g.separator)); err != nil {
+ return false, err
+ }
+ }
+ if g.multi {
+ // For multi-line blocks, we insert a new line before each non-null item.
+ if _, err := w.Write([]byte("\n")); err != nil {
+ return false, err
+ }
+ }
+ if err := code.render(f, w, nil); err != nil {
+ return false, err
+ }
+ first = false
+ }
+ return first, nil
+}
+
+// Render renders the Group to the provided writer.
+func (g *Group) Render(writer io.Writer) error {
+ return g.RenderWithFile(writer, NewFile(""))
+}
+
+// GoString renders the Group for testing. Any error will cause a panic.
+func (g *Group) GoString() string {
+ buf := bytes.Buffer{}
+ if err := g.Render(&buf); err != nil {
+ panic(err)
+ }
+ return buf.String()
+}
+
+// RenderWithFile renders the Group to the provided writer, using imports from the provided file.
+func (g *Group) RenderWithFile(writer io.Writer, file *File) error {
+ buf := &bytes.Buffer{}
+ if err := g.render(file, buf, nil); err != nil {
+ return err
+ }
+ b, err := format.Source(buf.Bytes())
+ if err != nil {
+ return fmt.Errorf("Error %s while formatting source:\n%s", err, buf.String())
+ }
+ if _, err := writer.Write(b); err != nil {
+ return err
+ }
+ return nil
+}
+
diff --git a/vendor/github.com/dave/jennifer/jen/group_test.go b/vendor/github.com/dave/jennifer/jen/group_test.go
new file mode 100644
index 00000000..0e9489e4
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/group_test.go
@@ -0,0 +1,35 @@
+package jen_test
+
+import (
+ "bytes"
+ "testing"
+
+ . "github.com/dave/jennifer/jen"
+)
+
+func TestGroup_Render(t *testing.T) {
+ file := NewFile("main")
+ file.ImportAlias("fmt", "fmtalias")
+
+ var g *Group
+ BlockFunc(func(group *Group) {
+ g = group
+ })
+
+ g.Qual("fmt", "Errorf").Call(Lit("error"))
+
+ expect := `{
+ fmtalias.Errorf("error")
+}`
+
+ var got bytes.Buffer
+
+ err := g.RenderWithFile(&got, file)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if got.String() != expect {
+ t.Fatalf("Got: %v, expect: %v", got.String(), expect)
+ }
+}
diff --git a/vendor/github.com/dave/jennifer/jen/hints.go b/vendor/github.com/dave/jennifer/jen/hints.go
new file mode 100644
index 00000000..7bc307a6
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/hints.go
@@ -0,0 +1,273 @@
+// This file is generated - do not edit.
+
+package jen
+
+// standardLibraryHints contains package name hints
+var standardLibraryHints = map[string]string{
+ "archive/tar": "tar",
+ "archive/zip": "zip",
+ "bufio": "bufio",
+ "builtin": "builtin",
+ "bytes": "bytes",
+ "cmd/asm/internal/arch": "arch",
+ "cmd/asm/internal/asm": "asm",
+ "cmd/asm/internal/flags": "flags",
+ "cmd/asm/internal/lex": "lex",
+ "cmd/compile/internal/amd64": "amd64",
+ "cmd/compile/internal/arm": "arm",
+ "cmd/compile/internal/arm64": "arm64",
+ "cmd/compile/internal/gc": "gc",
+ "cmd/compile/internal/mips": "mips",
+ "cmd/compile/internal/mips64": "mips64",
+ "cmd/compile/internal/ppc64": "ppc64",
+ "cmd/compile/internal/s390x": "s390x",
+ "cmd/compile/internal/ssa": "ssa",
+ "cmd/compile/internal/syntax": "syntax",
+ "cmd/compile/internal/test": "test",
+ "cmd/compile/internal/types": "types",
+ "cmd/compile/internal/wasm": "wasm",
+ "cmd/compile/internal/x86": "x86",
+ "cmd/go/internal/base": "base",
+ "cmd/go/internal/bug": "bug",
+ "cmd/go/internal/cache": "cache",
+ "cmd/go/internal/cfg": "cfg",
+ "cmd/go/internal/clean": "clean",
+ "cmd/go/internal/cmdflag": "cmdflag",
+ "cmd/go/internal/dirhash": "dirhash",
+ "cmd/go/internal/doc": "doc",
+ "cmd/go/internal/envcmd": "envcmd",
+ "cmd/go/internal/fix": "fix",
+ "cmd/go/internal/fmtcmd": "fmtcmd",
+ "cmd/go/internal/generate": "generate",
+ "cmd/go/internal/get": "get",
+ "cmd/go/internal/help": "help",
+ "cmd/go/internal/imports": "imports",
+ "cmd/go/internal/list": "list",
+ "cmd/go/internal/load": "load",
+ "cmd/go/internal/modcmd": "modcmd",
+ "cmd/go/internal/modconv": "modconv",
+ "cmd/go/internal/modfetch": "modfetch",
+ "cmd/go/internal/modfetch/codehost": "codehost",
+ "cmd/go/internal/modfile": "modfile",
+ "cmd/go/internal/modget": "modget",
+ "cmd/go/internal/modinfo": "modinfo",
+ "cmd/go/internal/modload": "modload",
+ "cmd/go/internal/module": "module",
+ "cmd/go/internal/mvs": "mvs",
+ "cmd/go/internal/par": "par",
+ "cmd/go/internal/run": "run",
+ "cmd/go/internal/search": "search",
+ "cmd/go/internal/semver": "semver",
+ "cmd/go/internal/str": "str",
+ "cmd/go/internal/test": "test",
+ "cmd/go/internal/tool": "tool",
+ "cmd/go/internal/txtar": "txtar",
+ "cmd/go/internal/version": "version",
+ "cmd/go/internal/vet": "vet",
+ "cmd/go/internal/web": "web",
+ "cmd/go/internal/web2": "web2",
+ "cmd/go/internal/webtest": "webtest",
+ "cmd/go/internal/work": "work",
+ "cmd/internal/bio": "bio",
+ "cmd/internal/browser": "browser",
+ "cmd/internal/buildid": "buildid",
+ "cmd/internal/dwarf": "dwarf",
+ "cmd/internal/edit": "edit",
+ "cmd/internal/gcprog": "gcprog",
+ "cmd/internal/goobj": "goobj",
+ "cmd/internal/obj": "obj",
+ "cmd/internal/obj/arm": "arm",
+ "cmd/internal/obj/arm64": "arm64",
+ "cmd/internal/obj/mips": "mips",
+ "cmd/internal/obj/ppc64": "ppc64",
+ "cmd/internal/obj/s390x": "s390x",
+ "cmd/internal/obj/wasm": "wasm",
+ "cmd/internal/obj/x86": "x86",
+ "cmd/internal/objabi": "objabi",
+ "cmd/internal/objfile": "objfile",
+ "cmd/internal/src": "src",
+ "cmd/internal/sys": "sys",
+ "cmd/internal/test2json": "test2json",
+ "cmd/link/internal/amd64": "amd64",
+ "cmd/link/internal/arm": "arm",
+ "cmd/link/internal/arm64": "arm64",
+ "cmd/link/internal/ld": "ld",
+ "cmd/link/internal/loadelf": "loadelf",
+ "cmd/link/internal/loadmacho": "loadmacho",
+ "cmd/link/internal/loadpe": "loadpe",
+ "cmd/link/internal/mips": "mips",
+ "cmd/link/internal/mips64": "mips64",
+ "cmd/link/internal/objfile": "objfile",
+ "cmd/link/internal/ppc64": "ppc64",
+ "cmd/link/internal/s390x": "s390x",
+ "cmd/link/internal/sym": "sym",
+ "cmd/link/internal/wasm": "wasm",
+ "cmd/link/internal/x86": "x86",
+ "cmd/vet/internal/cfg": "cfg",
+ "cmd/vet/internal/whitelist": "whitelist",
+ "compress/bzip2": "bzip2",
+ "compress/flate": "flate",
+ "compress/gzip": "gzip",
+ "compress/lzw": "lzw",
+ "compress/zlib": "zlib",
+ "container/heap": "heap",
+ "container/list": "list",
+ "container/ring": "ring",
+ "context": "context",
+ "crypto": "crypto",
+ "crypto/aes": "aes",
+ "crypto/cipher": "cipher",
+ "crypto/des": "des",
+ "crypto/dsa": "dsa",
+ "crypto/ecdsa": "ecdsa",
+ "crypto/elliptic": "elliptic",
+ "crypto/hmac": "hmac",
+ "crypto/internal/randutil": "randutil",
+ "crypto/internal/subtle": "subtle",
+ "crypto/md5": "md5",
+ "crypto/rand": "rand",
+ "crypto/rc4": "rc4",
+ "crypto/rsa": "rsa",
+ "crypto/sha1": "sha1",
+ "crypto/sha256": "sha256",
+ "crypto/sha512": "sha512",
+ "crypto/subtle": "subtle",
+ "crypto/tls": "tls",
+ "crypto/x509": "x509",
+ "crypto/x509/pkix": "pkix",
+ "database/sql": "sql",
+ "database/sql/driver": "driver",
+ "debug/dwarf": "dwarf",
+ "debug/elf": "elf",
+ "debug/gosym": "gosym",
+ "debug/macho": "macho",
+ "debug/pe": "pe",
+ "debug/plan9obj": "plan9obj",
+ "encoding": "encoding",
+ "encoding/ascii85": "ascii85",
+ "encoding/asn1": "asn1",
+ "encoding/base32": "base32",
+ "encoding/base64": "base64",
+ "encoding/binary": "binary",
+ "encoding/csv": "csv",
+ "encoding/gob": "gob",
+ "encoding/hex": "hex",
+ "encoding/json": "json",
+ "encoding/pem": "pem",
+ "encoding/xml": "xml",
+ "errors": "errors",
+ "expvar": "expvar",
+ "flag": "flag",
+ "fmt": "fmt",
+ "go/ast": "ast",
+ "go/build": "build",
+ "go/constant": "constant",
+ "go/doc": "doc",
+ "go/format": "format",
+ "go/importer": "importer",
+ "go/internal/gccgoimporter": "gccgoimporter",
+ "go/internal/gcimporter": "gcimporter",
+ "go/internal/srcimporter": "srcimporter",
+ "go/parser": "parser",
+ "go/printer": "printer",
+ "go/scanner": "scanner",
+ "go/token": "token",
+ "go/types": "types",
+ "hash": "hash",
+ "hash/adler32": "adler32",
+ "hash/crc32": "crc32",
+ "hash/crc64": "crc64",
+ "hash/fnv": "fnv",
+ "html": "html",
+ "html/template": "template",
+ "image": "image",
+ "image/color": "color",
+ "image/color/palette": "palette",
+ "image/draw": "draw",
+ "image/gif": "gif",
+ "image/internal/imageutil": "imageutil",
+ "image/jpeg": "jpeg",
+ "image/png": "png",
+ "index/suffixarray": "suffixarray",
+ "internal/bytealg": "bytealg",
+ "internal/cpu": "cpu",
+ "internal/nettrace": "nettrace",
+ "internal/poll": "poll",
+ "internal/race": "race",
+ "internal/singleflight": "singleflight",
+ "internal/syscall/unix": "unix",
+ "internal/syscall/windows": "windows",
+ "internal/syscall/windows/registry": "registry",
+ "internal/syscall/windows/sysdll": "sysdll",
+ "internal/testenv": "testenv",
+ "internal/testlog": "testlog",
+ "internal/trace": "trace",
+ "io": "io",
+ "io/ioutil": "ioutil",
+ "log": "log",
+ "log/syslog": "syslog",
+ "math": "math",
+ "math/big": "big",
+ "math/bits": "bits",
+ "math/cmplx": "cmplx",
+ "math/rand": "rand",
+ "mime": "mime",
+ "mime/multipart": "multipart",
+ "mime/quotedprintable": "quotedprintable",
+ "net": "net",
+ "net/http": "http",
+ "net/http/cgi": "cgi",
+ "net/http/cookiejar": "cookiejar",
+ "net/http/fcgi": "fcgi",
+ "net/http/httptest": "httptest",
+ "net/http/httptrace": "httptrace",
+ "net/http/httputil": "httputil",
+ "net/http/internal": "internal",
+ "net/http/pprof": "pprof",
+ "net/internal/socktest": "socktest",
+ "net/mail": "mail",
+ "net/rpc": "rpc",
+ "net/rpc/jsonrpc": "jsonrpc",
+ "net/smtp": "smtp",
+ "net/textproto": "textproto",
+ "net/url": "url",
+ "os": "os",
+ "os/exec": "exec",
+ "os/signal": "signal",
+ "os/signal/internal/pty": "pty",
+ "os/user": "user",
+ "path": "path",
+ "path/filepath": "filepath",
+ "plugin": "plugin",
+ "reflect": "reflect",
+ "regexp": "regexp",
+ "regexp/syntax": "syntax",
+ "runtime": "runtime",
+ "runtime/cgo": "cgo",
+ "runtime/debug": "debug",
+ "runtime/internal/atomic": "atomic",
+ "runtime/internal/sys": "sys",
+ "runtime/pprof": "pprof",
+ "runtime/pprof/internal/profile": "profile",
+ "runtime/race": "race",
+ "runtime/trace": "trace",
+ "sort": "sort",
+ "strconv": "strconv",
+ "strings": "strings",
+ "sync": "sync",
+ "sync/atomic": "atomic",
+ "syscall": "syscall",
+ "testing": "testing",
+ "testing/internal/testdeps": "testdeps",
+ "testing/iotest": "iotest",
+ "testing/quick": "quick",
+ "text/scanner": "scanner",
+ "text/tabwriter": "tabwriter",
+ "text/template": "template",
+ "text/template/parse": "parse",
+ "time": "time",
+ "unicode": "unicode",
+ "unicode/utf16": "utf16",
+ "unicode/utf8": "utf8",
+ "unsafe": "unsafe",
+}
diff --git a/vendor/github.com/dave/jennifer/jen/jen.go b/vendor/github.com/dave/jennifer/jen/jen.go
new file mode 100644
index 00000000..4cf480a1
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/jen.go
@@ -0,0 +1,168 @@
+// Package jen is a code generator for Go
+package jen
+
+import (
+ "bytes"
+ "fmt"
+ "go/format"
+ "io"
+ "io/ioutil"
+ "sort"
+ "strconv"
+)
+
+// Code represents an item of code that can be rendered.
+type Code interface {
+ render(f *File, w io.Writer, s *Statement) error
+ isNull(f *File) bool
+}
+
+// Save renders the file and saves to the filename provided.
+func (f *File) Save(filename string) error {
+ // notest
+ buf := &bytes.Buffer{}
+ if err := f.Render(buf); err != nil {
+ return err
+ }
+ if err := ioutil.WriteFile(filename, buf.Bytes(), 0644); err != nil {
+ return err
+ }
+ return nil
+}
+
+// Render renders the file to the provided writer.
+func (f *File) Render(w io.Writer) error {
+ body := &bytes.Buffer{}
+ if err := f.render(f, body, nil); err != nil {
+ return err
+ }
+ source := &bytes.Buffer{}
+ if len(f.headers) > 0 {
+ for _, c := range f.headers {
+ if err := Comment(c).render(f, source, nil); err != nil {
+ return err
+ }
+ if _, err := fmt.Fprint(source, "\n"); err != nil {
+ return err
+ }
+ }
+ // Append an extra newline so that header comments don't get lumped in
+ // with package comments.
+ if _, err := fmt.Fprint(source, "\n"); err != nil {
+ return err
+ }
+ }
+ for _, c := range f.comments {
+ if err := Comment(c).render(f, source, nil); err != nil {
+ return err
+ }
+ if _, err := fmt.Fprint(source, "\n"); err != nil {
+ return err
+ }
+ }
+ if _, err := fmt.Fprintf(source, "package %s", f.name); err != nil {
+ return err
+ }
+ if f.CanonicalPath != "" {
+ if _, err := fmt.Fprintf(source, " // import %q", f.CanonicalPath); err != nil {
+ return err
+ }
+ }
+ if _, err := fmt.Fprint(source, "\n\n"); err != nil {
+ return err
+ }
+ if err := f.renderImports(source); err != nil {
+ return err
+ }
+ if _, err := source.Write(body.Bytes()); err != nil {
+ return err
+ }
+ formatted, err := format.Source(source.Bytes())
+ if err != nil {
+ return fmt.Errorf("Error %s while formatting source:\n%s", err, source.String())
+ }
+ if _, err := w.Write(formatted); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (f *File) renderImports(source io.Writer) error {
+
+ // Render the "C" import if it's been used in a `Qual`, `Anon` or if there's a preamble comment
+ hasCgo := f.imports["C"].name != "" || len(f.cgoPreamble) > 0
+
+ // Only separate the import from the main imports block if there's a preamble
+ separateCgo := hasCgo && len(f.cgoPreamble) > 0
+
+ filtered := map[string]importdef{}
+ for path, def := range f.imports {
+ // filter out the "C" pseudo-package so it's not rendered in a block with the other
+ // imports, but only if it is accompanied by a preamble comment
+ if path == "C" && separateCgo {
+ continue
+ }
+ filtered[path] = def
+ }
+
+ if len(filtered) == 1 {
+ for path, def := range filtered {
+ if def.alias && path != "C" {
+ // "C" package should be rendered without alias even when used as an anonymous import
+ // (e.g. should never have an underscore).
+ if _, err := fmt.Fprintf(source, "import %s %s\n\n", def.name, strconv.Quote(path)); err != nil {
+ return err
+ }
+ } else {
+ if _, err := fmt.Fprintf(source, "import %s\n\n", strconv.Quote(path)); err != nil {
+ return err
+ }
+ }
+ }
+ } else if len(filtered) > 1 {
+ if _, err := fmt.Fprint(source, "import (\n"); err != nil {
+ return err
+ }
+ // We must sort the imports to ensure repeatable
+ // source.
+ paths := []string{}
+ for path := range filtered {
+ paths = append(paths, path)
+ }
+ sort.Strings(paths)
+ for _, path := range paths {
+ def := filtered[path]
+ if def.alias && path != "C" {
+ // "C" package should be rendered without alias even when used as an anonymous import
+ // (e.g. should never have an underscore).
+ if _, err := fmt.Fprintf(source, "%s %s\n", def.name, strconv.Quote(path)); err != nil {
+ return err
+ }
+
+ } else {
+ if _, err := fmt.Fprintf(source, "%s\n", strconv.Quote(path)); err != nil {
+ return err
+ }
+ }
+ }
+ if _, err := fmt.Fprint(source, ")\n\n"); err != nil {
+ return err
+ }
+ }
+
+ if separateCgo {
+ for _, c := range f.cgoPreamble {
+ if err := Comment(c).render(f, source, nil); err != nil {
+ return err
+ }
+ if _, err := fmt.Fprint(source, "\n"); err != nil {
+ return err
+ }
+ }
+ if _, err := fmt.Fprint(source, "import \"C\"\n\n"); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/dave/jennifer/jen/jen_test.go b/vendor/github.com/dave/jennifer/jen/jen_test.go
new file mode 100644
index 00000000..ade18362
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/jen_test.go
@@ -0,0 +1,550 @@
+package jen_test
+
+import (
+ "fmt"
+ "go/format"
+ "strings"
+ "testing"
+
+ . "github.com/dave/jennifer/jen"
+)
+
+var o1 = Options{
+ Close: ")",
+ Multi: true,
+ Open: "(",
+ Separator: ",",
+}
+
+var o2 = Options{
+ Close: "",
+ Multi: false,
+ Open: "",
+ Separator: ",",
+}
+
+var cases = []tc{
+ {
+ desc: `scientific notation`,
+ code: Lit(1e3),
+ expect: `1000.0`,
+ },
+ {
+ desc: `big float`,
+ code: Lit(1000000.0),
+ expect: `1e+06`,
+ },
+ {
+ desc: `lit float whole numbers`,
+ code: Index().Float64().Values(Lit(-10.0), Lit(-2.0), Lit(-1.0), Lit(0.0), Lit(1.0), Lit(2.0), Lit(10.0)),
+ expect: "[]float64{-10.0, -2.0, -1.0, 0.0, 1.0, 2.0, 10.0}",
+ },
+ {
+ desc: `custom func group`,
+ code: ListFunc(func(g *Group) {
+ g.CustomFunc(o2, func(g *Group) {
+ g.Id("a")
+ g.Id("b")
+ g.Id("c")
+ })
+ }).Op("=").Id("foo").Call(),
+ expect: `a, b, c = foo()`,
+ },
+ {
+ desc: `custom group`,
+ code: ListFunc(func(g *Group) { g.Custom(o2, Id("a"), Id("b"), Id("c")) }).Op("=").Id("foo").Call(),
+ expect: `a, b, c = foo()`,
+ },
+ {
+ desc: `custom function`,
+ code: Id("foo").Add(Custom(o1, Lit("a"), Lit("b"), Lit("c"))),
+ expect: `foo(
+ "a",
+ "b",
+ "c",
+ )`,
+ },
+ {
+ desc: `custom function`,
+ code: Id("foo").Add(Custom(o1, Lit("a"), Lit("b"), Lit("c"))),
+ expect: `foo(
+ "a",
+ "b",
+ "c",
+ )`,
+ },
+ {
+ desc: `line statement`,
+ code: Block(Lit(1).Line(), Lit(2)),
+ expect: `{
+ 1
+
+ 2
+ }`,
+ },
+ {
+ desc: `line func`,
+ code: Block(Lit(1), Line(), Lit(2)),
+ expect: `{
+ 1
+
+ 2
+ }`,
+ },
+ {
+ desc: `line group`,
+ code: BlockFunc(func(g *Group) {
+ g.Id("a")
+ g.Line()
+ g.Id("b")
+ }),
+ expect: `{
+ a
+
+ b
+ }`,
+ },
+ {
+ desc: `op group`,
+ code: BlockFunc(func(g *Group) {
+ g.Op("*").Id("a")
+ }),
+ expect: `{*a}`,
+ },
+ {
+ desc: `empty group`,
+ code: BlockFunc(func(g *Group) {
+ g.Empty()
+ }),
+ expect: `{
+
+ }`,
+ },
+ {
+ desc: `null group`,
+ code: BlockFunc(func(g *Group) {
+ g.Null()
+ }),
+ expect: `{}`,
+ },
+ {
+ desc: `tag no backquote`,
+ code: Tag(map[string]string{"a": "`b`"}),
+ expect: "\"a:\\\"`b`\\\"\"",
+ },
+ {
+ desc: `tag null`,
+ code: Tag(map[string]string{}),
+ expect: ``,
+ },
+ {
+ desc: `litrunefunc group`,
+ code: BlockFunc(func(g *Group) {
+ g.LitByteFunc(func() byte { return byte(0xab) })
+ }),
+ expect: `{byte(0xab)}`,
+ },
+ {
+ desc: `litbyte group`,
+ code: BlockFunc(func(g *Group) {
+ g.LitByte(byte(0xab))
+ }),
+ expect: `{byte(0xab)}`,
+ },
+ {
+ desc: `litrunefunc group`,
+ code: BlockFunc(func(g *Group) {
+ g.LitRuneFunc(func() rune { return 'a' })
+ }),
+ expect: `{'a'}`,
+ },
+ {
+ desc: `litrune group`,
+ code: BlockFunc(func(g *Group) {
+ g.LitRune('a')
+ }),
+ expect: `{'a'}`,
+ },
+ {
+ desc: `litfunc group`,
+ code: BlockFunc(func(g *Group) {
+ g.LitFunc(func() interface{} {
+ return 1 + 1
+ })
+ }),
+ expect: `{2}`,
+ },
+ {
+ desc: `litfunc func`,
+ code: LitFunc(func() interface{} {
+ return 1 + 1
+ }),
+ expect: `2`,
+ },
+ {
+ desc: `group all null`,
+ code: List(Null(), Null()),
+ expect: ``,
+ },
+ {
+ desc: `do group`,
+ code: BlockFunc(func(g *Group) { g.Do(func(s *Statement) { s.Lit(1) }) }),
+ expect: `{1}`,
+ },
+ {
+ desc: `do func`,
+ code: Do(func(s *Statement) { s.Lit(1) }),
+ expect: `1`,
+ },
+ {
+ desc: `dict empty`,
+ code: Values(Dict{}),
+ expect: `{}`,
+ },
+ {
+ desc: `dict null`,
+ code: Values(Dict{Null(): Null()}),
+ expect: `{}`,
+ },
+ {
+ desc: `commentf group`,
+ code: BlockFunc(func(g *Group) { g.Commentf("%d", 1) }),
+ expect: `{
+ // 1
+ }`,
+ },
+ {
+ desc: `commentf func`,
+ code: Commentf("%d", 1),
+ expect: `// 1`,
+ },
+ {
+ desc: `add func`,
+ code: Add(Lit(1)),
+ expect: `1`,
+ },
+ {
+ desc: `add group`,
+ code: BlockFunc(func(g *Group) { g.Add(Lit(1)) }),
+ expect: `{1}`,
+ },
+ {
+ desc: `empty block`,
+ code: Block(),
+ expect: `{}`,
+ },
+ {
+ desc: `string literal`,
+ code: Lit("a"),
+ expect: `"a"`,
+ },
+ {
+ desc: `int literal`,
+ code: Lit(1),
+ expect: `1`,
+ },
+ {
+ desc: `simple id`,
+ code: Id("a"),
+ expect: `a`,
+ },
+ {
+ desc: `foreign id`,
+ code: Qual("x.y/z", "a"),
+ expect: `z.a`,
+ expectImports: map[string]string{
+ "x.y/z": "z",
+ },
+ },
+ {
+ desc: `var decl`,
+ code: Var().Id("a").Op("=").Lit("b"),
+ expect: `var a = "b"`,
+ },
+ {
+ desc: `short var decl`,
+ code: Id("a").Op(":=").Lit("b"),
+ expect: `a := "b"`,
+ },
+ {
+ desc: `simple if`,
+ code: If(Id("a").Op("==").Lit("b")).Block(),
+ expect: `if a == "b" {}`,
+ },
+ {
+ desc: `simple if`,
+ code: If(Id("a").Op("==").Lit("b")).Block(
+ Id("a").Op("++"),
+ ),
+ expect: `if a == "b" { a++ }`,
+ },
+ {
+ desc: `pointer`,
+ code: Op("*").Id("a"),
+ expect: `*a`,
+ },
+ {
+ desc: `address`,
+ code: Op("&").Id("a"),
+ expect: `&a`,
+ },
+ {
+ desc: `simple call`,
+ code: Id("a").Call(
+ Lit("b"),
+ Lit("c"),
+ ),
+ expect: `a("b", "c")`,
+ },
+ {
+ desc: `call fmt.Sprintf`,
+ code: Qual("fmt", "Sprintf").Call(
+ Lit("b"),
+ Id("c"),
+ ),
+ expect: `fmt.Sprintf("b", c)`,
+ },
+ {
+ desc: `slices`,
+ code: Id("a").Index(
+ Lit(1),
+ Empty(),
+ ),
+ expect: `a[1:]`,
+ },
+ {
+ desc: `return`,
+ code: Return(Id("a")),
+ expect: `return a`,
+ },
+ {
+ desc: `double return`,
+ code: Return(Id("a"), Id("b")),
+ expect: `return a, b`,
+ },
+ {
+ desc: `func`,
+ code: Func().Id("a").Params(
+ Id("a").String(),
+ ).Block(
+ Return(Id("a")),
+ ),
+ expect: `func a(a string){
+ return a
+ }`,
+ },
+ {
+ desc: `built in func`,
+ code: New(Id("a")),
+ expect: `new(a)`,
+ },
+ {
+ desc: `multip`,
+ code: Id("a").Op("*").Id("b"),
+ expect: `a * b`,
+ },
+ {
+ desc: `multip ptr`,
+ code: Id("a").Op("*").Op("*").Id("b"),
+ expect: `a * *b`,
+ },
+ {
+ desc: `field`,
+ code: Id("a").Dot("b"),
+ expect: `a.b`,
+ },
+ {
+ desc: `method`,
+ code: Id("a").Dot("b").Call(Id("c"), Id("d")),
+ expect: `a.b(c, d)`,
+ },
+ {
+ desc: `if else`,
+ code: If(Id("a").Op("==").Lit(1)).Block(
+ Id("b").Op("=").Lit(1),
+ ).Else().If(Id("a").Op("==").Lit(2)).Block(
+ Id("b").Op("=").Lit(2),
+ ).Else().Block(
+ Id("b").Op("=").Lit(3),
+ ),
+ expect: `if a == 1 { b = 1 } else if a == 2 { b = 2 } else { b = 3 }`,
+ },
+ {
+ desc: `literal array`,
+ code: Index().String().Values(Lit("a"), Lit("b")),
+ expect: `[]string{"a", "b"}`,
+ },
+ {
+ desc: `comment`,
+ code: Comment("a"),
+ expect: `// a`,
+ },
+ {
+ desc: `null`,
+ code: Id("a").Params(Id("b"), Null(), Id("c")),
+ expect: `a(b, c)`,
+ },
+ {
+ desc: `map literal single`,
+ code: Id("a").Values(Dict{
+ Id("b"): Id("c"),
+ }),
+ expect: `a{b: c}`,
+ },
+ {
+ desc: `map literal null`,
+ code: Id("a").Values(Dict{
+ Null(): Id("c"),
+ Id("b"): Null(),
+ Id("b"): Id("c"),
+ }),
+ expect: `a{b: c}`,
+ },
+ {
+ desc: `map literal multiple`,
+ code: Id("a").Values(Dict{
+ Id("b"): Id("c"),
+ Id("d"): Id("e"),
+ }),
+ expect: `a{
+ b: c,
+ d: e,
+ }`,
+ },
+ {
+ desc: `map literal func single`,
+ code: Id("a").Values(DictFunc(func(d Dict) {
+ d[Id("b")] = Id("c")
+ })),
+ expect: `a{b: c}`,
+ },
+ {
+ desc: `map literal func single null`,
+ code: Id("a").Values(DictFunc(func(d Dict) {
+ d[Null()] = Id("c")
+ d[Id("b")] = Null()
+ d[Id("b")] = Id("c")
+ })),
+ expect: `a{b: c}`,
+ },
+ {
+ desc: `map literal func multiple`,
+ code: Id("a").Values(DictFunc(func(d Dict) {
+ d[Id("b")] = Id("c")
+ d[Id("d")] = Id("e")
+ })),
+ expect: `a{
+ b: c,
+ d: e,
+ }`,
+ },
+ {
+ desc: `literal func`,
+ code: Id("a").Op(":=").LitFunc(func() interface{} {
+ return "b"
+ }),
+ expect: `a := "b"`,
+ },
+ {
+ desc: `dot`,
+ code: Id("a").Dot("b").Dot("c"),
+ expect: `a.b.c`,
+ },
+ {
+ desc: `do`,
+ code: Id("a").Do(func(s *Statement) { s.Dot("b") }),
+ expect: `a.b`,
+ },
+ {
+ desc: `tags should be ordered`,
+ code: Tag(map[string]string{"z": "1", "a": "2"}),
+ expect: "`a:\"2\" z:\"1\"`",
+ },
+ {
+ desc: `dict should be ordered`,
+ code: Map(String()).Int().Values(Dict{Id("z"): Lit(1), Id("a"): Lit(2)}),
+ expect: `map[string]int{
+ a:2,
+ z:1,
+ }`,
+ },
+}
+
+func TestJen(t *testing.T) {
+ caseTester(t, cases)
+}
+
+func caseTester(t *testing.T, cases []tc) {
+ for i, c := range cases {
+ onlyTest := ""
+ if onlyTest != "" && c.desc != onlyTest {
+ continue
+ }
+ rendered := fmt.Sprintf("%#v", c.code)
+
+ expected, err := format.Source([]byte(c.expect))
+ if err != nil {
+ panic(fmt.Sprintf("Error formatting expected source in test case %d. Description: %s\nError:\n%s", i, c.desc, err))
+ }
+
+ if strings.TrimSpace(string(rendered)) != strings.TrimSpace(string(expected)) {
+ t.Errorf("Test case %d failed. Description: %s\nExpected:\n%s\nOutput:\n%s", i, c.desc, expected, rendered)
+ }
+
+ //if c.expectImports != nil {
+ // f := FromContext(ctx)
+ // if !reflect.DeepEqual(f.Imports, c.expectImports) {
+ // t.Errorf("Test case %d failed. Description: %s\nImports expected:\n%s\nOutput:\n%s", i, c.desc, c.expectImports, f.Imports)
+ // }
+ //}
+ }
+}
+
+// a test case
+type tc struct {
+ // path
+ path string
+ // description for locating the test case
+ desc string
+ // code to generate
+ code Code
+ // expected generated source
+ expect string
+ // expected imports
+ expectImports map[string]string
+}
+
+func TestNilStatement(t *testing.T) {
+ var s *Statement
+ c := Func().Id("a").Params(
+ s,
+ )
+ got := fmt.Sprintf("%#v", c)
+ expect := "func a()"
+ if got != expect {
+ t.Fatalf("Got: %s, expect: %s", got, expect)
+ }
+}
+
+func TestNilGroup(t *testing.T) {
+ var g *Group
+ c := Func().Id("a").Params(
+ g,
+ )
+ got := fmt.Sprintf("%#v", c)
+ expect := "func a()"
+ if got != expect {
+ t.Fatalf("Got: %s, expect: %s", got, expect)
+ }
+}
+
+func TestGroup_GoString(t *testing.T) {
+ BlockFunc(func(g *Group) {
+ g.Lit(1)
+ got := fmt.Sprintf("%#v", g)
+ expect := "{\n\t1\n}"
+ if got != expect {
+ t.Fatalf("Got: %s, expect: %s", got, expect)
+ }
+ })
+}
diff --git a/vendor/github.com/dave/jennifer/jen/lit.go b/vendor/github.com/dave/jennifer/jen/lit.go
new file mode 100644
index 00000000..9791f1d2
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/lit.go
@@ -0,0 +1,154 @@
+package jen
+
+// Lit renders a literal. Lit supports only built-in types (bool, string, int, complex128, float64,
+// float32, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64).
+// Passing any other type will panic.
+func Lit(v interface{}) *Statement {
+ return newStatement().Lit(v)
+}
+
+// Lit renders a literal. Lit supports only built-in types (bool, string, int, complex128, float64,
+// float32, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64).
+// Passing any other type will panic.
+func (g *Group) Lit(v interface{}) *Statement {
+ s := Lit(v)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Lit renders a literal. Lit supports only built-in types (bool, string, int, complex128, float64,
+// float32, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64).
+// Passing any other type will panic.
+func (s *Statement) Lit(v interface{}) *Statement {
+ t := token{
+ typ: literalToken,
+ content: v,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// LitFunc renders a literal. LitFunc generates the value to render by executing the provided
+// function. LitFunc supports only built-in types (bool, string, int, complex128, float64, float32,
+// int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64).
+// Returning any other type will panic.
+func LitFunc(f func() interface{}) *Statement {
+ return newStatement().LitFunc(f)
+}
+
+// LitFunc renders a literal. LitFunc generates the value to render by executing the provided
+// function. LitFunc supports only built-in types (bool, string, int, complex128, float64, float32,
+// int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64).
+// Returning any other type will panic.
+func (g *Group) LitFunc(f func() interface{}) *Statement {
+ s := LitFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// LitFunc renders a literal. LitFunc generates the value to render by executing the provided
+// function. LitFunc supports only built-in types (bool, string, int, complex128, float64, float32,
+// int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr and complex64).
+// Returning any other type will panic.
+func (s *Statement) LitFunc(f func() interface{}) *Statement {
+ t := token{
+ typ: literalToken,
+ content: f(),
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// LitRune renders a rune literal.
+func LitRune(v rune) *Statement {
+ return newStatement().LitRune(v)
+}
+
+// LitRune renders a rune literal.
+func (g *Group) LitRune(v rune) *Statement {
+ s := LitRune(v)
+ g.items = append(g.items, s)
+ return s
+}
+
+// LitRune renders a rune literal.
+func (s *Statement) LitRune(v rune) *Statement {
+ t := token{
+ typ: literalRuneToken,
+ content: v,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// LitRuneFunc renders a rune literal. LitRuneFunc generates the value to
+// render by executing the provided function.
+func LitRuneFunc(f func() rune) *Statement {
+ return newStatement().LitRuneFunc(f)
+}
+
+// LitRuneFunc renders a rune literal. LitRuneFunc generates the value to
+// render by executing the provided function.
+func (g *Group) LitRuneFunc(f func() rune) *Statement {
+ s := LitRuneFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// LitRuneFunc renders a rune literal. LitRuneFunc generates the value to
+// render by executing the provided function.
+func (s *Statement) LitRuneFunc(f func() rune) *Statement {
+ t := token{
+ typ: literalRuneToken,
+ content: f(),
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// LitByte renders a byte literal.
+func LitByte(v byte) *Statement {
+ return newStatement().LitByte(v)
+}
+
+// LitByte renders a byte literal.
+func (g *Group) LitByte(v byte) *Statement {
+ s := LitByte(v)
+ g.items = append(g.items, s)
+ return s
+}
+
+// LitByte renders a byte literal.
+func (s *Statement) LitByte(v byte) *Statement {
+ t := token{
+ typ: literalByteToken,
+ content: v,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// LitByteFunc renders a byte literal. LitByteFunc generates the value to
+// render by executing the provided function.
+func LitByteFunc(f func() byte) *Statement {
+ return newStatement().LitByteFunc(f)
+}
+
+// LitByteFunc renders a byte literal. LitByteFunc generates the value to
+// render by executing the provided function.
+func (g *Group) LitByteFunc(f func() byte) *Statement {
+ s := LitByteFunc(f)
+ g.items = append(g.items, s)
+ return s
+}
+
+// LitByteFunc renders a byte literal. LitByteFunc generates the value to
+// render by executing the provided function.
+func (s *Statement) LitByteFunc(f func() byte) *Statement {
+ t := token{
+ typ: literalByteToken,
+ content: f(),
+ }
+ *s = append(*s, t)
+ return s
+}
diff --git a/vendor/github.com/dave/jennifer/jen/statement.go b/vendor/github.com/dave/jennifer/jen/statement.go
new file mode 100644
index 00000000..aa9ec497
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/statement.go
@@ -0,0 +1,101 @@
+package jen
+
+import (
+ "bytes"
+ "fmt"
+ "go/format"
+ "io"
+)
+
+// Statement represents a simple list of code items. When rendered the items
+// are separated by spaces.
+type Statement []Code
+
+func newStatement() *Statement {
+ return &Statement{}
+}
+
+// Clone makes a copy of the Statement, so further tokens can be appended
+// without affecting the original.
+func (s *Statement) Clone() *Statement {
+ return &Statement{s}
+}
+
+func (s *Statement) previous(c Code) Code {
+ index := -1
+ for i, item := range *s {
+ if item == c {
+ index = i
+ break
+ }
+ }
+ if index > 0 {
+ return (*s)[index-1]
+ }
+ return nil
+}
+
+func (s *Statement) isNull(f *File) bool {
+ if s == nil {
+ return true
+ }
+ for _, c := range *s {
+ if !c.isNull(f) {
+ return false
+ }
+ }
+ return true
+}
+
+func (s *Statement) render(f *File, w io.Writer, _ *Statement) error {
+ first := true
+ for _, code := range *s {
+ if code == nil || code.isNull(f) {
+ // Null() token produces no output but also
+ // no separator. Empty() token products no
+ // output but adds a separator.
+ continue
+ }
+ if !first {
+ if _, err := w.Write([]byte(" ")); err != nil {
+ return err
+ }
+ }
+ if err := code.render(f, w, s); err != nil {
+ return err
+ }
+ first = false
+ }
+ return nil
+}
+
+// Render renders the Statement to the provided writer.
+func (s *Statement) Render(writer io.Writer) error {
+ return s.RenderWithFile(writer, NewFile(""))
+}
+
+// GoString renders the Statement for testing. Any error will cause a panic.
+func (s *Statement) GoString() string {
+ buf := bytes.Buffer{}
+ if err := s.Render(&buf); err != nil {
+ panic(err)
+ }
+ return buf.String()
+}
+
+// RenderWithFile renders the Statement to the provided writer, using imports from the provided file.
+func (s *Statement) RenderWithFile(writer io.Writer, file *File) error {
+ buf := &bytes.Buffer{}
+ if err := s.render(file, buf, nil); err != nil {
+ return err
+ }
+ b, err := format.Source(buf.Bytes())
+ if err != nil {
+ return fmt.Errorf("Error %s while formatting source:\n%s", err, buf.String())
+ }
+ if _, err := writer.Write(b); err != nil {
+ return err
+ }
+ return nil
+}
+
diff --git a/vendor/github.com/dave/jennifer/jen/statement_test.go b/vendor/github.com/dave/jennifer/jen/statement_test.go
new file mode 100644
index 00000000..d774f6e9
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/statement_test.go
@@ -0,0 +1,32 @@
+package jen_test
+
+import (
+ "bytes"
+ "testing"
+
+ . "github.com/dave/jennifer/jen"
+)
+
+func TestStatement_Render(t *testing.T) {
+ file := NewFile("main")
+ file.ImportAlias("fmt", "fmtalias")
+
+ statement := file.Func().Id("main").Params().Block(
+ Qual("fmt", "Println").Call(Lit("something")),
+ )
+
+ expect := `func main() {
+ fmtalias.Println("something")
+}`
+
+ var got bytes.Buffer
+
+ err := statement.RenderWithFile(&got, file)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if got.String() != expect {
+ t.Fatalf("Got: %v, expect: %v", got.String(), expect)
+ }
+}
diff --git a/vendor/github.com/dave/jennifer/jen/tag.go b/vendor/github.com/dave/jennifer/jen/tag.go
new file mode 100644
index 00000000..ad99aafd
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/tag.go
@@ -0,0 +1,76 @@
+package jen
+
+import (
+ "fmt"
+ "io"
+ "sort"
+ "strconv"
+)
+
+// Tag renders a struct tag
+func Tag(items map[string]string) *Statement {
+ return newStatement().Tag(items)
+}
+
+// Tag renders a struct tag
+func (g *Group) Tag(items map[string]string) *Statement {
+ // notest
+ // don't think this can ever be used in valid code?
+ s := Tag(items)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Tag renders a struct tag
+func (s *Statement) Tag(items map[string]string) *Statement {
+ c := tag{
+ items: items,
+ }
+ *s = append(*s, c)
+ return s
+}
+
+type tag struct {
+ items map[string]string
+}
+
+func (t tag) isNull(f *File) bool {
+ return len(t.items) == 0
+}
+
+func (t tag) render(f *File, w io.Writer, s *Statement) error {
+
+ if t.isNull(f) {
+ // notest
+ // render won't be called if t is null
+ return nil
+ }
+
+ var str string
+
+ var sorted []string
+ for k := range t.items {
+ sorted = append(sorted, k)
+ }
+ sort.Strings(sorted)
+
+ for _, k := range sorted {
+ v := t.items[k]
+ if len(str) > 0 {
+ str += " "
+ }
+ str += fmt.Sprintf(`%s:"%s"`, k, v)
+ }
+
+ if strconv.CanBackquote(str) {
+ str = "`" + str + "`"
+ } else {
+ str = strconv.Quote(str)
+ }
+
+ if _, err := w.Write([]byte(str)); err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/dave/jennifer/jen/tokens.go b/vendor/github.com/dave/jennifer/jen/tokens.go
new file mode 100644
index 00000000..287a3cd6
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jen/tokens.go
@@ -0,0 +1,301 @@
+package jen
+
+import (
+ "fmt"
+ "io"
+ "strconv"
+ "strings"
+)
+
+type tokenType string
+
+const (
+ packageToken tokenType = "package"
+ identifierToken tokenType = "identifier"
+ qualifiedToken tokenType = "qualified"
+ keywordToken tokenType = "keyword"
+ operatorToken tokenType = "operator"
+ delimiterToken tokenType = "delimiter"
+ literalToken tokenType = "literal"
+ literalRuneToken tokenType = "literal_rune"
+ literalByteToken tokenType = "literal_byte"
+ nullToken tokenType = "null"
+ layoutToken tokenType = "layout"
+)
+
+type token struct {
+ typ tokenType
+ content interface{}
+}
+
+func (t token) isNull(f *File) bool {
+ if t.typ == packageToken {
+ // package token is null if the path is a dot-import or the local package path
+ return f.isDotImport(t.content.(string)) || f.isLocal(t.content.(string))
+ }
+ return t.typ == nullToken
+}
+
+func (t token) render(f *File, w io.Writer, s *Statement) error {
+ switch t.typ {
+ case literalToken:
+ var out string
+ switch t.content.(type) {
+ case bool, string, int, complex128:
+ // default constant types can be left bare
+ out = fmt.Sprintf("%#v", t.content)
+ case float64:
+ out = fmt.Sprintf("%#v", t.content)
+ if !strings.Contains(out, ".") && !strings.Contains(out, "e") {
+ // If the formatted value is not in scientific notation, and does not have a dot, then
+ // we add ".0". Otherwise it will be interpreted as an int.
+ // See:
+ // https://github.com/dave/jennifer/issues/39
+ // https://github.com/golang/go/issues/26363
+ out += ".0"
+ }
+ case float32, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr:
+ // other built-in types need specific type info
+ out = fmt.Sprintf("%T(%#v)", t.content, t.content)
+ case complex64:
+ // fmt package already renders parenthesis for complex64
+ out = fmt.Sprintf("%T%#v", t.content, t.content)
+ default:
+ panic(fmt.Sprintf("unsupported type for literal: %T", t.content))
+ }
+ if _, err := w.Write([]byte(out)); err != nil {
+ return err
+ }
+ case literalRuneToken:
+ if _, err := w.Write([]byte(strconv.QuoteRune(t.content.(rune)))); err != nil {
+ return err
+ }
+ case literalByteToken:
+ if _, err := w.Write([]byte(fmt.Sprintf("byte(%#v)", t.content))); err != nil {
+ return err
+ }
+ case keywordToken, operatorToken, layoutToken, delimiterToken:
+ if _, err := w.Write([]byte(fmt.Sprintf("%s", t.content))); err != nil {
+ return err
+ }
+ if t.content.(string) == "default" {
+ // Special case for Default, which must always be followed by a colon
+ if _, err := w.Write([]byte(":")); err != nil {
+ return err
+ }
+ }
+ case packageToken:
+ path := t.content.(string)
+ alias := f.register(path)
+ if _, err := w.Write([]byte(alias)); err != nil {
+ return err
+ }
+ case identifierToken:
+ if _, err := w.Write([]byte(t.content.(string))); err != nil {
+ return err
+ }
+ case nullToken: // notest
+ // do nothing (should never render a null token)
+ }
+ return nil
+}
+
+// Null adds a null item. Null items render nothing and are not followed by a
+// separator in lists.
+func Null() *Statement {
+ return newStatement().Null()
+}
+
+// Null adds a null item. Null items render nothing and are not followed by a
+// separator in lists.
+func (g *Group) Null() *Statement {
+ s := Null()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Null adds a null item. Null items render nothing and are not followed by a
+// separator in lists.
+func (s *Statement) Null() *Statement {
+ t := token{
+ typ: nullToken,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Empty adds an empty item. Empty items render nothing but are followed by a
+// separator in lists.
+func Empty() *Statement {
+ return newStatement().Empty()
+}
+
+// Empty adds an empty item. Empty items render nothing but are followed by a
+// separator in lists.
+func (g *Group) Empty() *Statement {
+ s := Empty()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Empty adds an empty item. Empty items render nothing but are followed by a
+// separator in lists.
+func (s *Statement) Empty() *Statement {
+ t := token{
+ typ: operatorToken,
+ content: "",
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Op renders the provided operator / token.
+func Op(op string) *Statement {
+ return newStatement().Op(op)
+}
+
+// Op renders the provided operator / token.
+func (g *Group) Op(op string) *Statement {
+ s := Op(op)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Op renders the provided operator / token.
+func (s *Statement) Op(op string) *Statement {
+ t := token{
+ typ: operatorToken,
+ content: op,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Dot renders a period followed by an identifier. Use for fields and selectors.
+func Dot(name string) *Statement {
+ // notest
+ // don't think this can be used in valid code?
+ return newStatement().Dot(name)
+}
+
+// Dot renders a period followed by an identifier. Use for fields and selectors.
+func (g *Group) Dot(name string) *Statement {
+ // notest
+ // don't think this can be used in valid code?
+ s := Dot(name)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Dot renders a period followed by an identifier. Use for fields and selectors.
+func (s *Statement) Dot(name string) *Statement {
+ d := token{
+ typ: delimiterToken,
+ content: ".",
+ }
+ t := token{
+ typ: identifierToken,
+ content: name,
+ }
+ *s = append(*s, d, t)
+ return s
+}
+
+// Id renders an identifier.
+func Id(name string) *Statement {
+ return newStatement().Id(name)
+}
+
+// Id renders an identifier.
+func (g *Group) Id(name string) *Statement {
+ s := Id(name)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Id renders an identifier.
+func (s *Statement) Id(name string) *Statement {
+ t := token{
+ typ: identifierToken,
+ content: name,
+ }
+ *s = append(*s, t)
+ return s
+}
+
+// Qual renders a qualified identifier. Imports are automatically added when
+// used with a File. If the path matches the local path, the package name is
+// omitted. If package names conflict they are automatically renamed. Note that
+// it is not possible to reliably determine the package name given an arbitrary
+// package path, so a sensible name is guessed from the path and added as an
+// alias. The names of all standard library packages are known so these do not
+// need to be aliased. If more control is needed of the aliases, see
+// [File.ImportName](#importname) or [File.ImportAlias](#importalias).
+func Qual(path, name string) *Statement {
+ return newStatement().Qual(path, name)
+}
+
+// Qual renders a qualified identifier. Imports are automatically added when
+// used with a File. If the path matches the local path, the package name is
+// omitted. If package names conflict they are automatically renamed. Note that
+// it is not possible to reliably determine the package name given an arbitrary
+// package path, so a sensible name is guessed from the path and added as an
+// alias. The names of all standard library packages are known so these do not
+// need to be aliased. If more control is needed of the aliases, see
+// [File.ImportName](#importname) or [File.ImportAlias](#importalias).
+func (g *Group) Qual(path, name string) *Statement {
+ s := Qual(path, name)
+ g.items = append(g.items, s)
+ return s
+}
+
+// Qual renders a qualified identifier. Imports are automatically added when
+// used with a File. If the path matches the local path, the package name is
+// omitted. If package names conflict they are automatically renamed. Note that
+// it is not possible to reliably determine the package name given an arbitrary
+// package path, so a sensible name is guessed from the path and added as an
+// alias. The names of all standard library packages are known so these do not
+// need to be aliased. If more control is needed of the aliases, see
+// [File.ImportName](#importname) or [File.ImportAlias](#importalias).
+func (s *Statement) Qual(path, name string) *Statement {
+ g := &Group{
+ close: "",
+ items: []Code{
+ token{
+ typ: packageToken,
+ content: path,
+ },
+ token{
+ typ: identifierToken,
+ content: name,
+ },
+ },
+ name: "qual",
+ open: "",
+ separator: ".",
+ }
+ *s = append(*s, g)
+ return s
+}
+
+// Line inserts a blank line.
+func Line() *Statement {
+ return newStatement().Line()
+}
+
+// Line inserts a blank line.
+func (g *Group) Line() *Statement {
+ s := Line()
+ g.items = append(g.items, s)
+ return s
+}
+
+// Line inserts a blank line.
+func (s *Statement) Line() *Statement {
+ t := token{
+ typ: layoutToken,
+ content: "\n",
+ }
+ *s = append(*s, t)
+ return s
+}
diff --git a/vendor/github.com/dave/jennifer/jennifer.go b/vendor/github.com/dave/jennifer/jennifer.go
new file mode 100644
index 00000000..37efad44
--- /dev/null
+++ b/vendor/github.com/dave/jennifer/jennifer.go
@@ -0,0 +1,9 @@
+// Package jennifer is a code generator for Go
+package jennifer
+
+//go:generate go get github.com/dave/jennifer/genjen
+//go:generate genjen
+//go:generate go get github.com/dave/jennifer/gennames
+//go:generate gennames -output "jen/hints.go" -package "jen" -name "standardLibraryHints" -standard -novendor -path "./..."
+//go:generate go get github.com/dave/rebecca/cmd/becca
+//go:generate becca -package=github.com/dave/jennifer/jen