11package com .bazel_diff ;
22
3+ import com .google .common .hash .Hasher ;
4+ import com .google .common .hash .Hashing ;
35import com .google .devtools .build .lib .query2 .proto .proto2api .Build ;
46
57import java .io .*;
68import java .nio .charset .StandardCharsets ;
79import java .io .IOException ;
810import java .nio .file .Files ;
911import java .nio .file .Path ;
10- import java .security .MessageDigest ;
11- import java .security .NoSuchAlgorithmException ;
1212import java .time .Duration ;
1313import java .time .Instant ;
1414import java .util .ArrayList ;
15- import java .util .HashMap ;
1615import java .util .List ;
1716import java .util .Map ;
17+ import java .util .concurrent .atomic .AtomicReference ;
1818import java .util .stream .Collectors ;
1919import java .util .Arrays ;
2020
2121interface BazelClient {
2222 List <BazelTarget > queryAllTargets () throws IOException ;
23- Map <String , BazelSourceFileTarget > queryAllSourcefileTargets () throws IOException , NoSuchAlgorithmException ;
23+
24+ Map <String , BazelSourceFileTarget > queryAllSourcefileTargets () throws Exception ;
2425}
2526
2627class BazelClientImpl implements BazelClient {
@@ -43,8 +44,8 @@ class BazelClientImpl implements BazelClient {
4344 ) {
4445 this .workingDirectory = workingDirectory .normalize ();
4546 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 >();
4849 this .verbose = verbose ;
4950 this .keepGoing = keepGoing ;
5051 this .debug = debug ;
@@ -59,11 +60,11 @@ public List<BazelTarget> queryAllTargets() throws IOException {
5960 long querySeconds = Duration .between (queryStartTime , queryEndTime ).getSeconds ();
6061 System .out .printf ("BazelDiff: All targets queried in %d seconds%n" , querySeconds );
6162 }
62- return targets .stream ().map ( target -> new BazelTargetImpl (target )).collect (Collectors .toList ());
63+ return targets .stream ().map (target -> new BazelTargetImpl (target )).collect (Collectors .toList ());
6364 }
6465
6566 @ Override
66- public Map <String , BazelSourceFileTarget > queryAllSourcefileTargets () throws IOException , NoSuchAlgorithmException {
67+ public Map <String , BazelSourceFileTarget > queryAllSourcefileTargets () throws Exception {
6768 Instant queryStartTime = Instant .now ();
6869 List <Build .Target > targets = performBazelQuery ("kind('source file', //...:all-targets)" );
6970 Instant queryEndTime = Instant .now ();
@@ -78,26 +79,59 @@ public Map<String, BazelSourceFileTarget> queryAllSourcefileTargets() throws IOE
7879 return sourceFileTargets ;
7980 }
8081
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 ;
99134 }
100- return sourceTargets ;
101135 }
102136
103137 private List <Build .Target > performBazelQuery (String query ) throws IOException {
@@ -134,18 +168,20 @@ private List<Build.Target> performBazelQuery(String query) throws IOException {
134168 BufferedReader stdError = new BufferedReader (new InputStreamReader (process .getErrorStream ()));
135169 Thread tStdError = new Thread (new Runnable () {
136170 String line = null ;
171+
137172 public void run () {
138173 try {
139174 while ((line = stdError .readLine ()) != null ) {
140175 if (verbose ) {
141176 System .out .println (line );
142177 }
143178
144- if (Thread .currentThread ().isInterrupted ()) {
179+ if (Thread .currentThread ().isInterrupted ()) {
145180 return ;
146181 }
147182 }
148- } catch (IOException e ) {}
183+ } catch (IOException e ) {
184+ }
149185 }
150186 });
151187 tStdError .start ();
0 commit comments