Skip to content
This repository was archived by the owner on Mar 6, 2020. It is now read-only.

Commit e56b63d

Browse files
committed
gb-vendor: parallelize dependencies download in rebuild
Upstreaming FiloSottile/gvt#10 by @petrkotek
1 parent fd27784 commit e56b63d

File tree

1 file changed

+69
-26
lines changed

1 file changed

+69
-26
lines changed

cmd/gb-vendor/restore.go

Lines changed: 69 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,45 @@ import (
55
"fmt"
66
"os"
77
"path/filepath"
8+
"sync"
9+
"sync/atomic"
810

911
"github.com/constabulary/gb"
1012
"github.com/constabulary/gb/cmd"
1113
"github.com/constabulary/gb/fileutils"
1214
"github.com/constabulary/gb/vendor"
1315
)
1416

17+
var (
18+
rbInsecure bool // Allow the use of insecure protocols
19+
rbConnections uint // Count of concurrent download connections
20+
)
21+
1522
func addRestoreFlags(fs *flag.FlagSet) {
16-
fs.BoolVar(&insecure, "precaire", false, "allow the use of insecure protocols")
23+
fs.BoolVar(&rbInsecure, "precaire", false, "allow the use of insecure protocols")
24+
fs.UintVar(&rbConnections, "connections", 8, "count of parallel download connections")
1725
}
1826

1927
var cmdRestore = &cmd.Command{
2028
Name: "restore",
21-
UsageLine: "restore [-precaire]",
22-
Short: "restore dependencies from the manifest",
23-
Long: `Restore vendor dependecies.
29+
UsageLine: "restore [-precaire] [-connections N]",
30+
Short: "restore dependencies from manifest",
31+
Long: `restore fetches the dependencies listed in the manifest.
2432
2533
Flags:
2634
-precaire
2735
allow the use of insecure protocols.
36+
-connections
37+
count of parallel download connections.
2838
2939
`,
3040
Run: func(ctx *gb.Context, args []string) error {
31-
return restore(ctx)
41+
switch len(args) {
42+
case 0:
43+
return restore(ctx)
44+
default:
45+
return fmt.Errorf("restore takes no arguments")
46+
}
3247
},
3348
AddFlags: addRestoreFlags,
3449
}
@@ -39,33 +54,61 @@ func restore(ctx *gb.Context) error {
3954
return fmt.Errorf("could not load manifest: %v", err)
4055
}
4156

57+
var errors uint32
58+
var wg sync.WaitGroup
59+
depC := make(chan vendor.Dependency)
60+
for i := 0; i < int(rbConnections); i++ {
61+
wg.Add(1)
62+
go func() {
63+
defer wg.Done()
64+
for d := range depC {
65+
if err := downloadDependency(ctx, d); err != nil {
66+
fmt.Printf("%s: %v", d.Importpath, err)
67+
atomic.AddUint32(&errors, 1)
68+
}
69+
}
70+
}()
71+
}
72+
4273
for _, dep := range m.Dependencies {
43-
fmt.Printf("Getting %s\n", dep.Importpath)
44-
repo, _, err := vendor.DeduceRemoteRepo(dep.Importpath, insecure)
45-
if err != nil {
46-
return fmt.Errorf("Could not process dependency: %s", err)
47-
}
48-
wc, err := repo.Checkout("", "", dep.Revision)
49-
if err != nil {
50-
return fmt.Errorf("Could not retrieve dependency: %s", err)
51-
}
52-
dst := filepath.Join(ctx.Projectdir(), "vendor", "src", dep.Importpath)
53-
src := filepath.Join(wc.Dir(), dep.Path)
74+
depC <- dep
75+
}
76+
close(depC)
77+
wg.Wait()
5478

55-
if _, err := os.Stat(dst); err == nil {
56-
if err := fileutils.RemoveAll(dst); err != nil {
57-
return fmt.Errorf("dependency could not be deleted: %v", err)
58-
}
59-
}
79+
if errors > 0 {
80+
return fmt.Errorf("failed to fetch %d dependencies", errors)
81+
}
6082

61-
if err := fileutils.Copypath(dst, src); err != nil {
62-
return err
63-
}
83+
return nil
84+
}
85+
86+
func downloadDependency(ctx *gb.Context, dep vendor.Dependency) error {
87+
fmt.Printf("Getting %s\n", dep.Importpath)
88+
repo, _, err := vendor.DeduceRemoteRepo(dep.Importpath, rbInsecure)
89+
if err != nil {
90+
return fmt.Errorf("dependency could not be processed: %s", err)
91+
}
92+
wc, err := repo.Checkout("", "", dep.Revision)
93+
if err != nil {
94+
return fmt.Errorf("dependency could not be fetched: %s", err)
95+
}
96+
dst := filepath.Join(ctx.Projectdir(), "vendor", "src", dep.Importpath)
97+
src := filepath.Join(wc.Dir(), dep.Path)
6498

65-
if err := wc.Destroy(); err != nil {
66-
return err
99+
if _, err := os.Stat(dst); err == nil {
100+
if err := fileutils.RemoveAll(dst); err != nil {
101+
return fmt.Errorf("dependency could not be deleted: %v", err)
67102
}
103+
}
68104

105+
if err := fileutils.Copypath(dst, src); err != nil {
106+
return err
69107
}
108+
109+
if err := wc.Destroy(); err != nil {
110+
return err
111+
}
112+
70113
return nil
71114
}

0 commit comments

Comments
 (0)