Skip to content

Commit

Permalink
fix tab-completion in distribution (#5308)
Browse files Browse the repository at this point in the history
* fix tab-completion in distribution

the `removeModuleInfoFromJars` hack only get's triggered for
`Universal/stage` - our release uses `Universal/packageBin` and that
doesn't seem to reuse anything related that we could trigger on
unfortunately...
So I thought it's easiest to just add the same hack to the start
script...

re #4625 (comment)

* abs dir

* handle both Universal/packageBin and stage: adapt mappings

* remove hack from start script

* refactor

* fix copy pasta

* simplify based on PR discussion
  • Loading branch information
mpollmeier authored Feb 17, 2025
1 parent b5fe810 commit 35dacc9
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 23 deletions.
39 changes: 17 additions & 22 deletions joern-cli/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -129,28 +129,23 @@ generateScaladocs := {
out
}

Universal / packageBin / mappings ++= sbt.Path.directory(new File("joern-cli/src/main/resources/scripts"))

lazy val removeModuleInfoFromJars = taskKey[Unit]("remove module-info.class from dependency jars - a hacky workaround for a scala3 compiler bug https://github.com/scala/scala3/issues/20421")
removeModuleInfoFromJars := {
import java.nio.file.{Files, FileSystems}
val logger = streams.value.log
val libDir = (Universal/stagingDirectory).value / "lib"

// remove all `/module-info.class` from all jars
Files.walk(libDir.toPath)
.filter(_.toString.endsWith(".jar"))
.forEach { jar =>
val zipFs = FileSystems.newFileSystem(jar)
zipFs.getRootDirectories.forEach { zipRootDir =>
Files.list(zipRootDir).filter(_.toString == "/module-info.class").forEach { moduleInfoClass =>
logger.info(s"workaround for scala completion bug: deleting $moduleInfoClass from $jar")
Files.delete(moduleInfoClass)
}
}
zipFs.close()
}
Universal/mappings ++= sbt.Path.directory(new File("joern-cli/src/main/resources/scripts"))

// remove module-info.class from dependency jars - a hacky workaround for a scala3 compiler bug
// see https://github.com/scala/scala3/issues/20421
val moduleInfoLocation = "module-info.class"
Universal/mappings := (Universal/mappings).value.collect {
case (jar, location)
if location.startsWith("lib")
&& location.endsWith(".jar")
&& FileUtils.jarContainsEntryInRoot(jar, moduleInfoLocation) =>
val newJar = target.value / "without-module-info" / jar.getName()
IO.copyFile(jar, newJar)
FileUtils.removeJarEntryFromRoot(newJar, moduleInfoLocation)
streams.value.log.info(s"workaround for scala completion bug: including a modified version of $jar without the $moduleInfoLocation entry: $newJar")
newJar -> location
case other =>
other // no need to change anything
}
removeModuleInfoFromJars := removeModuleInfoFromJars.triggeredBy(Universal/stage).value

maintainer := "[email protected]"
23 changes: 22 additions & 1 deletion project/FileUtils.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import java.io.File
import java.nio.file.Files
import java.nio.file.{Files, FileSystems}
import scala.collection.JavaConverters._

object FileUtils {
Expand All @@ -19,4 +19,25 @@ object FileUtils {
}
}

/** checks if the given jar contains the given entry in the root directory
*/
def jarContainsEntryInRoot(jar: File, entry: String): Boolean = {
val zipFs = FileSystems.newFileSystem(jar.toPath)
val result = zipFs.getRootDirectories.asScala.exists { zipRootDir =>
Files.list(zipRootDir).iterator.asScala.exists(_.getFileName.toString == entry)
}
zipFs.close()
result
}

/** removes the given entry from the given jar, only at root level */
def removeJarEntryFromRoot(jar: File, entry: String): Unit = {
val zipFs = FileSystems.newFileSystem(jar.toPath)
zipFs.getRootDirectories.forEach { zipRootDir =>
Files.list(zipRootDir).filter(_.getFileName.toString == entry).forEach(Files.delete(_))
}
zipFs.close()
}


}

0 comments on commit 35dacc9

Please sign in to comment.