Skip to content

Commit 83aee97

Browse files
authored
Merge pull request #2762 from digma-ai/support-python
Support python Closes #2761
2 parents 2720772 + 0d6c6a7 commit 83aee97

File tree

59 files changed

+2699
-1610
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+2699
-1610
lines changed

.github/workflows/build-branches.yml

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ jobs:
1515
build-profile: ${{ matrix.profile }}
1616
ref-name: ${{ github.ref_name }}
1717
build-with-rider: false
18+
build-with-pycharm: false
1819
secrets: inherit
1920
build-workflow-with-rider:
2021
strategy:
@@ -25,15 +26,17 @@ jobs:
2526
build-profile: ${{ matrix.profile }}
2627
ref-name: ${{ github.ref_name }}
2728
build-with-rider: true
29+
build-with-pycharm: false
2830
secrets: inherit
2931

30-
##todo: maybe we want to run plugin verifier on every commit to branch ?
31-
# plugin-verifier-workflow:
32-
# strategy:
33-
# matrix:
34-
# profile: [ p241, p242, p243, p251, p252 ]
35-
# uses: ./.github/workflows/plugin-verifier-workflow.yml
36-
# with:
37-
# build-profile: ${{ matrix.profile }}
38-
# ref-name: ${{ github.ref_name }}
39-
# secrets: inherit
32+
build-workflow-with-pycharm:
33+
strategy:
34+
matrix:
35+
profile: [ p241, p242, p243, p251, p252 ]
36+
uses: ./.github/workflows/build-workflow.yml
37+
with:
38+
build-profile: ${{ matrix.profile }}
39+
ref-name: ${{ github.ref_name }}
40+
build-with-rider: false
41+
build-with-pycharm: true
42+
secrets: inherit

.github/workflows/build-main.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ jobs:
1313
build-profile: ${{ matrix.profile }}
1414
ref-name: ${{ github.ref_name }}
1515
build-with-rider: false
16+
build-with-pycharm: false
1617
secrets: inherit
1718
## can do a double matrix for rider but then it's not clear in github which is the rider build.
1819
build-workflow-with-rider:
@@ -24,6 +25,19 @@ jobs:
2425
build-profile: ${{ matrix.profile }}
2526
ref-name: ${{ github.ref_name }}
2627
build-with-rider: true
28+
build-with-pycharm: false
29+
secrets: inherit
30+
31+
build-workflow-with-pycharm:
32+
strategy:
33+
matrix:
34+
profile: [ p241, p242, p243, p251, p252 ]
35+
uses: ./.github/workflows/build-workflow.yml
36+
with:
37+
build-profile: ${{ matrix.profile }}
38+
ref-name: ${{ github.ref_name }}
39+
build-with-rider: false
40+
build-with-pycharm: true
2741
secrets: inherit
2842

2943
plugin-verifier-workflow:

.github/workflows/build-pull-request.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ jobs:
1414
build-profile: ${{ matrix.profile }}
1515
ref-name: ${{ github.event.pull_request.head.sha }}
1616
build-with-rider: false
17+
build-with-pycharm: false
1718
secrets: inherit
1819

1920
build-workflow-with-rider:
@@ -25,6 +26,19 @@ jobs:
2526
build-profile: ${{ matrix.profile }}
2627
ref-name: ${{ github.event.pull_request.head.sha }}
2728
build-with-rider: true
29+
build-with-pycharm: false
30+
secrets: inherit
31+
32+
build-workflow-with-pycharm:
33+
strategy:
34+
matrix:
35+
profile: [ p241, p242, p243, p251, p252 ]
36+
uses: ./.github/workflows/build-workflow.yml
37+
with:
38+
build-profile: ${{ matrix.profile }}
39+
ref-name: ${{ github.event.pull_request.head.sha }}
40+
build-with-rider: false
41+
build-with-pycharm: true
2842
secrets: inherit
2943

3044
plugin-verifier-workflow:

.github/workflows/build-workflow.yml

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ on:
1212
build-with-rider:
1313
required: true
1414
type: string
15+
build-with-pycharm:
16+
required: true
17+
type: string
1518

1619
jobs:
1720
build:
@@ -51,15 +54,22 @@ jobs:
5154

5255

5356
- name: Build Plugin
54-
if: ${{ inputs.build-with-rider != 'true' }}
57+
if: ${{ inputs.build-with-rider != 'true' && inputs.build-with-pycharm != 'true' }}
5558
run: ./gradlew clean test buildPlugin --no-daemon -PbuildProfile=${{ inputs.build-profile }} -PbuildSearchableOptions=true
5659

5760
- name: Build Plugin with Rider
5861
if: ${{ inputs.build-with-rider == 'true' }}
59-
run: ./gradlew clean test buildPlugin --no-daemon -PbuildWithRider=true -PbuildProfile=${{ inputs.build-profile }} -PbuildSearchableOptions=true
62+
run: ./gradlew clean test buildPlugin --no-daemon -PbuildWithRider=true -PbuildProfile=${{ inputs.build-profile }} -PbuildSearchableOptions=false
63+
64+
- name: Build Plugin with pycharm
65+
if: ${{ inputs.build-with-pycharm == 'true' }}
66+
run: ./gradlew clean test buildPlugin --no-daemon -PbuildWithPycharm=true -PbuildProfile=${{ inputs.build-profile }} -PbuildSearchableOptions=false
67+
68+
69+
6070

6171
- name: Prepare Plugin Artifact
62-
if: ${{ inputs.build-with-rider != 'true' }}
72+
if: ${{ inputs.build-with-rider != 'true' && inputs.build-with-pycharm != 'true' }}
6373
id: artifact
6474
shell: bash
6575
run: |
@@ -69,7 +79,7 @@ jobs:
6979
echo "filename=${FILENAME:0:-4}" >> "$GITHUB_OUTPUT"
7080
7181
- name: Upload Artifact
72-
if: ${{ inputs.build-with-rider != 'true' }}
82+
if: ${{ inputs.build-with-rider != 'true' && inputs.build-with-pycharm != 'true' }}
7383
uses: actions/upload-artifact@v4
7484
with:
7585
name: ${{ steps.artifact.outputs.filename }}
@@ -79,7 +89,7 @@ jobs:
7989
# Collect Tests Result of failed tests
8090
##todo: add other modules test reports
8191
- name: Collect Tests Result
82-
if: ${{ inputs.build-with-rider != 'true' || failure() }}
92+
if: ${{ inputs.build-with-rider != 'true' && inputs.build-with-pycharm != 'true' }}
8393
uses: actions/upload-artifact@v4
8494
with:
8595
name: tests-result-${{ inputs.build-profile }}

.run/Run PyCharm - 2025.2.run.xml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="Run PyCharm - 2025.2" type="GradleRunConfiguration" factoryName="Gradle">
3+
<log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea_RD.log" />
4+
<ExternalSystemSettings>
5+
<option name="executionName" />
6+
<option name="externalProjectPath" value="$PROJECT_DIR$" />
7+
<option name="externalSystemIdString" value="GRADLE" />
8+
<option name="scriptParameters" value="-PbuildWithPycharm=true -PbuildProfile=p252 -Pdigma-no-info-logging -x test" />
9+
<option name="taskDescriptions">
10+
<list />
11+
</option>
12+
<option name="taskNames">
13+
<list>
14+
<option value="runIde" />
15+
</list>
16+
</option>
17+
<option name="vmOptions" value="" />
18+
</ExternalSystemSettings>
19+
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
20+
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
21+
<DebugAllEnabled>false</DebugAllEnabled>
22+
<RunAsTest>false</RunAsTest>
23+
<method v="2" />
24+
</configuration>
25+
</component>

