
com.codacy.plugins.utils.BinaryDockerHelper.scala Maven / Gradle / Ivy
package com.codacy.plugins.utils
import java.nio.file.{Files, Path}
import com.codacy.plugins.api.PatternDescription
import com.codacy.plugins.runners.{DockerConstants, IDocker}
import com.codacy.plugins.utils.impl.CacheDockerHelper
import scala.util.{Properties, Try}
class BinaryDockerHelper(useCachedDocs: Boolean = true) extends DockerHelper {
private val cacheDockerHelper = new CacheDockerHelper()
override def readDescription(docker: IDocker): Option[Set[PatternDescription]] = {
val cachedDescriptions = if (useCachedDocs) cacheDockerHelper.readDescription(docker) else None
cachedDescriptions.orElse {
val cmd =
s"${DockerConstants.dockerRunCmd} --entrypoint=cat ${docker.dockerImageName} ${cachedDescriptionsPathPrefix.resolve("description.json")}"
.split(" ")
.toList
val descriptionsOpt: Option[String] = CommandRunner.exec(cmd).map(_.mkString(System.lineSeparator())).toOption
parseDescriptions(docker, descriptionsOpt)
}
}
override def readRaw(docker: IDocker, path: Path): Option[String] =
Try {
val cachedFile = if (useCachedDocs) cacheDockerHelper.readRaw(docker, path) else None
cachedFile.orElse {
val shCmd =
s"""if [ -f $path ]; then
| cat $path;
| if [ $$? -ne 0 ]; then
| exit 2;
| fi
|else exit 1; fi""".stripMargin
val cmd =
s"""${DockerConstants.dockerRunCmd} --entrypoint=sh ${docker.dockerImageName} -c"""
.split(' ')
.filter(_ != "")
.toList :+ shCmd
val errorMsg = s"Failed to read docs from ${docker.dockerName} path $path"
CommandRunner.execSync(cmd) match {
case Right(CommandResult(0, stdout, stderr)) =>
Some(stdout.mkString(Properties.lineSeparator))
case Right(CommandResult(1, stdout, stderr)) => // file doesn't exist
None
case Right(CommandResult(code, stdout, stderr)) =>
Log.error(s"""$errorMsg
|stdout: ${stdout.mkString(Properties.lineSeparator)}
|stderr: ${stderr.mkString(Properties.lineSeparator)}""".stripMargin)
None
case Left(e) =>
Log.error(errorMsg, e)
None
}
}
}.toOption.flatten
protected def parseDescriptions(docker: IDocker, rawDescriptions: Option[String]): Option[Set[PatternDescription]] = {
rawDescriptions.flatMap(parseJsonDescriptions).map { descriptions =>
withDescriptionsDirectory(docker.dockerImageName) { directory =>
descriptions.map { pattern =>
val descPath = directory.resolve(s"${pattern.patternId}.md")
val fileContents = FileHelper.read(descPath.toFile).map(_.mkString(Properties.lineSeparator))
pattern.copy(explanation = fileContents)
}
}
}
}
private def withDescriptionsDirectory[T](dockerImageName: String)(block: Path => T): T = {
val sourceDir = Files.createTempDirectory("docker-test-folders")
val dockerStartedCmd = s"${DockerConstants.dockerRunNonDaemonCmd} -d --entrypoint=sh $dockerImageName"
for {
output <- CommandRunner.exec(dockerStartedCmd.split(" ").toList).toOption
containerId <- output.headOption
// Copy files from running container
_ <- CommandRunner.exec(s"docker cp $containerId:/docs/description $sourceDir".split(" ").toList).toOption
// Remove container
_ <- CommandRunner.exec(s"docker rm -f $containerId".split(" ").toList).toOption
} yield ()
val result = block(sourceDir.resolve("description"))
CommandRunner.exec(s"rm -f ${sourceDir.toString}".split(" ").toList)
result
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy