Skip to content

Commit d33789e

Browse files
Merge pull request #13 from Tinder/collapse_commands
Collapse impacted-tests into bazel-diff command
2 parents 6535f76 + 89f7186 commit d33789e

File tree

8 files changed

+58
-94
lines changed

8 files changed

+58
-94
lines changed

README.md

+3-21
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,13 @@ Open `bazel-diff-example.sh` to see how this is implemented. This is purely an e
5252

5353
* Next we checkout the initial revision, then we run `generate-hashes` with the file output of `modified-filepaths` and write that JSON to a file. Now we have our final hashmap representation for the Bazel graph.
5454

55-
* We run `bazel-diff` on the starting and final JSON hash filepaths to get our affected set of targets. This impacted set of targets is written to a file
56-
57-
* Finally we run `impacted-tests` with the filepath to the list of impacted targets. This returns us the impacted test targets.
55+
* We run `bazel-diff` on the starting and final JSON hash filepaths to get our impacted set of targets. This impacted set of targets is written to a file. You can also pass the `-t` flag to only return tests
5856

5957
## CLI Interface
6058

6159
`bazel-diff` Command
6260
~~~
63-
Usage: bazel-diff [-hV] -b=<bazelPath> [-fh=<finalHashesJSONPath>]
61+
Usage: bazel-diff [-htV] -b=<bazelPath> [-fh=<finalHashesJSONPath>]
6462
[-o=<outputPath>] [-sh=<startingHashesJSONPath>]
6563
-w=<workspacePath> [COMMAND]
6664
Writes to a file the impacted targets between two Bazel graph JSON files
@@ -76,28 +74,12 @@ Writes to a file the impacted targets between two Bazel graph JSON files
7674
-sh, --startingHashes=<startingHashesJSONPath>
7775
The path to the JSON file of target hashes for the initial
7876
revision. Run 'generate-hashes' to get this value.
77+
-t, --tests Return only targets of kind 'test')
7978
-V, --version Print version information and exit.
8079
-w, --workspacePath=<workspacePath>
8180
Path to Bazel workspace directory.
8281
~~~
8382

84-
`impacted-tests` Command
85-
~~~
86-
Usage: bazel-diff impacted-tests [-hV] -b=<bazelPath> -w=<workspacePath>
87-
<impactedBazelTargetsPath> <outputPath>
88-
Write to a file the impacted test targets for the list of Bazel targets in the
89-
provided file
90-
<impactedBazelTargetsPath>
91-
The filepath to a newline separated list of Bazel targets
92-
<outputPath> The filepath to write the impacted test targets to
93-
-b, --bazelPath=<bazelPath>
94-
Path to Bazel binary
95-
-h, --help Show this help message and exit.
96-
-V, --version Print version information and exit.
97-
-w, --workspacePath=<workspacePath>
98-
Path to Bazel workspace directory.
99-
~~~
100-
10183
`modified-filepaths` Command
10284
~~~
10385
Usage: bazel-diff modified-filepaths [-hV] -b=<bazelPath> -w=<workspacePath>

bazel-diff-example.sh

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ final_revision=$4
1111

1212
modified_filepaths_output="/tmp/modified_filepaths.txt"
1313
starting_hashes_json="/tmp/starting_hashes.json"
14-
final_hashes_json="/tmp/final_hashes_json.json"
14+
final_hashes_json="/tmp/final_hashes.json"
1515
impacted_targets_path="/tmp/impacted_targets.txt"
1616
impacted_test_targets_path="/tmp/impacted_test_targets.txt"
1717

@@ -28,7 +28,7 @@ git -C $workspace_path checkout $previous_revision --quiet
2828
echo "Generating Hashes for Revision '$previous_revision'"
2929
$bazel_path run :bazel-diff -- generate-hashes -w $workspace_path -b $bazel_path $starting_hashes_json
3030

31-
git -C $workspace_path checkout - --quiet
31+
git -C $workspace_path checkout - --quiet
3232

3333
echo "Generating Hashes for Revision '$final_revision'"
3434
$bazel_path run :bazel-diff -- generate-hashes -w $workspace_path -b $bazel_path -m $modified_filepaths_output $final_hashes_json
@@ -37,7 +37,7 @@ echo "Determining Impacted Targets"
3737
$bazel_path run :bazel-diff -- -sh $starting_hashes_json -fh $final_hashes_json -w $workspace_path -b $bazel_path -o $impacted_targets_path
3838

