13
13
// limitations under the License.
14
14
15
15
import * as vscode from "vscode" ;
16
+ import * as fs from "fs/promises" ;
16
17
import { BazelWorkspaceInfo , QueryLocation } from "../bazel" ;
17
18
import { IBazelCommandAdapter , IBazelCommandOptions } from "../bazel" ;
18
19
import { blaze_query } from "../protos" ;
19
20
import { IBazelTreeItem } from "./bazel_tree_item" ;
20
21
import { getBazelRuleIcon } from "./icons" ;
22
+ import { BazelInfo } from "../bazel/bazel_info" ;
23
+ import { getDefaultBazelExecutablePath } from "../extension/configuration" ;
21
24
22
25
/** A tree item representing a build target. */
23
26
export class BazelTargetTreeItem
@@ -27,6 +30,7 @@ export class BazelTargetTreeItem
27
30
* Initializes a new tree item with the given query result representing a
28
31
* build target.
29
32
*
33
+ * @param querier Querier for getting information inside a Bazel workspace.
30
34
* @param target An object representing a build target that was produced by a
31
35
* query.
32
36
*/
@@ -55,16 +59,36 @@ export class BazelTargetTreeItem
55
59
}
56
60
57
61
public getTooltip ( ) : string {
58
- return ` ${ this . target . rule . name } ` ;
62
+ return this . target . rule . name ;
59
63
}
60
64
61
- public getCommand ( ) : vscode . Command | undefined {
65
+ public async getCommand ( ) : Promise < vscode . Command | undefined > {
66
+ // Resolve the prefix if prefix is
67
+ // $(./prebuilts/bazel info output_base)/external/
62
68
const location = new QueryLocation ( this . target . rule . location ) ;
69
+ // Maybe we should cache this to prevent the repeating invocations.
70
+ const outputBase = await new BazelInfo (
71
+ getDefaultBazelExecutablePath ( ) ,
72
+ this . workspaceInfo . workspaceFolder . uri . fsPath ,
73
+ ) . getOne ( "output_base" ) ;
74
+ let locationPath = location . path ;
75
+ // If location is in pattern `${execRoot}/external/<repo>/...`, then it
76
+ // should be a file in local_repository(). Trying to remapping it back to
77
+ // the origin source folder by resolve the symlink
78
+ // ${execRoot}/external/<repo>.
79
+ const outputBaseExternalPath = `${ outputBase } /external/` ;
80
+ if ( location . path . startsWith ( outputBaseExternalPath ) ) {
81
+ const repoPath = location . path . substring ( outputBaseExternalPath . length ) ;
82
+ const repoPathMatch = repoPath . match ( / ^ ( [ ^ / ] + ) \/ ( .* ) $ / ) ;
83
+ if ( repoPathMatch . length === 3 ) {
84
+ const repo = repoPathMatch [ 1 ] ;
85
+ const rest = repoPathMatch [ 2 ] ;
86
+ const realRepo = await fs . realpath ( `${ outputBaseExternalPath } ${ repo } ` ) ;
87
+ locationPath = `${ realRepo } /${ rest } ` ;
88
+ }
89
+ }
63
90
return {
64
- arguments : [
65
- vscode . Uri . file ( location . path ) ,
66
- { selection : location . range } ,
67
- ] ,
91
+ arguments : [ vscode . Uri . file ( locationPath ) , { selection : location . range } ] ,
68
92
command : "vscode.open" ,
69
93
title : "Jump to Build Target" ,
70
94
} ;
@@ -81,7 +105,7 @@ export class BazelTargetTreeItem
81
105
public getBazelCommandOptions ( ) : IBazelCommandOptions {
82
106
return {
83
107
options : [ ] ,
84
- targets : [ ` ${ this . target . rule . name } ` ] ,
108
+ targets : [ this . target . rule . name ] ,
85
109
workspaceInfo : this . workspaceInfo ,
86
110
} ;
87
111
}
0 commit comments