From 321ae4ea5bbeac7c655160358d2476d50e579af0 Mon Sep 17 00:00:00 2001 From: shipp02 <51503822+shipp02@users.noreply.github.com> Date: Sat, 12 Dec 2020 22:26:58 +0800 Subject: [PATCH] - Downloading artifacts works - parseMavenArtifacts can parse source artifacts (tests added) --- .../kt/classpath/MavenClassPathResolver.kt | 89 +++++++++++++------ .../org/javacs/kt/MavenArtifactParsingTest.kt | 18 +++- 2 files changed, 77 insertions(+), 30 deletions(-) diff --git a/shared/src/main/kotlin/org/javacs/kt/classpath/MavenClassPathResolver.kt b/shared/src/main/kotlin/org/javacs/kt/classpath/MavenClassPathResolver.kt index bd4705ae5..b9c2926bf 100644 --- a/shared/src/main/kotlin/org/javacs/kt/classpath/MavenClassPathResolver.kt +++ b/shared/src/main/kotlin/org/javacs/kt/classpath/MavenClassPathResolver.kt @@ -1,28 +1,37 @@ package org.javacs.kt.classpath import org.javacs.kt.LOG -import org.javacs.kt.util.findCommandOnPath import org.javacs.kt.util.execAndReadStdoutAndStderr -import java.nio.file.Path -import java.nio.file.Files +import org.javacs.kt.util.findCommandOnPath import java.io.File +import java.nio.file.Files +import java.nio.file.Path /** Resolver for reading maven dependencies */ internal class MavenClassPathResolver private constructor(private val pom: Path) : ClassPathResolver { override val resolverType: String = "Maven" - override val classpath: Set get() { - val mavenOutput = generateMavenDependencyList(pom) - val artifacts = readMavenDependencyList(mavenOutput) - - when { - artifacts.isEmpty() -> LOG.warn("No artifacts found in {}", pom) - artifacts.size < 5 -> LOG.info("Found {} in {}", artifacts, pom) - else -> LOG.info("Found {} artifacts in {}", artifacts.size, pom) - } + override val classpath: Set + get() { + val artifacts = generateMavenDependencySet(pom) - Files.deleteIfExists(mavenOutput) - return artifacts.mapNotNull { findMavenArtifact(it, false) }.toSet() - } + when { + artifacts.isEmpty() -> LOG.warn("No artifacts found in {}", pom) + artifacts.size < 5 -> LOG.info("Found {} in {}", artifacts, pom) + else -> LOG.info("Found {} artifacts in {}", artifacts.size, pom) + } + + return artifacts.mapNotNull { findMavenArtifact(it, false) }.toSet() + } + val sourceJars: Set + get() { + val artifacts = generateMavenSourceJarSet(pom) + when { + artifacts.isEmpty() -> LOG.warn("No sources found in {}", pom) + artifacts.size < 5 -> LOG.info("Found {} sources in {}", artifacts, pom) + else -> LOG.info("Found {} sources in {}", artifacts.size, pom) + } + return artifacts.mapNotNull { findMavenArtifact(it, false) }.toSet() + } companion object { /** Create a maven resolver if a file is a pom. */ @@ -33,6 +42,7 @@ internal class MavenClassPathResolver private constructor(private val pom: Path) private val artifactPattern = "^[^:]+:(?:[^:]+:)+[^:]+".toRegex() +// Can be used to read sources private fun readMavenDependencyList(mavenOutput: Path): Set = mavenOutput.toFile() .readLines() @@ -59,17 +69,33 @@ private fun mavenJarName(a: Artifact, source: Boolean) = if (source) "${a.artifact}-${a.version}-sources.jar" else "${a.artifact}-${a.version}.jar" -private fun generateMavenDependencyList(pom: Path): Path { - val mavenOutput = Files.createTempFile("deps", ".txt") - val command = "$mvnCommand dependency:list -DincludeScope=test -DoutputFile=$mavenOutput" +private fun generateMavenDependencySet(pom: Path): Set { + val (_, path) = runMavenCommand(pom, "dependency:list", "-DincludeScope=test") + val deps = readMavenDependencyList(path) + Files.deleteIfExists(path) + return deps +} + +private fun generateMavenSourceJarSet(pom: Path): Set { + val (_, path) = runMavenCommand(pom, "dependency:sources", "") + val sources = readMavenDependencyList(path) + Files.deleteIfExists(path) + return sources +} + +private fun runMavenCommand(pom: Path, stage: String, options: String = ""): Pair { + val output = Files.createTempFile("""${stage}_output""", ".txt") + val command = """$mvnCommand $stage -DoutputFile=$output $options""" val workingDirectory = pom.toAbsolutePath().parent LOG.info("Run {} in {}", command, workingDirectory) val (result, errors) = execAndReadStdoutAndStderr(command, workingDirectory) LOG.debug(result) - if ("BUILD FAILURE" in errors) { + return if ("BUILD FAILURE" in errors) { LOG.warn("Maven task failed: {}", errors.lines().firstOrNull()) + Pair(false, output) + } else { + Pair(true, output) } - return mavenOutput } private val mvnCommand: Path by lazy { @@ -77,8 +103,11 @@ private val mvnCommand: Path by lazy { } fun parseMavenArtifact(rawArtifact: String, version: String? = null): Artifact { - val parts = rawArtifact.trim().split(':') + var parts = rawArtifact.trim().split(':') + val source = parts.contains("sources") + parts = parts.filter { it != "sources" } + // Creates artifact from parts of parts Array return when (parts.size) { 3 -> Artifact( group = parts[0], @@ -86,7 +115,8 @@ fun parseMavenArtifact(rawArtifact: String, version: String? = null): Artifact { packaging = null, classifier = null, version = version ?: parts[2], - scope = null + scope = null, + source = source ) 4 -> Artifact( group = parts[0], @@ -94,7 +124,8 @@ fun parseMavenArtifact(rawArtifact: String, version: String? = null): Artifact { packaging = parts[2], classifier = null, version = version ?: parts[3], - scope = null + scope = null, + source = source ) 5 -> Artifact( group = parts[0], @@ -102,7 +133,8 @@ fun parseMavenArtifact(rawArtifact: String, version: String? = null): Artifact { packaging = parts[2], classifier = null, version = version ?: parts[3], - scope = parts[4] + scope = parts[4], + source = source ) 6 -> Artifact( group = parts[0], @@ -110,7 +142,8 @@ fun parseMavenArtifact(rawArtifact: String, version: String? = null): Artifact { packaging = parts[2], classifier = parts[3], version = version ?: parts[4], - scope = parts[5] + scope = parts[5], + source = source ) else -> throw IllegalArgumentException("$rawArtifact is not a properly formed Maven/Gradle artifact") } @@ -122,7 +155,9 @@ data class Artifact( val packaging: String?, val classifier: String?, val version: String, - val scope: String? + val scope: String?, + var source: Boolean = false ) { - override fun toString() = "$group:$artifact:$version" + override fun toString() = "$group:$artifact:$version:$packaging:$scope:$classifier:$source" } +//$source:$classifier diff --git a/shared/src/test/kotlin/org/javacs/kt/MavenArtifactParsingTest.kt b/shared/src/test/kotlin/org/javacs/kt/MavenArtifactParsingTest.kt index e0edcd6ac..474bca7d6 100644 --- a/shared/src/test/kotlin/org/javacs/kt/MavenArtifactParsingTest.kt +++ b/shared/src/test/kotlin/org/javacs/kt/MavenArtifactParsingTest.kt @@ -17,7 +17,7 @@ class MavenArtifactParsingTest { version = "2.4", scope = "compile" ))) - + assertThat(parseMavenArtifact("io.netty:netty-transport-native-epoll:jar:linux-x86_64:4.1.36.Final:compile"), equalTo(Artifact( group = "io.netty", artifact = "netty-transport-native-epoll", @@ -26,7 +26,7 @@ class MavenArtifactParsingTest { version = "4.1.36.Final", scope = "compile" ))) - + assertThat(parseMavenArtifact("org.codehaus.mojo:my-project:1.0"), equalTo(Artifact( group = "org.codehaus.mojo", artifact = "my-project", @@ -35,7 +35,7 @@ class MavenArtifactParsingTest { version = "1.0", scope = null ))) - + assertThat(parseMavenArtifact("io.vertx:vertx-sql-client:test-jar:tests:3.8.0-SNAPSHOT:compile"), equalTo(Artifact( group = "io.vertx", artifact = "vertx-sql-client", @@ -45,4 +45,16 @@ class MavenArtifactParsingTest { scope = "compile" ))) } + @Test + fun `parse source artifact`() { + assertThat(parseMavenArtifact("com.googlecode.lanterna:lanterna:jar:sources:3.0.2:compile"), equalTo(Artifact( + group = "com.googlecode.lanterna", + artifact = "lanterna", + packaging = "jar", + source = true, + version = "3.0.2", + scope = "compile", + classifier = null + ))) + } }