-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
versions.go
142 lines (132 loc) · 3.94 KB
/
versions.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package gethwrappers
import (
"bufio"
"fmt"
"os"
"path/filepath"
"regexp"
"sort"
"strings"
"github.com/pkg/errors"
"go.uber.org/multierr"
)
// ContractVersion records information about the solidity compiler artifact a
// golang contract wrapper package depends on.
type ContractVersion struct {
// Hash of the artifact at the timem the wrapper was last generated
Hash string
// Path to compiled abi file
AbiPath string
// Path to compiled bin file (if exists, this can be empty)
BinaryPath string
}
// IntegratedVersion carries the full versioning information checked in this test
type IntegratedVersion struct {
// Version of geth last used to generate the wrappers
GethVersion string
// { golang-pkg-name: version_info }
ContractVersions map[string]ContractVersion
}
func dbPath() (path string, err error) {
dirOfThisTest, err := os.Getwd()
if err != nil {
return "", err
}
dBBasename := "generated-wrapper-dependency-versions-do-not-edit.txt"
return filepath.Join(dirOfThisTest, "generation", dBBasename), nil
}
func versionsDBLineReader() (*bufio.Scanner, error) {
versionsDBPath, err := dbPath()
if err != nil {
return nil, errors.Wrapf(err, "could not construct versions DB path")
}
versionsDBFile, err := os.Open(versionsDBPath)
if err != nil {
return nil, errors.Wrapf(err, "could not open versions database")
}
return bufio.NewScanner(versionsDBFile), nil
}
// ReadVersionsDB populates an IntegratedVersion with all the info in the
// versions DB
func ReadVersionsDB() (*IntegratedVersion, error) {
rv := IntegratedVersion{}
rv.ContractVersions = make(map[string]ContractVersion)
db, err := versionsDBLineReader()
if err != nil {
return nil, err
}
for db.Scan() {
line := strings.Fields(db.Text())
if !strings.HasSuffix(line[0], ":") {
return nil, errors.Errorf(
`each line in versions.txt should start with "$TOPIC:"`)
}
topic := stripTrailingColon(line[0], "")
if topic == "GETH_VERSION" {
if len(line) != 2 {
return nil, errors.Errorf("GETH_VERSION line should contain geth "+
"version, and only that: %s", line)
}
if rv.GethVersion != "" {
return nil, errors.Errorf("more than one geth version")
}
rv.GethVersion = line[1]
} else { // It's a wrapper from a compiler artifact
if len(line) != 4 {
return nil, errors.Errorf(`"%s" should have four elements `+
`"<pkgname>: <abi-path> <bin-path> <hash>"`,
db.Text())
}
_, alreadyExists := rv.ContractVersions[topic]
if alreadyExists {
return nil, errors.Errorf(`topic "%s" already mentioned`, topic)
}
rv.ContractVersions[topic] = ContractVersion{
AbiPath: line[1], BinaryPath: line[2], Hash: line[3],
}
}
}
return &rv, nil
}
var stripTrailingColon = regexp.MustCompile(":$").ReplaceAllString
func WriteVersionsDB(db *IntegratedVersion) (err error) {
versionsDBPath, err := dbPath()
if err != nil {
return errors.Wrap(err, "could not construct path to versions DB")
}
f, err := os.Create(versionsDBPath)
if err != nil {
return errors.Wrapf(err, "while opening %s", versionsDBPath)
}
defer func() {
if cerr := f.Close(); cerr != nil {
err = multierr.Append(err, cerr)
}
}()
gethLine := "GETH_VERSION: " + db.GethVersion + "\n"
n, err := f.WriteString(gethLine)
if err != nil {
return errors.Wrapf(err, "while recording geth version line")
}
if n != len(gethLine) {
return errors.Errorf("failed to write entire geth version line, %s", gethLine)
}
var pkgNames []string
for name := range db.ContractVersions {
pkgNames = append(pkgNames, name)
}
sort.Strings(pkgNames)
for _, name := range pkgNames {
vinfo := db.ContractVersions[name]
versionLine := fmt.Sprintf("%s: %s %s %s\n", name,
vinfo.AbiPath, vinfo.BinaryPath, vinfo.Hash)
n, err = f.WriteString(versionLine)
if err != nil {
return errors.Wrapf(err, "while recording %s version line", name)
}
if n != len(versionLine) {
return errors.Errorf("failed to write entire version line %s", versionLine)
}
}
return nil
}