@@ -5,30 +5,45 @@ import (
5
5
"fmt"
6
6
"os"
7
7
"path/filepath"
8
+ "sync"
9
+ "sync/atomic"
8
10
9
11
"github.com/constabulary/gb"
10
12
"github.com/constabulary/gb/cmd"
11
13
"github.com/constabulary/gb/fileutils"
12
14
"github.com/constabulary/gb/vendor"
13
15
)
14
16
17
+ var (
18
+ rbInsecure bool // Allow the use of insecure protocols
19
+ rbConnections uint // Count of concurrent download connections
20
+ )
21
+
15
22
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" )
17
25
}
18
26
19
27
var cmdRestore = & cmd.Command {
20
28
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 .
24
32
25
33
Flags:
26
34
-precaire
27
35
allow the use of insecure protocols.
36
+ -connections
37
+ count of parallel download connections.
28
38
29
39
` ,
30
40
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
+ }
32
47
},
33
48
AddFlags : addRestoreFlags ,
34
49
}
@@ -39,33 +54,61 @@ func restore(ctx *gb.Context) error {
39
54
return fmt .Errorf ("could not load manifest: %v" , err )
40
55
}
41
56
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
+
42
73
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 ()
54
78
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
+ }
60
82
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 )
64
98
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 )
67
102
}
103
+ }
68
104
105
+ if err := fileutils .Copypath (dst , src ); err != nil {
106
+ return err
69
107
}
108
+
109
+ if err := wc .Destroy (); err != nil {
110
+ return err
111
+ }
112
+
70
113
return nil
71
114
}
0 commit comments