3939
echo "Determining Impacted Test Targets"
40-
$bazel_path run :bazel-diff -- impacted-tests -w $workspace_path -b $bazel_path $impacted_targets_path $impacted_test_targets_path
40+
$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
4141

4242
IFS=$'\n' read -d '' -r -a impacted_targets < $impacted_targets_path
4343
formatted_impacted_targets=$(IFS=$'\n'; echo "${impacted_targets[*]}")

integration/integration_test.sh

+9-6
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,19 @@ ruby ./integration/update_final_hashes.rb
2828

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

31-
$bazel_path run :bazel-diff -- impacted-tests -w $workspace_path -b $bazel_path $impacted_targets_path $impacted_test_targets_path
31+
$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
3232

3333
IFS=$'\n' read -d '' -r -a impacted_targets < $impacted_targets_path
34-
target="//src/main/java/com/integration:StringGenerator.java"
35-
if containsElement $target "${impacted_targets[@]}";
34+
target1="//test/java/com/integration:bazel-diff-integration-test-lib"
35+
target2="//src/main/java/com/integration:bazel-diff-integration-lib"
36+
target3="//test/java/com/integration:bazel-diff-integration-tests"
37+
if containsElement $target1 "${impacted_targets[@]}" && \
38+
containsElement $target2 "${impacted_targets[@]}" && \
39+
containsElement $target3 "${impacted_targets[@]}"
3640
then
37-
echo "Correct first impacted target"
41+
echo "Correct impacted targets"
3842
else
39-
echo "Impacted Targets: ${impacted_targets[@]}"
40-
echo "Incorrect first impacted target: ${target}"
43+
echo "Incorrect impacted targets: ${impacted_targets[@]}"
4144
exit 1
4245
fi
4346

src/main/java/com/bazel-diff/BazelClient.java

+19-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515

1616
interface BazelClient {
1717
List<BazelTarget> queryAllTargets() throws IOException;
18-
Set<String> queryForImpactedTestTargets(Set<String> impactedTargets) throws IOException;
18+
Set<String> queryForImpactedTargets(Set<String> impactedTargets) throws IOException;
19+
Set<String> queryForTestTargets(Set<String> targets) throws IOException;
1920
Set<BazelSourceFileTarget> convertFilepathsToSourceTargets(Set<Path> filepaths) throws IOException, NoSuchAlgorithmException;
2021
}
2122

@@ -35,11 +36,11 @@ public List<BazelTarget> queryAllTargets() throws IOException {
3536
}
3637

