Skip to content

Commit

Permalink
[feature] add workspace/invalidTargets endpoint | #BAZEL-684 Done
Browse files Browse the repository at this point in the history
filtering out .bazelbsp from invalid targets

Merge remote-tracking branch 'origin/kasia/aspect-fallback-query' into kasia/aspect-fallback-query

format invalid target's labels according to bazel version

fixup! remove java class
remove java class

fix ProjectSyncService

fixup! change isFailure value if user specified an empty set of targets
change isFailure value if user specified an empty set of targets

cr fixes

fix test

add workspace/invalidtargets ep

adding invalid targets to project

move invocation to project resolver

refactoring + add target names from workspace context

add `BazelTargetsQuery`


Co-authored-by: Marcin Abramowicz <marcin.abramowicz@jetbrains.com>


Merge-request: BAZEL-MR-546
Merged-by: Katarzyna Mielnik <katarzyna.anna.mielnik@jetbrains.com>
  • Loading branch information
mielnikk authored and qodana-bot committed Oct 27, 2023
1 parent 2e5227d commit 14a117f
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import org.jetbrains.bsp.bazel.server.sync.ProjectSyncService;
import org.jetbrains.bsp.bazel.server.sync.RunWithDebugParams;
import org.jetbrains.bsp.bazel.server.sync.WorkspaceDirectoriesResult;
import org.jetbrains.bsp.bazel.server.sync.WorkspaceInvalidTargetsResult;
import org.jetbrains.bsp.bazel.server.sync.WorkspaceLibrariesResult;

public class BspServerApi
Expand Down Expand Up @@ -255,6 +256,11 @@ public CompletableFuture<WorkspaceLibrariesResult> workspaceLibraries() {
return runner.handleRequest("libraries", projectSyncService::workspaceBuildLibraries);
}

@Override
public CompletableFuture<WorkspaceInvalidTargetsResult> workspaceInvalidTargets() {
return runner.handleRequest("invalidTargets", projectSyncService::workspaceInvalidTargets);
}

