christophsturm / filepeek

peek into kotlin or java source files.
MIT License
4 stars 6 forks source link

FilePeek not working in MPP scenario #9

Open bkahlert opened 3 years ago

bkahlert commented 3 years ago

Hey Christoph, first of all. Compliments! Your tiny little helper is amazing. Thanks to it I managed to implement some kind of JUnit-Strikt crossover where all descriptors / test names are optional:

image

Here's the problem: It doesn't work with Kotlin's MPP file layout but just be easily fixed as the code simply missed the right directory by level: namely jvm. In my setting (Kotlin 1.4.21 and Gradle 6.8) FilePeek starts to look at

There is nothing that can be done on the configuration side by what I can see. Providing source roots does not help because the when block

 val buildDir = when {
            classFilePath.contains("${FS}out${FS}") -> "out${FS}test${FS}classes" // running inside IDEA
            classFilePath.contains("build${FS}classes${FS}java") -> "build${FS}classes${FS}java${FS}test" // gradle 4.x java source
            classFilePath.contains("build${FS}classes${FS}kotlin") -> "build${FS}classes${FS}kotlin${FS}test" // gradle 4.x kotlin sources
            classFilePath.contains("target${FS}classes") -> "target${FS}classes" // maven
            else -> "build${FS}classes${FS}test" // older gradle
        }

does to finish with a valid search pattern for the replacement.

bkahlert commented 3 years ago

An ugly as ugly can be workaround that works for my time being is

 val (matchDir, buildDir) = when {
            classFilePath.contains("${FS}out${FS}") -> "${FS}out${FS}" to "out${FS}test${FS}classes" // running inside IDEA
            classFilePath.contains("build${FS}classes${FS}java") -> "build${FS}classes${FS}java" to "build${FS}classes${FS}java${FS}test" // gradle 4.x java source
            classFilePath.contains("build${FS}classes${FS}kotlin") -> "build${FS}classes${FS}kotlin" to "build${FS}classes${FS}kotlin${FS}test" // gradle 4.x kotlin sources
            classFilePath.contains("target${FS}classes") -> "target${FS}classes" to "target${FS}classes" // maven
            else -> "build${FS}classes${FS}test" to "build${FS}classes${FS}test" // older gradle
        }

        val sourceFileCandidates: List<File> = this.sourceRoots
            .map { sourceRoot ->
                val replace = classFilePath.replace(buildDir, sourceRoot)
                val sourceFileWithoutExtension =
                    replace
                        .plus(FS + className.replace(".", FS))

                File(sourceFileWithoutExtension).parentFile
                    .resolve(callerStackTraceElement.fileName!!)
            }.let {
                val (baseDir, suffix) = classFilePath.split(matchDir).let {
                    val baseDir = it.first()
                    val suffixDir = it.last().withoutPrefix(FS).replace(FS, "-").convertKebabCaseToCamelCase()
                    baseDir to suffixDir
                }
                val sourceDir = baseDir.asPath().resolve("src").resolve(suffix).resolve("kotlin")
                val sourceFileWithoutExtension = sourceDir.resolve(className.replace(".", FS))

                it + sourceFileWithoutExtension.parent
                    .resolve(callerStackTraceElement.fileName!!).toFile()
            }

Basically I compute a third default candidate that only removes the "contains" pattern from the class path and uses the sanitized right half of the split path (here: /jvm/testjvm/test) to heuristically map to jvmTest which leads me to the right directory.

bkahlert commented 3 years ago

I just recognized there seems to be a problem with inlined functions as in this stack trace element: koodies.io.path.LocationsTest$paths$1$invoke$$inlined$asA$1.invoke(Tests.kt:420) FilePeek takes koodies/io/path/LocationsTest as the sourceFileWithoutExtension and replaces the whole file LocationsTest with Tests.kt. imho only the extension should be appended as the name already correctly states.

christophsturm commented 2 years ago

sorry i totally missed this issue, i was under the impression nobody uses filepeek. can you supply a test case for the problem with inlined functions?