Skip to content

Commit 6bee003

Browse files
WIP: Reenable modified filepaths entry
This should greatly speed up hash calculation time
1 parent 62df794 commit 6bee003

File tree

6 files changed

+108
-19
lines changed

6 files changed

+108
-19
lines changed

cli/BUILD

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
load("@rules_java//java:defs.bzl", "java_binary", "java_library", "java_proto_library")
2-
load("@rules_proto//proto:defs.bzl", "proto_library")
3-
load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_binary", "kt_jvm_library", "kt_jvm_test")
4-
load("@rules_jvm_external//:defs.bzl", "artifact")
1+
load("@rules_java//java:defs.bzl", "java_binary")
2+
load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library", "kt_jvm_test")
53

64
config_setting(
75
name = "enable_debug",
@@ -10,6 +8,13 @@ config_setting(
108
},
119
)
1210

11+
config_setting(
12+
name = "macos",
13+
constraint_values = [
14+
"@platforms//os:macos",
15+
],
16+
)
17+
1318
java_binary(
1419
name = "bazel-diff",
1520
jvm_flags = select({
@@ -39,6 +44,10 @@ kt_jvm_library(
3944

4045
kt_jvm_test(
4146
name = "BuildGraphHasherTest",
47+
jvm_flags = select({
48+
":macos": ["-Djava.security.manager=allow"],
49+
"//conditions:default": [],
50+
}),
4251
test_class = "com.bazel_diff.hash.BuildGraphHasherTest",
4352
runtime_deps = [":cli-test-lib"],
4453
)
@@ -48,42 +57,70 @@ kt_jvm_test(
4857
data = [
4958
":src/test/kotlin/com/bazel_diff/hash/fixture/foo.ts",
5059
],
60+
jvm_flags = select({
61+
":macos": ["-Djava.security.manager=allow"],
62+
"//conditions:default": [],
63+
}),
5164
test_class = "com.bazel_diff.hash.SourceFileHasherTest",
5265
runtime_deps = [":cli-test-lib"],
5366
)
5467

5568
kt_jvm_test(
5669
name = "CalculateImpactedTargetsInteractorTest",
70+
jvm_flags = select({
71+
":macos": ["-Djava.security.manager=allow"],
72+
"//conditions:default": [],
73+
}),
5774
test_class = "com.bazel_diff.interactor.CalculateImpactedTargetsInteractorTest",
5875
runtime_deps = [":cli-test-lib"],
5976
)
6077

6178
kt_jvm_test(
6279
name = "NormalisingPathConverterTest",
80+
jvm_flags = select({
81+
":macos": ["-Djava.security.manager=allow"],
82+
"//conditions:default": [],
83+
}),
6384
test_class = "com.bazel_diff.cli.converter.NormalisingPathConverterTest",
6485
runtime_deps = [":cli-test-lib"],
6586
)
6687

6788
kt_jvm_test(
6889
name = "OptionsConverterTest",
90+
jvm_flags = select({
91+
":macos": ["-Djava.security.manager=allow"],
92+
"//conditions:default": [],
93+
}),
6994
test_class = "com.bazel_diff.cli.converter.OptionsConverterTest",
7095
runtime_deps = [":cli-test-lib"],
7196
)
7297

7398
kt_jvm_test(
7499
name = "DeserialiseHashesInteractorTest",
100+
jvm_flags = select({
101+
":macos": ["-Djava.security.manager=allow"],
102+
"//conditions:default": [],
103+
}),
75104
test_class = "com.bazel_diff.interactor.DeserialiseHashesInteractorTest",
76105
runtime_deps = [":cli-test-lib"],
77106
)
78107

79108
kt_jvm_test(
80109
name = "BazelRuleTest",
110+
jvm_flags = select({
111+
":macos": ["-Djava.security.manager=allow"],
112+
"//conditions:default": [],
113+
}),
81114
test_class = "com.bazel_diff.bazel.BazelRuleTest",
82115
runtime_deps = [":cli-test-lib"],
83116
)
84117

85118
kt_jvm_test(
86119
name = "E2ETest",
120+
jvm_flags = select({
121+
":macos": ["-Djava.security.manager=allow"],
122+
"//conditions:default": [],
123+
}),
87124
test_class = "com.bazel_diff.e2e.E2ETest",
88125
runtime_deps = [":cli-test-lib"],
89126
)
@@ -94,6 +131,10 @@ kt_jvm_test(
94131
":src/test/kotlin/com/bazel_diff/io/fixture/correct.json",
95132
":src/test/kotlin/com/bazel_diff/io/fixture/wrong.json",
96133
],
134+
jvm_flags = select({
135+
":macos": ["-Djava.security.manager=allow"],
136+
"//conditions:default": [],
137+
}),
97138
test_class = "com.bazel_diff.io.ContentHashProviderTest",
98139
runtime_deps = [
99140
":cli-test-lib",

cli/src/main/kotlin/com/bazel_diff/bazel/BazelClient.kt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ package com.bazel_diff.bazel
22

33
import com.bazel_diff.log.Logger
44
import com.google.devtools.build.lib.query2.proto.proto2api.Build
5-
import org.koin.core.component.KoinComponent
6-
import org.koin.core.component.inject
5+
import java.nio.file.Path
76
import java.util.*
7+
import org.koin.core.component.inject
8+
import org.koin.core.component.KoinComponent
89

910
class BazelClient(private val useCquery: Boolean, private val fineGrainedHashExternalRepos: Set<String>) : KoinComponent {
1011
private val logger: Logger by inject()
@@ -63,5 +64,18 @@ class BazelClient(private val useCquery: Boolean, private val fineGrainedHashExt
6364

6465
return targets
6566
}
67+
68+
suspend fun queryModifiedSourcefileTargets(
69+
modifiedFilepaths: Set<Path>
70+
): List<Build.Target> {
71+
val queryEpoch = Calendar.getInstance().getTimeInMillis()
72+
val allReposToQuery = fineGrainedHashExternalRepos.map { "@$it" }
73+
val fineGrainedHashExternalReposSourceTargets = queryService.query("kind('source file', ${allReposToQuery.joinToString(" + ") { "'$it//...:all-targets'" }})")
74+
val modifiedSourceFileTargets = queryService.query("kind('source file', ${modifiedFilepaths.joinToString(" + ") { "'$it'" }})")
75+
val queryDuration = Calendar.getInstance().getTimeInMillis() - queryEpoch
76+
logger.i { "Modified source files queried in $queryDuration" }
77+
78+
return fineGrainedHashExternalReposSourceTargets + modifiedSourceFileTargets
79+
}
6680
}
6781

cli/src/main/kotlin/com/bazel_diff/cli/GenerateHashesCommand.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ class GenerateHashesCommand : Callable<Int> {
118118
)
119119
var ignoredRuleHashingAttributes: Set<String> = emptySet()
120120

121+
@CommandLine.Option(
122+
names = ["-m", "--modified-filepaths"],
123+
description = ["Experimental: A text file containing a newline separated list of filepaths, these filepaths should represent the modified files between the specified revisions and will be used to scope what files are hashed during hash generation."]
124+
)
125+
var modifiedFilepaths: File? = null
126+
121127
@CommandLine.Spec
122128
lateinit var spec: CommandLine.Model.CommandSpec
123129

@@ -142,7 +148,12 @@ class GenerateHashesCommand : Callable<Int> {
142148
)
143149
}
144150

145-
return when (GenerateHashesInteractor().execute(seedFilepaths, outputPath, ignoredRuleHashingAttributes)) {
151+
return when (GenerateHashesInteractor().execute(
152+
seedFilepaths,
153+
outputPath,
154+
ignoredRuleHashingAttributes,
155+
modifiedFilepaths
156+
)) {
146157
true -> CommandLine.ExitCode.OK
147158
false -> CommandLine.ExitCode.SOFTWARE
148159
}.also { stopKoin() }

cli/src/main/kotlin/com/bazel_diff/cli/VersionProvider.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ import picocli.CommandLine.IVersionProvider
44

55
class VersionProvider : IVersionProvider {
66
override fun getVersion(): Array<String> {
7-
return arrayOf("4.8.2")
7+
return arrayOf("5.0.0")
88
}
99
}

cli/src/main/kotlin/com/bazel_diff/hash/BuildGraphHasher.kt

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,19 @@ import com.bazel_diff.extensions.toHexString
88
import com.bazel_diff.log.Logger
99
import com.google.common.collect.Sets
1010
import com.google.devtools.build.lib.query2.proto.proto2api.Build
11-
import kotlinx.coroutines.Dispatchers
12-
import kotlinx.coroutines.async
13-
import kotlinx.coroutines.runBlocking
14-
import org.koin.core.component.KoinComponent
15-
import org.koin.core.component.inject
11+
import java.io.File
1612
import java.nio.file.Path
13+
import java.util.Calendar
14+
import java.util.concurrent.atomic.AtomicReference
1715
import java.util.concurrent.ConcurrentHashMap
1816
import java.util.concurrent.ConcurrentMap
19-
import java.util.concurrent.atomic.AtomicReference
2017
import java.util.stream.Collectors
2118
import kotlin.io.path.readBytes
22-
import java.util.Calendar
19+
import kotlinx.coroutines.async
20+
import kotlinx.coroutines.Dispatchers
21+
import kotlinx.coroutines.runBlocking
22+
import org.koin.core.component.inject
23+
import org.koin.core.component.KoinComponent
2324

2425
class BuildGraphHasher(private val bazelClient: BazelClient) : KoinComponent {
2526
private val targetHasher: TargetHasher by inject()
@@ -28,7 +29,8 @@ class BuildGraphHasher(private val bazelClient: BazelClient) : KoinComponent {
2829

2930
fun hashAllBazelTargetsAndSourcefiles(
3031
seedFilepaths: Set<Path> = emptySet(),
31-
ignoredAttrs: Set<String> = emptySet()
32+
ignoredAttrs: Set<String> = emptySet(),
33+
modifiedFilepaths: Set<Path> = emptySet()
3234
): Map<String, String> {
3335
/**
3436
* Bazel will lock parallel queries but this is still allowing us to hash source files while executing a parallel query
@@ -38,6 +40,9 @@ class BuildGraphHasher(private val bazelClient: BazelClient) : KoinComponent {
3840
* Source query is usually faster than targets query, so we prioritise it first
3941
*/
4042
val sourceTargetsFuture = async(Dispatchers.IO) {
43+
if (!modifiedFilepaths.isEmpty()) {
44+
return@async bazelClient.queryModifiedSourcefileTargets(modifiedFilepaths)
45+
}
4146
bazelClient.queryAllSourcefileTargets()
4247
}
4348
val sourceTargets = sourceTargetsFuture.await()
@@ -67,7 +72,9 @@ class BuildGraphHasher(private val bazelClient: BazelClient) : KoinComponent {
6772
)
6873
}
6974

70-
private fun hashSourcefiles(targets: List<Build.Target>): ConcurrentMap<String, ByteArray> {
75+
private fun hashSourcefiles(
76+
targets: List<Build.Target>
77+
): ConcurrentMap<String, ByteArray> {
7178
val exception = AtomicReference<Exception?>(null)
7279
val result: ConcurrentMap<String, ByteArray> = targets.parallelStream()
7380
.map { target: Build.Target ->

cli/src/main/kotlin/com/bazel_diff/interactor/GenerateHashesInteractor.kt

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@ class GenerateHashesInteractor : KoinComponent {
1818
private val logger: Logger by inject()
1919
private val gson: Gson by inject()
2020

21-
fun execute(seedFilepaths: File?, outputPath: File?, ignoredRuleHashingAttributes: Set<String>): Boolean {
21+
fun execute(
22+
seedFilepaths: File?,
23+
outputPath: File?,
24+
ignoredRuleHashingAttributes: Set<String>,
25+
modifiedFilepaths: File?
26+
): Boolean {
2227
return try {
2328
val epoch = Calendar.getInstance().getTimeInMillis()
2429
var seedFilepathsSet: Set<Path> = when {
@@ -31,9 +36,20 @@ class GenerateHashesInteractor : KoinComponent {
3136
}
3237
else -> emptySet()
3338
}
39+
var modifiedFilepathsSet: Set<Path> = when {
40+
modifiedFilepaths != null -> {
41+
BufferedReader(FileReader(modifiedFilepaths)).use {
42+
it.readLines()
43+
.map { line: String -> File(line).toPath() }
44+
.toSet()
45+
}
46+
}
47+
else -> emptySet()
48+
}
3449
val hashes = buildGraphHasher.hashAllBazelTargetsAndSourcefiles(
3550
seedFilepathsSet,
36-
ignoredRuleHashingAttributes
51+
ignoredRuleHashingAttributes,
52+
modifiedFilepathsSet
3753
)
3854
when (outputPath) {
3955
null -> FileWriter(FileDescriptor.out)

0 commit comments

Comments
 (0)