1
1
package com.bazel_diff.hash
2
2
3
+ import com.bazel_diff.log.Logger
3
4
import com.google.common.cache.CacheBuilder
4
5
import com.google.common.cache.CacheLoader
5
6
import org.koin.core.component.KoinComponent
7
+ import org.koin.core.component.inject
6
8
import java.nio.file.Files
7
9
import java.nio.file.Path
8
10
import java.nio.file.Paths
9
11
10
12
class ExternalRepoResolver (
11
- private val workingDirectory : Path ,
12
- private val bazelPath : Path ,
13
- private val outputBase : Path ,
13
+ private val workingDirectory : Path ,
14
+ private val bazelPath : Path ,
15
+ private val outputBase : Path ,
14
16
) : KoinComponent {
17
+ private val logger: Logger by inject()
18
+
15
19
private val externalRoot: Path by lazy {
16
20
outputBase.resolve(" external" )
17
21
}
@@ -30,13 +34,32 @@ class ExternalRepoResolver(
30
34
31
35
private fun resolveBzlModPath (repoName : String ): Path {
32
36
// Query result line should look something like "<exec root>/external/<canonical repo name>/some/bazel/target: <kind> <label>"
33
- val queryResultLine = runProcessAndCaptureFirstLine(bazelPath.toString(), " query" , " @$repoName //..." , " --output" , " location" )
37
+ val queryResultLine = runProcessAndCaptureFirstLine(
38
+ bazelPath.toString(),
39
+ " query" ,
40
+ " @$repoName //..." ,
41
+ " --keep_going" ,
42
+ " --output" ,
43
+ " location"
44
+ )
45
+ if (queryResultLine == null ) {
46
+ // Fallback to the default external repo root if nothing was found via bazel query.
47
+ // Normally this should not happen since any external repo should have at least one
48
+ // target to be consumed. But if it does, we just return the default external repo root
49
+ // and caller would handle the non-existent path.
50
+ logger.w {
51
+ " External repo $repoName has no target under it. You probably want to remove " +
52
+ " this repo from `fineGrainedHashExternalRepos` since bazel-diff is not " +
53
+ " able to correctly generate fine-grained hash for it."
54
+ }
55
+ return externalRoot.resolve(repoName);
56
+ }
34
57
val path = Paths .get(queryResultLine.split(" : " , limit = 2 )[0 ])
35
58
val bzlModRelativePath = path.relativize(externalRoot).first()
36
59
return externalRoot.resolve(bzlModRelativePath)
37
60
}
38
61
39
- private fun runProcessAndCaptureFirstLine (vararg command : String ): String {
62
+ private fun runProcessAndCaptureFirstLine (vararg command : String ): String? {
40
63
val process = ProcessBuilder (* command).directory(workingDirectory.toFile()).start()
41
64
process.inputStream.bufferedReader().use {
42
65
// read the first line and close the stream so that Bazel doesn't need to continue
0 commit comments