mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge Android Studio EE Canary 9
GitOrigin-RevId: 0050a742aebbf8ecbcd3a76198a8a8e7059c6604
This commit is contained in:
+1
-2
@@ -17,5 +17,4 @@ edu/dependencies/.gradle
|
||||
edu/dependencies/build
|
||||
native/**/build/
|
||||
stale_outputs_checked
|
||||
/android
|
||||
/tools/ideTestingFramework/intellij.tools.ide.starter
|
||||
/android
|
||||
Generated
+2
-2
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="aia-proto" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:proto:30.2.0.0" />
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:proto:221.0.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/proto/30.2.0.0/proto-30.2.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/proto/221.0.9.0/proto-221.0.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="android-test-plugin-host-device-info-proto" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:libstudio.android-test-plugin-host-device-info-proto:30.2.0.0" />
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:libstudio.android-test-plugin-host-device-info-proto:221.0.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/libstudio.android-test-plugin-host-device-info-proto/30.2.0.0/libstudio.android-test-plugin-host-device-info-proto-30.2.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/libstudio.android-test-plugin-host-device-info-proto/221.0.9.0/libstudio.android-test-plugin-host-device-info-proto-221.0.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
Generated
+2
-2
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="baksmali" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.smali:baksmali:2.2.4" />
|
||||
<properties include-transitive-deps="false" maven-id="org.smali:baksmali:2.5.2" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/smali/baksmali/2.2.4/baksmali-2.2.4.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/smali/baksmali/2.5.2/baksmali-2.5.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
Generated
+2
-9
@@ -1,15 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="dexlib2" type="repository">
|
||||
<properties maven-id="org.smali:dexlib2:2.2.4">
|
||||
<exclude>
|
||||
<dependency maven-id="com.beust:jcommander" />
|
||||
<dependency maven-id="com.google.code.findbugs:jsr305" />
|
||||
<dependency maven-id="com.google.guava:guava" />
|
||||
</exclude>
|
||||
</properties>
|
||||
<properties include-transitive-deps="false" maven-id="org.smali:dexlib2:2.5.2" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/smali/dexlib2/2.2.4/dexlib2-2.2.4.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/smali/util/2.2.4/util-2.2.4.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/smali/dexlib2/2.5.2/dexlib2-2.5.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
Generated
+2
-2
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="emulator-proto" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:emulator_java_proto:30.2.0.0" />
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:emulator_java_proto:221.0.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/emulator_java_proto/30.2.0.0/emulator_java_proto-30.2.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/emulator_java_proto/221.0.9.0/emulator_java_proto-221.0.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
Generated
+11
@@ -0,0 +1,11 @@
|
||||
<component name="libraryTable">
|
||||
<library name="ffmpeg" type="repository">
|
||||
<properties maven-id="org.bytedeco:ffmpeg:5.0-1.5.7" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/5.0-1.5.7/ffmpeg-5.0-1.5.7.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.7/javacpp-1.5.7.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
Generated
+41
@@ -0,0 +1,41 @@
|
||||
<component name="libraryTable">
|
||||
<library name="ffmpeg-platform" type="repository">
|
||||
<properties maven-id="org.bytedeco:ffmpeg-platform:5.0-1.5.7" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg-platform/5.0-1.5.7/ffmpeg-platform-5.0-1.5.7.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp-platform/1.5.7/javacpp-platform-1.5.7.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.7/javacpp-1.5.7.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.7/javacpp-1.5.7-android-arm.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.7/javacpp-1.5.7-android-arm64.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.7/javacpp-1.5.7-android-x86.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.7/javacpp-1.5.7-android-x86_64.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.7/javacpp-1.5.7-ios-arm64.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.7/javacpp-1.5.7-ios-x86_64.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.7/javacpp-1.5.7-linux-armhf.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.7/javacpp-1.5.7-linux-arm64.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.7/javacpp-1.5.7-linux-ppc64le.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.7/javacpp-1.5.7-linux-x86.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.7/javacpp-1.5.7-linux-x86_64.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.7/javacpp-1.5.7-macosx-arm64.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.7/javacpp-1.5.7-macosx-x86_64.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.7/javacpp-1.5.7-windows-x86.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.7/javacpp-1.5.7-windows-x86_64.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/5.0-1.5.7/ffmpeg-5.0-1.5.7.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/5.0-1.5.7/ffmpeg-5.0-1.5.7-android-arm.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/5.0-1.5.7/ffmpeg-5.0-1.5.7-android-arm64.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/5.0-1.5.7/ffmpeg-5.0-1.5.7-android-x86.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/5.0-1.5.7/ffmpeg-5.0-1.5.7-android-x86_64.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/5.0-1.5.7/ffmpeg-5.0-1.5.7-linux-x86.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/5.0-1.5.7/ffmpeg-5.0-1.5.7-linux-x86_64.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/5.0-1.5.7/ffmpeg-5.0-1.5.7-linux-armhf.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/5.0-1.5.7/ffmpeg-5.0-1.5.7-linux-arm64.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/5.0-1.5.7/ffmpeg-5.0-1.5.7-linux-ppc64le.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/5.0-1.5.7/ffmpeg-5.0-1.5.7-macosx-arm64.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/5.0-1.5.7/ffmpeg-5.0-1.5.7-macosx-x86_64.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/5.0-1.5.7/ffmpeg-5.0-1.5.7-windows-x86.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/5.0-1.5.7/ffmpeg-5.0-1.5.7-windows-x86_64.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="layout_inspector_compose_java_proto" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:layout_inspector_compose_java_proto:30.2.0.0" />
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:layout_inspector_compose_java_proto:221.0.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/layout_inspector_compose_java_proto/30.2.0.0/layout_inspector_compose_java_proto-30.2.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/layout_inspector_compose_java_proto/221.0.9.0/layout_inspector_compose_java_proto-221.0.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="layout_inspector_snapshot_java_proto" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:layout_inspector_snapshot_java_proto:30.2.0.0" />
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:layout_inspector_snapshot_java_proto:221.0.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/layout_inspector_snapshot_java_proto/30.2.0.0/layout_inspector_snapshot_java_proto-30.2.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/layout_inspector_snapshot_java_proto/221.0.9.0/layout_inspector_snapshot_java_proto-221.0.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="layout_inspector_view_java_proto" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:layout_inspector_view_java_proto:30.2.0.0" />
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:layout_inspector_view_java_proto:221.0.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/layout_inspector_view_java_proto/30.2.0.0/layout_inspector_view_java_proto-30.2.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/layout_inspector_view_java_proto/221.0.9.0/layout_inspector_view_java_proto-221.0.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="layoutinspector-skia-proto" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:layout_inspector_skia_java_proto:30.2.0.0" />
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:layout_inspector_skia_java_proto:221.0.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/layout_inspector_skia_java_proto/30.2.0.0/layout_inspector_skia_java_proto-30.2.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/layout_inspector_skia_java_proto/221.0.9.0/layout_inspector_skia_java_proto-221.0.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
Generated
+2
-2
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="layoutlib" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:jb-layoutlib-jdk11:30.2.0.0" />
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:jb-layoutlib-jdk11:221.0.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/jb-layoutlib-jdk11/30.2.0.0/jb-layoutlib-jdk11-30.2.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/jb-layoutlib-jdk11/221.0.9.0/jb-layoutlib-jdk11-221.0.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="libam-instrumentation-data-proto" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:libam-instrumentation-data-proto:30.2.0.0" />
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:libam-instrumentation-data-proto:221.0.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/libam-instrumentation-data-proto/30.2.0.0/libam-instrumentation-data-proto-30.2.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/libam-instrumentation-data-proto/221.0.9.0/libam-instrumentation-data-proto-221.0.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="libapp-processes-proto" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:libapp-processes-proto:30.2.0.0" />
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:libapp-processes-proto:221.0.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/libapp-processes-proto/30.2.0.0/libapp-processes-proto-30.2.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/libapp-processes-proto/221.0.9.0/libapp-processes-proto-221.0.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="network_inspector_java_proto" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:network_inspector_java_proto:30.2.0.0" />
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:network_inspector_java_proto:221.0.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/network_inspector_java_proto/30.2.0.0/network_inspector_java_proto-30.2.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/network_inspector_java_proto/221.0.9.0/network_inspector_java_proto-221.0.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
Generated
+2
-2
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="perfetto-proto" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:perfetto-protos:30.2.0.0" />
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:perfetto-protos:221.0.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/perfetto-protos/30.2.0.0/perfetto-protos-30.2.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/perfetto-protos/221.0.9.0/perfetto-protos-221.0.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="sqlite-inspector-proto" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:sqlite_inspector_proto:30.2.0.0" />
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:sqlite_inspector_proto:221.0.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/sqlite_inspector_proto/30.2.0.0/sqlite_inspector_proto-30.2.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/sqlite_inspector_proto/221.0.9.0/sqlite_inspector_proto-221.0.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="studio-analytics-proto" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:libstudio.proto:30.2.0.0" />
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:libstudio.proto:221.0.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/libstudio.proto/30.2.0.0/libstudio.proto-30.2.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/libstudio.proto/221.0.9.0/libstudio.proto-221.0.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
Generated
+2
-2
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="studio-grpc" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:studio-grpc:30.2.0.0" />
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:studio-grpc:221.0.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/studio-grpc/30.2.0.0/studio-grpc-30.2.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/studio-grpc/221.0.9.0/studio-grpc-221.0.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
Generated
+2
-2
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="studio-proto" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:studio-proto:30.2.0.0" />
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:studio-proto:221.0.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/studio-proto/30.2.0.0/studio-proto-30.2.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/studio-proto/221.0.9.0/studio-proto-221.0.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
Generated
+2
-2
@@ -1,8 +1,8 @@
|
||||
<component name="libraryTable">
|
||||
<library name="transport-proto" type="repository">
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:transport_java_proto:30.2.0.0" />
|
||||
<properties include-transitive-deps="false" maven-id="org.jetbrains.intellij.deps.android.tools.base:transport_java_proto:221.0.9.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/transport_java_proto/30.2.0.0/transport_java_proto-30.2.0.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/android/tools/base/transport_java_proto/221.0.9.0/transport_java_proto-221.0.9.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
Generated
+66
-49
@@ -317,11 +317,14 @@
|
||||
</component>
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/android/analytics/analytics.iml" filepath="$PROJECT_DIR$/android/analytics/analytics.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/analytics-crash.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/analytics-crash.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/analytics-shared.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/analytics-shared.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/analytics-tracker.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/analytics-tracker.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.adblib.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.adblib.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.analytics-crash.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.analytics-crash.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.analytics-shared.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.analytics-shared.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.adblib.ddmlibcompatibility.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.adblib.ddmlibcompatibility.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.adblib.tools.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.adblib.tools.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.analytics-testing.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.analytics-testing.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.analytics-tracker.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.analytics-tracker.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.analyzer.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.analyzer.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.android-annotations.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.android-annotations.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.binary-resources.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.binary-resources.iml" />
|
||||
@@ -329,18 +332,12 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.chunkio.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.chunkio.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.common.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.common.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.common.testfixtures.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.common.testfixtures.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.db-baseLibrary.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.db-baseLibrary.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.db-baseLibrarySupport.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.db-baseLibrarySupport.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.db-compiler.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.db-compiler.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.db-compilerCommon.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.db-compilerCommon.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.ddmlib.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.ddmlib.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.deployer.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.deployer.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.draw9patch.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.draw9patch.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.dvlib.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.dvlib.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.dynamic-layout-inspector.common.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.dynamic-layout-inspector.common.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.fakeadbserver.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.fakeadbserver.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.flags.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.flags.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.layoutinspector.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.layoutinspector.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.layoutlib-api.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.layoutlib-api.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.lint-api.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.lint-api.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.lint-checks.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.lint-checks.iml" />
|
||||
@@ -349,7 +346,6 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.manifest-parser.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.manifest-parser.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.mlkit-common.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.mlkit-common.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.ninepatch.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.ninepatch.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.perf-logger.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.perf-logger.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.perflib.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.perflib.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.pixelprobe.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.pixelprobe.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.repository.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.repository.iml" />
|
||||
@@ -357,57 +353,63 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.sdk-common.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.sdk-common.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.sdklib.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.sdklib.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.testutils.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.testutils.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.threading-agent-callback.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.threading-agent-callback.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.tracer.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.tracer.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.usb-devices.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.usb-devices.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.wizardTemplate.impl.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.wizardTemplate.impl.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.wizardTemplate.plugin.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.wizardTemplate.plugin.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.zipflinger.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/android.sdktools.zipflinger.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/api/app-inspection.api.iml" filepath="$PROJECT_DIR$/android/app-inspection/api/app-inspection.api.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/ide/app-inspection.ide.iml" filepath="$PROJECT_DIR$/android/app-inspection/ide/app-inspection.ide.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/ide/app-inspection.ide.tests.iml" filepath="$PROJECT_DIR$/android/app-inspection/ide/app-inspection.ide.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspector/api/app-inspection.inspector.api.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspector/api/app-inspection.inspector.api.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspector/ide/app-inspection.inspector.ide.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspector/ide/app-inspection.inspector.ide.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/backgroundtask/ide/app-inspection.inspectors.backgroundtask.ide.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/backgroundtask/ide/app-inspection.inspectors.backgroundtask.ide.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/backgroundtask/model/app-inspection.inspectors.backgroundtask.model.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/backgroundtask/model/app-inspection.inspectors.backgroundtask.model.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/backgroundtask/view/app-inspection.inspectors.backgroundtask.view.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/backgroundtask/view/app-inspection.inspectors.backgroundtask.view.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/backgroundtask/view/app-inspection.inspectors.backgroundtask.view.tests.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/backgroundtask/view/app-inspection.inspectors.backgroundtask.view.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/database/app-inspection.inspectors.database.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/database/app-inspection.inspectors.database.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/database/app-inspection.inspectors.database.tests.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/database/app-inspection.inspectors.database.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/network/ide/app-inspection.inspectors.network.ide.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/network/ide/app-inspection.inspectors.network.ide.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/network/ide/app-inspection.inspectors.network.ide.tests.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/network/ide/app-inspection.inspectors.network.ide.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/network/model/app-inspection.inspectors.network.model.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/network/model/app-inspection.inspectors.network.model.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/network/view/app-inspection.inspectors.network.view.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/network/view/app-inspection.inspectors.network.view.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/network/view/app-inspection.inspectors.network.view.tests.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/network/view/app-inspection.inspectors.network.view.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/workmanager/ide/app-inspection.inspectors.workmanager.ide.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/workmanager/ide/app-inspection.inspectors.workmanager.ide.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/workmanager/model/app-inspection.inspectors.workmanager.model.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/workmanager/model/app-inspection.inspectors.workmanager.model.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/workmanager/view/app-inspection.inspectors.workmanager.view.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/workmanager/view/app-inspection.inspectors.workmanager.view.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/workmanager/view/app-inspection.inspectors.workmanager.view.tests.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/workmanager/view/app-inspection.inspectors.workmanager.view.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/as-driver/agent/as-driver.agent.iml" filepath="$PROJECT_DIR$/android/as-driver/agent/as-driver.agent.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/as-driver/utils/as-driver.utils.iml" filepath="$PROJECT_DIR$/android/as-driver/utils/as-driver.utils.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/assistant/assistant.iml" filepath="$PROJECT_DIR$/android/assistant/assistant.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/assistant/assistant-test.iml" filepath="$PROJECT_DIR$/android/assistant/assistant-test.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/codenavigation/codenavigation.iml" filepath="$PROJECT_DIR$/android/codenavigation/codenavigation.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/connection-assistant/connection-assistant.iml" filepath="$PROJECT_DIR$/android/connection-assistant/connection-assistant.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/connection-assistant/connection-assistant-test.iml" filepath="$PROJECT_DIR$/android/connection-assistant/connection-assistant-test.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/db-baseLibrary.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/db-baseLibrary.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/db-baseLibrarySupport.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/db-baseLibrarySupport.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/db-compiler.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/db-compiler.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/db-compilerCommon.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/db-compilerCommon.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/dynamic-layout-inspector.common.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/dynamic-layout-inspector.common.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-adb/intellij.android.adb.iml" filepath="$PROJECT_DIR$/android/android-adb/intellij.android.adb.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-adb/intellij.android.adb.tests.iml" filepath="$PROJECT_DIR$/android/android-adb/intellij.android.adb.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-adb-ui/intellij.android.adb.ui.iml" filepath="$PROJECT_DIR$/android/android-adb-ui/intellij.android.adb.ui.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-adb-ui/intellij.android.adb.ui.tests.iml" filepath="$PROJECT_DIR$/android/android-adb-ui/intellij.android.adb.ui.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/swingp/intellij.android.adt.swingp.iml" filepath="$PROJECT_DIR$/android/swingp/intellij.android.adt.swingp.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/adt-testutils/intellij.android.adt.testutils.iml" filepath="$PROJECT_DIR$/android/adt-testutils/intellij.android.adt.testutils.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/adt-ui/intellij.android.adt.ui.iml" filepath="$PROJECT_DIR$/android/adt-ui/intellij.android.adt.ui.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/adt-ui-model/intellij.android.adt.ui.model.iml" filepath="$PROJECT_DIR$/android/adt-ui-model/intellij.android.adt.ui.model.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-layout-inspector/intellij.android.android-layout-inspector.iml" filepath="$PROJECT_DIR$/android/android-layout-inspector/intellij.android.android-layout-inspector.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-layout-inspector/intellij.android.android-layout-inspector-test.iml" filepath="$PROJECT_DIR$/android/android-layout-inspector/intellij.android.android-layout-inspector-test.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/androidx-integration-tests/intellij.android.androidx-integration-tests.iml" filepath="$PROJECT_DIR$/android/androidx-integration-tests/intellij.android.androidx-integration-tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/apkanalyzer/intellij.android.apkanalyzer.iml" filepath="$PROJECT_DIR$/android/apkanalyzer/intellij.android.apkanalyzer.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/api/intellij.android.app-inspection.api.iml" filepath="$PROJECT_DIR$/android/app-inspection/api/intellij.android.app-inspection.api.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/ide/intellij.android.app-inspection.ide.iml" filepath="$PROJECT_DIR$/android/app-inspection/ide/intellij.android.app-inspection.ide.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/ide/intellij.android.app-inspection.ide.tests.iml" filepath="$PROJECT_DIR$/android/app-inspection/ide/intellij.android.app-inspection.ide.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspector/api/intellij.android.app-inspection.inspector.api.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspector/api/intellij.android.app-inspection.inspector.api.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspector/ide/intellij.android.app-inspection.inspector.ide.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspector/ide/intellij.android.app-inspection.inspector.ide.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/backgroundtask/ide/intellij.android.app-inspection.inspectors.backgroundtask.ide.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/backgroundtask/ide/intellij.android.app-inspection.inspectors.backgroundtask.ide.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/backgroundtask/model/intellij.android.app-inspection.inspectors.backgroundtask.model.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/backgroundtask/model/intellij.android.app-inspection.inspectors.backgroundtask.model.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/backgroundtask/view/intellij.android.app-inspection.inspectors.backgroundtask.view.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/backgroundtask/view/intellij.android.app-inspection.inspectors.backgroundtask.view.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/backgroundtask/view/intellij.android.app-inspection.inspectors.backgroundtask.view.tests.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/backgroundtask/view/intellij.android.app-inspection.inspectors.backgroundtask.view.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/database/intellij.android.app-inspection.inspectors.database.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/database/intellij.android.app-inspection.inspectors.database.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/database/intellij.android.app-inspection.inspectors.database.tests.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/database/intellij.android.app-inspection.inspectors.database.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/network/ide/intellij.android.app-inspection.inspectors.network.ide.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/network/ide/intellij.android.app-inspection.inspectors.network.ide.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/network/ide/intellij.android.app-inspection.inspectors.network.ide.tests.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/network/ide/intellij.android.app-inspection.inspectors.network.ide.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/network/model/intellij.android.app-inspection.inspectors.network.model.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/network/model/intellij.android.app-inspection.inspectors.network.model.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/network/view/intellij.android.app-inspection.inspectors.network.view.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/network/view/intellij.android.app-inspection.inspectors.network.view.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/network/view/intellij.android.app-inspection.inspectors.network.view.tests.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/network/view/intellij.android.app-inspection.inspectors.network.view.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/workmanager/ide/intellij.android.app-inspection.inspectors.workmanager.ide.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/workmanager/ide/intellij.android.app-inspection.inspectors.workmanager.ide.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/workmanager/model/intellij.android.app-inspection.inspectors.workmanager.model.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/workmanager/model/intellij.android.app-inspection.inspectors.workmanager.model.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/workmanager/view/intellij.android.app-inspection.inspectors.workmanager.view.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/workmanager/view/intellij.android.app-inspection.inspectors.workmanager.view.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/app-inspection/inspectors/workmanager/view/intellij.android.app-inspection.inspectors.workmanager.view.tests.iml" filepath="$PROJECT_DIR$/android/app-inspection/inspectors/workmanager/view/intellij.android.app-inspection.inspectors.workmanager.view.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/artwork/intellij.android.artwork.iml" filepath="$PROJECT_DIR$/android/artwork/intellij.android.artwork.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/assistant/intellij.android.assistant.iml" filepath="$PROJECT_DIR$/android/assistant/intellij.android.assistant.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/assistant/intellij.android.assistant-test.iml" filepath="$PROJECT_DIR$/android/assistant/intellij.android.assistant-test.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/bleak/intellij.android.bleak.iml" filepath="$PROJECT_DIR$/android/bleak/intellij.android.bleak.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/build-attribution/intellij.android.build-attribution.iml" filepath="$PROJECT_DIR$/android/build-attribution/intellij.android.build-attribution.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/build-attribution/intellij.android.build-attribution.tests.iml" filepath="$PROJECT_DIR$/android/build-attribution/intellij.android.build-attribution.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/build-common/intellij.android.buildCommon.iml" filepath="$PROJECT_DIR$/android/build-common/intellij.android.buildCommon.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/codenavigation/intellij.android.codenavigation.iml" filepath="$PROJECT_DIR$/android/codenavigation/intellij.android.codenavigation.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-common/intellij.android.common.iml" filepath="$PROJECT_DIR$/android/android-common/intellij.android.common.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/intellij.android.compose-common/intellij.android.compose-common.iml" filepath="$PROJECT_DIR$/android/intellij.android.compose-common/intellij.android.compose-common.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/compose-designer/intellij.android.compose-designer.iml" filepath="$PROJECT_DIR$/android/compose-designer/intellij.android.compose-designer.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/compose-designer/intellij.android.compose-designer.integration.iml" filepath="$PROJECT_DIR$/android/compose-designer/intellij.android.compose-designer.integration.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/compose-designer/intellij.android.compose-designer.tests.iml" filepath="$PROJECT_DIR$/android/compose-designer/intellij.android.compose-designer.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/compose-ide-plugin/intellij.android.compose-ide-plugin.iml" filepath="$PROJECT_DIR$/android/compose-ide-plugin/intellij.android.compose-ide-plugin.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/compose-ide-plugin/intellij.android.compose-ide-plugin.tests.iml" filepath="$PROJECT_DIR$/android/compose-ide-plugin/intellij.android.compose-ide-plugin.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/connection-assistant/intellij.android.connection-assistant.iml" filepath="$PROJECT_DIR$/android/connection-assistant/intellij.android.connection-assistant.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/connection-assistant/intellij.android.connection-assistant-test.iml" filepath="$PROJECT_DIR$/android/connection-assistant/intellij.android.connection-assistant-test.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/intellij.android.core.iml" filepath="$PROJECT_DIR$/android/android/intellij.android.core.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/intellij.android.core.agp-integration-tests.iml" filepath="$PROJECT_DIR$/android/android/intellij.android.core.agp-integration-tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/intellij.android.core.tests.iml" filepath="$PROJECT_DIR$/android/android/intellij.android.core.tests.iml" />
|
||||
@@ -426,6 +428,10 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/android/designer/intellij.android.designer.tests.iml" filepath="$PROJECT_DIR$/android/designer/intellij.android.designer.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/device-explorer/intellij.android.device-explorer.iml" filepath="$PROJECT_DIR$/android/device-explorer/intellij.android.device-explorer.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/device-explorer/intellij.android.device-explorer.tests.iml" filepath="$PROJECT_DIR$/android/device-explorer/intellij.android.device-explorer.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/device-manager/intellij.android.device-manager.iml" filepath="$PROJECT_DIR$/android/device-manager/intellij.android.device-manager.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/device-manager/intellij.android.device-manager.tests.iml" filepath="$PROJECT_DIR$/android/device-manager/intellij.android.device-manager.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/device-monitor/intellij.android.device-monitor.iml" filepath="$PROJECT_DIR$/android/device-monitor/intellij.android.device-monitor.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/device-monitor/intellij.android.device-monitor.tests.iml" filepath="$PROJECT_DIR$/android/device-monitor/intellij.android.device-monitor.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/emulator/intellij.android.emulator.iml" filepath="$PROJECT_DIR$/android/emulator/intellij.android.emulator.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/emulator/intellij.android.emulator.tests.iml" filepath="$PROJECT_DIR$/android/emulator/intellij.android.emulator.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/gradle-tooling/studio-gradle-tooling-api/intellij.android.gradle-tooling.api.iml" filepath="$PROJECT_DIR$/android/gradle-tooling/studio-gradle-tooling-api/intellij.android.gradle-tooling.api.iml" />
|
||||
@@ -434,12 +440,12 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/android/gradle-dsl-kotlin/intellij.android.gradle.dsl.kotlin.iml" filepath="$PROJECT_DIR$/android/gradle-dsl-kotlin/intellij.android.gradle.dsl.kotlin.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/gradle-dsl/intellij.android.gradle.dsl.tests.iml" filepath="$PROJECT_DIR$/android/gradle-dsl/intellij.android.gradle.dsl.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/gradle-dsl/intellij.android.gradle.dsl.testutils.iml" filepath="$PROJECT_DIR$/android/gradle-dsl/intellij.android.gradle.dsl.testutils.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/gradle-dsl-toml/intellij.android.gradle.dsl.toml.iml" filepath="$PROJECT_DIR$/android/gradle-dsl-toml/intellij.android.gradle.dsl.toml.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/ide-perf-tests/intellij.android.ide-perf-tests.iml" filepath="$PROJECT_DIR$/android/ide-perf-tests/intellij.android.ide-perf-tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/idea-integration-tests/intellij.android.ideaIntegrationTests.iml" filepath="$PROJECT_DIR$/android/idea-integration-tests/intellij.android.ideaIntegrationTests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/inspectors-common/api/intellij.android.inspectors-common.api.iml" filepath="$PROJECT_DIR$/android/inspectors-common/api/intellij.android.inspectors-common.api.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/inspectors-common/api-ide/intellij.android.inspectors-common.api-ide.iml" filepath="$PROJECT_DIR$/android/inspectors-common/api-ide/intellij.android.inspectors-common.api-ide.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/inspectors-common/ui/intellij.android.inspectors-common.ui.iml" filepath="$PROJECT_DIR$/android/inspectors-common/ui/intellij.android.inspectors-common.ui.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/kotlin-integration/intellij.android.kotlin-integration-tests.iml" filepath="$PROJECT_DIR$/android/kotlin-integration/intellij.android.kotlin-integration-tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/jps-model/intellij.android.jps.model.iml" filepath="$PROJECT_DIR$/android/jps-model/intellij.android.jps.model.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-kotlin/android-extensions-idea/intellij.android.kotlin.extensions.iml" filepath="$PROJECT_DIR$/android/android-kotlin/android-extensions-idea/intellij.android.kotlin.extensions.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-kotlin/android-extensions-idea-common/intellij.android.kotlin.extensions.common.iml" filepath="$PROJECT_DIR$/android/android-kotlin/android-extensions-idea-common/intellij.android.kotlin.extensions.common.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-kotlin/idea-android/intellij.android.kotlin.idea.iml" filepath="$PROJECT_DIR$/android/android-kotlin/idea-android/intellij.android.kotlin.idea.iml" />
|
||||
@@ -456,13 +462,11 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/android/layoutlib-loader/intellij.android.layoutlib-loader.iml" filepath="$PROJECT_DIR$/android/layoutlib-loader/intellij.android.layoutlib-loader.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/layoutlib/intellij.android.layoutlib.tests.iml" filepath="$PROJECT_DIR$/android/layoutlib/intellij.android.layoutlib.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-lint/intellij.android.lint.iml" filepath="$PROJECT_DIR$/android/android-lint/intellij.android.lint.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/lint/intellij.android.lint.common.iml" filepath="$PROJECT_DIR$/android/lint/intellij.android.lint.common.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/lint/tests/intellij.android.lint.common.tests.iml" filepath="$PROJECT_DIR$/android/lint/tests/intellij.android.lint.common.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-lint/intellij.android.lint.tests.iml" filepath="$PROJECT_DIR$/android/android-lint/intellij.android.lint.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/logcat/intellij.android.logcat.iml" filepath="$PROJECT_DIR$/android/logcat/intellij.android.logcat.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/logcat/intellij.android.logcat.tests.iml" filepath="$PROJECT_DIR$/android/logcat/intellij.android.logcat.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/mlkit/intellij.android.mlkit.iml" filepath="$PROJECT_DIR$/android/mlkit/intellij.android.mlkit.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/mlkit/intellij.android.mlkit.tests.iml" filepath="$PROJECT_DIR$/android/mlkit/intellij.android.mlkit.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/native-symbolizer/intellij.android.native-symbolizer.iml" filepath="$PROJECT_DIR$/android/native-symbolizer/intellij.android.native-symbolizer.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/nav/editor/intellij.android.nav.editor.iml" filepath="$PROJECT_DIR$/android/nav/editor/intellij.android.nav.editor.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/nav/editor/intellij.android.nav.editor.tests.iml" filepath="$PROJECT_DIR$/android/nav/editor/intellij.android.nav.editor.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/nav/safeargs/intellij.android.nav.safeargs.iml" filepath="$PROJECT_DIR$/android/nav/safeargs/intellij.android.nav.safeargs.iml" />
|
||||
@@ -472,7 +476,6 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-npw/intellij.android.newProjectWizard.iml" filepath="$PROJECT_DIR$/android/android-npw/intellij.android.newProjectWizard.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-npw/intellij.android.newProjectWizard.tests.iml" filepath="$PROJECT_DIR$/android/android-npw/intellij.android.newProjectWizard.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/observable/intellij.android.observable.iml" filepath="$PROJECT_DIR$/android/observable/intellij.android.observable.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/observable-demo/intellij.android.observable-demo.iml" filepath="$PROJECT_DIR$/android/observable-demo/intellij.android.observable-demo.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/observable-ui/intellij.android.observable.ui.iml" filepath="$PROJECT_DIR$/android/observable-ui/intellij.android.observable.ui.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/old-agp-tests/intellij.android.old-agp-tests.iml" filepath="$PROJECT_DIR$/android/old-agp-tests/intellij.android.old-agp-tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-plugin/intellij.android.plugin.iml" filepath="$PROJECT_DIR$/android/android-plugin/intellij.android.plugin.iml" />
|
||||
@@ -499,6 +502,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/android/sdk-updates/intellij.android.sdkUpdates.tests.iml" filepath="$PROJECT_DIR$/android/sdk-updates/intellij.android.sdkUpdates.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/server-flags/intellij.android.server-flags.iml" filepath="$PROJECT_DIR$/android/server-flags/intellij.android.server-flags.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/smali/intellij.android.smali.iml" filepath="$PROJECT_DIR$/android/smali/intellij.android.smali.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/studio/integration/intellij.android.studio.integration/intellij.android.studio.integration.iml" filepath="$PROJECT_DIR$/android/studio/integration/intellij.android.studio.integration/intellij.android.studio.integration.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/studio/tests/intellij.android.studio.tests.iml" filepath="$PROJECT_DIR$/android/studio/tests/intellij.android.studio.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/sync-perf-tests/intellij.android.sync-perf-tests.iml" filepath="$PROJECT_DIR$/android/sync-perf-tests/intellij.android.sync-perf-tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-templates/intellij.android.templates.iml" filepath="$PROJECT_DIR$/android/android-templates/intellij.android.templates.iml" />
|
||||
@@ -506,13 +510,17 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-test-framework/intellij.android.testFramework.iml" filepath="$PROJECT_DIR$/android/android-test-framework/intellij.android.testFramework.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-test-retention/intellij.android.testRetention.iml" filepath="$PROJECT_DIR$/android/android-test-retention/intellij.android.testRetention.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-test-retention/intellij.android.testRetention.tests.iml" filepath="$PROJECT_DIR$/android/android-test-retention/intellij.android.testRetention.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/threading-checker/intellij.android.threading-checker.iml" filepath="$PROJECT_DIR$/android/threading-checker/intellij.android.threading-checker.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/threading-checker/intellij.android.threading-checker.tests.iml" filepath="$PROJECT_DIR$/android/threading-checker/intellij.android.threading-checker.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android-transport/intellij.android.transport.iml" filepath="$PROJECT_DIR$/android/android-transport/intellij.android.transport.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/transport-database/intellij.android.transportDatabase.iml" filepath="$PROJECT_DIR$/android/transport-database/intellij.android.transportDatabase.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/utp/intellij.android.utp.iml" filepath="$PROJECT_DIR$/android/utp/intellij.android.utp.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/whats-new-assistant/intellij.android.whats-new-assistant.iml" filepath="$PROJECT_DIR$/android/whats-new-assistant/intellij.android.whats-new-assistant.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/whats-new-assistant/intellij.android.whats-new-assistant-test.iml" filepath="$PROJECT_DIR$/android/whats-new-assistant/intellij.android.whats-new-assistant-test.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/wear-pairing/intellij.android.wear-pairing.iml" filepath="$PROJECT_DIR$/android/wear-pairing/intellij.android.wear-pairing.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/wear-pairing/intellij.android.wear-pairing.tests.iml" filepath="$PROJECT_DIR$/android/wear-pairing/intellij.android.wear-pairing.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/wizard/intellij.android.wizard.iml" filepath="$PROJECT_DIR$/android/wizard/intellij.android.wizard.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/wizard-model/intellij.android.wizard.model.iml" filepath="$PROJECT_DIR$/android/wizard-model/intellij.android.wizard.model.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/wizard/intellij.android.wizard.tests.iml" filepath="$PROJECT_DIR$/android/wizard/intellij.android.wizard.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/intellij.android.wizardTemplate.impl.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/intellij.android.wizardTemplate.impl.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/intellij.android.wizardTemplate.plugin.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/intellij.android.wizardTemplate.plugin.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/ant/intellij.ant.iml" filepath="$PROJECT_DIR$/plugins/ant/intellij.ant.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/ant/jps-plugin/intellij.ant.jps.iml" filepath="$PROJECT_DIR$/plugins/ant/jps-plugin/intellij.ant.jps.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/color-schemes/all-hallows-eve-color-scheme/intellij.color.scheme.all_hallows_eve.iml" filepath="$PROJECT_DIR$/plugins/color-schemes/all-hallows-eve-color-scheme/intellij.color.scheme.all_hallows_eve.iml" />
|
||||
@@ -708,6 +716,8 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/kotlin/intellij.kotlin.plugin.community.main.iml" filepath="$PROJECT_DIR$/plugins/kotlin/intellij.kotlin.plugin.community.main.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/laf/macos/intellij.laf.macos.iml" filepath="$PROJECT_DIR$/plugins/laf/macos/intellij.laf.macos.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/laf/win10/intellij.laf.win10.iml" filepath="$PROJECT_DIR$/plugins/laf/win10/intellij.laf.win10.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/lint/intellij.lint.iml" filepath="$PROJECT_DIR$/android/lint/intellij.lint.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/lint/tests/intellij.lint.tests.iml" filepath="$PROJECT_DIR$/android/lint/tests/intellij.lint.tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/lombok/intellij.lombok.iml" filepath="$PROJECT_DIR$/plugins/lombok/intellij.lombok.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/lombok/generated/intellij.lombok.generated.iml" filepath="$PROJECT_DIR$/plugins/lombok/generated/intellij.lombok.generated.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/markdown/intellij.markdown.iml" filepath="$PROJECT_DIR$/plugins/markdown/intellij.markdown.iml" />
|
||||
@@ -1022,6 +1032,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/xslt-debugger/engine/impl/intellij.xslt.debugger.impl.rt.iml" filepath="$PROJECT_DIR$/plugins/xslt-debugger/engine/impl/intellij.xslt.debugger.impl.rt.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/xslt-debugger/engine/intellij.xslt.debugger.rt.iml" filepath="$PROJECT_DIR$/plugins/xslt-debugger/engine/intellij.xslt.debugger.rt.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/yaml/intellij.yaml.iml" filepath="$PROJECT_DIR$/plugins/yaml/intellij.yaml.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/kotlin-integration/kotlin-integration-tests.iml" filepath="$PROJECT_DIR$/android/kotlin-integration/kotlin-integration-tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/kotlin/all-tests/kotlin.all-tests.iml" filepath="$PROJECT_DIR$/plugins/kotlin/all-tests/kotlin.all-tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/kotlin/base/analysis/kotlin.base.analysis.iml" filepath="$PROJECT_DIR$/plugins/kotlin/base/analysis/kotlin.base.analysis.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/kotlin/base/analysis-api-providers/kotlin.base.analysis-api-providers.iml" filepath="$PROJECT_DIR$/plugins/kotlin/base/analysis-api-providers/kotlin.base.analysis-api-providers.iml" />
|
||||
@@ -1204,6 +1215,12 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/kotlin/util/test-generator/kotlin.util.test-generator.iml" filepath="$PROJECT_DIR$/plugins/kotlin/util/test-generator/kotlin.util.test-generator.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/kotlin/util/test-generator-fe10/kotlin.util.test-generator-fe10.iml" filepath="$PROJECT_DIR$/plugins/kotlin/util/test-generator-fe10/kotlin.util.test-generator-fe10.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/kotlin/util/test-generator-fir/kotlin.util.test-generator-fir.iml" filepath="$PROJECT_DIR$/plugins/kotlin/util/test-generator-fir/kotlin.util.test-generator-fir.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/native-symbolizer/native-symbolizer.iml" filepath="$PROJECT_DIR$/android/native-symbolizer/native-symbolizer.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/perf-logger.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/perf-logger.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/android/prebuilts/sdktools/usb-devices.iml" filepath="$PROJECT_DIR$/android/android/prebuilts/sdktools/usb-devices.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/utp/utp.iml" filepath="$PROJECT_DIR$/android/utp/utp.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/whats-new-assistant/whats-new-assistant.iml" filepath="$PROJECT_DIR$/android/whats-new-assistant/whats-new-assistant.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/whats-new-assistant/whats-new-assistant-test.iml" filepath="$PROJECT_DIR$/android/whats-new-assistant/whats-new-assistant-test.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
@@ -1,6 +1,5 @@
|
||||
### Starter for IntelliJ IDEA based IDE's
|
||||
|
||||
|
||||
#### Overview
|
||||
|
||||
Starter helps you write tests/code, that will start IntelliJ-based IDE from installer in external process.
|
||||
@@ -14,7 +13,6 @@ Aside from that, you may find useful functionality as below:
|
||||
* reporting of artifacts to CI (optional)
|
||||
* run a test with a profiler (not yet included)
|
||||
|
||||
|
||||
#### Supported products
|
||||
|
||||
* IDEA
|
||||
@@ -26,7 +24,6 @@ Aside from that, you may find useful functionality as below:
|
||||
* RubyMine
|
||||
* Android Studio
|
||||
|
||||
|
||||
##### How to setup
|
||||
|
||||
Configure maven repositories in your `build.gradle` file
|
||||
@@ -48,6 +45,7 @@ OR
|
||||
`maven { url = "https://www.jetbrains.com/intellij-repository/nightly" }`
|
||||
|
||||
But don't forget to change accordingly version of the packages as such:
|
||||
|
||||
* nightly -> LATEST-TRUNK-SNAPSHOT
|
||||
* snapshots -> LATEST-EAP-SNAPSHOT
|
||||
* releases -> semver package version
|
||||
@@ -80,8 +78,6 @@ compileTestKotlin {
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### Run with JUnit4
|
||||
|
||||
[Example of simple test, that will download IntelliJ IDEA and start import of gradle project](https://github.com/JetBrains/intellij-ide-starter/tree/master/testSrc/com/intellij/ide/starter/tests/examples/junit4)
|
||||
@@ -92,10 +88,10 @@ You should create appropriate classes in your tests for JUnit4StarterRule, IdeaC
|
||||
|
||||
[Example of simple test, that will download IntelliJ IDEA and start import of gradle project](https://github.com/JetBrains/intellij-ide-starter/tree/master/testSrc/com/intellij/ide/starter/tests/examples/junit5)
|
||||
|
||||
|
||||
##### Available commands from plugins
|
||||
|
||||
Dependency `performance-testing-commands`
|
||||
|
||||
- waitForSmartMode()
|
||||
- flushIndexes()
|
||||
- setupProjectSdk(sdkName: String, sdkType: String, sdkPath: String)
|
||||
@@ -132,9 +128,11 @@ Dependency `performance-testing-commands`
|
||||
- ... **TBD**
|
||||
|
||||
Dependency `performance-testing-maven-commands`
|
||||
|
||||
- importMavenProject()
|
||||
|
||||
Dependency `performance-testing-gradle-commands`
|
||||
|
||||
- importGradleProject()
|
||||
|
||||
#### What behaviour might be extended / modified
|
||||
@@ -146,6 +144,7 @@ For example, you might write your own implementation of CIServer and provide it
|
||||
NOTE: Be sure to use the same version of Kodein, that is used in `build.gradle` for starter project.
|
||||
|
||||
E.g:
|
||||
|
||||
```
|
||||
di = DI {
|
||||
extend(di)
|
||||
|
||||
@@ -2,14 +2,16 @@
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="3" platform="JVM 11" allPlatforms="JVM [11]" useProjectSettings="false">
|
||||
<configuration version="5" platform="JVM 11" allPlatforms="JVM [11]" useProjectSettings="false">
|
||||
<compilerSettings>
|
||||
<option name="additionalArguments" value="-version -Xjvm-default=enable -Xopt-in=kotlin.time.ExperimentalTime" />
|
||||
<option name="additionalArguments" value="-version -Xjvm-default=enable -opt-in=kotlin.time.ExperimentalTime" />
|
||||
</compilerSettings>
|
||||
<compilerArguments>
|
||||
<option name="jvmTarget" value="11" />
|
||||
<option name="languageVersion" value="1.7" />
|
||||
<option name="apiVersion" value="1.7" />
|
||||
<stringArguments>
|
||||
<stringArg name="jvmTarget" arg="11" />
|
||||
<stringArg name="apiVersion" arg="1.7" />
|
||||
<stringArg name="languageVersion" arg="1.7" />
|
||||
</stringArguments>
|
||||
</compilerArguments>
|
||||
</configuration>
|
||||
</facet>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# JVM TI agent that logs loading and preparation stages of class lifecycle
|
||||
# Set JAVA_HOME to JBR 17 location
|
||||
|
||||
# Usage VM Options: -agentpath:/var/tmp/libvmtrace.so=output.log
|
||||
# Original source: https://github.com/odnoklassniki/jvmti-tools#vmtrace
|
||||
|
||||
build-linux:
|
||||
g++ -O2 -fPIC -shared -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/linux -olibvmtrace.so vmtrace.cpp
|
||||
|
||||
build-macos:
|
||||
g++ -O2 -fPIC -shared -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/darwin -olibvmtrace.dylib vmtrace.cpp
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2019 Odnoklassniki Ltd, Mail.Ru Group
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// Original source: https://github.com/odnoklassniki/jvmti-tools#vmtrace
|
||||
|
||||
#include <jvmti.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static FILE* out;
|
||||
static jrawMonitorID vmtrace_lock;
|
||||
static jlong start_time;
|
||||
|
||||
static void trace(jvmtiEnv* jvmti, const char* fmt, ...) {
|
||||
jlong current_time;
|
||||
jvmti->GetTime(¤t_time);
|
||||
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
jvmti->RawMonitorEnter(vmtrace_lock);
|
||||
|
||||
fprintf(out, "[%.5f] %s\n", (current_time - start_time) / 1000000000.0, buf);
|
||||
|
||||
jvmti->RawMonitorExit(vmtrace_lock);
|
||||
}
|
||||
|
||||
static char* fix_class_name(char* class_name) {
|
||||
// Strip 'L' and ';' from class signature
|
||||
class_name[strlen(class_name) - 1] = 0;
|
||||
return class_name + 1;
|
||||
}
|
||||
|
||||
class ClassName {
|
||||
private:
|
||||
jvmtiEnv* _jvmti;
|
||||
char* _name;
|
||||
|
||||
public:
|
||||
ClassName(jvmtiEnv* jvmti, jclass klass) : _jvmti(jvmti), _name(NULL) {
|
||||
_jvmti->GetClassSignature(klass, &_name, NULL);
|
||||
}
|
||||
|
||||
~ClassName() {
|
||||
_jvmti->Deallocate((unsigned char*) _name);
|
||||
}
|
||||
|
||||
char* name() {
|
||||
return _name == NULL ? NULL : fix_class_name(_name);
|
||||
}
|
||||
};
|
||||
|
||||
void JNICALL ClassFileLoadHook(jvmtiEnv* jvmti, JNIEnv* env,
|
||||
jclass class_being_redefined, jobject loader,
|
||||
const char* name, jobject protection_domain,
|
||||
jint data_len, const unsigned char* data,
|
||||
jint* new_data_len, unsigned char** new_data) {
|
||||
trace(jvmti, "Loading class: %s (%d bytes)", name, data_len);
|
||||
}
|
||||
|
||||
void JNICALL ClassPrepare(jvmtiEnv* jvmti, JNIEnv* env,
|
||||
jthread thread, jclass klass) {
|
||||
ClassName cn(jvmti, klass);
|
||||
trace(jvmti, "Class prepared: %s", cn.name());
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* vm, char* options, void* reserved) {
|
||||
if (options == NULL || !options[0]) {
|
||||
out = stderr;
|
||||
} else if ((out = fopen(options, "w")) == NULL) {
|
||||
fprintf(stderr, "Cannot open output file: %s\n", options);
|
||||
return 1;
|
||||
}
|
||||
|
||||
jvmtiEnv* jvmti;
|
||||
vm->GetEnv((void**) &jvmti, JVMTI_VERSION_1_0);
|
||||
|
||||
jvmti->CreateRawMonitor("vmtrace_lock", &vmtrace_lock);
|
||||
jvmti->GetTime(&start_time);
|
||||
|
||||
trace(jvmti, "VMTrace started");
|
||||
|
||||
jvmtiCapabilities capabilities = {0};
|
||||
capabilities.can_generate_all_class_hook_events = 1;
|
||||
jvmti->AddCapabilities(&capabilities);
|
||||
|
||||
jvmtiEventCallbacks callbacks = {0};
|
||||
callbacks.ClassFileLoadHook = ClassFileLoadHook;
|
||||
callbacks.ClassPrepare = ClassPrepare;
|
||||
jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));
|
||||
|
||||
jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
|
||||
jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Agent_OnUnload(JavaVM* vm) {
|
||||
if (out != NULL && out != stderr) {
|
||||
fclose(out);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<application>
|
||||
<component name="GeneralSettings">
|
||||
<option name="useSafeWrite" value="false" />
|
||||
<option name="useSafeWrite" value="false"/>
|
||||
<option name="confirmExit" value="false"/>
|
||||
<option name="showTipsOnStartup" value="false"/>
|
||||
</component>
|
||||
|
||||
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
+28
-26
@@ -1,10 +1,10 @@
|
||||
package com.intellij.ide.starter
|
||||
|
||||
import com.intellij.ide.starter.di.di
|
||||
import com.intellij.ide.starter.exec.ExecOutputRedirect
|
||||
import com.intellij.ide.starter.exec.exec
|
||||
import com.intellij.ide.starter.ide.IDETestContext
|
||||
import com.intellij.ide.starter.path.GlobalPaths
|
||||
import com.intellij.ide.starter.process.exec.ExecOutputRedirect
|
||||
import com.intellij.ide.starter.process.exec.ProcessExecutor
|
||||
import com.intellij.ide.starter.system.SystemInfo
|
||||
import com.intellij.ide.starter.utils.FileSystem
|
||||
import com.intellij.ide.starter.utils.HttpClient
|
||||
@@ -71,32 +71,32 @@ fun downloadLatestAndroidSdk(javaHome: Path): Path {
|
||||
home.toFile().mkdirs()
|
||||
/// https://stackoverflow.com/questions/38096225/automatically-accept-all-sdk-licences
|
||||
/// sending "yes" to the process in the STDIN :(
|
||||
exec(presentablePurpose = "android-sdk-licenses",
|
||||
workDir = home,
|
||||
environmentVariables = envVariablesWithJavaHome,
|
||||
args = listOf(sdkManager.toString(), "--sdk_root=$home", "--licenses"),
|
||||
stderrRedirect = ExecOutputRedirect.ToStdOut("[sdkmanager-err]"),
|
||||
stdInBytes = "yes\n".repeat(10).toByteArray(), // it asks the confirmation at least two times
|
||||
timeout = 15.minutes
|
||||
)
|
||||
ProcessExecutor(presentableName = "android-sdk-licenses",
|
||||
workDir = home,
|
||||
environmentVariables = envVariablesWithJavaHome,
|
||||
args = listOf(sdkManager.toString(), "--sdk_root=$home", "--licenses"),
|
||||
stderrRedirect = ExecOutputRedirect.ToStdOut("[sdkmanager-err]"),
|
||||
stdInBytes = "yes\n".repeat(10).toByteArray(), // it asks the confirmation at least two times
|
||||
timeout = 15.minutes
|
||||
).start()
|
||||
|
||||
//loading SDK
|
||||
exec(presentablePurpose = "android-sdk-loading",
|
||||
workDir = home,
|
||||
environmentVariables = envVariablesWithJavaHome,
|
||||
args = listOf(sdkManager.toString(), "--sdk_root=$home", "--list"),
|
||||
stderrRedirect = ExecOutputRedirect.ToStdOut("[sdkmanager-err]"),
|
||||
timeout = 15.minutes
|
||||
)
|
||||
ProcessExecutor(presentableName = "android-sdk-loading",
|
||||
workDir = home,
|
||||
environmentVariables = envVariablesWithJavaHome,
|
||||
args = listOf(sdkManager.toString(), "--sdk_root=$home", "--list"),
|
||||
stderrRedirect = ExecOutputRedirect.ToStdOut("[sdkmanager-err]"),
|
||||
timeout = 15.minutes
|
||||
).start()
|
||||
|
||||
//loading SDK
|
||||
exec(presentablePurpose = "android-sdk-installing",
|
||||
workDir = home,
|
||||
environmentVariables = envVariablesWithJavaHome,
|
||||
args = listOf(sdkManager.toString(), "--sdk_root=$home", "--install", "--verbose") + packages,
|
||||
stderrRedirect = ExecOutputRedirect.ToStdOut("[sdkmanager-err]"),
|
||||
timeout = 15.minutes
|
||||
)
|
||||
ProcessExecutor(presentableName = "android-sdk-installing",
|
||||
workDir = home,
|
||||
environmentVariables = envVariablesWithJavaHome,
|
||||
args = listOf(sdkManager.toString(), "--sdk_root=$home", "--install", "--verbose") + packages,
|
||||
stderrRedirect = ExecOutputRedirect.ToStdOut("[sdkmanager-err]"),
|
||||
timeout = 15.minutes
|
||||
).start()
|
||||
return home
|
||||
}
|
||||
catch (t: Throwable) {
|
||||
@@ -148,13 +148,15 @@ fun IDETestContext.downloadAndroidPluginProject(): IDETestContext {
|
||||
|
||||
val stdout = ExecOutputRedirect.ToString()
|
||||
val stderr = ExecOutputRedirect.ToString()
|
||||
exec(
|
||||
|
||||
ProcessExecutor(
|
||||
"git-clone-android-plugin",
|
||||
workDir = projectHome, timeout = 10.minutes,
|
||||
args = scriptContent.split(" "),
|
||||
stdoutRedirect = stdout,
|
||||
stderrRedirect = stderr
|
||||
)
|
||||
).start()
|
||||
|
||||
logOutput(stdout.read().trim())
|
||||
}
|
||||
return this
|
||||
|
||||
-1
@@ -2,7 +2,6 @@ package com.intellij.ide.starter.bus
|
||||
|
||||
import com.intellij.ide.starter.utils.catchAll
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.drop
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
|
||||
|
||||
+4
-3
@@ -23,8 +23,9 @@ inline fun <reified T : Any> FlowBus.getFlow() = getFlow(T::class.java)
|
||||
* @param callback The callback function
|
||||
* @return This instance of [EventsReceiver] for chaining
|
||||
*/
|
||||
inline fun <reified T : Any> EventsReceiver.subscribe(skipRetained: Boolean = false, noinline callback: suspend (event: T) -> Unit): EventsReceiver {
|
||||
return subscribeTo(T::class.java, skipRetained, callback)
|
||||
inline fun <reified T : Any> EventsReceiver.subscribe(skipRetained: Boolean = false,
|
||||
noinline callback: suspend (event: T) -> Unit): EventsReceiver {
|
||||
return subscribeTo(T::class.java, skipRetained, callback)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,5 +37,5 @@ inline fun <reified T : Any> EventsReceiver.subscribe(skipRetained: Boolean = fa
|
||||
* @see [subscribe]
|
||||
*/
|
||||
inline fun <reified T : Any> EventsReceiver.subscribe(callback: EventCallback<T>, skipRetained: Boolean = false): EventsReceiver {
|
||||
return subscribeTo(T::class.java, callback, skipRetained)
|
||||
return subscribeTo(T::class.java, callback, skipRetained)
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
Copyright 2021 Robert Kosakowski
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+6
-6
@@ -3,22 +3,22 @@ package com.intellij.ide.starter.community
|
||||
import org.apache.http.client.utils.URIBuilder
|
||||
|
||||
data class ProductInfoRequestParameters(
|
||||
val code: String,
|
||||
val type: String = "release",
|
||||
val type: String,
|
||||
val snapshot: String = "release",
|
||||
// e.g "2022.2"
|
||||
val majorVersion: String = "",
|
||||
// e.g "221.5591.52",
|
||||
val build: String = "",
|
||||
val buildNumber: String = "",
|
||||
// e.g "2022.1.1"
|
||||
val version: String = ""
|
||||
val versionNumber: String = ""
|
||||
) {
|
||||
fun toUriQuery(): URIBuilder {
|
||||
val builder = URIBuilder()
|
||||
|
||||
// API seems to filter only by code and type. It doesn't respond to majorVersion, build or version params
|
||||
|
||||
if (code.isNotBlank()) builder.addParameter("code", code)
|
||||
if (type.isNotBlank()) builder.addParameter("type", type)
|
||||
if (type.isNotBlank()) builder.addParameter("code", type)
|
||||
if (snapshot.isNotBlank()) builder.addParameter("type", snapshot)
|
||||
|
||||
return builder
|
||||
}
|
||||
|
||||
+7
-7
@@ -21,19 +21,19 @@ object PublicIdeDownloader : IdeDownloader {
|
||||
if (filteringParams.majorVersion.isNotBlank()) return sorted.first { it.majorVersion == filteringParams.majorVersion }
|
||||
|
||||
// find latest release / eap, if no specific params were provided
|
||||
if (filteringParams.version.isBlank() && filteringParams.build.isBlank()) return sorted.first()
|
||||
if (filteringParams.versionNumber.isBlank() && filteringParams.buildNumber.isBlank()) return sorted.first()
|
||||
|
||||
if (filteringParams.version.isNotBlank()) return sorted.first { it.version == filteringParams.version }
|
||||
if (filteringParams.build.isNotBlank()) return sorted.first { it.build == filteringParams.build }
|
||||
if (filteringParams.versionNumber.isNotBlank()) return sorted.first { it.version == filteringParams.versionNumber }
|
||||
if (filteringParams.buildNumber.isNotBlank()) return sorted.first { it.build == filteringParams.buildNumber }
|
||||
|
||||
throw NoSuchElementException("Couldn't find specified release by parameters $filteringParams")
|
||||
}
|
||||
|
||||
override fun downloadIdeInstaller(ideInfo: IdeInfo, installerDirectory: Path): IdeInstaller {
|
||||
val params = ProductInfoRequestParameters(code = ideInfo.productCode,
|
||||
type = ideInfo.buildType,
|
||||
build = ideInfo.buildNumber,
|
||||
version = ideInfo.version)
|
||||
val params = ProductInfoRequestParameters(type = ideInfo.productCode,
|
||||
snapshot = ideInfo.buildType,
|
||||
buildNumber = ideInfo.buildNumber,
|
||||
versionNumber = ideInfo.version)
|
||||
|
||||
val releaseInfoMap = JetBrainsDataServiceClient.getReleases(params)
|
||||
if (releaseInfoMap.size != 1) throw RuntimeException("Only one product can be downloaded at once. Found ${releaseInfoMap.keys}")
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.intellij.ide.starter.coroutine
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
|
||||
val supervisorScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
|
||||
val simpleScope = CoroutineScope(Job() + Dispatchers.IO)
|
||||
+3
-1
@@ -16,6 +16,7 @@ import com.intellij.ide.starter.report.publisher.ReportPublisher
|
||||
import com.intellij.ide.starter.report.publisher.impl.ConsoleTestResultPublisher
|
||||
import com.intellij.ide.starter.report.publisher.impl.QodanaTestResultPublisher
|
||||
import com.intellij.ide.starter.runner.CodeBuilderHost
|
||||
import com.intellij.ide.starter.runner.CurrentTestMethod
|
||||
import com.intellij.ide.starter.utils.logOutput
|
||||
import org.kodein.di.DI
|
||||
import org.kodein.di.bindFactory
|
||||
@@ -40,7 +41,7 @@ var di = DI {
|
||||
bindFactory { testContext: IDETestContext -> PluginConfigurator(testContext) }
|
||||
bindSingleton<IdeDownloader> { PublicIdeDownloader }
|
||||
bindFactory<IdeInfo, IdeInstallator> { ideInfo ->
|
||||
if (ideInfo.productCode == "AI") {
|
||||
if (ideInfo.productCode == IdeProductProvider.AI.productCode) {
|
||||
AndroidInstaller()
|
||||
}
|
||||
else {
|
||||
@@ -50,6 +51,7 @@ var di = DI {
|
||||
bindFactory<IDETestContext, BuildToolProvider> { testContext: IDETestContext -> BuildToolDefaultProvider(testContext) }
|
||||
bindSingleton<List<ReportPublisher>> { listOf(ConsoleTestResultPublisher, QodanaTestResultPublisher) }
|
||||
bindSingleton<IdeProduct> { IdeProductImp }
|
||||
bindSingleton<CurrentTestMethod> { CurrentTestMethod }
|
||||
}.apply {
|
||||
logOutput("DI was initialized")
|
||||
}
|
||||
|
||||
-269
@@ -1,269 +0,0 @@
|
||||
package com.intellij.ide.starter.exec
|
||||
|
||||
import com.intellij.ide.starter.system.SystemInfo
|
||||
import com.intellij.ide.starter.utils.catchAll
|
||||
import com.intellij.ide.starter.utils.logError
|
||||
import com.intellij.ide.starter.utils.logOutput
|
||||
import java.io.IOException
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.concurrent.thread
|
||||
import kotlin.io.path.div
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.readText
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
private fun redirectProcessOutput(
|
||||
process: Process,
|
||||
outOrErrStream: Boolean,
|
||||
redirectOutput: ExecOutputRedirect
|
||||
): Thread {
|
||||
val inputStream = if (outOrErrStream) process.inputStream else process.errorStream
|
||||
return thread(start = true, isDaemon = true, name = "Redirect " + (if (outOrErrStream) "stdout" else "stderr")) {
|
||||
val reader = inputStream.bufferedReader()
|
||||
redirectOutput.open()
|
||||
try {
|
||||
while (true) {
|
||||
val line = try {
|
||||
reader.readLine() ?: break
|
||||
}
|
||||
catch (e: IOException) {
|
||||
break
|
||||
}
|
||||
redirectOutput.redirectLine(line)
|
||||
}
|
||||
}
|
||||
finally {
|
||||
redirectOutput.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun redirectProcessInput(process: Process, inputBytes: ByteArray): Thread? {
|
||||
if (inputBytes.isEmpty()) {
|
||||
catchAll { process.outputStream.close() }
|
||||
return null
|
||||
}
|
||||
|
||||
return thread(start = true, isDaemon = true, name = "Redirect input") {
|
||||
catchAll {
|
||||
process.outputStream.use {
|
||||
it.write(inputBytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun ProcessBuilder.actualizeEnvVariables(environmentVariables: Map<String, String> = System.getenv(),
|
||||
onlyEnrichExistedEnvVariables: Boolean = false): ProcessBuilder {
|
||||
val processEnvironment = environment()
|
||||
if (processEnvironment == environmentVariables) return this
|
||||
|
||||
environmentVariables.filter { it.value == null }.forEach { logError("Env variable: ${it.key} has null value ${it.value}") }
|
||||
val notNullValues = environmentVariables.filter { it.value != null }
|
||||
|
||||
// env variables enrichment
|
||||
processEnvironment.putAll(notNullValues)
|
||||
|
||||
if (!onlyEnrichExistedEnvVariables) {
|
||||
val missingKeys = processEnvironment.keys - notNullValues.keys
|
||||
missingKeys.forEach { key -> processEnvironment.remove(key) }
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new process and wait for it's completion
|
||||
*/
|
||||
@Throws(ExecTimeoutException::class)
|
||||
fun exec(
|
||||
presentablePurpose: String,
|
||||
workDir: Path?,
|
||||
timeout: Duration = 10.minutes,
|
||||
environmentVariables: Map<String, String> = System.getenv(),
|
||||
args: List<String>,
|
||||
errorDiagnosticFiles: List<Path> = emptyList(),
|
||||
stdoutRedirect: ExecOutputRedirect = ExecOutputRedirect.NoRedirect,
|
||||
stderrRedirect: ExecOutputRedirect = ExecOutputRedirect.NoRedirect,
|
||||
onProcessCreated: (Process, Long) -> Unit = { _, _ -> },
|
||||
onBeforeKilled: (Process, Long) -> Unit = { _, _ -> },
|
||||
stdInBytes: ByteArray = byteArrayOf(),
|
||||
onlyEnrichExistedEnvVariables: Boolean = false
|
||||
) {
|
||||
logOutput(buildString {
|
||||
appendLine("Running external process for `$presentablePurpose`")
|
||||
appendLine(" Working directory: $workDir")
|
||||
appendLine(" Arguments: [${args.joinToString()}]")
|
||||
appendLine(" STDOUT will be redirected to: $stdoutRedirect")
|
||||
appendLine(" STDERR will be redirected to: $stderrRedirect")
|
||||
append(" STDIN is empty: " + stdInBytes.isEmpty())
|
||||
})
|
||||
|
||||
require(args.isNotEmpty()) { "Arguments must be not empty to start external process" }
|
||||
|
||||
val processBuilder = ProcessBuilder()
|
||||
.directory(workDir?.toFile())
|
||||
.command(*args.toTypedArray())
|
||||
.redirectInput(ProcessBuilder.Redirect.PIPE)
|
||||
.redirectOutput(ProcessBuilder.Redirect.PIPE)
|
||||
.redirectError(ProcessBuilder.Redirect.PIPE)
|
||||
.actualizeEnvVariables(environmentVariables, onlyEnrichExistedEnvVariables)
|
||||
|
||||
logOutput(
|
||||
"""
|
||||
Process: `$presentablePurpose`
|
||||
Arguments: ${args.joinToString(separator = " ")}
|
||||
Environment variables: [${processBuilder.environment().entries.joinToString { "${it.key}=${it.value}" }}]
|
||||
""".trimIndent())
|
||||
val process = processBuilder.start()
|
||||
|
||||
val processId = process.pid()
|
||||
catchAll {
|
||||
logOutput(" ... started external process `$presentablePurpose` with process ID = $processId")
|
||||
onProcessCreated(process, processId)
|
||||
}
|
||||
|
||||
val inputThread = redirectProcessInput(process, stdInBytes)
|
||||
val stdoutThread = redirectProcessOutput(process, true, stdoutRedirect)
|
||||
val stderrThread = redirectProcessOutput(process, false, stderrRedirect)
|
||||
val threads = listOfNotNull(inputThread, stdoutThread, stderrThread)
|
||||
|
||||
fun killProcess() {
|
||||
catchAll { onBeforeKilled(process, processId) }
|
||||
catchAll { process.descendants().forEach { catchAll { it.destroyForcibly() } } }
|
||||
catchAll { process.destroy() }
|
||||
catchAll { process.destroyForcibly() }
|
||||
catchAll { threads.forEach { it.interrupt() } }
|
||||
}
|
||||
|
||||
val stopper = Runnable {
|
||||
logOutput(
|
||||
" ... terminating process `$presentablePurpose` by request from external process (either SIGTERM or SIGKILL is caught) ...")
|
||||
killProcess()
|
||||
}
|
||||
|
||||
val stopperThread = Thread(stopper, "process-shutdown-hook")
|
||||
try {
|
||||
Runtime.getRuntime().addShutdownHook(stopperThread)
|
||||
}
|
||||
catch (e: IllegalStateException) {
|
||||
logError("Process: $presentablePurpose. Shutdown hook cannot be added because: ${e.message}")
|
||||
}
|
||||
|
||||
try {
|
||||
if (!runCatching { process.waitFor(timeout.inWholeSeconds, TimeUnit.SECONDS) }.getOrDefault(false)) {
|
||||
stopperThread.apply {
|
||||
start()
|
||||
join(20.seconds.inWholeMilliseconds)
|
||||
}
|
||||
throw ExecTimeoutException(args.joinToString(" "), timeout)
|
||||
}
|
||||
}
|
||||
finally {
|
||||
catchAll { Runtime.getRuntime().removeShutdownHook(stopperThread) }
|
||||
}
|
||||
|
||||
threads.forEach { catchAll { it.join() } }
|
||||
|
||||
val code = process.exitValue()
|
||||
if (code != 0) {
|
||||
val linesLimit = 100
|
||||
|
||||
logOutput(" ... failed external process `$presentablePurpose` with exit code $code")
|
||||
val message = buildString {
|
||||
appendLine("External process `$presentablePurpose` failed with code $code")
|
||||
for (diagnosticFile in errorDiagnosticFiles.filter { it.exists() && Files.size(it) > 0 }) {
|
||||
appendLine(diagnosticFile.fileName.toString())
|
||||
appendLine(diagnosticFile.readText().lines().joinToString(System.lineSeparator()) { " $it" })
|
||||
}
|
||||
|
||||
stderrRedirect.read().lines().apply {
|
||||
take(linesLimit).dropWhile { it.trim().isBlank() }.let { lines ->
|
||||
if (lines.isNotEmpty()) {
|
||||
appendLine(" FIRST $linesLimit lines of the standard error stream")
|
||||
lines.forEach { appendLine(" $it") }
|
||||
}
|
||||
}
|
||||
|
||||
if (size > linesLimit) {
|
||||
appendLine("...")
|
||||
|
||||
takeLast(linesLimit).dropWhile { it.trim().isBlank() }.let { lines ->
|
||||
if (lines.isNotEmpty()) {
|
||||
appendLine(" LAST $linesLimit lines of the standard error stream")
|
||||
lines.forEach { appendLine(" $it") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stdoutRedirect.read().lines().takeLast(linesLimit).dropWhile { it.trim().isEmpty() }.let { lines ->
|
||||
if (lines.isNotEmpty()) {
|
||||
appendLine(" LAST $linesLimit lines of the standard output stream")
|
||||
lines.forEach { appendLine(" $it") }
|
||||
}
|
||||
}
|
||||
}
|
||||
error(message)
|
||||
}
|
||||
logOutput(" ... successfully finished external process for `$presentablePurpose` with exit code 0")
|
||||
}
|
||||
|
||||
class ExecTimeoutException(private val processName: String,
|
||||
private val timeout: Duration) : RuntimeException() {
|
||||
override val message
|
||||
get() = "Failed to wait for the process `$processName` to complete in $timeout"
|
||||
}
|
||||
|
||||
fun executeScript(fileNameToExecute: String, projectDirPath: Path) {
|
||||
val stdout = ExecOutputRedirect.ToString()
|
||||
val stderr = ExecOutputRedirect.ToString()
|
||||
|
||||
exec(
|
||||
presentablePurpose = "Executing of $fileNameToExecute",
|
||||
workDir = projectDirPath,
|
||||
timeout = 20.minutes,
|
||||
args = listOf(fileNameToExecute),
|
||||
stdoutRedirect = stdout,
|
||||
stderrRedirect = stderr
|
||||
)
|
||||
|
||||
val commit = stdout.read().trim()
|
||||
val error = stderr.read().trim()
|
||||
|
||||
logOutput("Stdout of command execution $commit")
|
||||
logOutput("Stderr of command execution $error")
|
||||
}
|
||||
|
||||
fun execGradlew(pathToProject: Path, args: List<String>) {
|
||||
val stdout = ExecOutputRedirect.ToString()
|
||||
val stderr = ExecOutputRedirect.ToString()
|
||||
|
||||
val command = when (SystemInfo.isWindows) {
|
||||
true -> (pathToProject / "gradlew.bat").toString()
|
||||
false -> "./gradlew"
|
||||
}
|
||||
|
||||
if (!SystemInfo.isWindows) {
|
||||
exec(
|
||||
presentablePurpose = "chmod gradlew",
|
||||
workDir = pathToProject,
|
||||
timeout = 1.minutes,
|
||||
args = listOf("chmod", "+x", "gradlew"),
|
||||
stdoutRedirect = stdout,
|
||||
stderrRedirect = stderr
|
||||
)
|
||||
}
|
||||
exec(
|
||||
presentablePurpose = "Gradle Format",
|
||||
workDir = pathToProject,
|
||||
timeout = 1.minutes,
|
||||
args = listOf(command) + args,
|
||||
stdoutRedirect = stdout,
|
||||
stderrRedirect = stderr
|
||||
)
|
||||
}
|
||||
-235
@@ -1,235 +0,0 @@
|
||||
package com.intellij.ide.starter.ide;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
// code has been borrowed from Intellij Community sources
|
||||
// Some parts, that requires dependency on Community, were removed
|
||||
public class BuildNumber implements Comparable<BuildNumber> {
|
||||
private static final String STAR = "*";
|
||||
private static final String SNAPSHOT = "SNAPSHOT";
|
||||
private static final String FALLBACK_VERSION = "999.SNAPSHOT";
|
||||
|
||||
public static final int SNAPSHOT_VALUE = Integer.MAX_VALUE;
|
||||
|
||||
private final String myProductCode;
|
||||
private final int[] myComponents;
|
||||
|
||||
public BuildNumber(String productCode, int baselineVersion, int buildNumber) {
|
||||
this(productCode, new int[]{baselineVersion, buildNumber});
|
||||
}
|
||||
|
||||
public BuildNumber(String productCode, int... components) {
|
||||
myProductCode = productCode;
|
||||
myComponents = components;
|
||||
}
|
||||
|
||||
private static boolean isPlaceholder(String value) {
|
||||
return "__BUILD_NUMBER__".equals(value) || "__BUILD__".equals(value);
|
||||
}
|
||||
|
||||
public String getProductCode() {
|
||||
return myProductCode;
|
||||
}
|
||||
|
||||
public int getBaselineVersion() {
|
||||
return myComponents[0];
|
||||
}
|
||||
|
||||
public int[] getComponents() {
|
||||
return myComponents.clone();
|
||||
}
|
||||
|
||||
public boolean isSnapshot() {
|
||||
for (int value : myComponents) {
|
||||
if (value == SNAPSHOT_VALUE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public BuildNumber withoutProductCode() {
|
||||
return myProductCode.isEmpty() ? this : new BuildNumber("", myComponents);
|
||||
}
|
||||
|
||||
public String asString() {
|
||||
return asString(true, true);
|
||||
}
|
||||
|
||||
public String asStringWithoutProductCode() {
|
||||
return asString(false, true);
|
||||
}
|
||||
|
||||
public String asStringWithoutProductCodeAndSnapshot() {
|
||||
return asString(false, false);
|
||||
}
|
||||
|
||||
private String asString(boolean includeProductCode, boolean withSnapshotMarker) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
if (includeProductCode && !myProductCode.isEmpty()) {
|
||||
builder.append(myProductCode).append('-');
|
||||
}
|
||||
|
||||
for (int each : myComponents) {
|
||||
if (each != SNAPSHOT_VALUE) {
|
||||
builder.append(each);
|
||||
}
|
||||
else if (withSnapshotMarker) {
|
||||
builder.append(SNAPSHOT);
|
||||
}
|
||||
builder.append('.');
|
||||
}
|
||||
if (builder.charAt(builder.length() - 1) == '.') {
|
||||
builder.setLength(builder.length() - 1);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static BuildNumber fromPluginsCompatibleBuild() {
|
||||
return fromString(getPluginsCompatibleBuild());
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to parse build number from the specified string.
|
||||
* Returns {@code null} if the string is not a valid build number.
|
||||
*/
|
||||
public static BuildNumber fromStringOrNull(String version) {
|
||||
try {
|
||||
return fromString(version);
|
||||
}
|
||||
catch (RuntimeException ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static BuildNumber fromString(String version) {
|
||||
if (version == null) {
|
||||
return null;
|
||||
}
|
||||
version = version.trim();
|
||||
return fromString(version, null, null);
|
||||
}
|
||||
|
||||
public static BuildNumber fromStringWithProductCode(String version, String productCode) {
|
||||
return fromString(version, null, productCode);
|
||||
}
|
||||
|
||||
public static BuildNumber fromString(String version, String pluginName, String productCodeIfAbsentInVersion) {
|
||||
if (version.isEmpty()) return null;
|
||||
String code = version;
|
||||
int productSeparator = code.indexOf('-');
|
||||
String productCode;
|
||||
if (productSeparator > 0) {
|
||||
productCode = code.substring(0, productSeparator);
|
||||
code = code.substring(productSeparator + 1);
|
||||
}
|
||||
else {
|
||||
productCode = productCodeIfAbsentInVersion != null ? productCodeIfAbsentInVersion : "";
|
||||
}
|
||||
|
||||
int baselineVersionSeparator = code.indexOf('.');
|
||||
|
||||
if (baselineVersionSeparator > 0) {
|
||||
String baselineVersionString = code.substring(0, baselineVersionSeparator);
|
||||
if (baselineVersionString.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] stringComponents = code.split("\\.");
|
||||
int[] intComponentsList = new int[stringComponents.length];
|
||||
for (int i = 0, n = stringComponents.length; i < n; i++) {
|
||||
String stringComponent = stringComponents[i];
|
||||
int comp = parseBuildNumber(version, stringComponent, pluginName);
|
||||
intComponentsList[i] = comp;
|
||||
if (comp == SNAPSHOT_VALUE && (i + 1) != n) {
|
||||
intComponentsList = Arrays.copyOf(intComponentsList, i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new BuildNumber(productCode, intComponentsList);
|
||||
}
|
||||
else {
|
||||
int buildNumber = parseBuildNumber(version, code, pluginName);
|
||||
if (buildNumber <= 2000) {
|
||||
// it's probably a baseline, not a build number
|
||||
return new BuildNumber(productCode, buildNumber, 0);
|
||||
}
|
||||
|
||||
int baselineVersion = getBaseLineForHistoricBuilds(buildNumber);
|
||||
return new BuildNumber(productCode, baselineVersion, buildNumber);
|
||||
}
|
||||
}
|
||||
|
||||
private static int parseBuildNumber(String version, String code, String pluginName) {
|
||||
if (SNAPSHOT.equals(code) || isPlaceholder(code) || STAR.equals(code)) {
|
||||
return SNAPSHOT_VALUE;
|
||||
}
|
||||
|
||||
try {
|
||||
return Integer.parseInt(code);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw new RuntimeException("Invalid version number: " + version + "; plugin name: " + pluginName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(BuildNumber o) {
|
||||
int[] c1 = myComponents;
|
||||
int[] c2 = o.myComponents;
|
||||
|
||||
for (int i = 0; i < Math.min(c1.length, c2.length); i++) {
|
||||
if (c1[i] == c2[i] && c1[i] == SNAPSHOT_VALUE) return 0;
|
||||
if (c1[i] == SNAPSHOT_VALUE) return 1;
|
||||
if (c2[i] == SNAPSHOT_VALUE) return -1;
|
||||
int result = c1[i] - c2[i];
|
||||
if (result != 0) return result;
|
||||
}
|
||||
|
||||
return c1.length - c2.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
BuildNumber that = (BuildNumber)o;
|
||||
|
||||
if (!myProductCode.equals(that.myProductCode)) return false;
|
||||
return Arrays.equals(myComponents, that.myComponents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = myProductCode.hashCode();
|
||||
result = 31 * result + Arrays.hashCode(myComponents);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return asString();
|
||||
}
|
||||
|
||||
// http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html
|
||||
private static int getBaseLineForHistoricBuilds(int bn) {
|
||||
if (bn >= 10000) return 88; // Maia, 9x builds
|
||||
if (bn >= 9500) return 85; // 8.1 builds
|
||||
if (bn >= 9100) return 81; // 8.0.x builds
|
||||
if (bn >= 8000) return 80; // 8.0, including pre-release builds
|
||||
if (bn >= 7500) return 75; // 7.0.2+
|
||||
if (bn >= 7200) return 72; // 7.0 final
|
||||
if (bn >= 6900) return 69; // 7.0 pre-M2
|
||||
if (bn >= 6500) return 65; // 7.0 pre-M1
|
||||
if (bn >= 6000) return 60; // 6.0.2+
|
||||
if (bn >= 5000) return 55; // 6.0 branch, including all 6.0 EAP builds
|
||||
if (bn >= 4000) return 50; // 5.1 branch
|
||||
return 40;
|
||||
}
|
||||
|
||||
private static String getPluginsCompatibleBuild() {
|
||||
return System.getProperty("idea.plugins.compatible.build");
|
||||
}
|
||||
}
|
||||
+21
-9
@@ -5,7 +5,10 @@ import com.intellij.ide.starter.ci.CIServer
|
||||
import com.intellij.ide.starter.di.di
|
||||
import com.intellij.ide.starter.ide.command.CommandChain
|
||||
import com.intellij.ide.starter.ide.command.MarshallableCommand
|
||||
import com.intellij.ide.starter.models.*
|
||||
import com.intellij.ide.starter.models.IDEStartResult
|
||||
import com.intellij.ide.starter.models.TestCase
|
||||
import com.intellij.ide.starter.models.VMOptions
|
||||
import com.intellij.ide.starter.models.andThen
|
||||
import com.intellij.ide.starter.path.IDEDataPaths
|
||||
import com.intellij.ide.starter.plugins.PluginConfigurator
|
||||
import com.intellij.ide.starter.profiler.ProfilerType
|
||||
@@ -21,6 +24,7 @@ import org.kodein.di.newInstance
|
||||
import org.w3c.dom.Node
|
||||
import org.w3c.dom.NodeList
|
||||
import java.io.FileOutputStream
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import javax.xml.parsers.DocumentBuilderFactory
|
||||
import javax.xml.transform.TransformerFactory
|
||||
@@ -202,6 +206,14 @@ data class IDETestContext(
|
||||
paths.logsDir.toFile().deleteRecursively()
|
||||
}
|
||||
|
||||
fun wipeReportDir() = apply {
|
||||
logOutput("Cleaning report dir for $this at $paths")
|
||||
Files.walk(paths.reportsDir)
|
||||
.filter { Files.isRegularFile(it) }
|
||||
.map { it.toFile() }
|
||||
.forEach { it.delete() }
|
||||
}
|
||||
|
||||
fun wipeProjectsDir() = apply {
|
||||
val path = paths.systemDir / "projects"
|
||||
logOutput("Cleaning project cache dir for $this at $path")
|
||||
@@ -336,19 +348,19 @@ data class IDETestContext(
|
||||
): IDEStartResult {
|
||||
val updatedContext = this.copy(testName = "${this.testName}/warmup")
|
||||
val result = updatedContext.runIDE(
|
||||
patchVMOptions = {
|
||||
val warmupReports = IDEStartupReports(paths.reportsDir)
|
||||
patchVMOptions = {
|
||||
this.run {
|
||||
if (storeClassReport) {
|
||||
this.enableStartupPerformanceLog(warmupReports).enableClassLoadingReport(
|
||||
paths.reportsDir / "class-report.txt").patchVMOptions()
|
||||
this.enableClassLoadingReport(paths.reportsDir / "class-report.txt")
|
||||
}
|
||||
else {
|
||||
this
|
||||
}
|
||||
},
|
||||
commands = testCase.commands.plus(commands),
|
||||
runTimeout = runTimeout
|
||||
)
|
||||
}.patchVMOptions()
|
||||
},
|
||||
commands = testCase.commands.plus(commands),
|
||||
runTimeout = runTimeout
|
||||
)
|
||||
updatedContext.publishArtifact(this.paths.reportsDir)
|
||||
return result
|
||||
}
|
||||
|
||||
+21
-18
@@ -1,9 +1,9 @@
|
||||
package com.intellij.ide.starter.ide
|
||||
|
||||
import com.intellij.ide.starter.di.di
|
||||
import com.intellij.ide.starter.exec.ExecOutputRedirect
|
||||
import com.intellij.ide.starter.exec.exec
|
||||
import com.intellij.ide.starter.path.GlobalPaths
|
||||
import com.intellij.ide.starter.process.exec.ExecOutputRedirect
|
||||
import com.intellij.ide.starter.process.exec.ProcessExecutor
|
||||
import com.intellij.ide.starter.utils.FileSystem
|
||||
import com.intellij.ide.starter.utils.HttpClient
|
||||
import com.intellij.ide.starter.utils.catchAll
|
||||
@@ -41,13 +41,14 @@ object IdeArchiveExtractor {
|
||||
|
||||
val mountDir = File(dmgFile.path + "-mount${System.currentTimeMillis()}")
|
||||
try {
|
||||
exec(presentablePurpose = "hdiutil",
|
||||
workDir = target,
|
||||
timeout = 10.minutes,
|
||||
stderrRedirect = ExecOutputRedirect.ToStdOut("hdiutil"),
|
||||
stdoutRedirect = ExecOutputRedirect.ToStdOut("hdiutil"),
|
||||
args = listOf("hdiutil", "attach", "-readonly", "-noautoopen", "-noautofsck", "-nobrowse", "-mountpoint", "$mountDir",
|
||||
"$dmgFile"))
|
||||
ProcessExecutor(presentableName = "hdiutil",
|
||||
workDir = target,
|
||||
timeout = 10.minutes,
|
||||
stderrRedirect = ExecOutputRedirect.ToStdOut("hdiutil"),
|
||||
stdoutRedirect = ExecOutputRedirect.ToStdOut("hdiutil"),
|
||||
args = listOf("hdiutil", "attach", "-readonly", "-noautoopen", "-noautofsck", "-nobrowse", "-mountpoint", "$mountDir",
|
||||
"$dmgFile")
|
||||
).start()
|
||||
}
|
||||
catch (t: Throwable) {
|
||||
dmgFile.delete()
|
||||
@@ -59,24 +60,26 @@ object IdeArchiveExtractor {
|
||||
?: error("Failed to find the only one .app folder in $dmgFile")
|
||||
|
||||
val targetAppDir = target / appDir.name
|
||||
exec(
|
||||
presentablePurpose = "copy-dmg",
|
||||
ProcessExecutor(
|
||||
presentableName = "copy-dmg",
|
||||
workDir = target,
|
||||
timeout = 10.minutes,
|
||||
stderrRedirect = ExecOutputRedirect.ToStdOut("cp"),
|
||||
args = listOf("cp", "-R", "$appDir", "$targetAppDir"))
|
||||
args = listOf("cp", "-R", "$appDir", "$targetAppDir")
|
||||
).start()
|
||||
|
||||
return targetAppDir
|
||||
}
|
||||
finally {
|
||||
catchAll {
|
||||
exec(
|
||||
presentablePurpose = "hdiutil",
|
||||
ProcessExecutor(
|
||||
presentableName = "hdiutil",
|
||||
workDir = target,
|
||||
timeout = 10.minutes,
|
||||
stdoutRedirect = ExecOutputRedirect.ToStdOut("hdiutil"),
|
||||
stderrRedirect = ExecOutputRedirect.ToStdOut("hdiutil"),
|
||||
args = listOf("hdiutil", "detach", "-force", "$mountDir"))
|
||||
args = listOf("hdiutil", "detach", "-force", "$mountDir")
|
||||
).start()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,11 +100,11 @@ object IdeArchiveExtractor {
|
||||
val severZipToolExe = sevenZipTool.resolve("7z.exe")
|
||||
|
||||
targetDir.mkdirs()
|
||||
exec(
|
||||
presentablePurpose = "unpack-zip",
|
||||
ProcessExecutor(
|
||||
presentableName = "unpack-zip",
|
||||
workDir = targetDir.toPath(),
|
||||
timeout = 10.minutes,
|
||||
args = listOf(severZipToolExe.toAbsolutePath().toString(), "x", "-y", "-o$targetDir", exeFile.path)
|
||||
)
|
||||
).start()
|
||||
}
|
||||
}
|
||||
+3
@@ -3,5 +3,8 @@ package com.intellij.ide.starter.ide
|
||||
import com.intellij.ide.starter.models.IdeInfo
|
||||
|
||||
interface IdeInstallator {
|
||||
/**
|
||||
* @return <Build Number, InstalledIde>
|
||||
*/
|
||||
fun install(ideInfo: IdeInfo): Pair<String, InstalledIde>
|
||||
}
|
||||
+3
@@ -35,5 +35,8 @@ object IdeProductProvider {
|
||||
/** PyCharm Professional */
|
||||
val PY: IdeInfo = di.direct.instance<IdeProduct>().PY
|
||||
|
||||
/** CLion */
|
||||
val CL: IdeInfo = di.direct.instance<IdeProduct>().CL
|
||||
|
||||
fun getProducts(): List<IdeInfo> = IdeProductProvider::class.declaredMemberProperties.map { it.get(IdeProductProvider) as IdeInfo }
|
||||
}
|
||||
+6
-5
@@ -1,8 +1,8 @@
|
||||
package com.intellij.ide.starter.ide
|
||||
|
||||
import com.intellij.ide.starter.exec.ExecOutputRedirect
|
||||
import com.intellij.ide.starter.exec.exec
|
||||
import com.intellij.ide.starter.models.VMOptions
|
||||
import com.intellij.ide.starter.process.exec.ExecOutputRedirect
|
||||
import com.intellij.ide.starter.process.exec.ProcessExecutor
|
||||
import com.intellij.ide.starter.system.SystemInfo
|
||||
import com.intellij.ide.starter.utils.callJavaVersion
|
||||
import com.intellij.ide.starter.utils.logOutput
|
||||
@@ -18,9 +18,10 @@ class LinuxIdeDistribution : IdeDistribution() {
|
||||
val toolName = "xvfb-run"
|
||||
|
||||
val homePath = Path(System.getProperty("user.home")).toAbsolutePath()
|
||||
exec("xvfb-run", homePath, timeout = 5.seconds, args = listOf("which", toolName),
|
||||
stdoutRedirect = ExecOutputRedirect.ToStdOut("xvfb-run-out"),
|
||||
stderrRedirect = ExecOutputRedirect.ToStdOut("xvfb-run-err"))
|
||||
ProcessExecutor("xvfb-run", homePath, timeout = 5.seconds, args = listOf("which", toolName),
|
||||
stdoutRedirect = ExecOutputRedirect.ToStdOut("xvfb-run-out"),
|
||||
stderrRedirect = ExecOutputRedirect.ToStdOut("xvfb-run-err")
|
||||
).start()
|
||||
toolName
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -27,4 +27,7 @@ interface IdeProduct {
|
||||
|
||||
/** PyCharm Professional */
|
||||
val PY: IdeInfo
|
||||
|
||||
/** CLion */
|
||||
val CL: IdeInfo
|
||||
}
|
||||
+7
@@ -63,4 +63,11 @@ object IdeProductImp : IdeProduct {
|
||||
platformPrefix = "Python",
|
||||
executableFileName = "pycharm"
|
||||
)
|
||||
|
||||
/** CLion */
|
||||
override val CL: IdeInfo = IdeInfo(
|
||||
productCode = "CL",
|
||||
platformPrefix = "CLion",
|
||||
executableFileName = "clion"
|
||||
)
|
||||
}
|
||||
+1
-4
@@ -16,13 +16,10 @@ data class TestCase(
|
||||
|
||||
fun withCommands(commands: Iterable<MarshallableCommand> = this.commands): TestCase = copy(commands = commands.toList())
|
||||
|
||||
/** Project in this case will be reused between tests */
|
||||
fun markNotReusable(): TestCase = markReusable(false)
|
||||
|
||||
/** On each test run the project will be unpacked again.
|
||||
* This guarantees that there is not side effects from previous test runs
|
||||
**/
|
||||
fun markReusable(isReusable: Boolean = true) = copy(projectInfo = (projectInfo as ProjectInfo).copy(isReusable = isReusable))
|
||||
fun markNotReusable(): TestCase = copy(projectInfo = (projectInfo as ProjectInfo).copy(isReusable = false))
|
||||
|
||||
/**
|
||||
* [buildNumber] - EAP build number to download
|
||||
|
||||
+10
@@ -108,6 +108,16 @@ data class VMOptions(
|
||||
.addSystemProperty("idea.record.classpath.info", "true")
|
||||
}
|
||||
|
||||
fun enableVmtraceClassLoadingReport(filePath: Path): VMOptions {
|
||||
if (!VMTrace.isSupported) return this
|
||||
|
||||
val vmTraceFile = VMTrace.vmTraceFile
|
||||
|
||||
return this
|
||||
.addSystemProperty("idea.log.vmtrace.file", filePath)
|
||||
.addLine("-agentpath:${vmTraceFile.toAbsolutePath()}=${filePath.toAbsolutePath()}")
|
||||
}
|
||||
|
||||
fun configureLoggers(
|
||||
debugLoggers: List<String> = emptyList(),
|
||||
traceLoggers: List<String> = emptyList()
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package com.intellij.ide.starter.models
|
||||
|
||||
import com.intellij.ide.starter.system.SystemInfo
|
||||
import com.intellij.openapi.util.io.FileUtilRt
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
|
||||
/**
|
||||
* Holds path to libvmtrace.so on disk.
|
||||
*/
|
||||
object VMTrace {
|
||||
val vmTraceFile: Path
|
||||
|
||||
val isSupported: Boolean
|
||||
get() = SystemInfo.isLinux || SystemInfo.isMac
|
||||
|
||||
init {
|
||||
if (isSupported) {
|
||||
val resourceName = when {
|
||||
SystemInfo.isLinux -> "/libvmtrace.so"
|
||||
SystemInfo.isMac && !SystemInfo.isAarch64 -> "/libvmtrace.dylib"
|
||||
SystemInfo.isMac && SystemInfo.isAarch64 -> "/libvmtrace-aarch64.dylib"
|
||||
else -> throw UnsupportedOperationException("Unsupported platform for libvmtrace")
|
||||
}
|
||||
|
||||
vmTraceFile = Files.createTempFile("libvmtrace", "." + FileUtilRt.getExtension(resourceName))
|
||||
|
||||
val vmTraceBytes = VMOptions::class.java.getResourceAsStream(resourceName)!!
|
||||
.use { it.readAllBytes() }
|
||||
Files.write(vmTraceFile, vmTraceBytes)
|
||||
}
|
||||
else {
|
||||
vmTraceFile = Path.of("unsupported-platform-libvmtrace")
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -25,14 +25,14 @@ abstract class GlobalPaths(val checkoutDir: Path) {
|
||||
false -> intelliJOutDirectory // Local run
|
||||
}
|
||||
|
||||
open val testHomePath:Path = intelliJOutDirectory.resolve("perf-startup").createDirectories()
|
||||
open val testHomePath: Path = intelliJOutDirectory.resolve("perf-startup").createDirectories()
|
||||
|
||||
val installersDirectory = (testHomePath / "installers").createDirectories()
|
||||
|
||||
val testsDirectory = (testHomePath / "tests").createDirectories()
|
||||
|
||||
private val cacheDirectory: Path = if (di.direct.instance<CIServer>().isBuildRunningOnCI &&
|
||||
!System.getProperty("agent.persistent.cache").isNullOrEmpty()
|
||||
!System.getProperty("agent.persistent.cache").isNullOrEmpty()
|
||||
) {
|
||||
(Paths.get(System.getProperty("agent.persistent.cache"), "perf-tests-cache")).createDirectories()
|
||||
}
|
||||
|
||||
+2
-1
@@ -60,7 +60,8 @@ open class PluginConfigurator(val testContext: IDETestContext) {
|
||||
logError("Plugin $pluginId downloading failed, skipping")
|
||||
return@apply
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
FileSystem.unpack(downloadedPlugin, testContext.paths.pluginsDir)
|
||||
}
|
||||
logOutput("Plugin $pluginId setup finished")
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.intellij.ide.starter.exec
|
||||
package com.intellij.ide.starter.process.exec
|
||||
|
||||
import com.intellij.ide.starter.exec.ExecOutputRedirect.*
|
||||
import com.intellij.ide.starter.process.exec.ExecOutputRedirect.*
|
||||
import com.intellij.ide.starter.utils.logOutput
|
||||
import java.io.File
|
||||
import java.io.PrintWriter
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.intellij.ide.starter.process.exec
|
||||
|
||||
import kotlin.time.Duration
|
||||
|
||||
class ExecTimeoutException(private val processName: String,
|
||||
private val timeout: Duration) : RuntimeException() {
|
||||
override val message
|
||||
get() = "Failed to wait for the process `$processName` to complete in $timeout"
|
||||
}
|
||||
+228
@@ -0,0 +1,228 @@
|
||||
package com.intellij.ide.starter.process.exec
|
||||
|
||||
import com.intellij.ide.starter.coroutine.supervisorScope
|
||||
import com.intellij.ide.starter.utils.catchAll
|
||||
import com.intellij.ide.starter.utils.logError
|
||||
import com.intellij.ide.starter.utils.logOutput
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.future.await
|
||||
import java.io.IOException
|
||||
import java.lang.Runnable
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.concurrent.thread
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.readText
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
class ProcessExecutor(val presentableName: String,
|
||||
val workDir: Path?,
|
||||
val timeout: Duration = 10.minutes,
|
||||
val environmentVariables: Map<String, String> = System.getenv(),
|
||||
val args: List<String>,
|
||||
val errorDiagnosticFiles: List<Path> = emptyList(),
|
||||
val stdoutRedirect: ExecOutputRedirect = ExecOutputRedirect.NoRedirect,
|
||||
val stderrRedirect: ExecOutputRedirect = ExecOutputRedirect.NoRedirect,
|
||||
val onProcessCreated: suspend (Process, Long) -> Unit = { _, _ -> },
|
||||
val onBeforeKilled: suspend (Process, Long) -> Unit = { _, _ -> },
|
||||
val stdInBytes: ByteArray = byteArrayOf(),
|
||||
val onlyEnrichExistedEnvVariables: Boolean = false) {
|
||||
|
||||
private fun redirectProcessOutput(
|
||||
process: Process,
|
||||
outOrErrStream: Boolean,
|
||||
redirectOutput: ExecOutputRedirect
|
||||
): Thread {
|
||||
val inputStream = if (outOrErrStream) process.inputStream else process.errorStream
|
||||
return thread(start = true, isDaemon = true, name = "Redirect " + (if (outOrErrStream) "stdout" else "stderr")) {
|
||||
val reader = inputStream.bufferedReader()
|
||||
redirectOutput.open()
|
||||
try {
|
||||
while (true) {
|
||||
val line = try {
|
||||
reader.readLine() ?: break
|
||||
}
|
||||
catch (e: IOException) {
|
||||
break
|
||||
}
|
||||
redirectOutput.redirectLine(line)
|
||||
}
|
||||
}
|
||||
finally {
|
||||
redirectOutput.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun redirectProcessInput(process: Process, inputBytes: ByteArray): Thread? {
|
||||
if (inputBytes.isEmpty()) {
|
||||
catchAll { process.outputStream.close() }
|
||||
return null
|
||||
}
|
||||
|
||||
return thread(start = true, isDaemon = true, name = "Redirect input") {
|
||||
catchAll {
|
||||
process.outputStream.use {
|
||||
it.write(inputBytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun ProcessBuilder.actualizeEnvVariables(environmentVariables: Map<String, String> = System.getenv(),
|
||||
onlyEnrichExistedEnvVariables: Boolean = false): ProcessBuilder {
|
||||
val processEnvironment = environment()
|
||||
if (processEnvironment == environmentVariables) return this
|
||||
|
||||
environmentVariables.filter { it.value == null }.forEach { logError("Env variable: ${it.key} has null value ${it.value}") }
|
||||
val notNullValues = environmentVariables.filter { it.value != null }
|
||||
|
||||
// env variables enrichment
|
||||
processEnvironment.putAll(notNullValues)
|
||||
|
||||
if (!onlyEnrichExistedEnvVariables) {
|
||||
val missingKeys = processEnvironment.keys - notNullValues.keys
|
||||
missingKeys.forEach { key -> processEnvironment.remove(key) }
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
private fun killProcessGracefully(process: ProcessHandle) {
|
||||
process.destroy()
|
||||
runBlocking { withTimeout(20.seconds) { process.onExit().await() } }
|
||||
process.destroyForcibly()
|
||||
}
|
||||
|
||||
private fun analyzeProcessExit(process: Process) {
|
||||
val code = process.exitValue()
|
||||
if (code != 0) {
|
||||
val linesLimit = 100
|
||||
|
||||
logOutput(" ... failed external process `$presentableName` with exit code $code")
|
||||
val message = buildString {
|
||||
appendLine("External process `$presentableName` failed with code $code")
|
||||
for (diagnosticFile in errorDiagnosticFiles.filter { it.exists() && Files.size(it) > 0 }) {
|
||||
appendLine(diagnosticFile.fileName.toString())
|
||||
appendLine(diagnosticFile.readText().lines().joinToString(System.lineSeparator()) { " $it" })
|
||||
}
|
||||
|
||||
stderrRedirect.read().lines().apply {
|
||||
take(linesLimit).dropWhile { it.trim().isBlank() }.let { lines ->
|
||||
if (lines.isNotEmpty()) {
|
||||
appendLine(" FIRST $linesLimit lines of the standard error stream")
|
||||
lines.forEach { appendLine(" $it") }
|
||||
}
|
||||
}
|
||||
|
||||
if (size > linesLimit) {
|
||||
appendLine("...")
|
||||
|
||||
takeLast(linesLimit).dropWhile { it.trim().isBlank() }.let { lines ->
|
||||
if (lines.isNotEmpty()) {
|
||||
appendLine(" LAST $linesLimit lines of the standard error stream")
|
||||
lines.forEach { appendLine(" $it") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stdoutRedirect.read().lines().takeLast(linesLimit).dropWhile { it.trim().isEmpty() }.let { lines ->
|
||||
if (lines.isNotEmpty()) {
|
||||
appendLine(" LAST $linesLimit lines of the standard output stream")
|
||||
lines.forEach { appendLine(" $it") }
|
||||
}
|
||||
}
|
||||
}
|
||||
error(message)
|
||||
}
|
||||
|
||||
logOutput(" ... successfully finished external process for `$presentableName` with exit code 0")
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new process and wait for it's completion
|
||||
*/
|
||||
@Throws(ExecTimeoutException::class)
|
||||
fun start() {
|
||||
logOutput(buildString {
|
||||
appendLine("Running external process for `$presentableName`")
|
||||
appendLine(" Working directory: $workDir")
|
||||
appendLine(" Arguments: [${args.joinToString()}]")
|
||||
appendLine(" STDOUT will be redirected to: $stdoutRedirect")
|
||||
appendLine(" STDERR will be redirected to: $stderrRedirect")
|
||||
append(" STDIN is empty: " + stdInBytes.isEmpty())
|
||||
})
|
||||
|
||||
require(args.isNotEmpty()) { "Arguments must be not empty to start external process" }
|
||||
|
||||
val processBuilder = ProcessBuilder()
|
||||
.directory(workDir?.toFile())
|
||||
.command(*args.toTypedArray())
|
||||
.redirectInput(ProcessBuilder.Redirect.PIPE)
|
||||
.redirectOutput(ProcessBuilder.Redirect.PIPE)
|
||||
.redirectError(ProcessBuilder.Redirect.PIPE)
|
||||
.actualizeEnvVariables(environmentVariables, onlyEnrichExistedEnvVariables)
|
||||
|
||||
logOutput(
|
||||
"""
|
||||
Process: `$presentableName`
|
||||
Arguments: ${args.joinToString(separator = " ")}
|
||||
Environment variables: [${processBuilder.environment().entries.joinToString { "${it.key}=${it.value}" }}]
|
||||
""".trimIndent())
|
||||
val process = processBuilder.start()
|
||||
|
||||
val processId = process.pid()
|
||||
val onProcessCreatedJob: Job = supervisorScope.launch {
|
||||
logOutput(" ... started external process `$presentableName` with process ID = $processId")
|
||||
onProcessCreated(process, processId)
|
||||
}
|
||||
|
||||
val inputThread = redirectProcessInput(process, stdInBytes)
|
||||
val stdoutThread = redirectProcessOutput(process, true, stdoutRedirect)
|
||||
val stderrThread = redirectProcessOutput(process, false, stderrRedirect)
|
||||
val ioThreads = listOfNotNull(inputThread, stdoutThread, stderrThread)
|
||||
|
||||
fun killProcess() {
|
||||
catchAll { runBlocking { onProcessCreatedJob.cancelAndJoin() } }
|
||||
catchAll { runBlocking { withTimeout(1.minutes) { onBeforeKilled(process, processId) } } }
|
||||
process.descendants().forEach { catchAll { killProcessGracefully(it) } }
|
||||
catchAll { killProcessGracefully(process.toHandle()) }
|
||||
catchAll { ioThreads.forEach { it.interrupt() } }
|
||||
}
|
||||
|
||||
val stopper = Runnable {
|
||||
logOutput(
|
||||
" ... terminating process `$presentableName` by request from external process (either SIGTERM or SIGKILL is caught) ...")
|
||||
killProcess()
|
||||
}
|
||||
|
||||
val stopperThread = Thread(stopper, "process-shutdown-hook")
|
||||
try {
|
||||
Runtime.getRuntime().addShutdownHook(stopperThread)
|
||||
}
|
||||
catch (e: IllegalStateException) {
|
||||
logError("Process: $presentableName. Shutdown hook cannot be added because: ${e.message}")
|
||||
}
|
||||
|
||||
try {
|
||||
if (!runCatching { process.waitFor(timeout.inWholeSeconds, TimeUnit.SECONDS) }.getOrDefault(false)) {
|
||||
stopperThread.apply {
|
||||
start()
|
||||
join(20.seconds.inWholeMilliseconds)
|
||||
}
|
||||
throw ExecTimeoutException(args.joinToString(" "), timeout)
|
||||
}
|
||||
}
|
||||
finally {
|
||||
catchAll { Runtime.getRuntime().removeShutdownHook(stopperThread) }
|
||||
}
|
||||
|
||||
ioThreads.forEach { catchAll { it.join() } }
|
||||
|
||||
analyzeProcessExit(process)
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.intellij.ide.starter.process.exec
|
||||
|
||||
import com.intellij.ide.starter.system.SystemInfo
|
||||
import com.intellij.ide.starter.utils.logOutput
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.div
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
|
||||
|
||||
fun executeScript(fileNameToExecute: String, projectDirPath: Path) {
|
||||
val stdout = ExecOutputRedirect.ToString()
|
||||
val stderr = ExecOutputRedirect.ToString()
|
||||
|
||||
ProcessExecutor(
|
||||
presentableName = "Executing of $fileNameToExecute",
|
||||
workDir = projectDirPath,
|
||||
timeout = 20.minutes,
|
||||
args = listOf(fileNameToExecute),
|
||||
stdoutRedirect = stdout,
|
||||
stderrRedirect = stderr
|
||||
).start()
|
||||
|
||||
val commit = stdout.read().trim()
|
||||
val error = stderr.read().trim()
|
||||
|
||||
logOutput("Stdout of command execution $commit")
|
||||
logOutput("Stderr of command execution $error")
|
||||
}
|
||||
|
||||
fun execGradlew(pathToProject: Path, args: List<String>) {
|
||||
val stdout = ExecOutputRedirect.ToString()
|
||||
val stderr = ExecOutputRedirect.ToString()
|
||||
|
||||
val command = when (SystemInfo.isWindows) {
|
||||
true -> (pathToProject / "gradlew.bat").toString()
|
||||
false -> "./gradlew"
|
||||
}
|
||||
|
||||
if (!SystemInfo.isWindows) {
|
||||
ProcessExecutor(
|
||||
presentableName = "chmod gradlew",
|
||||
workDir = pathToProject,
|
||||
timeout = 1.minutes,
|
||||
args = listOf("chmod", "+x", "gradlew"),
|
||||
stdoutRedirect = stdout,
|
||||
stderrRedirect = stderr
|
||||
).start()
|
||||
}
|
||||
|
||||
ProcessExecutor(
|
||||
presentableName = "Gradle Format",
|
||||
workDir = pathToProject,
|
||||
timeout = 1.minutes,
|
||||
args = listOf(command) + args,
|
||||
stdoutRedirect = stdout,
|
||||
stderrRedirect = stderr
|
||||
).start()
|
||||
}
|
||||
+26
-20
@@ -1,9 +1,9 @@
|
||||
package com.intellij.ide.starter.process
|
||||
|
||||
import com.intellij.ide.starter.di.di
|
||||
import com.intellij.ide.starter.exec.ExecOutputRedirect
|
||||
import com.intellij.ide.starter.exec.exec
|
||||
import com.intellij.ide.starter.path.GlobalPaths
|
||||
import com.intellij.ide.starter.process.exec.ExecOutputRedirect
|
||||
import com.intellij.ide.starter.process.exec.ProcessExecutor
|
||||
import com.intellij.ide.starter.system.SystemInfo
|
||||
import com.intellij.ide.starter.utils.catchAll
|
||||
import com.intellij.ide.starter.utils.logOutput
|
||||
@@ -46,11 +46,13 @@ fun killOutdatedProcessesOnUnix(commandsToSearch: Iterable<String> = listOf("/pe
|
||||
fun dumpListOfProcessesOnMacOS(): List<MacOsProcessMetaInfo> {
|
||||
check(SystemInfo.isMac)
|
||||
val stdoutRedirect = ExecOutputRedirect.ToString()
|
||||
exec("ps",
|
||||
di.direct.instance<GlobalPaths>().testsDirectory,
|
||||
timeout = 1.minutes,
|
||||
args = listOf("ps", "-ax"),
|
||||
stdoutRedirect = stdoutRedirect)
|
||||
ProcessExecutor("ps",
|
||||
di.direct.instance<GlobalPaths>().testsDirectory,
|
||||
timeout = 1.minutes,
|
||||
args = listOf("ps", "-ax"),
|
||||
stdoutRedirect = stdoutRedirect
|
||||
).start()
|
||||
|
||||
val processLines = stdoutRedirect.read().lines().drop(1).map { it.trim() }.filterNot { it.isBlank() }
|
||||
//PID TTY TIME CMD
|
||||
// 1 ?? 0:43.67 /sbin/launchd
|
||||
@@ -75,11 +77,13 @@ fun dumpListOfProcessesOnMacOS(): List<MacOsProcessMetaInfo> {
|
||||
fun dumpListOfProcessesOnLinux(): List<LinuxProcessMetaInfo> {
|
||||
check(SystemInfo.isLinux)
|
||||
val stdoutRedirect = ExecOutputRedirect.ToString()
|
||||
exec("ps",
|
||||
di.direct.instance<GlobalPaths>().testsDirectory,
|
||||
timeout = 1.minutes,
|
||||
args = listOf("ps", "-aux"),
|
||||
stdoutRedirect = stdoutRedirect)
|
||||
ProcessExecutor("ps",
|
||||
di.direct.instance<GlobalPaths>().testsDirectory,
|
||||
timeout = 1.minutes,
|
||||
args = listOf("ps", "-aux"),
|
||||
stdoutRedirect = stdoutRedirect
|
||||
).start()
|
||||
|
||||
val processLines = stdoutRedirect.read().lines().drop(1).map { it.trim() }.filterNot { it.isBlank() }
|
||||
//USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
|
||||
//root 823 0.0 0.0 1576524 8128 ? Ssl дек01 0:08 /usr/bin/containerd
|
||||
@@ -111,14 +115,14 @@ private fun killProcessOnUnix(pid: Int) {
|
||||
check(SystemInfo.isUnix)
|
||||
logOutput("Killing process $pid")
|
||||
|
||||
exec(
|
||||
ProcessExecutor(
|
||||
"kill-process-$pid",
|
||||
di.direct.instance<GlobalPaths>().testsDirectory,
|
||||
timeout = 1.minutes,
|
||||
args = listOf("kill", "-9", pid.toString()),
|
||||
stdoutRedirect = ExecOutputRedirect.ToStdOut("[kill-$pid-out]"),
|
||||
stderrRedirect = ExecOutputRedirect.ToStdOut("[kill-$pid-err]")
|
||||
)
|
||||
).start()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,14 +139,15 @@ fun getJavaProcessId(javaHome: Path, workDir: Path, originalProcessId: Long, ori
|
||||
|
||||
val stdout = ExecOutputRedirect.ToString()
|
||||
val stderr = ExecOutputRedirect.ToString()
|
||||
exec(
|
||||
ProcessExecutor(
|
||||
"jcmd-run",
|
||||
workDir,
|
||||
timeout = 1.minutes,
|
||||
args = listOf(javaHome.resolve("bin/jcmd").toAbsolutePath().toString()),
|
||||
stdoutRedirect = stdout,
|
||||
stderrRedirect = stderr
|
||||
)
|
||||
).start()
|
||||
|
||||
val mergedOutput = stdout.read() + "\n" + stderr.read()
|
||||
val candidates = arrayListOf<Long>()
|
||||
val candidatesFromProcessHandle = arrayListOf<Long>()
|
||||
@@ -213,14 +218,14 @@ fun collectJavaThreadDump(
|
||||
|
||||
val command = listOf(jstackPath.toAbsolutePath().toString(), "-l", javaProcessId.toString())
|
||||
|
||||
exec(
|
||||
ProcessExecutor(
|
||||
"jstack",
|
||||
workDir,
|
||||
timeout = 1.minutes,
|
||||
args = command,
|
||||
stdoutRedirect = ExecOutputRedirect.ToFile(dumpFile.toFile()),
|
||||
stderrRedirect = ExecOutputRedirect.ToStdOut("[jstack-err]")
|
||||
)
|
||||
).start()
|
||||
|
||||
if (includeStdout) {
|
||||
logOutput("jstack output:\n${dumpFile.toFile().readLines().joinToString("\n")}")
|
||||
@@ -229,13 +234,14 @@ fun collectJavaThreadDump(
|
||||
|
||||
fun destroyGradleDaemonProcessIfExists() {
|
||||
val stdout = ExecOutputRedirect.ToString()
|
||||
exec(
|
||||
ProcessExecutor(
|
||||
"get jps process",
|
||||
workDir = null,
|
||||
timeout = 30.seconds,
|
||||
args = listOf("jps", "-l"),
|
||||
stdoutRedirect = stdout
|
||||
)
|
||||
).start()
|
||||
|
||||
logOutput("List of java processes: " + stdout.read())
|
||||
|
||||
if (stdout.read().contains("GradleDaemon")) {
|
||||
|
||||
+10
-2
@@ -2,6 +2,7 @@ package com.intellij.ide.starter.report
|
||||
|
||||
import com.intellij.ide.starter.ci.CIServer
|
||||
import com.intellij.ide.starter.di.di
|
||||
import com.intellij.ide.starter.runner.CurrentTestMethod
|
||||
import com.intellij.ide.starter.utils.convertToHashCodeWithOnlyLetters
|
||||
import com.intellij.ide.starter.utils.generifyErrorMessage
|
||||
import org.kodein.di.direct
|
||||
@@ -14,11 +15,18 @@ import kotlin.io.path.listDirectoryEntries
|
||||
object ErrorReporter {
|
||||
private const val MAX_TEST_NAME_LENGTH = 250
|
||||
|
||||
private fun getTestMethodName(): String {
|
||||
val method = di.direct.instance<CurrentTestMethod>().get()
|
||||
return if (method == null) "" else "${method.declaringClass.name}.${method.name}"
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort things out from errors directories, written by performance testing plugin
|
||||
* Take a look at [com.jetbrains.performancePlugin.ProjectLoaded.reportErrorsFromMessagePool]
|
||||
*/
|
||||
fun reportErrorsAsFailedTests(scriptErrorsDir: Path, contextName: String): List<Pair<File, File>> {
|
||||
val testMethodName = getTestMethodName().ifEmpty { contextName }
|
||||
|
||||
return if (scriptErrorsDir.isDirectory()) {
|
||||
val errorsDirectories = scriptErrorsDir.listDirectoryEntries()
|
||||
|
||||
@@ -30,7 +38,7 @@ object ErrorReporter {
|
||||
val messageText = generifyErrorMessage(messageFile.readText().trim())
|
||||
val stackTraceContent = stacktraceFile.readText().trim()
|
||||
|
||||
var testName: String
|
||||
val testName: String
|
||||
|
||||
val onlyLettersHash = convertToHashCodeWithOnlyLetters(generifyErrorMessage(stackTraceContent).hashCode())
|
||||
|
||||
@@ -44,7 +52,7 @@ object ErrorReporter {
|
||||
}
|
||||
|
||||
val stackTrace = """
|
||||
Test: $contextName
|
||||
Test: $testMethodName
|
||||
|
||||
$stackTraceContent
|
||||
""".trimIndent().trimMargin().trim()
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import com.intellij.ide.starter.report.sarif.TestContextToQodanaSarifMapper
|
||||
object QodanaTestResultPublisher : ReportPublisher {
|
||||
|
||||
override fun publish(ideStartResult: IDEStartResult) {
|
||||
QodanaClient.report(TestContextToQodanaSarifMapper.map(ideStartResult))
|
||||
QodanaClient.report(TestContextToQodanaSarifMapper.map(ideStartResult))
|
||||
}
|
||||
|
||||
}
|
||||
+1
@@ -23,6 +23,7 @@ fun taxa(init: ReportingDescriptor.() -> Unit): ReportingDescriptor {
|
||||
taxa.init()
|
||||
return taxa
|
||||
}
|
||||
|
||||
fun invocation(init: Invocation.() -> Unit): Invocation {
|
||||
val invocation = Invocation()
|
||||
invocation.init()
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ object TestContextToQodanaSarifMapper {
|
||||
fun map(ideStartResult: IDEStartResult): SarifReport {
|
||||
|
||||
val defaultReportPath = this::class.java.classLoader.getResource("sarif/qodana.sarif.json")?.path
|
||||
if(defaultReportPath==null) throw RuntimeException("Default report doesn' exits")
|
||||
if (defaultReportPath == null) throw RuntimeException("Default report doesn' exits")
|
||||
val sarifReport = SarifUtil.readReport(Path.of(defaultReportPath))
|
||||
|
||||
return sarifReport(sarifReport) {
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.intellij.ide.starter.runner
|
||||
|
||||
import java.lang.reflect.Method
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
/**
|
||||
* Container, that pass around test method reference
|
||||
*/
|
||||
object CurrentTestMethod {
|
||||
private lateinit var testMethod: AtomicReference<Method>
|
||||
|
||||
fun set(method: Method) {
|
||||
if (this::testMethod.isInitialized) {
|
||||
testMethod.set(method)
|
||||
}
|
||||
else {
|
||||
testMethod = AtomicReference(method)
|
||||
}
|
||||
}
|
||||
|
||||
fun get(): Method? {
|
||||
return if (this::testMethod.isInitialized) {
|
||||
testMethod.get()
|
||||
}
|
||||
else null
|
||||
}
|
||||
}
|
||||
+47
-30
@@ -3,9 +3,6 @@ package com.intellij.ide.starter.runner
|
||||
import com.intellij.ide.starter.bus.EventState
|
||||
import com.intellij.ide.starter.bus.StarterBus
|
||||
import com.intellij.ide.starter.di.di
|
||||
import com.intellij.ide.starter.exec.ExecOutputRedirect
|
||||
import com.intellij.ide.starter.exec.ExecTimeoutException
|
||||
import com.intellij.ide.starter.exec.exec
|
||||
import com.intellij.ide.starter.ide.CodeInjector
|
||||
import com.intellij.ide.starter.ide.IDETestContext
|
||||
import com.intellij.ide.starter.ide.command.MarshallableCommand
|
||||
@@ -14,12 +11,16 @@ import com.intellij.ide.starter.models.VMOptions
|
||||
import com.intellij.ide.starter.models.andThen
|
||||
import com.intellij.ide.starter.process.collectJavaThreadDump
|
||||
import com.intellij.ide.starter.process.destroyGradleDaemonProcessIfExists
|
||||
import com.intellij.ide.starter.process.exec.ExecOutputRedirect
|
||||
import com.intellij.ide.starter.process.exec.ExecTimeoutException
|
||||
import com.intellij.ide.starter.process.exec.ProcessExecutor
|
||||
import com.intellij.ide.starter.process.getJavaProcessId
|
||||
import com.intellij.ide.starter.profiler.ProfilerInjector
|
||||
import com.intellij.ide.starter.profiler.ProfilerType
|
||||
import com.intellij.ide.starter.report.ErrorReporter
|
||||
import com.intellij.ide.starter.system.SystemInfo
|
||||
import com.intellij.ide.starter.utils.*
|
||||
import kotlinx.coroutines.delay
|
||||
import org.kodein.di.direct
|
||||
import org.kodein.di.instance
|
||||
import java.io.Closeable
|
||||
@@ -27,8 +28,10 @@ import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import kotlin.concurrent.thread
|
||||
import kotlin.io.path.*
|
||||
import kotlin.io.path.absolutePathString
|
||||
import kotlin.io.path.createDirectories
|
||||
import kotlin.io.path.div
|
||||
import kotlin.io.path.listDirectoryEntries
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
@@ -45,7 +48,7 @@ data class IDERunContext(
|
||||
val commands: Iterable<MarshallableCommand> = listOf(),
|
||||
val codeBuilder: (CodeInjector.() -> Unit)? = null,
|
||||
val runTimeout: Duration = 10.minutes,
|
||||
val traceStacksEvery: Duration = 10.minutes,
|
||||
val dumpThreadInterval: Duration = 10.minutes,
|
||||
val useStartupScript: Boolean = true,
|
||||
val closeHandlers: List<IDERunCloseContext.() -> Unit> = listOf(),
|
||||
val verboseOutput: Boolean = false,
|
||||
@@ -72,12 +75,12 @@ data class IDERunContext(
|
||||
|
||||
fun addCompletionHandler(handler: IDERunCloseContext.() -> Unit) = this.copy(closeHandlers = closeHandlers + handler)
|
||||
|
||||
fun uploadProfileResultsToTeamCity(profilerSnapshotsDir: Path, artifactName: String) =
|
||||
fun uploadProfilerResultsToCIServer(profilerSnapshotsDir: Path, artifactName: String) =
|
||||
this.addCompletionHandler {
|
||||
testContext.publishArtifact(source = profilerSnapshotsDir, artifactName = artifactName)
|
||||
}
|
||||
|
||||
fun installProfiler(): IDERunContext {
|
||||
private fun installProfiler(): IDERunContext {
|
||||
return when (val profilerType = testContext.profilerType) {
|
||||
ProfilerType.ASYNC, ProfilerType.YOURKIT -> {
|
||||
val profiler = di.direct.instance<ProfilerInjector>(tag = profilerType)
|
||||
@@ -91,7 +94,7 @@ data class IDERunContext(
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: refactor this
|
||||
// TODO: refactor this https://youtrack.jetbrains.com/issue/AT-18/Simplify-refactor-code-for-starting-IDE-in-IdeRunContext
|
||||
private fun prepareToRunIDE(): IDEStartResult {
|
||||
StarterBus.post(IdeLaunchEvent(EventState.BEFORE, this))
|
||||
|
||||
@@ -109,7 +112,7 @@ data class IDERunContext(
|
||||
val stdout = if (verboseOutput) ExecOutputRedirect.ToStdOut("[ide-${contextName}-out]") else ExecOutputRedirect.ToString()
|
||||
val stderr = ExecOutputRedirect.ToStdOut("[ide-${contextName}-err]")
|
||||
|
||||
var successfulRun = true
|
||||
var isRunSuccessful = true
|
||||
val host by lazy { di.direct.instance<CodeInjector>() }
|
||||
|
||||
try {
|
||||
@@ -182,8 +185,8 @@ data class IDERunContext(
|
||||
File(finalArgs.first()).setExecutable(true)
|
||||
|
||||
val executionTime = measureTime {
|
||||
exec(
|
||||
presentablePurpose = "run-ide-$contextName",
|
||||
ProcessExecutor(
|
||||
presentableName = "run-ide-$contextName",
|
||||
workDir = startConfig.workDir,
|
||||
environmentVariables = extendedEnvVariablesWithJavaHome,
|
||||
timeout = runTimeout,
|
||||
@@ -193,17 +196,16 @@ data class IDERunContext(
|
||||
stderrRedirect = stderr,
|
||||
onProcessCreated = { process, pid ->
|
||||
val javaProcessId by lazy { getJavaProcessId(jdkHome, startConfig.workDir, pid, process) }
|
||||
thread(name = "jstack-${testContext.testName}", isDaemon = true) {
|
||||
var cnt = 0
|
||||
while (process.isAlive) {
|
||||
Thread.sleep(traceStacksEvery.inWholeMilliseconds)
|
||||
if (!process.isAlive) break
|
||||
val monitoringThreadDumpDir = logsDir.resolve("monitoring-thread-dumps").createDirectories()
|
||||
|
||||
val dumpFile = logsDir.resolve("threadDump-${++cnt}-${System.currentTimeMillis()}" + ".txt")
|
||||
logOutput("Dumping threads to $dumpFile")
|
||||
logOutput(Runtime.getRuntime().getRuntimeInfo())
|
||||
catchAll { collectJavaThreadDump(jdkHome, startConfig.workDir, javaProcessId, dumpFile, false) }
|
||||
}
|
||||
var cnt = 0
|
||||
while (process.isAlive) {
|
||||
delay(dumpThreadInterval)
|
||||
if (!process.isAlive) break
|
||||
|
||||
val dumpFile = monitoringThreadDumpDir.resolve("threadDump-${++cnt}-${System.currentTimeMillis()}" + ".txt")
|
||||
logOutput("Dumping threads to $dumpFile")
|
||||
catchAll { collectJavaThreadDump(jdkHome, startConfig.workDir, javaProcessId, dumpFile, false) }
|
||||
}
|
||||
},
|
||||
onBeforeKilled = { process, pid ->
|
||||
@@ -212,7 +214,7 @@ data class IDERunContext(
|
||||
if (collectNativeThreads) {
|
||||
val fileToStoreNativeThreads = logsDir.resolve("native-thread-dumps.txt")
|
||||
startProfileNativeThreads(javaProcessId.toString())
|
||||
Thread.sleep(15.seconds.inWholeMilliseconds)
|
||||
delay(15.seconds)
|
||||
stopProfileNativeThreads(javaProcessId.toString(), fileToStoreNativeThreads.toAbsolutePath().toString())
|
||||
}
|
||||
val dumpFile = logsDir.resolve("threadDump-before-kill-${System.currentTimeMillis()}" + ".txt")
|
||||
@@ -220,7 +222,7 @@ data class IDERunContext(
|
||||
}
|
||||
takeScreenshot(logsDir)
|
||||
}
|
||||
)
|
||||
).start()
|
||||
}
|
||||
|
||||
logOutput("IDE run $contextName completed in $executionTime")
|
||||
@@ -247,7 +249,7 @@ data class IDERunContext(
|
||||
return IDEStartResult(runContext = this, executionTime = executionTime, vmOptionsDiff = vmOptionsDiff, logsDir = logsDir)
|
||||
}
|
||||
catch (t: Throwable) {
|
||||
successfulRun = false
|
||||
isRunSuccessful = false
|
||||
if (t is ExecTimeoutException && !expectedKill) {
|
||||
error("Timeout of IDE run $contextName for $runTimeout")
|
||||
}
|
||||
@@ -281,14 +283,14 @@ data class IDERunContext(
|
||||
}.forEach { it.toFile().deleteRecursively() }
|
||||
|
||||
ErrorReporter.reportErrorsAsFailedTests(logsDir / "script-errors", contextName)
|
||||
val (artifactPath, artifactName) = if (successfulRun) contextName to "logs" else "run/$contextName" to "crash"
|
||||
testContext.publishArtifact(logsDir, artifactPath, formatArtifactName(artifactName, testContext.testName))
|
||||
publishArtifacts(isRunSuccessful)
|
||||
|
||||
if (codeBuilder != null) {
|
||||
host.tearDown(testContext)
|
||||
}
|
||||
|
||||
val closeContext = object : IDERunCloseContext {
|
||||
override val wasRunSuccessful: Boolean = successfulRun
|
||||
override val wasRunSuccessful: Boolean = isRunSuccessful
|
||||
}
|
||||
|
||||
closeHandlers.forEach {
|
||||
@@ -307,9 +309,24 @@ data class IDERunContext(
|
||||
}
|
||||
}
|
||||
|
||||
private fun publishArtifacts(isRunSuccessful: Boolean) {
|
||||
// publish artifacts to directory with a test in any case
|
||||
testContext.publishArtifact(
|
||||
source = testContext.paths.logsDir,
|
||||
artifactPath = contextName,
|
||||
artifactName = formatArtifactName("logs", testContext.testName)
|
||||
)
|
||||
|
||||
if (!isRunSuccessful)
|
||||
testContext.publishArtifact(
|
||||
source = testContext.paths.logsDir,
|
||||
artifactPath = "_crashes/$contextName",
|
||||
artifactName = formatArtifactName("crash", testContext.testName)
|
||||
)
|
||||
}
|
||||
|
||||
fun runIDE(): IDEStartResult {
|
||||
return installProfiler()
|
||||
.prepareToRunIDE()
|
||||
return installProfiler().prepareToRunIDE()
|
||||
}
|
||||
|
||||
private fun deleteSavedAppStateOnMac() {
|
||||
|
||||
+18
-14
@@ -1,5 +1,7 @@
|
||||
package com.intellij.ide.starter.runner
|
||||
|
||||
import com.intellij.ide.starter.bus.EventState
|
||||
import com.intellij.ide.starter.bus.StarterBus
|
||||
import com.intellij.ide.starter.ci.CIServer
|
||||
import com.intellij.ide.starter.di.di
|
||||
import com.intellij.ide.starter.ide.*
|
||||
@@ -22,13 +24,11 @@ import kotlin.io.path.div
|
||||
interface TestContainer<T> : Closeable {
|
||||
val ciServer: CIServer
|
||||
var useLatestDownloadedIdeBuild: Boolean
|
||||
val allContexts: MutableList<IDETestContext>
|
||||
var testContext: IDETestContext
|
||||
val setupHooks: MutableList<IDETestContext.() -> IDETestContext>
|
||||
|
||||
override fun close() {
|
||||
for (context in allContexts) {
|
||||
catchAll { context.paths.close() }
|
||||
}
|
||||
catchAll { testContext.paths.close() }
|
||||
|
||||
logOutput("TestContainer $this disposed")
|
||||
}
|
||||
@@ -48,6 +48,9 @@ interface TestContainer<T> : Closeable {
|
||||
useLatestDownloadedIdeBuild = true
|
||||
} as T
|
||||
|
||||
/**
|
||||
* @return <Build Number, InstalledIde>
|
||||
*/
|
||||
fun resolveIDE(ideInfo: IdeInfo): Pair<String, InstalledIde> {
|
||||
return di.direct.factory<IdeInfo, IdeInstallator>().invoke(ideInfo).install(ideInfo)
|
||||
}
|
||||
@@ -63,10 +66,8 @@ interface TestContainer<T> : Closeable {
|
||||
}
|
||||
|
||||
/** Starting point to run your test */
|
||||
fun initializeTestRunner(testName: String, testCase: TestCase): IDETestContext {
|
||||
check(allContexts.none { it.testName == testName }) { "Test $testName is already initialized. Use another name." }
|
||||
fun initializeTestContext(testName: String, testCase: TestCase): IDETestContext {
|
||||
logOutput("Resolving IDE build for $testName...")
|
||||
|
||||
val (buildNumber, ide) = resolveIDE(testCase.ideInfo)
|
||||
|
||||
require(ide.productCode == testCase.ideInfo.productCode) { "Product code of $ide must be the same as for $testCase" }
|
||||
@@ -78,16 +79,15 @@ interface TestContainer<T> : Closeable {
|
||||
logOutput("IDE to run for $testName: $ide")
|
||||
|
||||
val projectHome = testCase.projectInfo?.downloadAndUnpackProject()
|
||||
val context = IDETestContext(paths, ide, testCase, testName, projectHome, patchVMOptions = { this }, ciServer = ciServer)
|
||||
allContexts += context
|
||||
testContext = IDETestContext(paths, ide, testCase, testName, projectHome, patchVMOptions = { this }, ciServer = ciServer)
|
||||
|
||||
val baseContext = when (testCase.ideInfo == IdeProductProvider.AI) {
|
||||
true -> context
|
||||
testContext = when (testCase.ideInfo == IdeProductProvider.AI) {
|
||||
true -> testContext
|
||||
.addVMOptionsPatch {
|
||||
overrideDirectories(paths)
|
||||
.withEnv("STUDIO_VM_OPTIONS", ide.patchedVMOptionsFile.toString())
|
||||
}
|
||||
false -> context
|
||||
false -> testContext
|
||||
.disableInstantIdeShutdown()
|
||||
.disableFusSendingOnIdeClose()
|
||||
.disableJcef()
|
||||
@@ -101,8 +101,12 @@ interface TestContainer<T> : Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
return setupHooks
|
||||
.fold(baseContext.updateGeneralSettings()) { acc, hook -> acc.hook() }
|
||||
val contextWithAppliedHooks = setupHooks
|
||||
.fold(testContext.updateGeneralSettings()) { acc, hook -> acc.hook() }
|
||||
.apply { installPerformanceTestingPluginIfMissing(this) }
|
||||
|
||||
StarterBus.post(TestContextInitializedEvent(EventState.AFTER, contextWithAppliedHooks))
|
||||
|
||||
return contextWithAppliedHooks
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -9,6 +9,7 @@ import org.kodein.di.instance
|
||||
class TestContainerImpl(
|
||||
override val ciServer: CIServer = di.direct.instance(),
|
||||
override var useLatestDownloadedIdeBuild: Boolean = false,
|
||||
override val allContexts: MutableList<IDETestContext> = mutableListOf(),
|
||||
override val setupHooks: MutableList<IDETestContext.() -> IDETestContext> = mutableListOf()
|
||||
) : TestContainer<TestContainerImpl>
|
||||
) : TestContainer<TestContainerImpl> {
|
||||
override lateinit var testContext: IDETestContext
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.intellij.ide.starter.runner
|
||||
|
||||
import com.intellij.ide.starter.bus.Event
|
||||
import com.intellij.ide.starter.bus.EventState
|
||||
import com.intellij.ide.starter.ide.IDETestContext
|
||||
|
||||
class TestContextInitializedEvent(state: EventState, testContext: IDETestContext) : Event<IDETestContext>(state, testContext)
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.intellij.ide.starter.runner
|
||||
|
||||
import com.intellij.ide.starter.ide.IDETestContext
|
||||
import com.intellij.ide.starter.utils.catchAll
|
||||
import com.intellij.ide.starter.utils.logOutput
|
||||
import com.intellij.util.io.exists
|
||||
import java.util.*
|
||||
|
||||
class TestWatcherActions {
|
||||
private val _onFailureActions: MutableList<(IDETestContext) -> Unit> = Collections.synchronizedList(mutableListOf())
|
||||
val onFailureActions: List<(IDETestContext) -> Unit>
|
||||
get() = synchronized(_onFailureActions) { _onFailureActions.toList() }
|
||||
|
||||
private val _onFinishedActions: MutableList<(IDETestContext) -> Unit> = Collections.synchronizedList(mutableListOf())
|
||||
val onFinishedActions: List<(IDETestContext) -> Unit>
|
||||
get() = synchronized(_onFinishedActions) { _onFinishedActions.toList() }
|
||||
|
||||
companion object {
|
||||
/** Archive and add to test artifact entire ide's `system` dir */
|
||||
fun getSystemDirAsArtifactAction(): (IDETestContext) -> Unit = { testContext ->
|
||||
catchAll {
|
||||
logOutput("Archive with system directory created and will be published to artifacts")
|
||||
testContext.publishArtifact(source = testContext.paths.systemDir, artifactName = "testSystemDirSnapshot.zip")
|
||||
|
||||
val ideaDirPath = testContext.resolvedProjectHome.resolve(".idea")
|
||||
|
||||
if (ideaDirPath.exists()) {
|
||||
logOutput("Archive with .idea dir created and will be published to artifacts")
|
||||
testContext.publishArtifact(source = ideaDirPath, artifactName = ".idea.zip")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun addOnFailureAction(action: (IDETestContext) -> Unit): TestWatcherActions {
|
||||
synchronized(_onFailureActions) { _onFailureActions.add(action) }
|
||||
return this
|
||||
}
|
||||
|
||||
fun addOnFinishedAction(action: (IDETestContext) -> Unit): TestWatcherActions {
|
||||
synchronized(_onFinishedActions) { _onFinishedActions.add(action) }
|
||||
return this
|
||||
}
|
||||
}
|
||||
+14
-10
@@ -73,18 +73,22 @@ object JdkDownloaderFacade {
|
||||
}
|
||||
|
||||
private fun downloadJdkItem(jdk: JdkItem, predicate: JdkPredicate): JdkItemPaths {
|
||||
val targetJdkHome = when (predicate) {
|
||||
JdkPredicate.forWSL() -> {
|
||||
if (SystemInfo.isWindows && WslDistributionManager.getInstance().installedDistributions.isNotEmpty()) {
|
||||
val wslDistribution = WslDistributionManager.getInstance().installedDistributions[0]
|
||||
Path.of(wslDistribution.getWindowsPath("/tmp/jdks/${jdk.installFolderName}"))
|
||||
}
|
||||
else {
|
||||
throw WslDistributionNotFoundException()
|
||||
}
|
||||
val targetJdkHome: Path
|
||||
|
||||
// hack for wsl on windows
|
||||
if (predicate == JdkPredicate.forWSL() && SystemInfo.isWindows && WslDistributionManager.getInstance().installedDistributions.isNotEmpty()) {
|
||||
try {
|
||||
val wslDistribution = WslDistributionManager.getInstance().installedDistributions[0]
|
||||
targetJdkHome = Path.of(wslDistribution.getWindowsPath("/tmp/jdks/${jdk.installFolderName}"))
|
||||
}
|
||||
catch (_: Exception) {
|
||||
throw WslDistributionNotFoundException(predicate)
|
||||
}
|
||||
else -> di.direct.instance<GlobalPaths>().getCacheDirectoryFor("jdks").resolve(jdk.installFolderName)
|
||||
}
|
||||
else {
|
||||
targetJdkHome = di.direct.instance<GlobalPaths>().getCacheDirectoryFor("jdks").resolve(jdk.installFolderName)
|
||||
}
|
||||
|
||||
val targetHomeMarker = targetJdkHome.resolve("home.link")
|
||||
logOutput("Checking JDK at $targetJdkHome")
|
||||
|
||||
|
||||
+2
@@ -19,6 +19,8 @@ object SystemInfo {
|
||||
val isUnix = !isWindows
|
||||
val isXWindow = isUnix && !isMac
|
||||
|
||||
val isAarch64: Boolean = OS_ARCH == "aarch64"
|
||||
|
||||
private fun getRtVersion(fallback: String): String? {
|
||||
val rtVersion = System.getProperty("java.runtime.version")
|
||||
return if (Character.isDigit(rtVersion[0])) rtVersion else fallback
|
||||
|
||||
+5
-5
@@ -1,9 +1,9 @@
|
||||
package com.intellij.ide.starter.utils
|
||||
|
||||
import com.intellij.ide.starter.di.di
|
||||
import com.intellij.ide.starter.exec.ExecOutputRedirect
|
||||
import com.intellij.ide.starter.exec.exec
|
||||
import com.intellij.ide.starter.path.GlobalPaths
|
||||
import com.intellij.ide.starter.process.exec.ExecOutputRedirect
|
||||
import com.intellij.ide.starter.process.exec.ProcessExecutor
|
||||
import com.intellij.ide.starter.system.SystemInfo
|
||||
import org.kodein.di.instance
|
||||
import org.rauschig.jarchivelib.ArchiveFormat
|
||||
@@ -129,13 +129,13 @@ object FileSystem {
|
||||
}
|
||||
else if (SystemInfo.isLinux || SystemInfo.isMac) {
|
||||
Files.createDirectories(targetDir)
|
||||
exec(
|
||||
presentablePurpose = "extract-tar",
|
||||
ProcessExecutor(
|
||||
presentableName = "extract-tar",
|
||||
workDir = targetDir,
|
||||
timeout = 10.minutes,
|
||||
stderrRedirect = ExecOutputRedirect.ToStdOut("tar"),
|
||||
args = listOf("tar", "-z", "-x", "-f", tarFile.toAbsolutePath().toString(), "-C", targetDir.toAbsolutePath().toString())
|
||||
)
|
||||
).start()
|
||||
}
|
||||
}
|
||||
catch (e: Exception) {
|
||||
|
||||
+8
-6
@@ -1,7 +1,7 @@
|
||||
package com.intellij.ide.starter.utils
|
||||
|
||||
import com.intellij.ide.starter.exec.ExecOutputRedirect
|
||||
import com.intellij.ide.starter.exec.exec
|
||||
import com.intellij.ide.starter.process.exec.ExecOutputRedirect
|
||||
import com.intellij.ide.starter.process.exec.ProcessExecutor
|
||||
import java.io.IOException
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
@@ -15,12 +15,14 @@ object Git {
|
||||
@Throws(IOException::class, InterruptedException::class)
|
||||
private fun getLocalGitBranch(): String {
|
||||
val stdout = ExecOutputRedirect.ToString()
|
||||
exec(
|
||||
|
||||
ProcessExecutor(
|
||||
"git-local-branch-get",
|
||||
workDir = null, timeout = 1.minutes,
|
||||
args = listOf("git", "rev-parse", "--abbrev-ref", "HEAD"),
|
||||
stdoutRedirect = stdout
|
||||
)
|
||||
).start()
|
||||
|
||||
return stdout.read().trim()
|
||||
}
|
||||
|
||||
@@ -41,12 +43,12 @@ object Git {
|
||||
val stdout = ExecOutputRedirect.ToString()
|
||||
|
||||
try {
|
||||
exec(
|
||||
ProcessExecutor(
|
||||
"git-repo-root-get",
|
||||
workDir = null, timeout = 1.minutes,
|
||||
args = listOf("git", "rev-parse", "--show-toplevel", "HEAD"),
|
||||
stdoutRedirect = stdout
|
||||
)
|
||||
).start()
|
||||
}
|
||||
catch (e: Exception) {
|
||||
val workDir = Paths.get("").toAbsolutePath()
|
||||
|
||||
+1
@@ -11,6 +11,7 @@ import kotlin.io.path.name
|
||||
fun String.hyphenateTestName(): String {
|
||||
|
||||
fun hyphenateString(input: String) = input
|
||||
.replace(Regex("( )+"), "-")
|
||||
.replace(" ", "-").trim()
|
||||
.replaceFirstChar { it.lowercase(Locale.getDefault()) }.toCharArray()
|
||||
.map {
|
||||
|
||||
+35
-23
@@ -1,9 +1,9 @@
|
||||
package com.intellij.ide.starter.utils
|
||||
|
||||
import com.intellij.ide.starter.di.di
|
||||
import com.intellij.ide.starter.exec.ExecOutputRedirect
|
||||
import com.intellij.ide.starter.exec.exec
|
||||
import com.intellij.ide.starter.path.GlobalPaths
|
||||
import com.intellij.ide.starter.process.exec.ExecOutputRedirect
|
||||
import com.intellij.ide.starter.process.exec.ProcessExecutor
|
||||
import com.intellij.ide.starter.system.SystemInfo
|
||||
import org.kodein.di.direct
|
||||
import org.kodein.di.instance
|
||||
@@ -31,13 +31,18 @@ fun getThrowableText(t: Throwable): String {
|
||||
return writer.buffer.toString()
|
||||
}
|
||||
|
||||
inline fun catchAll(action: () -> Unit) {
|
||||
/**
|
||||
* In case of success - return T
|
||||
* In case of error - print error to stderr and return null
|
||||
*/
|
||||
inline fun <T> catchAll(action: () -> T): T? {
|
||||
try {
|
||||
action()
|
||||
return action()
|
||||
}
|
||||
catch (t: Throwable) {
|
||||
logError("CatchAll swallowed error: ${t.message}")
|
||||
logError(getThrowableText(t))
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,14 +76,14 @@ fun execJavaCmd(javaHome: Path, args: Iterable<String> = listOf()): List<String>
|
||||
|
||||
val processArguments = listOf(java.toString()).plus(args)
|
||||
|
||||
exec(
|
||||
presentablePurpose = prefix,
|
||||
ProcessExecutor(
|
||||
presentableName = prefix,
|
||||
workDir = javaHome,
|
||||
timeout = 1.minutes,
|
||||
args = processArguments,
|
||||
stdoutRedirect = stdout,
|
||||
stderrRedirect = stderr
|
||||
)
|
||||
).start()
|
||||
|
||||
val mergedOutput = listOf(stdout, stderr)
|
||||
.flatMap { it.read().split(System.lineSeparator()) }
|
||||
@@ -184,14 +189,14 @@ fun takeScreenshot(logsDir: Path) {
|
||||
|
||||
val toolPath = screenshotTool.resolve("$toolName.jar")
|
||||
val javaPath = ProcessHandle.current().info().command().orElseThrow().toString()
|
||||
exec(
|
||||
presentablePurpose = "take-screenshot",
|
||||
ProcessExecutor(
|
||||
presentableName = "take-screenshot",
|
||||
workDir = toolsDir,
|
||||
timeout = 15.seconds,
|
||||
args = mutableListOf(javaPath, "-jar", toolPath.absolutePathString(), screenshotFile.toString()),
|
||||
environmentVariables = mapOf("DISPLAY" to ":88"),
|
||||
onlyEnrichExistedEnvVariables = true
|
||||
)
|
||||
).start()
|
||||
|
||||
if (screenshotFile.exists()) {
|
||||
logOutput("Screenshot saved in $screenshotFile")
|
||||
@@ -204,32 +209,38 @@ fun takeScreenshot(logsDir: Path) {
|
||||
fun startProfileNativeThreads(pid: String) {
|
||||
if (!SystemInfo.isWindows) {
|
||||
val toolsDir = di.direct.instance<GlobalPaths>().getCacheDirectoryFor("tools")
|
||||
val toolName = "async-profiler-2.7-macos"
|
||||
val toolName = when {
|
||||
SystemInfo.isMac -> "async-profiler-2.7-macos"
|
||||
SystemInfo.isLinux -> "async-profiler-2.7-linux-x64"
|
||||
else -> error("Not supported OS")
|
||||
}
|
||||
val profiler = toolsDir / toolName
|
||||
downloadAsyncProfilerIfNeeded(profiler, toolsDir)
|
||||
givePermissionsToExecutables(profiler)
|
||||
exec(
|
||||
presentablePurpose = "start-profile",
|
||||
|
||||
ProcessExecutor(
|
||||
presentableName = "start-profile",
|
||||
workDir = profiler,
|
||||
timeout = 15.seconds,
|
||||
args = mutableListOf("./profiler.sh", "start", pid)
|
||||
)
|
||||
).start()
|
||||
}
|
||||
}
|
||||
|
||||
private fun givePermissionsToExecutables(profiler: Path) {
|
||||
exec(
|
||||
presentablePurpose = "give-permissions-to-jattach",
|
||||
ProcessExecutor(
|
||||
presentableName = "give-permissions-to-jattach",
|
||||
workDir = profiler.resolve("build"),
|
||||
timeout = 10.seconds,
|
||||
args = mutableListOf("chmod", "+x", "jattach")
|
||||
)
|
||||
exec(
|
||||
presentablePurpose = "give-permissions-to-profiler",
|
||||
).start()
|
||||
|
||||
ProcessExecutor(
|
||||
presentableName = "give-permissions-to-profiler",
|
||||
workDir = profiler,
|
||||
timeout = 10.seconds,
|
||||
args = mutableListOf("chmod", "+x", "profiler.sh")
|
||||
)
|
||||
).start()
|
||||
}
|
||||
|
||||
fun stopProfileNativeThreads(pid: String, fileToStoreInfo: String) {
|
||||
@@ -237,12 +248,13 @@ fun stopProfileNativeThreads(pid: String, fileToStoreInfo: String) {
|
||||
val toolsDir = di.direct.instance<GlobalPaths>().getCacheDirectoryFor("tools")
|
||||
val toolName = "async-profiler-2.7-macos"
|
||||
val profiler = toolsDir / toolName
|
||||
exec(
|
||||
presentablePurpose = "stop-profile",
|
||||
|
||||
ProcessExecutor(
|
||||
presentableName = "stop-profile",
|
||||
workDir = profiler,
|
||||
timeout = 15.seconds,
|
||||
args = mutableListOf("./profiler.sh", "stop", pid, "-f", fileToStoreInfo)
|
||||
)
|
||||
).start()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -3,8 +3,9 @@ package com.intellij.ide.starter.wsl
|
||||
import com.intellij.execution.wsl.WslDistributionManager
|
||||
import com.intellij.ide.starter.system.SystemInfo
|
||||
import com.intellij.ide.starter.utils.logOutput
|
||||
import com.intellij.openapi.projectRoots.impl.jdkDownloader.JdkPredicate
|
||||
|
||||
class WslDistributionNotFoundException() : Exception() {
|
||||
class WslDistributionNotFoundException(val jdkPredicate: JdkPredicate? = null) : Exception() {
|
||||
override val message: String
|
||||
get() {
|
||||
val red = "\u001b[31m"
|
||||
@@ -31,6 +32,7 @@ class WslDistributionNotFoundException() : Exception() {
|
||||
appendLine("Can't run test on WSL")
|
||||
appendLine("Current OS: ${SystemInfo.OS_NAME} ${SystemInfo.OS_VERSION}")
|
||||
appendLine("WSL distributions installed: ${WslDistributionManager.getInstance().installedDistributions}")
|
||||
jdkPredicate?.let { appendLine(jdkPredicate) }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user