Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 14 additions & 19 deletions integration/integration_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ bazel_path=$(which bazelisk)

previous_revision="HEAD^"
final_revision="HEAD"
output_dir=$(mktemp -d)
modified_filepaths_output="$PWD/integration/modified_filepaths.txt"
starting_hashes_json="/tmp/starting_hashes.json"
final_hashes_json="/tmp/final_hashes_json.json"
impacted_targets_path="/tmp/impacted_targets.txt"
impacted_test_targets_path="/tmp/impacted_test_targets.txt"
starting_hashes_json="$output_dir/starting_hashes.json"
final_hashes_json="$output_dir/final_hashes_json.json"
impacted_targets_path="$output_dir/impacted_targets.txt"

export USE_BAZEL_VERSION=last_downstream_green

Expand All @@ -26,31 +26,26 @@ $bazel_path run :bazel-diff -- generate-hashes -w $workspace_path -b $bazel_path

ruby ./integration/update_final_hashes.rb

$bazel_path run :bazel-diff -- -sh $starting_hashes_json -fh $final_hashes_json -w $workspace_path -b $bazel_path -o $impacted_targets_path

$bazel_path run :bazel-diff -- -sh $starting_hashes_json -fh $final_hashes_json -w $workspace_path -b $bazel_path -o $impacted_test_targets_path -t
$bazel_path run :bazel-diff -- -sh $starting_hashes_json -fh $final_hashes_json -w $workspace_path -b $bazel_path -o $impacted_targets_path -aq "attr('tags', 'manual', //...)"

IFS=$'\n' read -d '' -r -a impacted_targets < $impacted_targets_path
target1="//test/java/com/integration:bazel-diff-integration-test-lib"
target2="//src/main/java/com/integration:bazel-diff-integration-lib"
target3="//test/java/com/integration:bazel-diff-integration-tests"
target4="//src/main/java/com/integration/submodule:Submodule"
if containsElement $target1 "${impacted_targets[@]}" && \
containsElement $target2 "${impacted_targets[@]}" && \
containsElement $target3 "${impacted_targets[@]}"
then
echo "Correct impacted targets"
if containsElement $target4 "${impacted_targets[@]}"
then
echo "Incorrect impacted targets: ${impacted_targets[@]}"
exit 1
else
echo "Correct impacted targets: ${impacted_targets[@]}"
exit 0
fi
else
echo "Incorrect impacted targets: ${impacted_targets[@]}"
exit 1
fi

IFS=$'\n' read -d '' -r -a impacted_test_targets < $impacted_test_targets_path
target="//test/java/com/integration:bazel-diff-integration-tests"
if containsElement $target "${impacted_test_targets[@]}";
then
echo "Correct first impacted test target"
else
echo "Impacted test targets: ${impacted_test_targets[@]}"
echo "Incorrect first impacted test target: ${target}"
exit 1
fi
1 change: 1 addition & 0 deletions integration/modified_filepaths.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
README.md
src/main/java/com/integration/StringGenerator.java
src/main/java/com/integration/submodule/Submodule.java
3 changes: 3 additions & 0 deletions integration/src/main/java/com/integration/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@ load("@rules_java//java:defs.bzl", "java_library")
java_library(
name = "bazel-diff-integration-lib",
srcs = glob(["*.java"]),
deps = [
"//src/main/java/com/integration/submodule:Submodule"
],
visibility = ["//visibility:public"]
)
10 changes: 10 additions & 0 deletions integration/src/main/java/com/integration/submodule/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
load("@rules_java//java:defs.bzl", "java_library")

java_library(
name = "Submodule",
srcs = glob(["*.java"]),
tags = [
"manual"
],
visibility = ["//visibility:public"]
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
public class Submodule {

}
43 changes: 26 additions & 17 deletions src/main/java/com/bazel_diff/BazelClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
Expand All @@ -20,8 +21,8 @@

interface BazelClient {
List<BazelTarget> queryAllTargets() throws IOException;
Set<String> queryForImpactedTargets(Set<String> impactedTargets) throws IOException;
Set<String> queryForTestTargets(Set<String> targets) throws IOException;
Set<Path> queryAllSourceFiles() throws IOException;
Set<String> queryForImpactedTargets(Set<String> impactedTargets, String avoidQuery) throws IOException;
Set<BazelSourceFileTarget> convertFilepathsToSourceTargets(Set<Path> filepaths) throws IOException, NoSuchAlgorithmException;
}

Expand All @@ -45,24 +46,26 @@ public List<BazelTarget> queryAllTargets() throws IOException {
}

@Override
public Set<String> queryForImpactedTargets(Set<String> impactedTargets) throws IOException {
Set<String> impactedTestTargets = new HashSet<>();
String targetQuery = impactedTargets.stream().collect(Collectors.joining(" + "));
List<Build.Target> targets = performBazelQuery(String.format("rdeps(//..., %s)", targetQuery));
for (Build.Target target : targets) {
if (target.hasRule()) {
impactedTestTargets.add(target.getRule().getName());
}
}
return impactedTestTargets;
public Set<Path> queryAllSourceFiles() throws IOException {
List<Build.Target> sources = performBazelQuery("kind('source file', deps(//...))");
return sources.stream()
.map(source -> source.getSourceFile().getName())
.filter(name -> !name.startsWith("@"))
.map(bazelName -> bazelName.replaceFirst("//", "").replace(":", "/"))
.map(Paths::get)
.collect(Collectors.toSet());
}

@Override
public Set<String> queryForTestTargets(Set<String> targets) throws IOException {
public Set<String> queryForImpactedTargets(Set<String> impactedTargets, String avoidQuery) throws IOException {
Set<String> impactedTestTargets = new HashSet<>();
String targetQuery = targets.stream().collect(Collectors.joining(" + "));
List<Build.Target> testTargets = performBazelQuery(String.format("kind(test, %s)", targetQuery));
for (Build.Target target : testTargets) {
String targetQuery = impactedTargets.stream().collect(Collectors.joining(" + "));
String query = String.format("rdeps(//..., %s)", targetQuery);
if (avoidQuery != null) {
query = String.format("(%s) except %s", query, avoidQuery);
}
List<Build.Target> targets = performBazelQuery(query);
for (Build.Target target : targets) {
if (target.hasRule()) {
impactedTestTargets.add(target.getRule().getName());
}
Expand All @@ -73,7 +76,13 @@ public Set<String> queryForTestTargets(Set<String> targets) throws IOException {
@Override
public Set<BazelSourceFileTarget> convertFilepathsToSourceTargets(Set<Path> filepaths) throws IOException, NoSuchAlgorithmException {
Set<BazelSourceFileTarget> sourceTargets = new HashSet<>();
for (List<Path> partition : Iterables.partition(filepaths, 1)) {

// filter out only valid bazel source files
Set<Path> allSources = this.queryAllSourceFiles();
Set<Path> validFilePaths = new HashSet<>(allSources);
validFilePaths.retainAll(filepaths);

for (List<Path> partition : Iterables.partition(validFilePaths, 100)) {
String targetQuery = partition
.stream()
.map(path -> path.toString())
Expand Down
18 changes: 8 additions & 10 deletions src/main/java/com/bazel_diff/TargetHashingClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.stream.Collectors;

interface TargetHashingClient {
Map<String, String> hashAllBazelTargets(Set<Path> modifiedFilepaths) throws IOException, NoSuchAlgorithmException;
Set<String> getImpactedTargets(Map<String, String> startHashes, Map<String, String> endHashes) throws IOException;
Set<String> getImpactedTestTargets(Map<String, String> startHashes, Map<String, String> endHashes) throws IOException;
Set<String> getImpactedTargets(Map<String, String> startHashes, Map<String, String> endHashes, String avoidQuery) throws IOException;
}

class TargetHashingClientImpl implements TargetHashingClient {
Expand Down Expand Up @@ -52,21 +52,19 @@ public Map<String, String> hashAllBazelTargets(Set<Path> modifiedFilepaths) thro
}

@Override
public Set<String> getImpactedTargets(Map<String, String> startHashes, Map<String, String> endHashes) throws IOException {
public Set<String> getImpactedTargets(
Map<String, String> startHashes,
Map<String, String> endHashes,
String avoidQuery)
throws IOException {
Set<String> impactedTargets = new HashSet<>();
for ( Map.Entry<String,String> entry : endHashes.entrySet()) {
String startHashValue = startHashes.get(entry.getKey());
if (startHashValue == null || !startHashValue.equals(entry.getValue())) {
impactedTargets.add(entry.getKey());
}
}
return bazelClient.queryForImpactedTargets(impactedTargets);
}

@Override
public Set<String> getImpactedTestTargets(Map<String, String> startHashes, Map<String, String> endHashes) throws IOException {
Set<String> impactedTargets = getImpactedTargets(startHashes, endHashes);
return bazelClient.queryForTestTargets(impactedTargets);
return bazelClient.queryForImpactedTargets(impactedTargets, avoidQuery);
}

private MessageDigest createDigestForTarget(
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/bazel_diff/VersionProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
class VersionProvider implements IVersionProvider {
public String[] getVersion() throws Exception {
return new String[] {
"1.2.1"
"2.0.0"
};
}
}
11 changes: 3 additions & 8 deletions src/main/java/com/bazel_diff/main.java
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ class BazelDiff implements Callable<Integer> {
@Option(names = {"-o", "--output"}, scope = ScopeType.LOCAL, description = "Filepath to write the impacted Bazel targets to, newline separated")
File outputPath;

@Option(names = {"-t", "--tests"}, scope = ScopeType.LOCAL, description = "Return only targets of kind 'test'")
boolean testTargets;
@Option(names = {"-aq", "--avoid-query"}, scope = ScopeType.LOCAL, description = "A Bazel query string, any targets that pass this query will be removed from the returned set of targets")
String avoidQuery;

@Option(names = {"-so", "--bazelStartupOptions"}, description = "Additional space separated Bazel client startup options used when invoking Bazel", scope = ScopeType.INHERIT)
String bazelStartupOptions;
Expand Down Expand Up @@ -190,12 +190,7 @@ public Integer call() throws IOException {
Map<String, String > gsonHash = new HashMap<>();
Map<String, String> startingHashes = gson.fromJson(startingFileReader, gsonHash.getClass());
Map<String, String> finalHashes = gson.fromJson(finalFileReader, gsonHash.getClass());
Set<String> impactedTargets;
if (testTargets) {
impactedTargets = hashingClient.getImpactedTestTargets(startingHashes, finalHashes);
} else {
impactedTargets = hashingClient.getImpactedTargets(startingHashes, finalHashes);
}
Set<String> impactedTargets = hashingClient.getImpactedTargets(startingHashes, finalHashes, avoidQuery);
try {
FileWriter myWriter = new FileWriter(outputPath);
myWriter.write(impactedTargets.stream().collect(Collectors.joining(System.lineSeparator())));
Expand Down
18 changes: 8 additions & 10 deletions test/java/com/bazel_diff/TargetHashingClientImplTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public void hashAllBazelTargets_sourceTargets_modifiedSources() throws IOExcepti

@Test
public void getImpactedTargets() throws IOException {
when(bazelClientMock.queryForImpactedTargets(anySet())).thenReturn(
when(bazelClientMock.queryForImpactedTargets(anySet(), anyObject())).thenReturn(
new HashSet<>(Arrays.asList("rule1", "rule3"))
);
TargetHashingClientImpl client = new TargetHashingClientImpl(bazelClientMock);
Expand All @@ -126,17 +126,17 @@ public void getImpactedTargets() throws IOException {
hash2.put("rule1", "differentrule1hash");
hash2.put("rule2", "rule2hash");
hash2.put("rule3", "rule3hash");
Set<String> impactedTargets = client.getImpactedTargets(hash1, hash2);
Set<String> impactedTargets = client.getImpactedTargets(hash1, hash2, null);
Set<String> expectedSet = new HashSet<>();
expectedSet.add("rule1");
expectedSet.add("rule3");
assertEquals(expectedSet, impactedTargets);
}

@Test
public void getImpactedTestTargets() throws IOException {
when(bazelClientMock.queryForTestTargets(anySet())).thenReturn(
new HashSet<>(Arrays.asList("rule1test", "rule3test", "someothertest"))
public void getImpactedTargets_withAvoidQuery() throws IOException {
when(bazelClientMock.queryForImpactedTargets(anySet(), eq("some_query"))).thenReturn(
new HashSet<>(Arrays.asList("rule1"))
);
TargetHashingClientImpl client = new TargetHashingClientImpl(bazelClientMock);
Map<String, String> hash1 = new HashMap<>();
Expand All @@ -146,12 +146,10 @@ public void getImpactedTestTargets() throws IOException {
hash2.put("rule1", "differentrule1hash");
hash2.put("rule2", "rule2hash");
hash2.put("rule3", "rule3hash");
Set <String> impactedTestTargets = client.getImpactedTestTargets(hash1, hash2);
Set<String> impactedTargets = client.getImpactedTargets(hash1, hash2, "some_query");
Set<String> expectedSet = new HashSet<>();
expectedSet.add("rule1test");
expectedSet.add("someothertest");
expectedSet.add("rule3test");
assertEquals(expectedSet, impactedTestTargets);
expectedSet.add("rule1");
assertEquals(expectedSet, impactedTargets);
}

private BazelTarget createRuleTarget(String ruleName, List<String> ruleInputs, String ruleDigest) throws NoSuchAlgorithmException {
Expand Down