Skip to content

Commit 5773418

Browse files
committed
Minimize the number of 'bazel-query...'
1 parent 9542833 commit 5773418

File tree

5 files changed

+148
-25
lines changed

5 files changed

+148
-25
lines changed

bundles/com.salesforce.bazel.eclipse.core/src/com/salesforce/bazel/eclipse/core/model/BazelPackage.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99

1010
import java.nio.file.Path;
1111
import java.util.List;
12+
import java.util.Map;
1213
import java.util.Objects;
1314

1415
import org.eclipse.core.runtime.CoreException;
1516
import org.eclipse.core.runtime.IPath;
1617
import org.eclipse.core.runtime.Status;
1718

19+
import com.salesforce.bazel.sdk.command.querylight.Target;
1820
import com.salesforce.bazel.sdk.model.BazelLabel;
1921

2022
/**
@@ -71,6 +73,7 @@ public static boolean isBuildFileName(String fileName) {
7173
private final BazelWorkspace parent;
7274
private final BazelLabel label;
7375
private final IPath packagePath;
76+
private Map<String, Target> targets;
7477

7578
BazelPackage(BazelWorkspace parent, IPath packagePath) throws NullPointerException, IllegalArgumentException {
7679
this.packagePath =
@@ -87,7 +90,9 @@ protected BazelPackageInfo createInfo() throws CoreException {
8790
Status.error(format("Package '%s' does not exist in workspace '%s'!", label, parent.getName())));
8891
}
8992

90-
var targets = BazelPackageInfo.queryForTargets(this, getCommandExecutor());
93+
if (targets == null) {
94+
targets = BazelPackageInfo.queryForTargets(this, getCommandExecutor());
95+
}
9196
return new BazelPackageInfo(buildFile, this, targets);
9297
}
9398

@@ -344,4 +349,8 @@ public void rediscoverBazelProject() throws CoreException {
344349
getInfo();
345350
}
346351

352+
public void setTargets(Map<String, Target> targets) {
353+
this.targets = targets;
354+
}
355+
347356
}

bundles/com.salesforce.bazel.eclipse.core/src/com/salesforce/bazel/eclipse/core/model/BazelWorkspace.java

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,20 @@
1717
import static com.salesforce.bazel.eclipse.core.BazelCoreSharedContstants.FILE_NAME_REPO_BAZEL;
1818
import static com.salesforce.bazel.eclipse.core.BazelCoreSharedContstants.FILE_NAME_WORKSPACE;
1919
import static com.salesforce.bazel.eclipse.core.BazelCoreSharedContstants.FILE_NAME_WORKSPACE_BAZEL;
20-
import static com.salesforce.bazel.eclipse.core.model.BazelPackageInfo.queryForTargets;
2120
import static java.lang.String.format;
2221
import static java.nio.file.Files.isDirectory;
2322
import static java.nio.file.Files.isRegularFile;
2423
import static java.util.Objects.requireNonNull;
2524
import static java.util.function.Predicate.not;
25+
import static java.util.stream.Collectors.joining;
2626
import static java.util.stream.Collectors.toList;
2727

2828
import java.nio.file.Path;
2929
import java.util.Collection;
3030
import java.util.Collections;
31+
import java.util.HashMap;
3132
import java.util.List;
33+
import java.util.Map;
3234
import java.util.Objects;
3335
import java.util.function.Predicate;
3436
import java.util.stream.Stream;
@@ -43,6 +45,8 @@
4345
import com.salesforce.bazel.eclipse.core.projectview.BazelProjectView;
4446
import com.salesforce.bazel.sdk.BazelVersion;
4547
import com.salesforce.bazel.sdk.command.BazelBinary;
48+
import com.salesforce.bazel.sdk.command.BazelQueryForTargetProtoCommand;
49+
import com.salesforce.bazel.sdk.command.querylight.Target;
4650
import com.salesforce.bazel.sdk.model.BazelLabel;
4751

4852
/**
@@ -616,7 +620,7 @@ public void open(Collection<BazelPackage> bazelPackages) throws CoreException {
616620
}
617621

618622
// open all closed projects
619-
var targetsByPackage = queryForTargets(this, closedPackages, getCommandExecutor());
623+
var targetsByPackage = queryForTargetsWithDependencies(this, closedPackages, getCommandExecutor());
620624
for (BazelPackage bazelPackage : closedPackages) {
621625
if (bazelPackage.hasInfo()) {
622626
continue;
@@ -644,6 +648,75 @@ public void open(Collection<BazelPackage> bazelPackages) throws CoreException {
644648
}
645649
}
646650

651+
public Map<BazelPackage, Map<String, Target>> queryForTargetsWithDependencies(BazelWorkspace bazelWorkspace,
652+
Collection<BazelPackage> bazelPackages, BazelElementCommandExecutor bazelElementCommandExecutor)
653+
throws CoreException {
654+
// bazel query 'kind(rule, deps(//foo:all + //bar:all))"'
655+
656+
if (bazelPackages.isEmpty()) {
657+
return Collections.emptyMap();
658+
}
659+
var workspaceRoot = bazelWorkspace.getLocation().toPath();
660+
var query = bazelPackages.stream()
661+
.map(bazelPackage -> format("//%s:all", bazelPackage.getWorkspaceRelativePath()))
662+
.collect(joining(" + "));
663+
664+
Map<String, BazelPackage> bazelPackageByWorkspaceRelativePath = new HashMap<>();
665+
bazelPackages.stream()
666+
.forEach(p -> bazelPackageByWorkspaceRelativePath.put(p.getWorkspaceRelativePath().toString(), p));
667+
668+
query = "kind(rule, deps(" + query + "))";
669+
Map<BazelPackage, Map<String, Target>> result = new HashMap<>();
670+
LOG.debug("{}: querying Bazel for list of targets from: {}", bazelWorkspace, query);
671+
var queryResult = bazelElementCommandExecutor.runQueryWithoutLock(
672+
new BazelQueryForTargetProtoCommand(
673+
workspaceRoot,
674+
query,
675+
true /* keep going */,
676+
List.of("--noproto:locations", "--noproto:default_values", "--noimplicit_deps", "--notool_deps"),
677+
format(
678+
"Loading targets for %d %s",
679+
bazelPackages.size(),
680+
bazelPackages.size() == 1 ? "package" : "packages")));
681+
for (Target target : queryResult) {
682+
if (!target.hasRule()) {
683+
LOG.trace("{}: ignoring target: {}", bazelWorkspace, target);
684+
System.out.println();
685+
continue;
686+
}
687+
688+
try {
689+
BazelLabel.validateLabelPath(target.rule().name(), true);
690+
} catch (Exception e) {
691+
LOG.trace("{}: ignoring target: {}", bazelWorkspace, target);
692+
continue;
693+
}
694+
LOG.trace("{}: found target: {}", bazelWorkspace, target);
695+
var targetLabel = new BazelLabel(target.rule().name());
696+
697+
var bazelPackage = bazelPackageByWorkspaceRelativePath.get(targetLabel.getPackagePath());
698+
if (bazelPackage == null) {
699+
// LOG.debug("{}: ignoring target for unknown package: {}", bazelWorkspace, targetLabel);
700+
// continue;
701+
var packageLabel = targetLabel.getPackageLabel();
702+
if (bazelWorkspace.isRootedAtThisWorkspace(packageLabel)) {
703+
bazelPackage = bazelWorkspace.getBazelPackage(packageLabel);
704+
}
705+
}
706+
if (bazelPackage == null) {
707+
LOG.debug("{}: ignoring target for unknown package: {}", bazelWorkspace, targetLabel);
708+
continue;
709+
}
710+
if (!result.containsKey(bazelPackage)) {
711+
result.put(bazelPackage, new HashMap<>());
712+
}
713+
714+
var targetName = targetLabel.getTargetName();
715+
result.get(bazelPackage).put(targetName, target);
716+
}
717+
return result;
718+
}
719+
647720
Path workspacePath() {
648721
return root.toPath();
649722
}

bundles/com.salesforce.bazel.eclipse.core/src/com/salesforce/bazel/eclipse/core/model/discovery/BuildfileDrivenProvisioningStrategy.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import com.google.idea.blaze.base.model.primitives.TargetName;
2929
import com.salesforce.bazel.eclipse.core.classpath.BazelClasspathScope;
3030
import com.salesforce.bazel.eclipse.core.classpath.CompileAndRuntimeClasspath;
31+
import com.salesforce.bazel.eclipse.core.model.BazelPackage;
3132
import com.salesforce.bazel.eclipse.core.model.BazelProject;
3233
import com.salesforce.bazel.eclipse.core.model.BazelTarget;
3334
import com.salesforce.bazel.eclipse.core.model.BazelWorkspace;
@@ -158,6 +159,7 @@ protected List<BazelProject> doProvisionProjects(Collection<TargetExpression> ta
158159

159160
monitor.beginTask("Provisioning projects", packages.size() * 3);
160161
var result = new ArrayList<BazelProject>();
162+
var bazelPackages = new ArrayList<BazelPackage>();
161163
for (Path packagePath : packages) {
162164
var bazelPackage = workspace.getBazelPackage(IPath.fromPath(packagePath));
163165

@@ -171,6 +173,13 @@ protected List<BazelProject> doProvisionProjects(Collection<TargetExpression> ta
171173
STRATEGY_NAME)));
172174
continue;
173175
}
176+
bazelPackages.add(bazelPackage);
177+
}
178+
var targetsByPackage =
179+
workspace.queryForTargetsWithDependencies(workspace, bazelPackages, workspace.getCommandExecutor());
180+
181+
for (BazelPackage bazelPackage : bazelPackages) {
182+
bazelPackage.setTargets(targetsByPackage.get(bazelPackage));
174183

175184
// get the top-level macro calls
176185
var topLevelMacroCalls = bazelPackage.getBazelBuildFile().getTopLevelCalls();

bundles/com.salesforce.bazel.eclipse.core/src/com/salesforce/bazel/eclipse/core/model/discovery/JavaAspectsClasspathInfo.java

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.util.HashSet;
3131
import java.util.LinkedHashSet;
3232
import java.util.List;
33+
import java.util.Map;
3334
import java.util.Set;
3435

3536
import org.eclipse.core.resources.IWorkspaceRoot;
@@ -61,13 +62,15 @@
6162
import com.google.idea.blaze.java.sync.model.BlazeJarLibrary;
6263
import com.salesforce.bazel.eclipse.core.classpath.CompileAndRuntimeClasspath;
6364
import com.salesforce.bazel.eclipse.core.classpath.CompileAndRuntimeClasspath.Builder;
65+
import com.salesforce.bazel.eclipse.core.model.BazelPackage;
6466
import com.salesforce.bazel.eclipse.core.model.BazelProject;
6567
import com.salesforce.bazel.eclipse.core.model.BazelTarget;
6668
import com.salesforce.bazel.eclipse.core.model.BazelWorkspace;
6769
import com.salesforce.bazel.eclipse.core.model.discovery.classpath.AccessRule;
6870
import com.salesforce.bazel.eclipse.core.model.discovery.classpath.ClasspathEntry;
6971
import com.salesforce.bazel.sdk.command.BazelBuildWithIntelliJAspectsCommand;
7072
import com.salesforce.bazel.sdk.command.querylight.BazelRuleAttribute;
73+
import com.salesforce.bazel.sdk.command.querylight.Target;
7174
import com.salesforce.bazel.sdk.model.BazelLabel;
7275

7376
/**
@@ -331,6 +334,11 @@ public IStatus addTarget(BazelTarget bazelTarget) throws CoreException {
331334
* @throws CoreException
332335
*/
333336
public CompileAndRuntimeClasspath compute() throws CoreException {
337+
return compute(null);
338+
}
339+
340+
public CompileAndRuntimeClasspath compute(Map<BazelPackage, Map<String, Target>> targetsByPackage)
341+
throws CoreException {
334342
// the code below is copied and adapted from BlazeJavaWorkspaceImporter
335343

336344
var classpathBuilder = new Builder();
@@ -359,7 +367,7 @@ public CompileAndRuntimeClasspath compute() throws CoreException {
359367
var targetKey = targetLabel != null ? TargetKey.forPlainTarget(targetLabel) : null;
360368
library = new BlazeJarLibrary(libraryArtifact, targetKey);
361369
}
362-
var entry = resolveLibrary(library);
370+
var entry = resolveLibrary(library, targetsByPackage);
363371
if (entry != null) {
364372
if (!validateEntry(entry)) {
365373
continue;
@@ -400,7 +408,7 @@ public CompileAndRuntimeClasspath compute() throws CoreException {
400408

401409
// Collect jars referenced by direct deps
402410
for (TargetKey targetKey : directDeps) {
403-
var entries = resolveDependency(targetKey);
411+
var entries = resolveDependency(targetKey, targetsByPackage);
404412
for (ClasspathEntry entry : entries) {
405413
if (validateEntry(entry)) {
406414
classpathBuilder.addCompileEntry(entry);
@@ -410,7 +418,7 @@ public CompileAndRuntimeClasspath compute() throws CoreException {
410418

411419
// Collect jars referenced by runtime deps
412420
for (TargetKey targetKey : runtimeDeps) {
413-
var entries = resolveDependency(targetKey);
421+
var entries = resolveDependency(targetKey, targetsByPackage);
414422
var addRuntimeDependencyAsCompileEntry = includeRuntimeDependencyAsProjectCompileDependency(targetKey);
415423

416424
for (ClasspathEntry entry : entries) {
@@ -585,8 +593,9 @@ protected boolean relevantDep(Deps.Dependency dep) {
585593
return (dep.getKind() == Deps.Dependency.Kind.EXPLICIT) || (dep.getKind() == Deps.Dependency.Kind.IMPLICIT);
586594
}
587595

588-
protected Collection<ClasspathEntry> resolveDependency(TargetKey targetKey) throws CoreException {
589-
var projectEntry = resolveProject(targetKey);
596+
protected Collection<ClasspathEntry> resolveDependency(TargetKey targetKey,
597+
Map<BazelPackage, Map<String, Target>> targetsByPackage) throws CoreException {
598+
var projectEntry = resolveProject(targetKey, targetsByPackage);
590599
if (projectEntry != null) {
591600
return Set.of(projectEntry);
592601
}
@@ -623,10 +632,11 @@ protected BlazeArtifact resolveJdepsOutput(TargetIdeInfo target) {
623632
return locationDecoder.resolveOutput(javaIdeInfo.getJdepsFile());
624633
}
625634

626-
private ClasspathEntry resolveLibrary(BlazeJarLibrary library) throws CoreException {
635+
private ClasspathEntry resolveLibrary(BlazeJarLibrary library,
636+
Map<BazelPackage, Map<String, Target>> targetsByPackage) throws CoreException {
627637
// find project in workspace if possible
628638
if (library.targetKey != null) {
629-
var projectEntry = resolveProject(library.targetKey);
639+
var projectEntry = resolveProject(library.targetKey, targetsByPackage);
630640
if (projectEntry != null) {
631641
return projectEntry;
632642
}
@@ -636,7 +646,8 @@ private ClasspathEntry resolveLibrary(BlazeJarLibrary library) throws CoreExcept
636646
return resolveJar(library.libraryArtifact);
637647
}
638648

639-
private ClasspathEntry resolveProject(final Label targetLabel) throws CoreException {
649+
private ClasspathEntry resolveProject(final Label targetLabel,
650+
Map<BazelPackage, Map<String, Target>> targetsByPackage) throws CoreException {
640651
var workspace = bazelWorkspace;
641652

642653
// check for project mapping (it trumps everything)
@@ -686,10 +697,18 @@ private ClasspathEntry resolveProject(final Label targetLabel) throws CoreExcept
686697
}
687698
}
688699
var bazelPackage = workspace.getBazelPackage(forPosix(targetLabel.blazePackage().relativePath()));
689-
var bazelTarget = bazelPackage.getBazelTarget(targetLabel.targetName().toString());
690-
if (bazelTarget.hasBazelProject() && bazelTarget.getBazelProject().getProject().isAccessible()) {
691-
// a direct target match is preferred
692-
return newProjectReference(targetLabel, bazelTarget.getBazelProject());
700+
if (targetsByPackage != null) {
701+
var targets = targetsByPackage.get(bazelPackage);
702+
bazelPackage.setTargets(targets);
703+
}
704+
var strategy = new TargetDiscoveryAndProvisioningExtensionLookup()
705+
.createTargetProvisioningStrategy(bazelWorkspace.getBazelProjectView());
706+
if (strategy instanceof ProjectPerTargetProvisioningStrategy) {
707+
var bazelTarget = bazelPackage.getBazelTarget(targetLabel.targetName().toString());
708+
if (bazelTarget.hasBazelProject() && bazelTarget.getBazelProject().getProject().isAccessible()) {
709+
// a direct target match is preferred
710+
return newProjectReference(targetLabel, bazelTarget.getBazelProject());
711+
}
693712
}
694713
if (bazelPackage.hasBazelProject() && bazelPackage.getBazelProject().getProject().isAccessible()) {
695714
// we have to check the target name is part of the enabled project list
@@ -701,7 +720,7 @@ private ClasspathEntry resolveProject(final Label targetLabel) throws CoreExcept
701720
.anyMatch(t -> t.getTargetName().equals(targetName))) {
702721
return newProjectReference(targetLabel, bazelPackage.getBazelProject());
703722
}
704-
723+
var bazelTarget = bazelPackage.getBazelTarget(targetLabel.targetName().toString());
705724
// it may be possible that the target is explicitly hidden from IDEs
706725
// in this case, it won't match in the above condition, however, we still want to make it a project references
707726
// the reason is that we do expect the project to represent the package adequately
@@ -715,12 +734,13 @@ private ClasspathEntry resolveProject(final Label targetLabel) throws CoreExcept
715734
return null;
716735
}
717736

718-
protected ClasspathEntry resolveProject(TargetKey targetKey) throws CoreException {
737+
protected ClasspathEntry resolveProject(TargetKey targetKey,
738+
Map<BazelPackage, Map<String, Target>> targetsByPackage) throws CoreException {
719739
if (!targetKey.isPlainTarget()) {
720740
return null;
721741
}
722742

723-
return resolveProject(targetKey.getLabel());
743+
return resolveProject(targetKey.getLabel(), targetsByPackage);
724744
}
725745

726746
/**

0 commit comments

Comments
 (0)