mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 06:36:43 +00:00
abigen: adding support for configurable template file for generating bindings
This commit is contained in:
parent
b135da2eac
commit
ec72537db5
5 changed files with 45 additions and 11 deletions
|
|
@ -294,7 +294,7 @@ func iterSorted[V any](inp map[string]V, onItem func(string, V) error) error {
|
|||
// to be used as is in client code, but rather as an intermediate struct which
|
||||
// enforces compile time type safety and naming convention as opposed to having to
|
||||
// manually maintain hard coded strings that break on runtime.
|
||||
func BindV2(types []string, abis []string, bytecodes []string, pkg string, libs map[string]string, aliases map[string]string) (string, error) {
|
||||
func BindV2(types []string, abis []string, bytecodes []string, pkg string, libs map[string]string, aliases map[string]string, templateContent string) (string, error) {
|
||||
b := binder{
|
||||
contracts: make(map[string]*tmplContractV2),
|
||||
structs: make(map[string]*tmplStruct),
|
||||
|
|
@ -360,7 +360,7 @@ func BindV2(types []string, abis []string, bytecodes []string, pkg string, libs
|
|||
"ispointertype": isPointerType,
|
||||
"underlyingbindtype": underlyingBindType,
|
||||
}
|
||||
tmpl := template.Must(template.New("").Funcs(funcs).Parse(tmplSourceV2))
|
||||
tmpl := template.Must(template.New("").Funcs(funcs).Parse(templateContent))
|
||||
if err := tmpl.Execute(buffer, data); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ func bindCombinedJSON(test *bindV2Test) (string, error) {
|
|||
if test.aliases == nil {
|
||||
test.aliases = make(map[string]string)
|
||||
}
|
||||
code, err := BindV2(types, abis, bins, "bindtests", libs, test.aliases)
|
||||
code, err := BindV2(types, abis, bins, "bindtests", libs, test.aliases, TmplSourceV2)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error creating bindings: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,4 +133,4 @@ var tmplSource string
|
|||
// for abigen v2 is based on.
|
||||
//
|
||||
//go:embed source2.go.tpl
|
||||
var tmplSourceV2 string
|
||||
var TmplSourceV2 string
|
||||
|
|
|
|||
|
|
@ -40,6 +40,26 @@ import (
|
|||
// TestBindingGeneration tests that re-running generation of bindings does not result in
|
||||
// mutations to the binding code.
|
||||
func TestBindingGeneration(t *testing.T) {
|
||||
BindGenerationWithExpectedOutput(t, abigen.TmplSourceV2, getCodeFromBindingsDotGo)
|
||||
}
|
||||
|
||||
func TestBindingGenerationWithDifferentTemplate(t *testing.T) {
|
||||
BindGenerationWithExpectedOutput(t, "package {{.Package}} //test template", getHarcodedCodeFromBindingsDotGo)
|
||||
}
|
||||
|
||||
func getHarcodedCodeFromBindingsDotGo(t *testing.T, basePath string) string {
|
||||
return "package " + strings.Replace(basePath, "internal/contracts/", "", -1) + " //test template\n"
|
||||
}
|
||||
|
||||
func getCodeFromBindingsDotGo(t *testing.T, basePath string) string {
|
||||
existingBindings, err := os.ReadFile(filepath.Join(basePath, "bindings.go"))
|
||||
if err != nil {
|
||||
t.Fatalf("ReadFile returned error: %v", err)
|
||||
}
|
||||
return string(existingBindings)
|
||||
}
|
||||
|
||||
func BindGenerationWithExpectedOutput(t *testing.T, templateContent string, getExpectedCodeFunc func(t *testing.T, basePath string) string) {
|
||||
matches, _ := filepath.Glob("internal/contracts/*")
|
||||
var dirs []string
|
||||
for _, match := range matches {
|
||||
|
|
@ -86,16 +106,13 @@ func TestBindingGeneration(t *testing.T) {
|
|||
libPattern := crypto.Keccak256Hash([]byte(name)).String()[2:36] // the first 2 chars are 0x
|
||||
libs[libPattern] = typeName
|
||||
}
|
||||
code, err := abigen.BindV2(types, abis, bins, dir, libs, make(map[string]string))
|
||||
code, err := abigen.BindV2(types, abis, bins, dir, libs, make(map[string]string), templateContent)
|
||||
if err != nil {
|
||||
t.Fatalf("error creating bindings for package %s: %v", dir, err)
|
||||
}
|
||||
|
||||
existingBindings, err := os.ReadFile(filepath.Join(basePath, "bindings.go"))
|
||||
if err != nil {
|
||||
t.Fatalf("ReadFile returned error: %v", err)
|
||||
}
|
||||
if code != string(existingBindings) {
|
||||
expectedCode := getExpectedCodeFunc(t, basePath)
|
||||
if code != expectedCode {
|
||||
t.Fatalf("code mismatch for %s", dir)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,6 +67,10 @@ var (
|
|||
Name: "alias",
|
||||
Usage: "Comma separated aliases for function and event renaming. If --v2 is set, errors are aliased as well. e.g. original1=alias1, original2=alias2",
|
||||
}
|
||||
templateFlag = &cli.StringFlag{
|
||||
Name: "template",
|
||||
Usage: "Input file to use as template for generating bindings",
|
||||
}
|
||||
v2Flag = &cli.BoolFlag{
|
||||
Name: "v2",
|
||||
Usage: "Generates v2 bindings",
|
||||
|
|
@ -86,6 +90,7 @@ func init() {
|
|||
pkgFlag,
|
||||
outFlag,
|
||||
aliasFlag,
|
||||
templateFlag,
|
||||
v2Flag,
|
||||
}
|
||||
app.Action = generate
|
||||
|
|
@ -100,6 +105,9 @@ func generate(c *cli.Context) error {
|
|||
if c.String(abiFlag.Name) == "" && c.String(jsonFlag.Name) == "" {
|
||||
utils.Fatalf("Either contract ABI source (--abi) or combined-json (--combined-json) are required")
|
||||
}
|
||||
if !c.Bool(v2Flag.Name) && c.IsSet(templateFlag.Name) {
|
||||
utils.Fatalf("Template configurabion only works with abigen v2")
|
||||
}
|
||||
// If the entire solidity code was specified, build and bind based on that
|
||||
var (
|
||||
abis []string
|
||||
|
|
@ -216,7 +224,16 @@ func generate(c *cli.Context) error {
|
|||
err error
|
||||
)
|
||||
if c.IsSet(v2Flag.Name) {
|
||||
code, err = abigen.BindV2(types, abis, bins, c.String(pkgFlag.Name), libs, aliases)
|
||||
template := abigen.TmplSourceV2
|
||||
if c.IsSet(templateFlag.Name) {
|
||||
templateLoc := c.String(templateFlag.Name)
|
||||
templateData, err := os.ReadFile(templateLoc)
|
||||
if err != nil {
|
||||
utils.Fatalf("Error reading template file: %s, error: %", templateLoc, err)
|
||||
}
|
||||
template = string(templateData)
|
||||
}
|
||||
code, err = abigen.BindV2(types, abis, bins, c.String(pkgFlag.Name), libs, aliases, template)
|
||||
} else {
|
||||
code, err = abigen.Bind(types, abis, bins, sigs, c.String(pkgFlag.Name), libs, aliases)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue