All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.pixee.maven.operator.AbstractQueryCommand.kt Maven / Gradle / Ivy

package io.github.pixee.maven.operator

import io.github.pixee.maven.operator.Util.which
import org.apache.commons.lang3.SystemUtils
import org.apache.maven.shared.invoker.DefaultInvocationRequest
import org.apache.maven.shared.invoker.InvocationRequest
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.io.File
import java.nio.file.Paths
import java.util.*

/**
 * Common Base Class - Meant to be used by Simple Queries using either Invoker and/or Embedder, thus
 * relying on dependency:tree mojo outputting into a text file - which might be cached.
 *
 */
abstract class AbstractQueryCommand : AbstractCommand() {
    /**
     * Generates a temporary file path used to store the output of the 
dependency:tree
mojo * * @param pomFilePath POM Original File Path */ private fun getOutputPath(pomFilePath: File): File { val basePath = pomFilePath.parentFile val outputBasename = "output-%08X.txt".format(pomFilePath.hashCode()) val outputPath = File(basePath, outputBasename) return outputPath } /** * Given a POM URI, returns a File Object * * @param d POMDocument */ protected fun getPomFilePath(d: POMDocument): File = Paths.get(d.pomPath!!.toURI()).toFile() /** * Abstract Method to extract dependencies * * @param outputPath Output Path to where to store the content * @param pomFilePath Input Pom Path * @param c Project Model */ abstract fun extractDependencyTree(outputPath: File, pomFilePath: File, c: ProjectModel) /** * Internal Holder Variable * * Todo: OF COURSE IT BREAKS THE PROTOCOL */ internal var result: Collection? = null /** * We declare the main logic here - details are made in the child classes for now */ override fun execute(pm: ProjectModel): Boolean { val pomFilePath = getPomFilePath(pm.pomFile) val outputPath = getOutputPath(pomFilePath) if (outputPath.exists()) { outputPath.delete() } try { extractDependencyTree(outputPath, pomFilePath, pm) } catch (e: InvalidContextException) { return false } this.result = extractDependencies(outputPath).values return true } /** * Given a File containing the output of the dependency:tree mojo, read its contents and parse, creating an array of dependencies * * About the file contents: We receive something such as this, then filter it out: * *
     *     br.com.ingenieux:pom-operator:jar:0.0.1-SNAPSHOT
     *     +- xerces:xercesImpl:jar:2.12.1:compile
     *     |  \- xml-apis:xml-apis:jar:1.4.01:compile
     *     \- org.jetbrains.kotlin:kotlin-test:jar:1.5.31:test
     * 
* * @param outputPath file to read */ protected fun extractDependencies(outputPath: File) = outputPath.readLines().drop(1).map { it.trim(*"+-|\\ ".toCharArray()) }.map { it to it.split(':') }.associate { (line, elements) -> val (groupId, artifactId, packaging, version, scope) = elements line to Dependency( groupId = groupId, artifactId = artifactId, version = version, packaging = packaging, scope = scope ) } protected fun buildInvocationRequest( outputPath: File, pomFilePath: File, c: ProjectModel ): InvocationRequest { val props = Properties(System.getProperties()).apply { setProperty("outputFile", outputPath.absolutePath) val localRepositoryPath = getLocalRepositoryPath(c).absolutePath setProperty("maven.repo.local", localRepositoryPath) } val request: InvocationRequest = DefaultInvocationRequest().apply { findMaven(this) pomFile = pomFilePath isShellEnvironmentInherited = true isNoTransferProgress = true isBatchMode = true isRecursive = false profiles = c.activeProfiles.toList() isDebug = true isOffline = c.offline properties = props goals = listOf(DEPENDENCY_TREE_MOJO_REFERENCE) } return request } /** * Locates where Maven is at - HOME var and main launcher script. * * @param invocationRequest InvocationRequest to be filled up */ private fun findMaven(invocationRequest: InvocationRequest) { /* * Step 1: Locate Maven Home */ val m2homeEnvVar = System.getenv("M2_HOME") if (null != m2homeEnvVar) { val m2HomeDir = File(m2homeEnvVar) if (m2HomeDir.isDirectory) invocationRequest.mavenHome = m2HomeDir } /** * Step 1.1: Try to guess if thats the case */ if (invocationRequest.mavenHome == null) { val inferredHome = File(SystemUtils.getUserHome(), ".m2") if (!(inferredHome.exists() && inferredHome.isDirectory)) { LOGGER.warn( "Inferred User Home - which does not exist or not a directory: {}", inferredHome ) } invocationRequest.mavenHome = inferredHome } /** * Step 2: Find Maven Executable given the operating system and PATH variable contents */ val foundExecutable = listOf("mvn", "mvnw").map { which(it) }.firstOrNull() if (null != foundExecutable) { invocationRequest.mavenExecutable = foundExecutable return } throw IllegalStateException("Missing Maven Home / Executable") } companion object { /** * Mojo Reference */ const val DEPENDENCY_TREE_MOJO_REFERENCE = "org.apache.maven.plugins:maven-dependency-plugin:3.3.0:tree" val LOGGER: Logger = LoggerFactory.getLogger(AbstractQueryCommand::class.java) } override fun postProcess(c: ProjectModel): Boolean = false }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy