26
26
import com .google .devtools .build .lib .actions .FileValue ;
27
27
import com .google .devtools .build .lib .analysis .BlazeDirectories ;
28
28
import com .google .devtools .build .lib .cmdline .LabelConstants ;
29
+ import com .google .devtools .build .lib .cmdline .LabelSyntaxException ;
29
30
import com .google .devtools .build .lib .cmdline .LabelValidator ;
30
31
import com .google .devtools .build .lib .cmdline .RepositoryName ;
31
32
import com .google .devtools .build .lib .skyframe .ActionEnvironmentFunction ;
@@ -76,25 +77,32 @@ public abstract static class Parser {
76
77
77
78
/**
78
79
* Parses a recorded input from the post-colon substring that identifies the specific input: for
79
- * example, the {@code MY_ENV_VAR} part of {@code ENV:MY_ENV_VAR}.
80
+ * example, the {@code MY_ENV_VAR} part of {@code ENV:MY_ENV_VAR}. Returns null if the parsed
81
+ * part is invalid.
80
82
*/
81
83
public abstract RepoRecordedInput parse (String s );
82
84
}
83
85
84
86
private static final Comparator <RepoRecordedInput > COMPARATOR =
85
- Comparator .comparing ((RepoRecordedInput rri ) -> rri .getParser ().getPrefix ())
86
- .thenComparing (RepoRecordedInput ::toStringInternal );
87
+ (o1 , o2 ) ->
88
+ o1 == o2
89
+ ? 0
90
+ : Comparator .comparing ((RepoRecordedInput rri ) -> rri .getParser ().getPrefix ())
91
+ .thenComparing (RepoRecordedInput ::toStringInternal )
92
+ .compare (o1 , o2 );
87
93
88
94
/**
89
95
* Parses a recorded input from its string representation.
90
96
*
91
97
* @param s the string representation
92
- * @return The parsed recorded input object, or {@code null } if the string representation is
93
- * invalid
98
+ * @return The parsed recorded input object, or {@link #NEVER_UP_TO_DATE } if the string
99
+ * representation is invalid
94
100
*/
95
- @ Nullable
96
101
public static RepoRecordedInput parse (String s ) {
97
102
List <String > parts = Splitter .on (':' ).limit (2 ).splitToList (s );
103
+ if (parts .size () < 2 ) {
104
+ return NEVER_UP_TO_DATE ;
105
+ }
98
106
for (Parser parser :
99
107
new Parser [] {
100
108
File .PARSER , Dirents .PARSER , DirTree .PARSER , EnvVar .PARSER , RecordedRepoMapping .PARSER
@@ -103,7 +111,7 @@ public static RepoRecordedInput parse(String s) {
103
111
return parser .parse (parts .get (1 ));
104
112
}
105
113
}
106
- return null ;
114
+ return NEVER_UP_TO_DATE ;
107
115
}
108
116
109
117
/**
@@ -172,6 +180,42 @@ public abstract boolean isUpToDate(
172
180
Environment env , BlazeDirectories directories , @ Nullable String oldValue )
173
181
throws InterruptedException ;
174
182
183
+ /** A sentinel "input" that's always out-of-date to signify parse failure. */
184
+ public static final RepoRecordedInput NEVER_UP_TO_DATE =
185
+ new RepoRecordedInput () {
186
+ @ Override
187
+ public boolean equals (Object obj ) {
188
+ return this == obj ;
189
+ }
190
+
191
+ @ Override
192
+ public int hashCode () {
193
+ return 12345678 ;
194
+ }
195
+
196
+ @ Override
197
+ public String toStringInternal () {
198
+ throw new UnsupportedOperationException ("this sentinel input should never be serialized" );
199
+ }
200
+
201
+ @ Override
202
+ public Parser getParser () {
203
+ throw new UnsupportedOperationException ("this sentinel input should never be parsed" );
204
+ }
205
+
206
+ @ Override
207
+ public SkyKey getSkyKey (BlazeDirectories directories ) {
208
+ // Return a random SkyKey to satisfy the contract.
209
+ return PrecomputedValue .STARLARK_SEMANTICS .getKey ();
210
+ }
211
+
212
+ @ Override
213
+ public boolean isUpToDate (
214
+ Environment env , BlazeDirectories directories , @ Nullable String oldValue ) {
215
+ return false ;
216
+ }
217
+ };
218
+
175
219
/**
176
220
* Represents a filesystem path stored in a way that is repo-cache-friendly. That is, if the path
177
221
* happens to point inside the current Bazel workspace (in either the main repo or an external
@@ -213,12 +257,12 @@ public final String toString() {
213
257
return repoName ().map (repoName -> repoName + "//" + path ()).orElse (path ().toString ());
214
258
}
215
259
216
- public static RepoCacheFriendlyPath parse (String s ) {
260
+ public static RepoCacheFriendlyPath parse (String s ) throws LabelSyntaxException {
217
261
if (LabelValidator .isAbsolute (s )) {
218
262
int doubleSlash = s .indexOf ("//" );
219
263
int skipAts = s .startsWith ("@@" ) ? 2 : s .startsWith ("@" ) ? 1 : 0 ;
220
264
return createInsideWorkspace (
221
- RepositoryName .createUnvalidated (s .substring (skipAts , doubleSlash )),
265
+ RepositoryName .create (s .substring (skipAts , doubleSlash )),
222
266
PathFragment .create (s .substring (doubleSlash + 2 )));
223
267
}
224
268
return createOutsideWorkspace (PathFragment .create (s ));
@@ -264,7 +308,12 @@ public String getPrefix() {
264
308
265
309
@ Override
266
310
public RepoRecordedInput parse (String s ) {
267
- return new File (RepoCacheFriendlyPath .parse (s ));
311
+ try {
312
+ return new File (RepoCacheFriendlyPath .parse (s ));
313
+ } catch (LabelSyntaxException e ) {
314
+ // malformed inputs cause refetch
315
+ return NEVER_UP_TO_DATE ;
316
+ }
268
317
}
269
318
};
270
319
@@ -355,7 +404,12 @@ public String getPrefix() {
355
404
356
405
@ Override
357
406
public RepoRecordedInput parse (String s ) {
358
- return new Dirents (RepoCacheFriendlyPath .parse (s ));
407
+ try {
408
+ return new Dirents (RepoCacheFriendlyPath .parse (s ));
409
+ } catch (LabelSyntaxException e ) {
410
+ // malformed inputs cause refetch
411
+ return NEVER_UP_TO_DATE ;
412
+ }
359
413
}
360
414
};
361
415
@@ -439,7 +493,12 @@ public String getPrefix() {
439
493
440
494
@ Override
441
495
public RepoRecordedInput parse (String s ) {
442
- return new DirTree (RepoCacheFriendlyPath .parse (s ));
496
+ try {
497
+ return new DirTree (RepoCacheFriendlyPath .parse (s ));
498
+ } catch (LabelSyntaxException e ) {
499
+ // malformed inputs cause refetch
500
+ return NEVER_UP_TO_DATE ;
501
+ }
443
502
}
444
503
};
445
504
@@ -578,8 +637,12 @@ public String getPrefix() {
578
637
@ Override
579
638
public RepoRecordedInput parse (String s ) {
580
639
List <String > parts = Splitter .on (',' ).limit (2 ).splitToList (s );
581
- return new RecordedRepoMapping (
582
- RepositoryName .createUnvalidated (parts .get (0 )), parts .get (1 ));
640
+ try {
641
+ return new RecordedRepoMapping (RepositoryName .create (parts .get (0 )), parts .get (1 ));
642
+ } catch (LabelSyntaxException | IndexOutOfBoundsException e ) {
643
+ // malformed inputs cause refetch
644
+ return NEVER_UP_TO_DATE ;
645
+ }
583
646
}
584
647
};
585
648
@@ -635,9 +698,14 @@ public boolean isUpToDate(
635
698
throws InterruptedException {
636
699
RepositoryMappingValue repoMappingValue =
637
700
(RepositoryMappingValue ) env .getValue (getSkyKey (directories ));
638
- return repoMappingValue != RepositoryMappingValue .NOT_FOUND_VALUE
639
- && RepositoryName .createUnvalidated (oldValue )
640
- .equals (repoMappingValue .getRepositoryMapping ().get (apparentName ));
701
+ try {
702
+ return repoMappingValue != RepositoryMappingValue .NOT_FOUND_VALUE
703
+ && RepositoryName .create (oldValue )
704
+ .equals (repoMappingValue .getRepositoryMapping ().get (apparentName ));
705
+ } catch (LabelSyntaxException e ) {
706
+ // malformed old value causes refetch
707
+ return false ;
708
+ }
641
709
}
642
710
}
643
711
}
0 commit comments