mirror of https://github.com/ethereum/go-ethereum
cmd/abigen: change --exc to exclude by type name (#22620)
The abigen exclusion pattern, previously on the form "path:type", now supports wildcards. Examples "*:type" to exclude a named type in all files, or "/path/to/foo.sol:*" all types in foo.sol.pull/25859/head
parent
65f3c1b46f
commit
e87806727d
@ -0,0 +1,58 @@ |
||||
package main |
||||
|
||||
import ( |
||||
"fmt" |
||||
"strings" |
||||
) |
||||
|
||||
type nameFilter struct { |
||||
fulls map[string]bool // path/to/contract.sol:Type
|
||||
files map[string]bool // path/to/contract.sol:*
|
||||
types map[string]bool // *:Type
|
||||
} |
||||
|
||||
func newNameFilter(patterns ...string) (*nameFilter, error) { |
||||
f := &nameFilter{ |
||||
fulls: make(map[string]bool), |
||||
files: make(map[string]bool), |
||||
types: make(map[string]bool), |
||||
} |
||||
for _, pattern := range patterns { |
||||
if err := f.add(pattern); err != nil { |
||||
return nil, err |
||||
} |
||||
} |
||||
return f, nil |
||||
} |
||||
|
||||
func (f *nameFilter) add(pattern string) error { |
||||
ft := strings.Split(pattern, ":") |
||||
if len(ft) != 2 { |
||||
// filenames and types must not include ':' symbol
|
||||
return fmt.Errorf("invalid pattern: %s", pattern) |
||||
} |
||||
|
||||
file, typ := ft[0], ft[1] |
||||
if file == "*" { |
||||
f.types[typ] = true |
||||
return nil |
||||
} else if typ == "*" { |
||||
f.files[file] = true |
||||
return nil |
||||
} |
||||
f.fulls[pattern] = true |
||||
return nil |
||||
} |
||||
|
||||
func (f *nameFilter) Matches(name string) bool { |
||||
ft := strings.Split(name, ":") |
||||
if len(ft) != 2 { |
||||
// If contract names are always of the fully-qualified form
|
||||
// <filePath>:<type>, then this case will never happen.
|
||||
return false |
||||
} |
||||
|
||||
file, typ := ft[0], ft[1] |
||||
// full paths > file paths > types
|
||||
return f.fulls[name] || f.files[file] || f.types[typ] |
||||
} |
@ -0,0 +1,38 @@ |
||||
package main |
||||
|
||||
import ( |
||||
"testing" |
||||
|
||||
"github.com/stretchr/testify/assert" |
||||
"github.com/stretchr/testify/require" |
||||
) |
||||
|
||||
func TestNameFilter(t *testing.T) { |
||||
_, err := newNameFilter("Foo") |
||||
require.Error(t, err) |
||||
_, err = newNameFilter("too/many:colons:Foo") |
||||
require.Error(t, err) |
||||
|
||||
f, err := newNameFilter("a/path:A", "*:B", "c/path:*") |
||||
require.NoError(t, err) |
||||
|
||||
for _, tt := range []struct { |
||||
name string |
||||
match bool |
||||
}{ |
||||
{"a/path:A", true}, |
||||
{"unknown/path:A", false}, |
||||
{"a/path:X", false}, |
||||
{"unknown/path:X", false}, |
||||
{"any/path:B", true}, |
||||
{"c/path:X", true}, |
||||
{"c/path:foo:B", false}, |
||||
} { |
||||
match := f.Matches(tt.name) |
||||
if tt.match { |
||||
assert.True(t, match, "expected match") |
||||
} else { |
||||
assert.False(t, match, "expected no match") |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue