@@ -24,9 +24,14 @@ Usage: go run build/ci.go <command> <command flags/arguments>
24
24
25
25
Available commands are:
26
26
27
- install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables
28
- test [ -coverage ] [ packages... ] -- runs the tests
29
- lint -- runs certain pre-selected linters
27
+ lint -- runs certain pre-selected linters
28
+ check_tidy -- verifies that everything is 'go mod tidy'-ed
29
+ check_generate -- verifies that everything is 'go generate'-ed
30
+ check_baddeps -- verifies that certain dependencies are avoided
31
+
32
+ install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables
33
+ test [ -coverage ] [ packages... ] -- runs the tests
34
+
30
35
archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -signify key-envvar ] [ -upload dest ] -- archives build artifacts
31
36
importkeys -- imports signing keys from env
32
37
debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package
@@ -39,11 +44,9 @@ package main
39
44
40
45
import (
41
46
"bytes"
42
- "crypto/sha256"
43
47
"encoding/base64"
44
48
"flag"
45
49
"fmt"
46
- "io"
47
50
"log"
48
51
"os"
49
52
"os/exec"
@@ -156,6 +159,12 @@ func main() {
156
159
doTest (os .Args [2 :])
157
160
case "lint" :
158
161
doLint (os .Args [2 :])
162
+ case "check_tidy" :
163
+ doCheckTidy ()
164
+ case "check_generate" :
165
+ doCheckGenerate ()
166
+ case "check_baddeps" :
167
+ doCheckBadDeps ()
159
168
case "archive" :
160
169
doArchive (os .Args [2 :])
161
170
case "dockerx" :
@@ -168,8 +177,6 @@ func main() {
168
177
doPurge (os .Args [2 :])
169
178
case "sanitycheck" :
170
179
doSanityCheck ()
171
- case "generate" :
172
- doGenerate ()
173
180
default :
174
181
log .Fatal ("unknown command " , os .Args [1 ])
175
182
}
@@ -348,130 +355,93 @@ func downloadSpecTestFixtures(csdb *build.ChecksumDB, cachedir string) string {
348
355
return filepath .Join (cachedir , base )
349
356
}
350
357
351
- // hashAllSourceFiles iterates all files under the top-level project directory
352
- // computing the hash of each file (excluding files within the tests
353
- // subrepo)
354
- func hashAllSourceFiles () (map [string ][32 ]byte , error ) {
355
- res := make (map [string ][32 ]byte )
356
- err := filepath .WalkDir ("." , func (path string , d os.DirEntry , err error ) error {
357
- if strings .HasPrefix (path , filepath .FromSlash ("tests/testdata" )) {
358
- return filepath .SkipDir
359
- }
360
- if ! d .Type ().IsRegular () {
361
- return nil
362
- }
363
- // open the file and hash it
364
- f , err := os .OpenFile (path , os .O_RDONLY , 0666 )
365
- if err != nil {
366
- return err
367
- }
368
- hasher := sha256 .New ()
369
- if _ , err := io .Copy (hasher , f ); err != nil {
370
- return err
371
- }
372
- res [path ] = [32 ]byte (hasher .Sum (nil ))
373
- return nil
374
- })
375
- if err != nil {
376
- return nil , err
377
- }
378
- return res , nil
379
- }
358
+ // doCheckTidy assets that the Go modules files are tidied already.
359
+ func doCheckTidy () {
360
+ targets := []string {"go.mod" , "go.sum" }
380
361
381
- // hashSourceFiles iterates the provided set of filepaths (relative to the top-level geth project directory)
382
- // computing the hash of each file.
383
- func hashSourceFiles (files []string ) (map [string ][32 ]byte , error ) {
384
- res := make (map [string ][32 ]byte )
385
- for _ , filePath := range files {
386
- f , err := os .OpenFile (filePath , os .O_RDONLY , 0666 )
387
- if err != nil {
388
- return nil , err
389
- }
390
- hasher := sha256 .New ()
391
- if _ , err := io .Copy (hasher , f ); err != nil {
392
- return nil , err
393
- }
394
- res [filePath ] = [32 ]byte (hasher .Sum (nil ))
395
- }
396
- return res , nil
397
- }
398
-
399
- // compareHashedFilesets compares two maps (key is relative file path to top-level geth directory, value is its hash)
400
- // and returns the list of file paths whose hashes differed.
401
- func compareHashedFilesets (preHashes map [string ][32 ]byte , postHashes map [string ][32 ]byte ) []string {
402
- updates := []string {}
403
- for path , postHash := range postHashes {
404
- preHash , ok := preHashes [path ]
405
- if ! ok || preHash != postHash {
406
- updates = append (updates , path )
407
- }
362
+ hashes , err := build .HashFiles (targets )
363
+ if err != nil {
364
+ log .Fatalf ("failed to hash go.mod/go.sum: %v" , err )
408
365
}
409
- return updates
410
- }
366
+ build .MustRun (new (build.GoToolchain ).Go ("mod" , "tidy" ))
411
367
412
- // doGoModTidy runs 'go mod tidy' and asserts that go.sum/go.mod do not change
413
- // as a result.
414
- func doGoModTidy () {
415
- targetFiles := []string {"go.mod" , "go.sum" }
416
- preHashes , err := hashSourceFiles (targetFiles )
368
+ tidied , err := build .HashFiles (targets )
417
369
if err != nil {
418
- log .Fatal ("failed to hash go.mod/go.sum" , "err" , err )
419
- }
420
- tc := new (build.GoToolchain )
421
- c := tc .Go ("mod" , "tidy" )
422
- build .MustRun (c )
423
- postHashes , err := hashSourceFiles (targetFiles )
424
- updates := compareHashedFilesets (preHashes , postHashes )
425
- for _ , updatedFile := range updates {
426
- fmt .Fprintf (os .Stderr , "changed file %s\n " , updatedFile )
370
+ log .Fatalf ("failed to rehash go.mod/go.sum: %v" , err )
427
371
}
428
- if len (updates ) != 0 {
429
- log .Fatal ( "go.sum and/or go.mod were updated by running 'go mod tidy'" )
372
+ if updates := build . DiffHashes ( hashes , tidied ); len (updates ) > 0 {
373
+ log .Fatalf ( "files changed on running 'go mod tidy': %v" , updates )
430
374
}
375
+ fmt .Println ("No untidy module files detected." )
431
376
}
432
377
433
- // doGenerate ensures that re-generating generated files does not cause
434
- // any mutations in the source file tree: i.e. all generated files were
435
- // updated and committed. Any stale generated files are updated.
436
- func doGenerate () {
378
+ // doCheckGenerate ensures that re-generating generated files does not cause
379
+ // any mutations in the source file tree.
380
+ func doCheckGenerate () {
437
381
var (
438
- tc = new (build.GoToolchain )
439
382
cachedir = flag .String ("cachedir" , "./build/cache" , "directory for caching binaries." )
440
- verify = flag .Bool ("verify" , false , "check whether any files are changed by go generate" )
441
383
)
384
+ // Compute the origin hashes of all the files
385
+ var hashes map [string ][32 ]byte
442
386
443
- protocPath := downloadProtoc (* cachedir )
444
- protocGenGoPath := downloadProtocGenGo (* cachedir )
445
-
446
- var preHashes map [string ][32 ]byte
447
- if * verify {
448
- var err error
449
- preHashes , err = hashAllSourceFiles ()
450
- if err != nil {
451
- log .Fatal ("failed to compute map of source hashes" , "err" , err )
452
- }
387
+ var err error
388
+ hashes , err = build .HashFolder ("." , []string {"tests/testdata" , "build/cache" })
389
+ if err != nil {
390
+ log .Fatal ("Error computing hashes" , "err" , err )
453
391
}
454
-
455
- c := tc .Go ("generate" , "./..." )
392
+ // Run any go generate steps we might be missing
393
+ var (
394
+ protocPath = downloadProtoc (* cachedir )
395
+ protocGenGoPath = downloadProtocGenGo (* cachedir )
396
+ )
397
+ c := new (build.GoToolchain ).Go ("generate" , "./..." )
456
398
pathList := []string {filepath .Join (protocPath , "bin" ), protocGenGoPath , os .Getenv ("PATH" )}
457
399
c .Env = append (c .Env , "PATH=" + strings .Join (pathList , string (os .PathListSeparator )))
458
400
build .MustRun (c )
459
401
460
- if ! * verify {
461
- return
462
- }
463
- // Check if files were changed.
464
- postHashes , err := hashAllSourceFiles ()
402
+ // Check if generate file hashes have changed
403
+ generated , err := build .HashFolder ("." , []string {"tests/testdata" , "build/cache" })
465
404
if err != nil {
466
- log .Fatal ( "error computing source tree file hashes" , "err " , err )
405
+ log .Fatalf ( "Error re- computing hashes: %v " , err )
467
406
}
468
- updates := compareHashedFilesets ( preHashes , postHashes )
469
- for _ , updatedFile := range updates {
470
- fmt . Fprintf ( os . Stderr , " changed file %s \n " , updatedFile )
407
+ updates := build . DiffHashes ( hashes , generated )
408
+ for _ , file := range updates {
409
+ log . Printf ( "File changed: %s " , file )
471
410
}
472
411
if len (updates ) != 0 {
473
412
log .Fatal ("One or more generated files were updated by running 'go generate ./...'" )
474
413
}
414
+ fmt .Println ("No stale files detected." )
415
+ }
416
+
417
+ // doCheckBadDeps verifies whether certain unintended dependencies between some
418
+ // packages leak into the codebase due to a refactor. This is not an exhaustive
419
+ // list, rather something we build up over time at sensitive places.
420
+ func doCheckBadDeps () {
421
+ baddeps := [][2 ]string {
422
+ // Rawdb tends to be a dumping ground for db utils, sometimes leaking the db itself
423
+ {"github.com/ethereum/go-ethereum/core/rawdb" , "github.com/ethereum/go-ethereum/ethdb/leveldb" },
424
+ {"github.com/ethereum/go-ethereum/core/rawdb" , "github.com/ethereum/go-ethereum/ethdb/pebbledb" },
425
+ }
426
+ tc := new (build.GoToolchain )
427
+
428
+ var failed bool
429
+ for _ , rule := range baddeps {
430
+ out , err := tc .Go ("list" , "-deps" , rule [0 ]).CombinedOutput ()
431
+ if err != nil {
432
+ log .Fatalf ("Failed to list '%s' dependencies: %v" , rule [0 ], err )
433
+ }
434
+ for _ , line := range strings .Split (string (out ), "\n " ) {
435
+ if strings .TrimSpace (line ) == rule [1 ] {
436
+ log .Printf ("Found bad dependency '%s' -> '%s'" , rule [0 ], rule [1 ])
437
+ failed = true
438
+ }
439
+ }
440
+ }
441
+ if failed {
442
+ log .Fatalf ("Bad dependencies detected." )
443
+ }
444
+ fmt .Println ("No bad dependencies detected." )
475
445
}
476
446
477
447
// doLint runs golangci-lint on requested packages.
@@ -488,8 +458,6 @@ func doLint(cmdline []string) {
488
458
linter := downloadLinter (* cachedir )
489
459
lflags := []string {"run" , "--config" , ".golangci.yml" }
490
460
build .MustRunCommandWithOutput (linter , append (lflags , packages ... )... )
491
-
492
- doGoModTidy ()
493
461
fmt .Println ("You have achieved perfection." )
494
462
}
495
463
0 commit comments