1
1
package com .bazel_diff ;
2
2
3
+ import com .google .common .hash .Hasher ;
4
+ import com .google .common .hash .Hashing ;
3
5
import com .google .devtools .build .lib .query2 .proto .proto2api .Build ;
4
6
5
7
import java .io .*;
6
8
import java .nio .charset .StandardCharsets ;
7
9
import java .io .IOException ;
8
10
import java .nio .file .Files ;
9
11
import java .nio .file .Path ;
10
- import java .security .MessageDigest ;
11
- import java .security .NoSuchAlgorithmException ;
12
12
import java .time .Duration ;
13
13
import java .time .Instant ;
14
14
import java .util .ArrayList ;
15
- import java .util .HashMap ;
16
15
import java .util .List ;
17
16
import java .util .Map ;
17
+ import java .util .concurrent .atomic .AtomicReference ;
18
18
import java .util .stream .Collectors ;
19
19
import java .util .Arrays ;
20
20
21
21
interface BazelClient {
22
22
List <BazelTarget > queryAllTargets () throws IOException ;
23
- Map <String , BazelSourceFileTarget > queryAllSourcefileTargets () throws IOException , NoSuchAlgorithmException ;
23
+
24
+ Map <String , BazelSourceFileTarget > queryAllSourcefileTargets () throws Exception ;
24
25
}
25
26
26
27
class BazelClientImpl implements BazelClient {
@@ -43,8 +44,8 @@ class BazelClientImpl implements BazelClient {
43
44
) {
44
45
this .workingDirectory = workingDirectory .normalize ();
45
46
this .bazelPath = bazelPath ;
46
- this .startupOptions = startupOptions != null ? Arrays .asList (startupOptions .split (" " )): new ArrayList <String >();
47
- this .commandOptions = commandOptions != null ? Arrays .asList (commandOptions .split (" " )): new ArrayList <String >();
47
+ this .startupOptions = startupOptions != null ? Arrays .asList (startupOptions .split (" " )) : new ArrayList <String >();
48
+ this .commandOptions = commandOptions != null ? Arrays .asList (commandOptions .split (" " )) : new ArrayList <String >();
48
49
this .verbose = verbose ;
49
50
this .keepGoing = keepGoing ;
50
51
this .debug = debug ;
@@ -59,11 +60,11 @@ public List<BazelTarget> queryAllTargets() throws IOException {
59
60
long querySeconds = Duration .between (queryStartTime , queryEndTime ).getSeconds ();
60
61
System .out .printf ("BazelDiff: All targets queried in %d seconds%n" , querySeconds );
61
62
}
62
- return targets .stream ().map ( target -> new BazelTargetImpl (target )).collect (Collectors .toList ());
63
+ return targets .stream ().map (target -> new BazelTargetImpl (target )).collect (Collectors .toList ());
63
64
}
64
65
65
66
@ Override
66
- public Map <String , BazelSourceFileTarget > queryAllSourcefileTargets () throws IOException , NoSuchAlgorithmException {
67
+ public Map <String , BazelSourceFileTarget > queryAllSourcefileTargets () throws Exception {
67
68
Instant queryStartTime = Instant .now ();
68
69
List <Build .Target > targets = performBazelQuery ("kind('source file', //...:all-targets)" );
69
70
Instant queryEndTime = Instant .now ();
@@ -78,26 +79,59 @@ public Map<String, BazelSourceFileTarget> queryAllSourcefileTargets() throws IOE
78
79
return sourceFileTargets ;
79
80
}
80
81
81
- private Map <String , BazelSourceFileTarget > processBazelSourcefileTargets (List <Build .Target > targets , Boolean readSourcefileTargets ) throws IOException , NoSuchAlgorithmException {
82
- Map <String , BazelSourceFileTarget > sourceTargets = new HashMap <>();
83
- for (Build .Target target : targets ) {
84
- Build .SourceFile sourceFile = target .getSourceFile ();
85
- if (sourceFile != null ) {
86
- MessageDigest digest = MessageDigest .getInstance ("SHA-256" );
87
- digest .update (sourceFile .getNameBytes ().toByteArray ());
88
- for (String subinclude : sourceFile .getSubincludeList ()) {
89
- digest .update (subinclude .getBytes ());
90
- }
91
- BazelSourceFileTargetImpl sourceFileTarget = new BazelSourceFileTargetImpl (
92
- sourceFile .getName (),
93
- digest .digest ().clone (),
94
- readSourcefileTargets ? workingDirectory : null ,
95
- verbose
96
- );
97
- sourceTargets .put (sourceFileTarget .getName (), sourceFileTarget );
98
- }
82
+ private Map <String , BazelSourceFileTarget > processBazelSourcefileTargets (List <Build .Target > targets , Boolean readSourcefileTargets ) throws Exception {
83
+ AtomicReference <Exception > exception = new AtomicReference (null );
84
+ Map <String , BazelSourceFileTarget > result = targets .parallelStream ().map ((target -> {
85
+ Build .SourceFile sourceFile = target .getSourceFile ();
86
+ if (sourceFile != null ) {
87
+ Hasher hasher = Hashing .sha256 ().newHasher ();
88
+ hasher .putBytes (sourceFile .getNameBytes ().toByteArray ());
89
+ for (String subinclude : sourceFile .getSubincludeList ()) {
90
+ hasher .putBytes (subinclude .getBytes ());
91
+ }
92
+ BazelSourceFileTargetImpl sourceFileTarget = null ;
93
+ try {
94
+ sourceFileTarget = new BazelSourceFileTargetImpl (
95
+ sourceFile .getName (),
96
+ hasher .hash ().asBytes ().clone (),
97
+ readSourcefileTargets ? workingDirectory : null ,
98
+ verbose
99
+ );
100
+ } catch (Exception e ) {
101
+ exception .set (e );
102
+ }
103
+ return new SourceTargetEntry (sourceFileTarget .getName (), sourceFileTarget );
104
+ }
105
+ return null ;
106
+ }))
107
+ .filter (pair -> pair != null )
108
+ .collect (Collectors .toMap (SourceTargetEntry ::getKey , SourceTargetEntry ::getValue ));
109
+
110
+ //Rethrowing nested parallel exception
111
+ Exception nestedException = exception .get ();
112
+ if (nestedException != null ) {
113
+ throw nestedException ;
114
+ }
115
+
116
+ return result ;
117
+ }
118
+
119
+ private static class SourceTargetEntry <K extends String , V extends BazelSourceFileTargetImpl > {
120
+ private K key ;
121
+ private V value ;
122
+
123
+ public SourceTargetEntry (K key , V value ) {
124
+ this .key = key ;
125
+ this .value = value ;
126
+ }
127
+
128
+ public K getKey () {
129
+ return key ;
130
+ }
131
+
132
+ public V getValue () {
133
+ return value ;
99
134
}
100
- return sourceTargets ;
101
135
}
102
136
103
137
private List <Build .Target > performBazelQuery (String query ) throws IOException {
@@ -134,18 +168,20 @@ private List<Build.Target> performBazelQuery(String query) throws IOException {
134
168
BufferedReader stdError = new BufferedReader (new InputStreamReader (process .getErrorStream ()));
135
169
Thread tStdError = new Thread (new Runnable () {
136
170
String line = null ;
171
+
137
172
public void run () {
138
173
try {
139
174
while ((line = stdError .readLine ()) != null ) {
140
175
if (verbose ) {
141
176
System .out .println (line );
142
177
}
143
178
144
- if (Thread .currentThread ().isInterrupted ()) {
179
+ if (Thread .currentThread ().isInterrupted ()) {
145
180
return ;
146
181
}
147
182
}
148
- } catch (IOException e ) {}
183
+ } catch (IOException e ) {
184
+ }
149
185
}
150
186
});
151
187
tStdError .start ();
0 commit comments