build.gradle.kts

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ dependencies {
8787
pluginModule(implementation(project(":maven-support")))
8888
pluginModule(implementation(project(":rider")))
8989
pluginModule(implementation(project(":kotlin")))
90+
pluginModule(implementation(project(":python")))
9091

9192
pluginVerifier()
9293
zipSigner()
@@ -130,7 +131,6 @@ changelog {
130131
//}
131132

132133

133-
134134
intellijPlatform {
135135

136136
pluginConfiguration {
@@ -206,20 +206,26 @@ intellijPlatform {
206206
//there is a feature request: https://github.com/JetBrains/intellij-platform-gradle-plugin/issues/1715
207207
//ide(platformType, buildProfile.platformVersion)
208208
//use recommended() and hope it doesn't fail too much because sometimes it does fail for unknown reasons
209-
recommended()
210-
211-
val channel = if (buildProfile.isEAP) {
212-
ProductRelease.Channel.EAP
213-
} else {
214-
ProductRelease.Channel.RELEASE
215-
}
216-
select {
217-
types =
218-
listOf(IntelliJPlatformType.IntellijIdeaCommunity)
219-
channels = listOf(channel)
220-
sinceBuild = project.currentProfile().pluginSinceBuild
221-
untilBuild = project.currentProfile().pluginUntilBuild
222-
}
209+
// recommended()
210+
211+
// val channel = if (buildProfile.isEAP) {
212+
// ProductRelease.Channel.EAP
213+
// } else {
214+
// ProductRelease.Channel.RELEASE
215+
// }
216+
// select {
217+
// types =
218+
// listOf(IntelliJPlatformType.IntellijIdeaCommunity, IntelliJPlatformType.Rider, IntelliJPlatformType.PyCharmCommunity)
219+
// channels = listOf(channel)
220+
// sinceBuild = project.currentProfile().pluginSinceBuild
221+
// untilBuild = project.currentProfile().pluginUntilBuild
222+
// }
223+
224+
val useInstaller = project.useBinaryInstaller()
225+
226+
ide(IntelliJPlatformType.IntellijIdeaCommunity, buildProfile.platformVersion, useInstaller)
227+
// ide(IntelliJPlatformType.PyCharmCommunity, buildProfile.pycharmVersion, useInstaller)
228+
// ide(IntelliJPlatformType.Rider, buildProfile.riderVersion, useInstaller)
223229
}
224230
}
225231
subsystemsToCheck = VerifyPluginTask.Subsystems.WITHOUT_ANDROID
@@ -318,9 +324,9 @@ tasks {
318324
//see https://kotlin.github.io/analysis-api/testing-in-k2-locally.html
319325
"idea.kotlin.plugin.use.k2" to "true",
320326

321-
//"jcef.remote.enabled" to true,
322-
//"jcef.remote.debug" to true,
323-
//"ide.browser.jcef.log.level" to "error",
327+
//"jcef.remote.enabled" to true,
328+
//"jcef.remote.debug" to true,
329+
//"ide.browser.jcef.log.level" to "error",
324330

325331
//"idea.ProcessCanceledException" to "disabled"
326332

building-how-to/verify-all-profiles-short.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,7 @@ for i in {1..5}; do echo; done
1717

1818
echo "############ verifyPlugin with 251 ################"
1919
./gradlew clean verifyPlugin -PbuildProfile=p251
20+
for i in {1..5}; do echo; done
21+
22+
echo "############ verifyPlugin with 252 ################"
23+
./gradlew clean verifyPlugin -PbuildProfile=p252

common-build-logic/src/main/kotlin/common/BuildProfile.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ object BuildProfiles {
117117
)
118118

119119

120-
//todo: check products releases file, can be used to automatically to update the profiles
120+
//todo: check products releases file, can be used to automatically update the profiles
121121
// https://www.jetbrains.com/updates/updates.xml
122122
// IntelliJPluginConstants.IDEA_PRODUCTS_RELEASES_URL
123123
// https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#tasks-listproductsreleases
@@ -142,7 +142,7 @@ object BuildProfiles {
142142
profile = Profile.p241,
143143
platformVersion = "2024.1.7",
144144
riderVersion = "2024.1.6",
145-
pycharmVersion = "2024.1.5",
145+
pycharmVersion = "2024.1.7",
146146
riderTargetFramework = "net8.0",
147147
riderResharperVersionConstant = "",
148148
platformVersionCode = "241",
@@ -157,9 +157,9 @@ object BuildProfiles {
157157

158158
Profile.p242 to BuildProfile(
159159
profile = Profile.p242,
160-
platformVersion = "2024.2.4",
160+
platformVersion = "2024.2.6",
161161
riderVersion = "2024.2.7",
162-
pycharmVersion = "2024.2",
162+
pycharmVersion = "2024.2.6",
163163
riderTargetFramework = "net8.0",
164164
riderResharperVersionConstant = "",
165165
platformVersionCode = "242",
@@ -174,7 +174,7 @@ object BuildProfiles {
174174
profile = Profile.p243,
175175
platformVersion = "2024.3.5",
176176
riderVersion = "2024.3.6",
177-
pycharmVersion = "2024.3",
177+
pycharmVersion = "2024.3.5",
178178
riderTargetFramework = "net8.0",
179179
riderResharperVersionConstant = "PROFILE_2024_3",
180180
platformVersionCode = "243",
@@ -189,7 +189,7 @@ object BuildProfiles {
189189
profile = Profile.p251,
190190
platformVersion = "2025.1.2",
191191
riderVersion = "2025.1.2",
192-
pycharmVersion = "2025.1.1.1",
192+
pycharmVersion = "2025.1.2",
193193
riderTargetFramework = "net8.0",
194194
riderResharperVersionConstant = "PROFILE_2024_3",
195195
platformVersionCode = "251",
@@ -215,7 +215,6 @@ object BuildProfiles {
215215
kotlinJvmTarget = JvmTarget.JVM_21,
216216
javaVersion = JavaVersion.VERSION_21.majorVersion,
217217
)
218-
219218
)
220219

221220
}

ide-common/src/main/kotlin/org/digma/intellij/plugin/codelens/provider/CodeLensBuilder.kt

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ internal class CodeLensBuilder(private val project: Project) {
3232

3333
val methodsWithCodeLens = AnalyticsService.getInstance(project).getCodeLensByMethods(methodsWithCodeObjects).methodWithCodeLens
3434

35-
methodsWithCodeLens.forEach { methodWithCodeLens: MethodWithCodeLens ->
35+
distinctForPython(documentInfo, methodsWithCodeLens).forEach { methodWithCodeLens: MethodWithCodeLens ->
3636

3737
val codeObjectId = CodeObjectsUtil.stripMethodPrefix(methodWithCodeLens.methodCodeObjectId)
3838
val decorators: MutableList<Decorator> = methodWithCodeLens.decorators.toMutableList()
@@ -76,12 +76,43 @@ internal class CodeLensBuilder(private val project: Project) {
7676
title,
7777
1,
7878
liveDecorator.description,
79-
"Go to $title")
79+
"Go to $title"
80+
)
8081
return codeLens
8182
}
8283

8384

8485
private fun isImportant(importanceLevel: Int): Boolean {
8586
return importanceLevel <= InsightImportance.HighlyImportant.priority && importanceLevel >= InsightImportance.ShowStopper.priority
8687
}
88+
89+
90+
/*
91+
in python we send multiple ids for a method, we may get multiple MethodWithCodeLens for the same method, for each id or some of the ids.
92+
we want to keep only one MethodWithCodeLens for a method with the decorators from all the MethodWithCodeLens belonging to the same method.
93+
*/
94+
private fun distinctForPython(documentInfo: DocumentInfo, methodsWithCodeLens: List<MethodWithCodeLens>): List<MethodWithCodeLens> {
95+
//don't need to do it if it's not python
96+
if (documentInfo.languageId.lowercase() != "python") {
97+
return methodsWithCodeLens
98+
}
99+
100+
101+
val methodWithCodeLensByMethodIds = methodsWithCodeLens.associateBy { it.methodCodeObjectId }
102+
val newMethodsWithCodeLens = mutableMapOf<String, MutableSet<Decorator>>()
103+
documentInfo.methods.forEach { (methodId, methodInfo) ->
104+
methodInfo.allIdsWithType().forEach { id: String ->
105+
val methodWithCodeLens = methodWithCodeLensByMethodIds[id]
106+
if (methodWithCodeLens != null) {
107+
val newDecorators = newMethodsWithCodeLens.computeIfAbsent(methodId) { mutableSetOf() }
108+
//map the decorators to have the same method id
109+
val decorators = methodWithCodeLens.decorators.map { Decorator(it.title,it.description,methodId,it.spanCodeObjectId,it.importance) }.toSet()
110+
//relying on that Decorator is a data class with correct equals and hashCode so this will merge and ignore duplicates.
111+
newDecorators.addAll(decorators)
112+
}
113+
}
114+
}
115+
116+
return newMethodsWithCodeLens.map { (id, decorators) -> MethodWithCodeLens(id, decorators.toList()) }.toList()
117+
}
87118
}
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.digma.intellij.plugin.common
22

3+
import com.intellij.psi.search.GlobalSearchScope
34
import com.intellij.psi.search.SearchScope
45
import java.util.function.Supplier
56

@@ -8,4 +9,6 @@ import java.util.function.Supplier
89
* SearchScope must be created in ReadAccess, but sometimes we send a search scope for a method before
910
* opening read access. in these cases send a SearchScopeProvider and call get only in read access.
1011
*/
11-
fun interface SearchScopeProvider : Supplier<SearchScope>
12+
fun interface SearchScopeProvider : Supplier<SearchScope>
13+
14+
fun interface GlobalSearchScopeProvider : Supplier<GlobalSearchScope>

0 commit comments

Comments
 (0)