3738
@Override
38-
public Set<String> queryForImpactedTestTargets(Set<String> impactedTargets) throws IOException {
39+
public Set<String> queryForImpactedTargets(Set<String> impactedTargets) throws IOException {
3940
Set<String> impactedTestTargets = new HashSet<>();
4041
for (List<String> partition : Iterables.partition(impactedTargets, 100)) {
4142
String targetQuery = partition.stream().collect(Collectors.joining(" + "));
42-
List<Build.Target> targets = performBazelQuery(String.format("kind(test, rdeps(//..., %s))", targetQuery));
43+
List<Build.Target> targets = performBazelQuery(String.format("rdeps(//..., %s)", targetQuery));
4344
for (Build.Target target : targets) {
4445
if (target.hasRule()) {
4546
impactedTestTargets.add(target.getRule().getName());
@@ -49,6 +50,21 @@ public Set<String> queryForImpactedTestTargets(Set<String> impactedTargets) thro
4950
return impactedTestTargets;
5051
}
5152

53+
@Override
54+
public Set<String> queryForTestTargets(Set<String> targets) throws IOException {
55+
Set<String> impactedTestTargets = new HashSet<>();
56+
for (List<String> partition : Iterables.partition(targets, 100)) {
57+
String targetQuery = partition.stream().collect(Collectors.joining(" + "));
58+
List<Build.Target> testTargets = performBazelQuery(String.format("kind(test, %s)", targetQuery));
59+
for (Build.Target target : testTargets) {
60+
if (target.hasRule()) {
61+
impactedTestTargets.add(target.getRule().getName());
62+
}
63+
}
64+
}
65+
return impactedTestTargets;
66+
}
67+
5268
@Override
5369
public Set<BazelSourceFileTarget> convertFilepathsToSourceTargets(Set<Path> filepaths) throws IOException, NoSuchAlgorithmException {
5470
Set<BazelSourceFileTarget> sourceTargets = new HashSet<>();

src/main/java/com/bazel-diff/TargetHashingClient.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
interface TargetHashingClient {
88
Map<String, String> hashAllBazelTargets(Set<Path> modifiedFilepaths) throws IOException, NoSuchAlgorithmException;
9-
Set<String> getImpactedTargets(Map<String, String> startHashes, Map<String, String> endHashes);
9+
Set<String> getImpactedTargets(Map<String, String> startHashes, Map<String, String> endHashes) throws IOException;
1010
Set<String> getImpactedTestTargets(Map<String, String> startHashes, Map<String, String> endHashes) throws IOException;
1111
}
1212

@@ -50,21 +50,21 @@ public Map<String, String> hashAllBazelTargets(Set<Path> modifiedFilepaths) thro
5050
}
5151

5252
@Override
53-
public Set<String> getImpactedTargets(Map<String, String> startHashes, Map<String, String> endHashes) {
53+
public Set<String> getImpactedTargets(Map<String, String> startHashes, Map<String, String> endHashes) throws IOException {
5454
Set<String> impactedTargets = new HashSet<>();
5555
for ( Map.Entry<String,String> entry : endHashes.entrySet()) {
5656
String startHashValue = startHashes.get(entry.getKey());
5757
if (startHashValue == null || !startHashValue.equals(entry.getValue())) {
5858
impactedTargets.add(entry.getKey());
5959
}
6060
}
61-
return impactedTargets;
61+
return bazelClient.queryForImpactedTargets(impactedTargets);
6262
}
6363

6464
@Override
6565
public Set<String> getImpactedTestTargets(Map<String, String> startHashes, Map<String, String> endHashes) throws IOException {
6666
Set<String> impactedTargets = getImpactedTargets(startHashes, endHashes);
67-
return bazelClient.queryForImpactedTestTargets(impactedTargets);
67+
return bazelClient.queryForTestTargets(impactedTargets);
6868
}
6969

7070
private MessageDigest createDigestForTarget(

src/main/java/com/bazel-diff/VersionProvider.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
class VersionProvider implements IVersionProvider {
44
public String[] getVersion() throws Exception {
55
return new String[] {
6-
"1.0.2"
6+
"1.1.0"
77
};
88
}
99
}

src/main/java/com/bazel-diff/main.java

+14-54
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public Integer call() {
5353
Set<String> modifiedFilepaths = gitClient
5454
.getModifiedFilepaths(startingGitRevision, endingGitRevision)
5555
.stream()
56-
.map( path -> path.toString())
56+
.map(Path::toString)
5757
.collect(Collectors.toSet());
5858
FileWriter myWriter = new FileWriter(outputPath);
5959
myWriter.write(String.join(System.lineSeparator(), modifiedFilepaths));
@@ -115,58 +115,10 @@ public Integer call() {
115115
}
116116
}
117117

118-
@Command(
119-
name = "impacted-tests",
120-
description = "Write to a file the impacted test targets for the list of Bazel targets in the provided file",
121-
mixinStandardHelpOptions = true,
122-
versionProvider = VersionProvider.class
123-
)
124-
class ImpactedTests implements Callable<Integer> {
125-
126-
@ParentCommand
127-
private BazelDiff parent;
128-
129-
@Parameters(index = "0", description = "The filepath to a newline separated list of Bazel targets")
130-
File impactedBazelTargetsPath;
131-
132-
@Parameters(index = "1", description = "The filepath to write the impacted test targets to")
133-
File outputPath;
134-
135-
@Override
136-
public Integer call() {
137-
FileReader fileReader = null;
138-
try {
139-
fileReader = new FileReader(impactedBazelTargetsPath);
140-
} catch (FileNotFoundException e) {
141-
System.out.println("Unable to read impactedBazelTargetsPath! Exiting");
142-
return ExitCode.USAGE;
143-
}
144-
BufferedReader bufferedReader = new BufferedReader(fileReader);
145-
BazelClient bazelClient = new BazelClientImpl(parent.workspacePath, parent.bazelPath);
146-
Set<String> impactedTargets = bufferedReader.lines().collect(Collectors.toSet());
147-
Set<String> testTargets = null;
148-
try {
149-
testTargets = bazelClient.queryForImpactedTestTargets(impactedTargets);
150-
} catch (IOException e) {
151-
System.out.println("Unable to query rdeps tests of impacted targets");
152-
return ExitCode.SOFTWARE;
153-
}
154-
try {
155-
FileWriter myWriter = new FileWriter(outputPath);
156-
myWriter.write(testTargets.stream().collect(Collectors.joining(System.lineSeparator())));
157-
myWriter.close();
158-
} catch (IOException e) {
159-
System.out.println("Unable to write to outputPath!");
160-
return ExitCode.USAGE;
161-
}
162-
return ExitCode.OK;
163-
}
164-
}
165-
166118
@Command(
167119
name = "bazel-diff",
168120
description = "Writes to a file the impacted targets between two Bazel graph JSON files",
169-
subcommands = { GenerateHashes.class, FetchModifiedFilepaths.class, ImpactedTests.class },
121+
subcommands = { GenerateHashes.class, FetchModifiedFilepaths.class },
170122
mixinStandardHelpOptions = true,
171123
versionProvider = VersionProvider.class
172124
)
@@ -187,7 +139,10 @@ class BazelDiff implements Callable<Integer> {
187139
@Option(names = {"-o", "--output"}, scope = ScopeType.LOCAL, description = "Filepath to write the impacted Bazel targets to, newline separated")
188140
File outputPath;
189141

190-
public Integer call() {
142+
@Option(names = {"-t", "--tests"}, scope = ScopeType.LOCAL, description = "Return only targets of kind 'test')")
143+
boolean testTargets;
144+
145+
public Integer call() throws IOException {
191146
if (startingHashesJSONPath == null || !startingHashesJSONPath.canRead()) {
192147
System.out.println("startingHashesJSONPath does not exist! Exiting");
193148
return ExitCode.USAGE;
@@ -209,8 +164,8 @@ public Integer call() {
209164
return ExitCode.USAGE;
210165
}
211166
Gson gson = new Gson();
212-
FileReader startingFileReader = null;
213-
FileReader finalFileReader = null;
167+
FileReader startingFileReader;
168+
FileReader finalFileReader;
214169
try {
215170
startingFileReader = new FileReader(startingHashesJSONPath);
216171
} catch (FileNotFoundException e) {
@@ -226,7 +181,12 @@ public Integer call() {
226181
Map<String, String > gsonHash = new HashMap<>();
227182
Map<String, String> startingHashes = gson.fromJson(startingFileReader, gsonHash.getClass());
228183
Map<String, String> finalHashes = gson.fromJson(finalFileReader, gsonHash.getClass());
229-
Set<String> impactedTargets = hashingClient.getImpactedTargets(startingHashes, finalHashes);
184+
Set<String> impactedTargets;
185+
if (testTargets) {
186+
impactedTargets = hashingClient.getImpactedTestTargets(startingHashes, finalHashes);
187+
} else {
188+
impactedTargets = hashingClient.getImpactedTargets(startingHashes, finalHashes);
189+
}
230190
try {
231191
FileWriter myWriter = new FileWriter(outputPath);
232192
myWriter.write(impactedTargets.stream().collect(Collectors.joining(System.lineSeparator())));

test/java/com/bazel-diff/TargetHashingClientImplTests.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,10 @@ public void hashAllBazelTargets_sourceTargets_modifiedSources() throws IOExcepti
112112
}
113113

114114
@Test
115-
public void getImpactedTargets() {
115+
public void getImpactedTargets() throws IOException {
116+
when(bazelClientMock.queryForImpactedTargets(anySet())).thenReturn(
117+
new HashSet<>(Arrays.asList("rule1", "rule3"))
118+
);
116119
TargetHashingClientImpl client = new TargetHashingClientImpl(bazelClientMock);
117120
Map<String, String> hash1 = new HashMap<>();
118121
hash1.put("rule1", "rule1hash");
@@ -130,7 +133,7 @@ public void getImpactedTargets() {
130133

131134
@Test
132135
public void getImpactedTestTargets() throws IOException {
133-
when(bazelClientMock.queryForImpactedTestTargets(anySet())).thenReturn(
136+
when(bazelClientMock.queryForTestTargets(anySet())).thenReturn(
134137
new HashSet<>(Arrays.asList("rule1test", "rule3test", "someothertest"))
135138
);
136139
TargetHashingClientImpl client = new TargetHashingClientImpl(bazelClientMock);

0 commit comments

Comments
 (0)