Skip to content

Commit

Permalink
external commands (astgen, php-parser etc.): fix and consolidate base…
Browse files Browse the repository at this point in the history
… dir (#4956)

The logic to guess the base dir of the installation is quite fiddly but
works for our use cases for astgen. PhpParser implemented something similar, but
not quite - and it failed for buildbot.

On buildbot the installation path for php2cpg is
`/worker/sptestV2-php2cpg/build/x2cpg-internal/php2cpg/target/universal/stage`
which (prior to this PR) leads to an invalid derived php-parser name
and the following error:
```
2024-09-25 09:30:08.623 ERROR Invalid path for PhpParserBin: /worker/sptestV2-/php2cpg/bin/php-parser/php-parser.php
```
  • Loading branch information
mpollmeier authored Oct 7, 2024
1 parent 2935a1f commit 488fd7b
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,11 @@ object PhpParser {
}

private def defaultPhpParserBin: String = {
val dir = Paths.get(this.getClass.getProtectionDomain.getCodeSource.getLocation.toURI).toAbsolutePath.toString
val fixedDir = new java.io.File(dir.substring(0, dir.indexOf("php2cpg"))).toString
Paths.get(fixedDir, "php2cpg", "bin", "php-parser", "php-parser.php").toAbsolutePath.toString
val packagePath = Paths.get(this.getClass.getProtectionDomain.getCodeSource.getLocation.toURI)
ExternalCommand
.executableDir(packagePath)
.resolve("php-parser/php-parser.php")
.toString
}

private def configOverrideOrDefaultPath(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,11 @@ object AstGenRunner {
packagePath: URL
)

def executableDir(implicit metaData: AstGenProgramMetaData): String = {
val dir = metaData.packagePath.toString
val indexOfLib = dir.lastIndexOf("lib")
val fixedDir = if (indexOfLib != -1) {
new java.io.File(dir.substring("file:".length, indexOfLib)).toString
} else {
val indexOfTarget = dir.lastIndexOf("target")
if (indexOfTarget != -1) {
new java.io.File(dir.substring("file:".length, indexOfTarget)).toString
} else {
"."
}
}
Paths.get(fixedDir, "/bin/astgen").toAbsolutePath.toString
}
def executableDir(implicit metaData: AstGenProgramMetaData): String =
ExternalCommand
.executableDir(Paths.get(metaData.packagePath.toURI))
.resolve("astgen")
.toString

def hasCompatibleAstGenVersion(compatibleVersion: String)(implicit metaData: AstGenProgramMetaData): Boolean = {
ExternalCommand.run(s"$metaData.name -version", ".").toOption.map(_.mkString.strip()) match {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.joern.x2cpg.utils

import java.io.File
import java.net.URL
import java.nio.file.{Path, Paths}
import java.util.concurrent.ConcurrentLinkedQueue
import scala.sys.process.{Process, ProcessLogger}
import scala.util.{Failure, Success, Try}
Expand Down Expand Up @@ -53,4 +55,30 @@ trait ExternalCommand {
}
}

object ExternalCommand extends ExternalCommand
object ExternalCommand extends ExternalCommand {

/** Finds the absolute path to the executable directory (e.g. `/path/to/javasrc2cpg/bin`). Based on the package path
* of a loaded classfile based on some (potentially flakey?) filename heuristics. Context: we want to be able to
* invoke the x2cpg frontends from any directory, not just their install directory, and then invoke other
* executables, like astgen, php-parser et al.
*/
def executableDir(packagePath: Path): Path = {
val packagePathAbsolute = packagePath.toAbsolutePath
val fixedDir =
if (packagePathAbsolute.toString.contains("lib")) {
var dir = packagePathAbsolute
while (dir.toString.contains("lib"))
dir = dir.getParent
dir
} else if (packagePathAbsolute.toString.contains("target")) {
var dir = packagePathAbsolute
while (dir.toString.contains("target"))
dir = dir.getParent
dir
} else {
Paths.get(".")
}

fixedDir.resolve("bin/").toAbsolutePath
}
}

0 comments on commit 488fd7b

Please sign in to comment.