Skip to content

Commit fc7f454

Browse files
authored
Patch the Python aspect template after server install (#41)
The Python aspect template installed by the BSP server will only add a load statement for rules_python if the Bazel version is 8+. In our setup, we need this loaded always. We have added this upstream PR (JetBrains/hirschgarten#210), and also currently have some internal logic that patches this for our users as a workaround. However, I think the best place for it would be to add it here for now so it always runs immediately after install. We can remove this once we resume our own internal server releases.
1 parent ba9e361 commit fc7f454

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

src/server/install.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ export class BazelBSPInstaller {
106106
this.outputChannel.show()
107107
return false
108108
}
109+
110+
// Temporary: Patch the python_info file to be compatible with rules_py.
111+
await this.patchPythonAspect(root)
109112
return true
110113
}
111114

@@ -235,4 +238,43 @@ export class BazelBSPInstaller {
235238
bazelBinaryPath: bazelBinaryPath,
236239
}
237240
}
241+
242+
/**
243+
* Temporary solution to ensure that the rules_python load statement is always included in the Python aspect.
244+
* This is needed for compatibility with targets that no longer include the builtin Python providers (e.g. rules_py).
245+
* This will be addressed by https://github.com/JetBrains/hirschgarten/pull/210 once we have a standalone version of the server back in place.
246+
* @param root
247+
*/
248+
private async patchPythonAspect(root: string) {
249+
// Get the current contents of the Python aspect template, as added by the installer.
250+
const targetFile = path.join(
251+
root,
252+
'.bazelbsp/aspects/rules/python/python_info.bzl.template'
253+
)
254+
255+
let content = ''
256+
try {
257+
content = await fs.readFile(targetFile, 'utf8')
258+
} catch {
259+
this.outputChannel.appendLine(
260+
`Failed to read file ${targetFile}. Skipping patch.`
261+
)
262+
}
263+
264+
// Make rules_python load statement non-conditional for compatibility with rules_py.
265+
const regex =
266+
/#if\( \$pythonEnabled == "true" && \$bazel8OrAbove == "true" \)[\s\S]*?#end/
267+
const replacement =
268+
'load("@rules_python//python:defs.bzl", "PyInfo", "PyRuntimeInfo")'
269+
270+
// Replace the matched block with the replacement.
271+
content = content.replace(regex, replacement)
272+
try {
273+
await fs.writeFile(targetFile, content, 'utf8')
274+
} catch (err) {
275+
this.outputChannel.appendLine(
276+
`Failed to write updated Python aspect to ${targetFile}. Skipping patch.`
277+
)
278+
}
279+
}
238280
}

src/test/suite/install.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ suite('BSP Installer', () => {
7272
.withArgs(settings.SettingName.SERVER_INSTALL_MODE)
7373
.returns('Prompt')
7474

75+
sandbox.stub(fs, 'readFile').resolves(
76+
`#if( $pythonEnabled == "true" && $bazel8OrAbove == "true" )
77+
load("@rules_python//python:defs.bzl", "PyInfo", "PyRuntimeInfo")
78+
#end
79+
80+
load("//aspects:utils/utils.bzl", "create_struct", "file_location", "to_file_location")`
81+
)
82+
7583
// Simulated data returned by coursier download request.
7684
const sampleData = 'sample data'
7785
sandbox.stub(axios.default, 'get').resolves({data: sampleData} as any)
@@ -89,6 +97,12 @@ suite('BSP Installer', () => {
8997
assert.ok(spawnStub.getCalls()[0].args[0].includes(coursierPath))
9098
assert.ok(spawnStub.getCalls()[0].args[0].includes('--jvm openjdk:1.17.0'))
9199
assert.ok(installResult)
100+
101+
const updatedContents = writeFileSpy.getCalls()[1].args[1]
102+
const expectedContents = `load("@rules_python//python:defs.bzl", "PyInfo", "PyRuntimeInfo")
103+
104+
load("//aspects:utils/utils.bzl", "create_struct", "file_location", "to_file_location")`
105+
assert.equal(updatedContents, expectedContents)
92106
})
93107

94108
test('failed coursier download', async () => {

0 commit comments

Comments
 (0)