IDE: Fix friendly displaying of K/N KLIBs with components
Issue #KT-36213
This commit is contained in:
+33
-7
@@ -60,7 +60,9 @@ class KlibInfoProvider(
|
||||
val libraryPath = libraryFile.toPath()
|
||||
|
||||
val origin = detectOrigin(libraryPath) ?: return null
|
||||
val manifest = loadProperties(libraryPath.resolve(KLIB_MANIFEST_FILE_NAME))
|
||||
|
||||
val manifestFile = findManifestFile(libraryPath) ?: return null
|
||||
val manifest = loadProperties(manifestFile)
|
||||
|
||||
val name = manifest.getProperty(KLIB_PROPERTY_UNIQUE_NAME) ?: return null
|
||||
val target = (detectTarget(libraryPath) ?: return null).result
|
||||
@@ -84,15 +86,39 @@ class KlibInfoProvider(
|
||||
else -> null
|
||||
}
|
||||
|
||||
private fun findManifestFile(libraryPath: Path): Path? {
|
||||
libraryPath.resolve(KLIB_MANIFEST_FILE_NAME).let { propertiesPath ->
|
||||
// KLIB layout without components
|
||||
if (isRegularFile(propertiesPath)) return propertiesPath
|
||||
}
|
||||
|
||||
if (!isDirectory(libraryPath)) return null
|
||||
|
||||
// look up through all components and find all manifest files
|
||||
val candidates = newDirectoryStream(libraryPath).use { stream ->
|
||||
stream.mapNotNull { componentPath ->
|
||||
val candidate = componentPath.resolve(KLIB_MANIFEST_FILE_NAME)
|
||||
if (isRegularFile(candidate)) candidate else null
|
||||
}
|
||||
}
|
||||
|
||||
return when (candidates.size) {
|
||||
0 -> null
|
||||
1 -> candidates.single()
|
||||
else -> {
|
||||
// there are multiple components, let's take just the first one alphabetically
|
||||
candidates.minBy { it.getName(it.nameCount - 2).toString() }!!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadProperties(propertiesPath: Path): Properties = cachedProperties.computeIfAbsent(propertiesPath) {
|
||||
val properties = Properties()
|
||||
|
||||
if (isRegularFile(propertiesPath)) {
|
||||
try {
|
||||
newInputStream(propertiesPath).use { properties.load(it) }
|
||||
} catch (_: IOException) {
|
||||
// do nothing
|
||||
}
|
||||
try {
|
||||
newInputStream(propertiesPath).use { properties.load(it) }
|
||||
} catch (_: IOException) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
properties
|
||||
|
||||
+56
-43
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.configuration.klib
|
||||
|
||||
import com.intellij.testFramework.PlatformTestUtil.getTestName
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils.getHomeDirectory
|
||||
@@ -12,7 +13,16 @@ import java.io.File
|
||||
|
||||
class KlibInfoProviderTest : TestCase() {
|
||||
|
||||
fun testKlibsFromNativeDistributionRecognized() {
|
||||
fun testOldStyleKlibsFromNativeDistributionRecognized() = doTest()
|
||||
|
||||
fun testKlibsFromNativeDistributionWithSingleComponentRecognized() = doTest()
|
||||
|
||||
fun testKlibsFromNativeDistributionWithMultipleComponentsRecognized() = doTest()
|
||||
|
||||
private fun doTest() {
|
||||
val kotlinNativeHome = testDataDir.resolve(getTestName(name, true)).resolve("kotlin-native-PLATFORM-VERSION")
|
||||
val sourcesDir = kotlinNativeHome.resolve("sources")
|
||||
|
||||
val klibProvider = KlibInfoProvider(kotlinNativeHome = kotlinNativeHome)
|
||||
|
||||
val potentialKlibPaths = mutableListOf<File>()
|
||||
@@ -22,7 +32,12 @@ class KlibInfoProviderTest : TestCase() {
|
||||
|
||||
val actualKlibs = potentialKlibPaths
|
||||
.mapNotNull { klibProvider.getKlibInfo(it) as? NativeDistributionKlibInfo }
|
||||
.associateBy { it.path.relativeTo(testDataDir) }
|
||||
.associateBy { it.path.relativeTo(kotlinNativeHome) }
|
||||
|
||||
val expectedKlibsFromDistribution = generateExpectedKlibsFromDistribution(
|
||||
kotlinNativeHome = kotlinNativeHome,
|
||||
sourcesDir = sourcesDir
|
||||
)
|
||||
|
||||
assertEquals(expectedKlibsFromDistribution.keys, actualKlibs.keys)
|
||||
for (klibPath in actualKlibs.keys) {
|
||||
@@ -40,52 +55,50 @@ class KlibInfoProviderTest : TestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateExpectedKlibsFromDistribution(kotlinNativeHome: File, sourcesDir: File) = listOf(
|
||||
NativeDistributionKlibInfo(
|
||||
path = kotlinNativeHome.resolve("klib", "common", "stdlib"),
|
||||
sourcePaths = listOf(
|
||||
sourcesDir.resolve("kotlin-stdlib-native-sources.zip"),
|
||||
sourcesDir.resolve("kotlin-test-anotations-common-sources.zip")
|
||||
),
|
||||
name = "stdlib",
|
||||
target = null
|
||||
),
|
||||
NativeDistributionKlibInfo(
|
||||
path = kotlinNativeHome.resolve("klib", "common", "kotlinx-cli"),
|
||||
sourcePaths = listOf(
|
||||
sourcesDir.resolve("kotlinx-cli-common-sources.zip"),
|
||||
sourcesDir.resolve("kotlinx-cli-native-sources.zip")
|
||||
),
|
||||
name = "kotlinx-cli",
|
||||
target = null
|
||||
),
|
||||
NativeDistributionKlibInfo(
|
||||
path = kotlinNativeHome.resolve("klib", "platform", "macos_x64", "foo"),
|
||||
sourcePaths = emptyList(),
|
||||
name = "foo",
|
||||
target = KonanTarget.MACOS_X64
|
||||
),
|
||||
NativeDistributionKlibInfo(
|
||||
path = kotlinNativeHome.resolve("klib", "platform", "macos_x64", "bar"),
|
||||
sourcePaths = emptyList(),
|
||||
name = "bar",
|
||||
target = KonanTarget.MACOS_X64
|
||||
),
|
||||
NativeDistributionKlibInfo(
|
||||
path = kotlinNativeHome.resolve("klib", "platform", "macos_x64", "baz"),
|
||||
sourcePaths = emptyList(),
|
||||
name = "baz",
|
||||
target = KonanTarget.MACOS_X64
|
||||
)
|
||||
).associateBy { it.path.relativeTo(kotlinNativeHome) }
|
||||
|
||||
companion object {
|
||||
private val testDataDir = File(getHomeDirectory() + "/idea/testData/configuration/klib")
|
||||
.also { assertTrue("Test data directory does not exist: $it", it.isDirectory) }
|
||||
|
||||
private val externalLibsDir = testDataDir.resolve("external-libs")
|
||||
private val kotlinNativeHome = testDataDir.resolve("kotlin-native-PLATFORM-VERSION")
|
||||
private val sourcesDir = kotlinNativeHome.resolve("sources")
|
||||
|
||||
private val expectedKlibsFromDistribution = listOf(
|
||||
NativeDistributionKlibInfo(
|
||||
path = kotlinNativeHome.resolve("klib", "common", "stdlib"),
|
||||
sourcePaths = listOf(
|
||||
sourcesDir.resolve("kotlin-stdlib-native-sources.zip"),
|
||||
sourcesDir.resolve("kotlin-test-anotations-common-sources.zip")
|
||||
),
|
||||
name = "stdlib",
|
||||
target = null
|
||||
),
|
||||
NativeDistributionKlibInfo(
|
||||
path = kotlinNativeHome.resolve("klib", "common", "kotlinx-cli"),
|
||||
sourcePaths = listOf(
|
||||
sourcesDir.resolve("kotlinx-cli-common-sources.zip"),
|
||||
sourcesDir.resolve("kotlinx-cli-native-sources.zip")
|
||||
),
|
||||
name = "kotlinx-cli",
|
||||
target = null
|
||||
),
|
||||
NativeDistributionKlibInfo(
|
||||
path = kotlinNativeHome.resolve("klib", "platform", "macos_x64", "foo"),
|
||||
sourcePaths = emptyList(),
|
||||
name = "foo",
|
||||
target = KonanTarget.MACOS_X64
|
||||
),
|
||||
NativeDistributionKlibInfo(
|
||||
path = kotlinNativeHome.resolve("klib", "platform", "macos_x64", "bar"),
|
||||
sourcePaths = emptyList(),
|
||||
name = "bar",
|
||||
target = KonanTarget.MACOS_X64
|
||||
),
|
||||
NativeDistributionKlibInfo(
|
||||
path = kotlinNativeHome.resolve("klib", "platform", "macos_x64", "baz"),
|
||||
sourcePaths = emptyList(),
|
||||
name = "baz",
|
||||
target = KonanTarget.MACOS_X64
|
||||
)
|
||||
).associateBy { it.path.relativeTo(testDataDir) }
|
||||
|
||||
private fun File.children(): List<File> = (listFiles()?.toList() ?: emptyList())
|
||||
.also { assertTrue("$this does not have children files or directories", it.isNotEmpty()) }
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
SPOILED_unique_name=anotherBroken
|
||||
@@ -0,0 +1 @@
|
||||
SPOILED_unique_name=invalid2
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=invalid3
|
||||
-1
@@ -1 +0,0 @@
|
||||
unique_name=yetAnotherBroken
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=kotlinx-cli
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=stdlib
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=bar
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=baz
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=foo
|
||||
+1
@@ -0,0 +1 @@
|
||||
SPOILED_unique_name=invalid2
|
||||
+1
@@ -0,0 +1 @@
|
||||
SPOILED_unique_name=invalid2
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=invalid3
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=invalid3
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=kotlinx-cli
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=stdlib
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=bar
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=baz
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=foo
|
||||
+1
@@ -0,0 +1 @@
|
||||
SPOILED_unique_name=invalid2
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=invalid3
|
||||
+1
@@ -0,0 +1 @@
|
||||
// this file is empty
|
||||
BIN
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
// this file is empty
|
||||
+1
@@ -0,0 +1 @@
|
||||
// this file is empty
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
// this file is empty
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
-1
@@ -1 +0,0 @@
|
||||
SPOILED_unique_name=broken
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=kotlinx-cli
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=stdlib
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=bar
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=baz
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=foo
|
||||
+1
@@ -0,0 +1 @@
|
||||
SPOILED_unique_name=invalid2
|
||||
+1
@@ -0,0 +1 @@
|
||||
unique_name=invalid3
|
||||
+1
@@ -0,0 +1 @@
|
||||
// this file is empty
|
||||
BIN
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
// this file is empty
|
||||
+1
@@ -0,0 +1 @@
|
||||
// this file is empty
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
// this file is empty
|
||||
BIN
Binary file not shown.
Reference in New Issue
Block a user