@Override
public CompletableFuture<WorkspaceDirectoriesResult> workspaceDirectories() {
return runner.handleRequest("directories", projectSyncService::workspaceDirectories);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import org.jetbrains.bsp.bazel.server.bep.BepOutput
import org.jetbrains.bsp.bazel.server.bsp.utils.InternalAspectsResolver
import org.jetbrains.bsp.bazel.workspacecontext.TargetsSpec

data class BazelBspAspectsManagerResult(val bepOutput: BepOutput, val isFailure: Boolean)

class BazelBspAspectsManager(
private val bazelBspCompilationManager: BazelBspCompilationManager,
private val aspectsResolver: InternalAspectsResolver,
Expand All @@ -23,10 +25,10 @@ class BazelBspAspectsManager(
targetSpecs: TargetsSpec,
aspect: String,
outputGroups: List<String>,
): BepOutput {
): BazelBspAspectsManagerResult {
bazelBspEnvironmentManager.generateLanguageExtensions(cancelChecker)

return if (targetSpecs.values.isEmpty()) BepOutput()
return if (targetSpecs.values.isEmpty()) BazelBspAspectsManagerResult(BepOutput(), isFailure = false)
else bazelBspCompilationManager
.buildTargetsWithBep(
cancelChecker,
Expand All @@ -43,7 +45,8 @@ class BazelBspAspectsManager(
curses(false)
),
null
)
.bepOutput
).let {
BazelBspAspectsManagerResult(it.bepOutput, it.processResult.isNotSuccess)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.jetbrains.bsp.bazel.server.bsp.managers

import org.eclipse.lsp4j.jsonrpc.CancelChecker
import org.jetbrains.bsp.bazel.bazelrunner.BazelRunner
import org.jetbrains.bsp.bazel.workspacecontext.WorkspaceContextProvider

class BazelBspFallbackAspectsManager(
private val bazelRunner: BazelRunner,
private val workspaceContextProvider: WorkspaceContextProvider
) {
fun getAllPossibleTargets(cancelChecker: CancelChecker): List<String> {
val targets = workspaceContextProvider.currentWorkspaceContext().targets
return bazelRunner.commandBuilder().query()
.withTargets(targets)
.withFlags(listOf("--output=label", "--keep_going"))
.executeBazelCommand(parseProcessOutput = false)
.waitAndGetResult(cancelChecker, ensureAllOutputRead = true)
.stdoutLines
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import org.jetbrains.bsp.bazel.server.bsp.info.BspInfo
import org.jetbrains.bsp.bazel.server.bsp.managers.BazelBspAspectsManager
import org.jetbrains.bsp.bazel.server.bsp.managers.BazelBspCompilationManager
import org.jetbrains.bsp.bazel.server.bsp.managers.BazelBspEnvironmentManager
import org.jetbrains.bsp.bazel.server.bsp.managers.BazelBspFallbackAspectsManager
import org.jetbrains.bsp.bazel.server.bsp.managers.BazelExternalRulesQueryImpl
import org.jetbrains.bsp.bazel.server.bsp.utils.InternalAspectsResolver
import org.jetbrains.bsp.bazel.server.sync.*
Expand Down Expand Up @@ -56,6 +57,7 @@ class ServerContainer internal constructor(

val aspectsResolver = InternalAspectsResolver(bspInfo, bazelInfo.release)
val bazelBspEnvironmentManager = BazelBspEnvironmentManager(aspectsResolver, BazelExternalRulesQueryImpl(bazelRunner))
val bazelBspFallbackAspectsManager = BazelBspFallbackAspectsManager(bazelRunner, workspaceContextProvider)
val bazelBspAspectsManager = BazelBspAspectsManager(compilationManager, aspectsResolver, bazelBspEnvironmentManager)
val bazelPathsResolver = BazelPathsResolver(bazelInfo)
val jdkResolver = JdkResolver(bazelPathsResolver, JdkVersionResolver())
Expand All @@ -74,6 +76,7 @@ class ServerContainer internal constructor(
val targetInfoReader = TargetInfoReader()
val projectResolver = ProjectResolver(
bazelBspAspectsManager,
bazelBspFallbackAspectsManager,
workspaceContextProvider,
bazelProjectMapper,
bspClientLogger,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ data class WorkspaceLibrariesResult(
val libraries: List<LibraryItem>
)

data class WorkspaceInvalidTargetsResult(
val targets: List<BuildTargetIdentifier>
)

data class DirectoryItem(
val uri: String,
)
Expand All @@ -42,6 +46,9 @@ interface BazelBuildServer {
@JsonRequest("workspace/libraries")
fun workspaceLibraries(): CompletableFuture<WorkspaceLibrariesResult>

@JsonRequest("workspace/invalidTargets")
fun workspaceInvalidTargets(): CompletableFuture<WorkspaceInvalidTargetsResult>

@JsonRequest("workspace/directories")
fun workspaceDirectories(): CompletableFuture<WorkspaceDirectoriesResult>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class BazelProjectMapper(
fun createProject(
targets: Map<String, TargetInfo>,
rootTargets: Set<String>,
allTargetNames: List<String>,
workspaceContext: WorkspaceContext
): Project {
languagePluginsService.prepareSync(targets.values.asSequence())
Expand Down Expand Up @@ -88,7 +89,10 @@ class BazelProjectMapper(
val librariesToImport = measure("Merge all libraries") {
librariesFromDepsAndTargets + extraLibrariesFromJdeps.values.flatten().associateBy { it.label }
}
return Project(workspaceRoot, modifiedModules.toList(), sourceToTarget, librariesToImport)
val invalidTargets = measure("Save invalid target labels") {
(removeDotBazelBspTarget(allTargetNames) - targetsToImport.map(TargetInfo::getId).toList()).map { Label(it) }
}
return Project(workspaceRoot, modifiedModules.toList(), sourceToTarget, librariesToImport, invalidTargets)
}

private fun <K, V> concatenateMaps(
Expand Down Expand Up @@ -419,4 +423,8 @@ class BazelProjectMapper(
private fun collectInheritedEnvs(targetInfo: TargetInfo): Map<String, String> =
targetInfo.envInheritList.associateWith { System.getenv(it) }

private fun removeDotBazelBspTarget(targets: List<String>): List<String> {
val prefix = bazelInfo.release.mainRepositoryReferencePrefix() + ".bazelbsp"
return targets.filter { !it.startsWith(prefix) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ class BspProjectMapper(
return WorkspaceBuildTargetsResult(buildTargets)
}

fun workspaceInvalidTargets(project: Project): WorkspaceInvalidTargetsResult =
WorkspaceInvalidTargetsResult(project.invalidTargets.map { BuildTargetIdentifier(it.value) })

fun workspaceLibraries(project: Project): WorkspaceLibrariesResult {
val libraries = project.libraries.values.map {
LibraryItem(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ import org.eclipse.lsp4j.jsonrpc.CancelChecker
import org.jetbrains.bsp.bazel.bazelrunner.BazelInfo
import org.jetbrains.bsp.bazel.logger.BspClientLogger
import org.jetbrains.bsp.bazel.server.bep.BepOutput
import org.jetbrains.bsp.bazel.server.bsp.managers.BazelBspFallbackAspectsManager
import org.jetbrains.bsp.bazel.server.bsp.managers.BazelBspAspectsManager
import org.jetbrains.bsp.bazel.server.bsp.managers.BazelBspAspectsManagerResult
import org.jetbrains.bsp.bazel.server.sync.model.Project
import org.jetbrains.bsp.bazel.workspacecontext.WorkspaceContext
import org.jetbrains.bsp.bazel.workspacecontext.WorkspaceContextProvider

/** Responsible for querying bazel and constructing Project instance */
class ProjectResolver(
private val bazelBspAspectsManager: BazelBspAspectsManager,
private val bazelBspFallbackAspectsManager: BazelBspFallbackAspectsManager,
private val workspaceContextProvider: WorkspaceContextProvider,
private val bazelProjectMapper: BazelProjectMapper,
private val bspLogger: BspClientLogger,
Expand All @@ -29,35 +32,44 @@ class ProjectResolver(
"Reading project view and creating workspace context",
workspaceContextProvider::currentWorkspaceContext
)
val bepOutput = measured(
val buildAspectResult = measured(
"Building project with aspect"
) { buildProjectWithAspect(cancelChecker, workspaceContext) }
val allTargetNames =
if (buildAspectResult.isFailure)
measured(
"Fetching all possible target names"
) { bazelBspFallbackAspectsManager.getAllPossibleTargets(cancelChecker).let { formatTargetsIfNeeded(it) } }
else
emptyList()
val aspectOutputs = measured(
"Reading aspect output paths"
) { bepOutput.filesByOutputGroupNameTransitive(BSP_INFO_OUTPUT_GROUP) }
val rootTargets = when(bazelInfo.release.major){
// Since bazel 6, the main repository targets are stringified to "@//"-prefixed labels,
// contrary to "//"-prefixed in older Bazel versions. Unfortunately this does not apply
// to BEP data, probably due to a bug, so we need to add the "@" prefix here.
in 0..5 -> bepOutput.rootTargets()
else -> bepOutput.rootTargets().map { "@$it" }
}
) { buildAspectResult.bepOutput.filesByOutputGroupNameTransitive(BSP_INFO_OUTPUT_GROUP) }
val rootTargets = buildAspectResult.bepOutput.rootTargets().let { formatTargetsIfNeeded(it) }
val targets = measured(
"Parsing aspect outputs"
) { targetInfoReader.readTargetMapFromAspectOutputs(aspectOutputs) }
return measured(
"Mapping to internal model"
) { bazelProjectMapper.createProject(targets, rootTargets.toSet(), workspaceContext) }
) { bazelProjectMapper.createProject(targets, rootTargets.toSet(), allTargetNames, workspaceContext) }
}

private fun buildProjectWithAspect(cancelChecker: CancelChecker, workspaceContext: WorkspaceContext): BepOutput =
private fun buildProjectWithAspect(cancelChecker: CancelChecker, workspaceContext: WorkspaceContext): BazelBspAspectsManagerResult =
bazelBspAspectsManager.fetchFilesFromOutputGroups(
cancelChecker,
workspaceContext.targets,
ASPECT_NAME,
listOf(BSP_INFO_OUTPUT_GROUP, ARTIFACTS_OUTPUT_GROUP)
)

private fun formatTargetsIfNeeded(targets: Collection<String>): List<String> =
when(bazelInfo.release.major){
// Since bazel 6, the main repository targets are stringified to "@//"-prefixed labels,
// contrary to "//"-prefixed in older Bazel versions. Unfortunately this does not apply
// to BEP data, probably due to a bug, so we need to add the "@" prefix here.
in 0..5 -> targets.toList()
else -> targets.map { "@$it" }
}.toList()

companion object {
private const val ASPECT_NAME = "bsp_target_info_aspect"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ class ProjectSyncService(private val bspMapper: BspProjectMapper, private val pr
return bspMapper.workspaceDirectories(project)
}

fun workspaceInvalidTargets(cancelChecker: CancelChecker): WorkspaceInvalidTargetsResult {
val project = projectProvider.get(cancelChecker)
return bspMapper.workspaceInvalidTargets(project)
}

fun buildTargetSources(cancelChecker: CancelChecker, sourcesParams: SourcesParams): SourcesResult {
val project = projectProvider.get(cancelChecker)
return bspMapper.sources(project, sourcesParams)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ data class Project(
val workspaceRoot: URI,
val modules: List<Module>,
val sourceToTarget: Map<URI, Label>,
val libraries: Map<String, Library>
val libraries: Map<String, Library>,
val invalidTargets: List<Label>,
) {
private val moduleMap: Map<Label, Module> = modules.associateBy(Module::label)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class ProjectStorageTest {
),
mapOf(URI.create("file:///root/project/Lib.java") to Label("file:///root")),
emptyMap(),
emptyList(),
)
storage.store(project)
val loaded = storage.load()
Expand Down

0 comments on commit 14a117f

Please sign in to comment.