Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
26f508cc
Unverified
Commit
26f508cc
authored
Jan 08, 2025
by
Michael Amadi
Committed by
GitHub
Jan 08, 2025
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
transition snapshots script to common framework (#13398)
parent
b62e7740
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
161 additions
and
225 deletions
+161
-225
types.go
op-chain-ops/solc/types.go
+24
-3
main.go
...tracts-bedrock/scripts/autogen/generate-snapshots/main.go
+87
-198
util.go
packages/contracts-bedrock/scripts/checks/common/util.go
+22
-4
main.go
packages/contracts-bedrock/scripts/checks/test-names/main.go
+2
-2
main_test.go
.../contracts-bedrock/scripts/checks/test-names/main_test.go
+26
-18
No files found.
op-chain-ops/solc/types.go
View file @
26f508cc
package
solc
package
solc
import
(
import
(
"encoding/json"
"fmt"
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi"
)
)
type
AbiType
struct
{
Parsed
abi
.
ABI
Raw
interface
{}
}
func
(
a
*
AbiType
)
UnmarshalJSON
(
data
[]
byte
)
error
{
if
err
:=
json
.
Unmarshal
(
data
,
&
a
.
Raw
);
err
!=
nil
{
return
err
}
return
json
.
Unmarshal
(
data
,
&
a
.
Parsed
)
}
type
CompilerInput
struct
{
type
CompilerInput
struct
{
Language
string
`json:"language"`
Language
string
`json:"language"`
Sources
map
[
string
]
map
[
string
]
string
`json:"sources"`
Sources
map
[
string
]
map
[
string
]
string
`json:"sources"`
...
@@ -39,7 +52,7 @@ type CompilerOutputContracts map[string]CompilerOutputContract
...
@@ -39,7 +52,7 @@ type CompilerOutputContracts map[string]CompilerOutputContract
// CompilerOutputContract represents the solc compiler output for a contract.
// CompilerOutputContract represents the solc compiler output for a contract.
// Ignoring some fields such as devdoc and userdoc.
// Ignoring some fields such as devdoc and userdoc.
type
CompilerOutputContract
struct
{
type
CompilerOutputContract
struct
{
Abi
abi
.
ABI
`json:"abi"`
Abi
AbiType
`json:"abi"`
Evm
CompilerOutputEvm
`json:"evm"`
Evm
CompilerOutputEvm
`json:"evm"`
Metadata
string
`json:"metadata"`
Metadata
string
`json:"metadata"`
StorageLayout
StorageLayout
`json:"storageLayout"`
StorageLayout
StorageLayout
`json:"storageLayout"`
...
@@ -72,6 +85,14 @@ func (s *StorageLayout) GetStorageLayoutType(name string) (StorageLayoutType, er
...
@@ -72,6 +85,14 @@ func (s *StorageLayout) GetStorageLayoutType(name string) (StorageLayoutType, er
return
StorageLayoutType
{},
fmt
.
Errorf
(
"%s not found"
,
name
)
return
StorageLayoutType
{},
fmt
.
Errorf
(
"%s not found"
,
name
)
}
}
type
AbiSpecStorageLayoutEntry
struct
{
Bytes
uint
`json:"bytes,string"`
Label
string
`json:"label"`
Offset
uint
`json:"offset"`
Slot
uint
`json:"slot,string"`
Type
string
`json:"type"`
}
type
StorageLayoutEntry
struct
{
type
StorageLayoutEntry
struct
{
AstId
uint
`json:"astId"`
AstId
uint
`json:"astId"`
Contract
string
`json:"contract"`
Contract
string
`json:"contract"`
...
@@ -241,7 +262,7 @@ type Expression struct {
...
@@ -241,7 +262,7 @@ type Expression struct {
}
}
type
ForgeArtifact
struct
{
type
ForgeArtifact
struct
{
Abi
abi
.
ABI
`json:"abi"`
Abi
AbiType
`json:"abi"`
Bytecode
CompilerOutputBytecode
`json:"bytecode"`
Bytecode
CompilerOutputBytecode
`json:"bytecode"`
DeployedBytecode
CompilerOutputBytecode
`json:"deployedBytecode"`
DeployedBytecode
CompilerOutputBytecode
`json:"deployedBytecode"`
MethodIdentifiers
map
[
string
]
string
`json:"methodIdentifiers"`
MethodIdentifiers
map
[
string
]
string
`json:"methodIdentifiers"`
...
@@ -266,7 +287,7 @@ type ForgeCompilerInfo struct {
...
@@ -266,7 +287,7 @@ type ForgeCompilerInfo struct {
}
}
type
ForgeMetadataOutput
struct
{
type
ForgeMetadataOutput
struct
{
Abi
abi
.
ABI
`json:"abi"`
Abi
AbiType
`json:"abi"`
DevDoc
ForgeDocObject
`json:"devdoc"`
DevDoc
ForgeDocObject
`json:"devdoc"`
UserDoc
ForgeDocObject
`json:"userdoc"`
UserDoc
ForgeDocObject
`json:"userdoc"`
}
}
...
...
packages/contracts-bedrock/scripts/autogen/generate-snapshots/main.go
View file @
26f508cc
package
main
package
main
import
(
import
(
"bytes"
"encoding/json"
"flag"
"fmt"
"fmt"
"os"
"os"
"path/filepath"
"path/filepath"
"regexp"
"regexp"
"sort"
"strings"
"github.com/ethereum-optimism/optimism/op-chain-ops/solc"
"github.com/ethereum-optimism/optimism/packages/contracts-bedrock/scripts/checks/common"
)
)
type
ForgeArtifact
struct
{
const
(
// ABI is a nested JSON data structure, including some objects/maps.
storageLayoutDir
=
"snapshots/storageLayout"
// We declare it as interface, and not raw-message, such that Go decodes into map[string]interface{}
abiDir
=
"snapshots/abi"
// where possible. The JSON-encoder will then sort the keys (default Go JSON behavior on maps),
)
// to reproduce the sortKeys(abi) result of the legacy Typescript version of the snapshort-generator.
ABI
interface
{}
`json:"abi"`
Ast
*
struct
{
NodeType
string
`json:"nodeType"`
Nodes
[]
struct
{
NodeType
string
`json:"nodeType"`
Name
string
`json:"name"`
ContractKind
string
`json:"contractKind"`
Abstract
bool
`json:"abstract"`
}
`json:"nodes"`
}
`json:"ast"`
StorageLayout
struct
{
Storage
[]
struct
{
Type
string
`json:"type"`
Label
json
.
RawMessage
`json:"label"`
Offset
json
.
RawMessage
`json:"offset"`
Slot
json
.
RawMessage
`json:"slot"`
}
`json:"storage"`
Types
map
[
string
]
struct
{
Label
string
`json:"label"`
NumberOfBytes
json
.
RawMessage
`json:"numberOfBytes"`
}
`json:"types"`
}
`json:"storageLayout"`
Bytecode
struct
{
Object
string
`json:"object"`
}
`json:"bytecode"`
}
type
AbiSpecStorageLayoutEntry
struct
{
type
SnapshotResult
struct
{
Bytes
json
.
RawMessage
`json:"bytes"`
ContractName
string
Label
json
.
RawMessage
`json:"label"`
Abi
interface
{}
Offset
json
.
RawMessage
`json:"offset"`
StorageLayout
[]
solc
.
AbiSpecStorageLayoutEntry
Slot
json
.
RawMessage
`json:"slot"`
Type
string
`json:"type"`
}
}
func
main
()
{
func
main
()
{
flag
.
Parse
()
if
err
:=
resetDirectory
(
storageLayoutDir
);
err
!=
nil
{
if
flag
.
NArg
()
!=
1
{
fmt
.
Printf
(
"failed to reset storage layout directory: %v
\n
"
,
err
)
fmt
.
Println
(
"Expected path of contracts-bedrock as CLI argument"
)
os
.
Exit
(
1
)
os
.
Exit
(
1
)
}
}
rootDir
:=
flag
.
Arg
(
0
)
if
err
:=
resetDirectory
(
abiDir
);
err
!=
nil
{
err
:=
generateSnapshots
(
rootDir
)
fmt
.
Printf
(
"failed to reset abi directory: %v
\n
"
,
err
)
os
.
Exit
(
1
)
}
results
,
err
:=
common
.
ProcessFilesGlob
(
[]
string
{
"forge-artifacts/**/*.json"
},
[]
string
{},
processFile
,
)
if
err
!=
nil
{
if
err
!=
nil
{
fmt
.
Printf
(
"Failed to generate snapshots: %v
\n
"
,
err
)
fmt
.
Printf
(
"Failed to generate snapshots: %v
\n
"
,
err
)
os
.
Exit
(
1
)
os
.
Exit
(
1
)
}
}
}
func
generateSnapshots
(
rootDir
string
)
error
{
for
_
,
result
:=
range
results
{
if
result
==
nil
{
forgeArtifactsDir
:=
filepath
.
Join
(
rootDir
,
"forge-artifacts"
)
continue
srcDir
:=
filepath
.
Join
(
rootDir
,
"src"
)
outDir
:=
filepath
.
Join
(
rootDir
,
"snapshots"
)
storageLayoutDir
:=
filepath
.
Join
(
outDir
,
"storageLayout"
)
abiDir
:=
filepath
.
Join
(
outDir
,
"abi"
)
fmt
.
Printf
(
"writing abi and storage layout snapshots to %s
\n
"
,
outDir
)
// Clean and recreate directories
if
err
:=
os
.
RemoveAll
(
storageLayoutDir
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to remove storage layout dir: %w"
,
err
)
}
if
err
:=
os
.
RemoveAll
(
abiDir
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to remove ABI dir: %w"
,
err
)
}
if
err
:=
os
.
MkdirAll
(
storageLayoutDir
,
os
.
ModePerm
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create storage layout dir: %w"
,
err
)
}
if
err
:=
os
.
MkdirAll
(
abiDir
,
os
.
ModePerm
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to create ABI dir: %w"
,
err
)
}
}
contractSources
,
err
:=
getAllContractsSources
(
srcDir
)
err
:=
common
.
WriteJSON
(
result
.
Abi
,
filepath
.
Join
(
abiDir
,
fmt
.
Sprintf
(
"%s.json"
,
result
.
ContractName
))
)
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to retrieve contract sources: %w"
,
err
)
fmt
.
Printf
(
"failed to write abi: %v
\n
"
,
err
)
os
.
Exit
(
1
)
}
}
knownAbis
:=
make
(
map
[
string
]
interface
{})
err
=
common
.
WriteJSON
(
result
.
StorageLayout
,
filepath
.
Join
(
storageLayoutDir
,
fmt
.
Sprintf
(
"%s.json"
,
result
.
ContractName
)))
for
_
,
contractFile
:=
range
contractSources
{
contractArtifacts
:=
filepath
.
Join
(
forgeArtifactsDir
,
contractFile
)
files
,
err
:=
os
.
ReadDir
(
contractArtifacts
)
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to scan contract artifacts of %q: %w"
,
contractFile
,
err
)
fmt
.
Printf
(
"failed to write storage layout: %v
\n
"
,
err
)
os
.
Exit
(
1
)
}
}
}
}
for
_
,
file
:=
range
files
{
func
processFile
(
file
string
)
(
*
SnapshotResult
,
[]
error
)
{
artifactPath
:=
filepath
.
Join
(
contractArtifacts
,
file
.
Name
())
artifact
,
err
:=
common
.
ReadForgeArtifact
(
file
)
data
,
err
:=
os
.
ReadFile
(
artifactPath
)
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to read artifact %q: %w"
,
artifactPath
,
err
)
return
nil
,
[]
error
{
err
}
}
var
artifact
ForgeArtifact
if
err
:=
json
.
Unmarshal
(
data
,
&
artifact
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to decode artifact %q: %w"
,
artifactPath
,
err
)
}
}
contractName
,
err
:=
parseArtifactName
(
file
.
Name
()
)
contractName
,
err
:=
parseArtifactName
(
file
)
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to parse artifact name %q: %w"
,
file
.
Name
(),
err
)
return
nil
,
[]
error
{
fmt
.
Errorf
(
"failed to parse artifact name %q: %w"
,
file
,
err
)}
}
}
// HACK: This is a hack to ignore libraries and abstract contracts. Not robust against changes to solc's internal ast repr
// Skip anything that isn't in the src directory.
if
artifact
.
Ast
==
nil
{
if
!
strings
.
HasPrefix
(
artifact
.
Ast
.
AbsolutePath
,
"src/"
)
{
return
fmt
.
Errorf
(
"ast isn't present in forge-artifacts. Did you run forge build with `--ast`? Artifact: %s"
,
artifactPath
)
return
nil
,
nil
}
}
// Check if the artifact is a contract
// Skip anything that isn't a proper contract.
isContract
:=
false
isContract
:=
false
for
_
,
node
:=
range
artifact
.
Ast
.
Nodes
{
for
_
,
node
:=
range
artifact
.
Ast
.
Nodes
{
if
node
.
NodeType
==
"ContractDefinition"
&&
if
node
.
NodeType
==
"ContractDefinition"
&&
...
@@ -136,18 +89,19 @@ func generateSnapshots(rootDir string) error {
...
@@ -136,18 +89,19 @@ func generateSnapshots(rootDir string) error {
}
}
}
}
if
!
isContract
{
if
!
isContract
{
fmt
.
Printf
(
"ignoring library/interface %s
\n
"
,
contractName
)
return
nil
,
nil
continue
}
}
storageLayout
:=
make
([]
AbiSpecStorageLayoutEntry
,
0
,
len
(
artifact
.
StorageLayout
.
Storage
))
storageLayout
:=
make
([]
solc
.
AbiSpecStorageLayoutEntry
,
0
,
len
(
artifact
.
StorageLayout
.
Storage
))
for
_
,
storageEntry
:=
range
artifact
.
StorageLayout
.
Storage
{
for
_
,
storageEntry
:=
range
artifact
.
StorageLayout
.
Storage
{
// convert ast-based type to solidity type
// Convert ast-based type to Solidity type.
typ
,
ok
:=
artifact
.
StorageLayout
.
Types
[
storageEntry
.
Type
]
typ
,
ok
:=
artifact
.
StorageLayout
.
Types
[
storageEntry
.
Type
]
if
!
ok
{
if
!
ok
{
return
fmt
.
Errorf
(
"undefined type for %s:%s"
,
contractName
,
storageEntry
.
Label
)
return
nil
,
[]
error
{
fmt
.
Errorf
(
"undefined type for %s:%s"
,
contractName
,
storageEntry
.
Label
)}
}
}
storageLayout
=
append
(
storageLayout
,
AbiSpecStorageLayoutEntry
{
// Convert to Solidity storage layout entry.
storageLayout
=
append
(
storageLayout
,
solc
.
AbiSpecStorageLayoutEntry
{
Label
:
storageEntry
.
Label
,
Label
:
storageEntry
.
Label
,
Bytes
:
typ
.
NumberOfBytes
,
Bytes
:
typ
.
NumberOfBytes
,
Offset
:
storageEntry
.
Offset
,
Offset
:
storageEntry
.
Offset
,
...
@@ -156,96 +110,31 @@ func generateSnapshots(rootDir string) error {
...
@@ -156,96 +110,31 @@ func generateSnapshots(rootDir string) error {
})
})
}
}
if
existingAbi
,
exists
:=
knownAbis
[
contractName
];
exists
{
return
&
SnapshotResult
{
if
!
jsonEqual
(
existingAbi
,
artifact
.
ABI
)
{
ContractName
:
contractName
,
return
fmt
.
Errorf
(
"detected multiple artifact versions with different ABIs for %s"
,
contractFile
)
Abi
:
artifact
.
Abi
.
Raw
,
}
else
{
StorageLayout
:
storageLayout
,
fmt
.
Printf
(
"detected multiple artifacts for %s
\n
"
,
contractName
)
},
nil
}
}
else
{
knownAbis
[
contractName
]
=
artifact
.
ABI
}
// Sort and write snapshots
if
err
:=
writeJSON
(
filepath
.
Join
(
abiDir
,
contractName
+
".json"
),
artifact
.
ABI
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to write ABI snapshot JSON of %q: %w"
,
contractName
,
err
)
}
if
err
:=
writeJSON
(
filepath
.
Join
(
storageLayoutDir
,
contractName
+
".json"
),
storageLayout
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to write storage layout snapshot JSON of %q: %w"
,
contractName
,
err
)
}
}
}
return
nil
}
func
getAllContractsSources
(
srcDir
string
)
([]
string
,
error
)
{
var
paths
[]
string
if
err
:=
readFilesRecursively
(
srcDir
,
&
paths
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to retrieve files: %w"
,
err
)
}
var
solFiles
[]
string
for
_
,
p
:=
range
paths
{
if
filepath
.
Ext
(
p
)
==
".sol"
{
solFiles
=
append
(
solFiles
,
filepath
.
Base
(
p
))
}
}
sort
.
Strings
(
solFiles
)
return
solFiles
,
nil
}
func
readFilesRecursively
(
dir
string
,
paths
*
[]
string
)
error
{
files
,
err
:=
os
.
ReadDir
(
dir
)
if
err
!=
nil
{
return
err
}
for
_
,
file
:=
range
files
{
filePath
:=
filepath
.
Join
(
dir
,
file
.
Name
())
if
file
.
IsDir
()
{
if
err
:=
readFilesRecursively
(
filePath
,
paths
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to recurse into %q: %w"
,
filePath
,
err
)
}
}
else
{
*
paths
=
append
(
*
paths
,
filePath
)
}
}
return
nil
}
}
// ContractName.0.9.8.json -> ContractName.sol
// ContractName.0.9.8.json -> ContractName.sol
// ContractName.json -> ContractName.sol
// ContractName.json -> ContractName.sol
func
parseArtifactName
(
artifactVersionFile
string
)
(
string
,
error
)
{
func
parseArtifactName
(
artifactVersionFile
string
)
(
string
,
error
)
{
re
:=
regexp
.
MustCompile
(
`(.*?)\.([0-9]+\.[0-9]+\.[0-9]+)?`
)
re
:=
regexp
.
MustCompile
(
`(.*?)\.([0-9]+\.[0-9]+\.[0-9]+)?`
)
match
:=
re
.
FindStringSubmatch
(
artifactVersionFile
)
baseName
:=
filepath
.
Base
(
artifactVersionFile
)
match
:=
re
.
FindStringSubmatch
(
baseName
)
if
len
(
match
)
<
2
{
if
len
(
match
)
<
2
{
return
""
,
fmt
.
Errorf
(
"invalid artifact file name: %q"
,
artifactVersionFile
)
return
""
,
fmt
.
Errorf
(
"invalid artifact file name: %q"
,
artifactVersionFile
)
}
}
return
match
[
1
],
nil
return
match
[
1
],
nil
}
}
func
writeJSON
(
filename
string
,
data
interface
{})
error
{
func
resetDirectory
(
dir
string
)
error
{
var
out
bytes
.
Buffer
if
err
:=
os
.
RemoveAll
(
dir
);
err
!=
nil
{
enc
:=
json
.
NewEncoder
(
&
out
)
return
fmt
.
Errorf
(
"failed to remove directory %q: %w"
,
dir
,
err
)
enc
.
SetEscapeHTML
(
false
)
enc
.
SetIndent
(
""
,
" "
)
err
:=
enc
.
Encode
(
data
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to encode data: %w"
,
err
)
}
}
jsonData
:=
out
.
Bytes
()
if
err
:=
os
.
MkdirAll
(
dir
,
os
.
ModePerm
);
err
!=
nil
{
if
len
(
jsonData
)
>
0
&&
jsonData
[
len
(
jsonData
)
-
1
]
==
'\n'
{
// strip newline
return
fmt
.
Errorf
(
"failed to create directory %q: %w"
,
dir
,
err
)
jsonData
=
jsonData
[
:
len
(
jsonData
)
-
1
]
}
if
err
:=
os
.
WriteFile
(
filename
,
jsonData
,
0644
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to write file: %w"
,
err
)
}
}
return
nil
return
nil
}
}
func
jsonEqual
(
a
,
b
interface
{})
bool
{
jsonA
,
errA
:=
json
.
Marshal
(
a
)
jsonB
,
errB
:=
json
.
Marshal
(
b
)
return
errA
==
nil
&&
errB
==
nil
&&
string
(
jsonA
)
==
string
(
jsonB
)
}
packages/contracts-bedrock/scripts/checks/common/util.go
View file @
26f508cc
package
common
package
common
import
(
import
(
"bytes"
"encoding/json"
"encoding/json"
"fmt"
"fmt"
"os"
"os"
"path/filepath"
"runtime"
"runtime"
"sync"
"sync"
"sync/atomic"
"sync/atomic"
...
@@ -100,8 +100,7 @@ func FindFiles(includes, excludes []string) (map[string]string, error) {
...
@@ -100,8 +100,7 @@ func FindFiles(includes, excludes []string) (map[string]string, error) {
return
nil
,
fmt
.
Errorf
(
"glob pattern error: %w"
,
err
)
return
nil
,
fmt
.
Errorf
(
"glob pattern error: %w"
,
err
)
}
}
for
_
,
match
:=
range
matches
{
for
_
,
match
:=
range
matches
{
name
:=
filepath
.
Base
(
match
)
included
[
match
]
=
match
included
[
name
]
=
match
}
}
}
}
...
@@ -112,7 +111,7 @@ func FindFiles(includes, excludes []string) (map[string]string, error) {
...
@@ -112,7 +111,7 @@ func FindFiles(includes, excludes []string) (map[string]string, error) {
return
nil
,
fmt
.
Errorf
(
"glob pattern error: %w"
,
err
)
return
nil
,
fmt
.
Errorf
(
"glob pattern error: %w"
,
err
)
}
}
for
_
,
match
:=
range
matches
{
for
_
,
match
:=
range
matches
{
excluded
[
filepath
.
Base
(
match
)
]
=
struct
{}{}
excluded
[
match
]
=
struct
{}{}
}
}
}
}
...
@@ -137,3 +136,22 @@ func ReadForgeArtifact(path string) (*solc.ForgeArtifact, error) {
...
@@ -137,3 +136,22 @@ func ReadForgeArtifact(path string) (*solc.ForgeArtifact, error) {
return
&
artifact
,
nil
return
&
artifact
,
nil
}
}
func
WriteJSON
(
data
interface
{},
path
string
)
error
{
var
out
bytes
.
Buffer
enc
:=
json
.
NewEncoder
(
&
out
)
enc
.
SetEscapeHTML
(
false
)
enc
.
SetIndent
(
""
,
" "
)
err
:=
enc
.
Encode
(
data
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to encode data: %w"
,
err
)
}
jsonData
:=
out
.
Bytes
()
if
len
(
jsonData
)
>
0
&&
jsonData
[
len
(
jsonData
)
-
1
]
==
'\n'
{
// strip newline
jsonData
=
jsonData
[
:
len
(
jsonData
)
-
1
]
}
if
err
:=
os
.
WriteFile
(
path
,
jsonData
,
0644
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to write file: %w"
,
err
)
}
return
nil
}
packages/contracts-bedrock/scripts/checks/test-names/main.go
View file @
26f508cc
...
@@ -41,7 +41,7 @@ func processFile(path string) (*common.Void, []error) {
...
@@ -41,7 +41,7 @@ func processFile(path string) (*common.Void, []error) {
func
extractTestNames
(
artifact
*
solc
.
ForgeArtifact
)
[]
string
{
func
extractTestNames
(
artifact
*
solc
.
ForgeArtifact
)
[]
string
{
isTest
:=
false
isTest
:=
false
for
_
,
entry
:=
range
artifact
.
Abi
.
Methods
{
for
_
,
entry
:=
range
artifact
.
Abi
.
Parsed
.
Methods
{
if
entry
.
Name
==
"IS_TEST"
{
if
entry
.
Name
==
"IS_TEST"
{
isTest
=
true
isTest
=
true
break
break
...
@@ -52,7 +52,7 @@ func extractTestNames(artifact *solc.ForgeArtifact) []string {
...
@@ -52,7 +52,7 @@ func extractTestNames(artifact *solc.ForgeArtifact) []string {
}
}
names
:=
[]
string
{}
names
:=
[]
string
{}
for
_
,
entry
:=
range
artifact
.
Abi
.
Methods
{
for
_
,
entry
:=
range
artifact
.
Abi
.
Parsed
.
Methods
{
if
!
strings
.
HasPrefix
(
entry
.
Name
,
"test"
)
{
if
!
strings
.
HasPrefix
(
entry
.
Name
,
"test"
)
{
continue
continue
}
}
...
...
packages/contracts-bedrock/scripts/checks/test-names/main_test.go
View file @
26f508cc
...
@@ -218,7 +218,8 @@ func TestExtractTestNames(t *testing.T) {
...
@@ -218,7 +218,8 @@ func TestExtractTestNames(t *testing.T) {
{
{
name
:
"valid test contract"
,
name
:
"valid test contract"
,
artifact
:
&
solc
.
ForgeArtifact
{
artifact
:
&
solc
.
ForgeArtifact
{
Abi
:
abi
.
ABI
{
Abi
:
solc
.
AbiType
{
Parsed
:
abi
.
ABI
{
Methods
:
map
[
string
]
abi
.
Method
{
Methods
:
map
[
string
]
abi
.
Method
{
"IS_TEST"
:
{
Name
:
"IS_TEST"
},
"IS_TEST"
:
{
Name
:
"IS_TEST"
},
"test_something_succeeds"
:
{
Name
:
"test_something_succeeds"
},
"test_something_succeeds"
:
{
Name
:
"test_something_succeeds"
},
...
@@ -228,6 +229,7 @@ func TestExtractTestNames(t *testing.T) {
...
@@ -228,6 +229,7 @@ func TestExtractTestNames(t *testing.T) {
},
},
},
},
},
},
},
want
:
[]
string
{
want
:
[]
string
{
"test_something_succeeds"
,
"test_something_succeeds"
,
"test_other_fails"
,
"test_other_fails"
,
...
@@ -237,28 +239,33 @@ func TestExtractTestNames(t *testing.T) {
...
@@ -237,28 +239,33 @@ func TestExtractTestNames(t *testing.T) {
{
{
name
:
"non-test contract"
,
name
:
"non-test contract"
,
artifact
:
&
solc
.
ForgeArtifact
{
artifact
:
&
solc
.
ForgeArtifact
{
Abi
:
abi
.
ABI
{
Abi
:
solc
.
AbiType
{
Parsed
:
abi
.
ABI
{
Methods
:
map
[
string
]
abi
.
Method
{
Methods
:
map
[
string
]
abi
.
Method
{
"test_something_succeeds"
:
{
Name
:
"test_something_succeeds"
},
"test_something_succeeds"
:
{
Name
:
"test_something_succeeds"
},
"not_a_test"
:
{
Name
:
"not_a_test"
},
"not_a_test"
:
{
Name
:
"not_a_test"
},
},
},
},
},
},
},
},
want
:
nil
,
want
:
nil
,
},
},
{
{
name
:
"empty contract"
,
name
:
"empty contract"
,
artifact
:
&
solc
.
ForgeArtifact
{
artifact
:
&
solc
.
ForgeArtifact
{
Abi
:
abi
.
ABI
{
Abi
:
solc
.
AbiType
{
Parsed
:
abi
.
ABI
{
Methods
:
map
[
string
]
abi
.
Method
{},
Methods
:
map
[
string
]
abi
.
Method
{},
},
},
},
},
},
want
:
nil
,
want
:
nil
,
},
},
{
{
name
:
"test contract with no test methods"
,
name
:
"test contract with no test methods"
,
artifact
:
&
solc
.
ForgeArtifact
{
artifact
:
&
solc
.
ForgeArtifact
{
Abi
:
abi
.
ABI
{
Abi
:
solc
.
AbiType
{
Parsed
:
abi
.
ABI
{
Methods
:
map
[
string
]
abi
.
Method
{
Methods
:
map
[
string
]
abi
.
Method
{
"IS_TEST"
:
{
Name
:
"IS_TEST"
},
"IS_TEST"
:
{
Name
:
"IS_TEST"
},
"not_a_test"
:
{
Name
:
"not_a_test"
},
"not_a_test"
:
{
Name
:
"not_a_test"
},
...
@@ -266,6 +273,7 @@ func TestExtractTestNames(t *testing.T) {
...
@@ -266,6 +273,7 @@ func TestExtractTestNames(t *testing.T) {
},
},
},
},
},
},
},
want
:
[]
string
{},
want
:
[]
string
{},
},
},
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment