diff --git a/src/main/kotlin/com/beust/kobalt/ResolveDependency.kt b/src/main/kotlin/com/beust/kobalt/ResolveDependency.kt index 876902c7..e5d31565 100644 --- a/src/main/kotlin/com/beust/kobalt/ResolveDependency.kt +++ b/src/main/kotlin/com/beust/kobalt/ResolveDependency.kt @@ -30,7 +30,7 @@ class ResolveDependency @Inject constructor(val repoFinder: RepoFinder) { root.addChildren(findChildren(root, seen)) val repoResult = repoFinder.findCorrectRepo(id) - val simpleDep = SimpleDep(MavenId(id)) + val simpleDep = SimpleDep(MavenId.create(id)) val url = repoResult.hostConfig.url + simpleDep.toJarFile(repoResult) AsciiArt.logBox(listOf(id, url).map { " $it" }, {s -> println(s) }) diff --git a/src/main/kotlin/com/beust/kobalt/api/IMavenIdInterceptor.kt b/src/main/kotlin/com/beust/kobalt/api/IMavenIdInterceptor.kt new file mode 100644 index 00000000..fd9fc115 --- /dev/null +++ b/src/main/kotlin/com/beust/kobalt/api/IMavenIdInterceptor.kt @@ -0,0 +1,10 @@ +package com.beust.kobalt.api + +import com.beust.kobalt.maven.MavenId + +/** + * Plug-ins can rewrite Maven id's before Kobalt sees them with this interface. + */ +interface IMavenIdInterceptor: IInterceptor { + fun intercept(mavenId: MavenId) : MavenId +} diff --git a/src/main/kotlin/com/beust/kobalt/internal/KobaltPluginXml.kt b/src/main/kotlin/com/beust/kobalt/internal/KobaltPluginXml.kt index c3c00b2d..56e88b17 100644 --- a/src/main/kotlin/com/beust/kobalt/internal/KobaltPluginXml.kt +++ b/src/main/kotlin/com/beust/kobalt/internal/KobaltPluginXml.kt @@ -75,6 +75,8 @@ class PluginInfo(val xml: KobaltPluginXml, val classLoader: ClassLoader?) { val buildConfigFieldContributors = arrayListOf() val taskContributors = arrayListOf() + val mavenIdInterceptors = arrayListOf() + companion object { val PLUGIN_XML = "META-INF/kobalt-plugin.xml" // Plugins.PLUGIN_XML) @@ -142,6 +144,7 @@ class PluginInfo(val xml: KobaltPluginXml, val classLoader: ClassLoader?) { if (this is ITestRunnerContributor) testRunnerContributors.add(this) // Not documented yet + if (this is IMavenIdInterceptor) mavenIdInterceptors.add(this) if (this is ITestSourceDirectoryContributor) testSourceDirContributors.add(this) } } @@ -171,6 +174,7 @@ class PluginInfo(val xml: KobaltPluginXml, val classLoader: ClassLoader?) { buildConfigFieldContributors.addAll(pluginInfo.buildConfigFieldContributors) taskContributors.addAll(pluginInfo.taskContributors) testSourceDirContributors.addAll(pluginInfo.testSourceDirContributors) + mavenIdInterceptors.addAll(pluginInfo.mavenIdInterceptors) } } diff --git a/src/main/kotlin/com/beust/kobalt/maven/DepFactory.kt b/src/main/kotlin/com/beust/kobalt/maven/DepFactory.kt index 9c49bc91..6f85bb8d 100644 --- a/src/main/kotlin/com/beust/kobalt/maven/DepFactory.kt +++ b/src/main/kotlin/com/beust/kobalt/maven/DepFactory.kt @@ -30,7 +30,7 @@ public class DepFactory @Inject constructor(val localRepo: LocalRepo, if (id.startsWith(FileDependency.PREFIX_FILE)) { return FileDependency(id.substring(FileDependency.PREFIX_FILE.length)) } else { - val mavenId = MavenId(id) + val mavenId = MavenId.create(id) var version = mavenId.version var packaging = mavenId.packaging var repoResult: RepoFinder.RepoResult? diff --git a/src/main/kotlin/com/beust/kobalt/maven/MavenId.kt b/src/main/kotlin/com/beust/kobalt/maven/MavenId.kt index f550704f..fb93ed9a 100644 --- a/src/main/kotlin/com/beust/kobalt/maven/MavenId.kt +++ b/src/main/kotlin/com/beust/kobalt/maven/MavenId.kt @@ -1,5 +1,7 @@ package com.beust.kobalt.maven +import com.beust.kobalt.api.Kobalt + /** * Encapsulate a Maven id captured in one string, as used by Gradle or Ivy, e.g. "org.testng:testng:6.9.9". * These id's are somewhat painful to manipulate because on top of containing groupId, artifactId @@ -10,19 +12,61 @@ package com.beust.kobalt.maven * This class accepts a versionless id, which needs to end with a :, e.g. "com.beust:jcommander:" (which * usually means "latest version") but it doesn't handle version ranges yet. */ -public class MavenId(val id: String) { - lateinit var groupId: String - lateinit var artifactId: String - var packaging: String? = null - var version: String? = null +class MavenId private constructor(val groupId: String, val artifactId: String, val packaging: String?, + val version: String?) { companion object { fun isMavenId(id: String) = with(id.split(":")) { size == 3 || size == 4 } + private fun isVersion(s: String) : Boolean = Character.isDigit(s[0]) + + /** + * Similar to create(MavenId) but don't run IMavenIdInterceptors. + */ + fun createNoInterceptors(id: String) : MavenId { + var groupId: String? = null + var artifactId: String? = null + var version: String? = null + var packaging: String? = null + if (!isMavenId(id)) { + throw IllegalArgumentException("Illegal id: $id") + } + + val c = id.split(":") + groupId = c[0] + artifactId = c[1] + if (!c[2].isEmpty()) { + if (isVersion(c[2])) { + version = c[2] + } else { + packaging = c[2] + version = c[3] + } + } + + return MavenId(groupId, artifactId, packaging, version) + } + + /** + * The main entry point to create Maven Id's. Id's created by this function + * will run through IMavenIdInterceptors. + */ + fun create(id: String) : MavenId { + var originalMavenId = createNoInterceptors(id) + var interceptedMavenId = originalMavenId + val interceptors = Kobalt.context?.pluginInfo?.mavenIdInterceptors + if (interceptors != null) { + interceptedMavenId = interceptors.fold(originalMavenId, { + id, interceptor -> interceptor.intercept(id) }) + } + + return interceptedMavenId + } + fun create(groupId: String, artifactId: String, packaging: String?, version: String?) = - MavenId(toId(groupId, artifactId, packaging, version)) + create(toId(groupId, artifactId, packaging, version)) fun toId(groupId: String, artifactId: String, packaging: String? = null, version: String?) = "$groupId:$artifactId" + @@ -30,24 +74,6 @@ public class MavenId(val id: String) { ":$version" } - init { - if (! isMavenId(id)) { - throw IllegalArgumentException("Illegal id: $id") - } - val c = id.split(":") - groupId = c[0] - artifactId = c[1] - if (! c[2].isEmpty()) { - if (isVersion(c[2])) { - version = c[2] - } else { - packaging = c[2] - version = c[3] - } - } - } - - private fun isVersion(s: String) : Boolean = Character.isDigit(s[0]) val hasVersion = version != null diff --git a/src/main/kotlin/com/beust/kobalt/maven/RepoFinder.kt b/src/main/kotlin/com/beust/kobalt/maven/RepoFinder.kt index 5c3e81f9..d79eab24 100644 --- a/src/main/kotlin/com/beust/kobalt/maven/RepoFinder.kt +++ b/src/main/kotlin/com/beust/kobalt/maven/RepoFinder.kt @@ -72,7 +72,7 @@ public class RepoFinder @Inject constructor(val executors: KobaltExecutors) { val repoUrl = repo.url log(2, " Checking $repoUrl for $id") - val mavenId = MavenId(id) + val mavenId = MavenId.create(id) val groupId = mavenId.groupId val artifactId = mavenId.artifactId diff --git a/src/main/kotlin/com/beust/kobalt/maven/SimpleDep.kt b/src/main/kotlin/com/beust/kobalt/maven/SimpleDep.kt index 0dddbbc5..9f1c7c71 100644 --- a/src/main/kotlin/com/beust/kobalt/maven/SimpleDep.kt +++ b/src/main/kotlin/com/beust/kobalt/maven/SimpleDep.kt @@ -4,8 +4,8 @@ import com.beust.kobalt.misc.Strings open public class SimpleDep(open val mavenId: MavenId) : UnversionedDep(mavenId.groupId, mavenId.artifactId) { companion object { - fun create(id: String) = MavenId(id).let { - SimpleDep(MavenId(id)) + fun create(id: String) = MavenId.create(id).let { + SimpleDep(it) } } diff --git a/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt index 1c4850f9..76185689 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/android/AndroidPlugin.kt @@ -24,7 +24,7 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, val executors: KobaltExecutors, val dependencyManager: DependencyManager) : ConfigPlugin(), IClasspathContributor, IRepoContributor, ICompilerFlagContributor, ICompilerInterceptor, IBuildDirectoryIncerceptor, IRunnerContributor, IClasspathInterceptor, - ISourceDirectoryContributor, IBuildConfigFieldContributor, ITaskContributor { + ISourceDirectoryContributor, IBuildConfigFieldContributor, ITaskContributor, IMavenIdInterceptor { companion object { const val PLUGIN_NAME = "Android" const val TASK_GENERATE_DEX = "generateDex" @@ -121,7 +121,7 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, project.compileDependencies.filter { it.jarFile.get().name.endsWith(".aar") }.forEach { - val mavenId = MavenId(it.id) + val mavenId = MavenId.create(it.id) val outputDir = AndroidFiles.intermediates(project) val destDir = Paths.get(outputDir, "exploded-aar", mavenId.groupId, mavenId.artifactId, mavenId.version) @@ -378,14 +378,17 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, } } + private fun isAar(id: MavenId) = id.groupId == "com.android.support" && id.artifactId != "support-annotations" + /** - * Automatically add the "aar" packaging for support libraries. + * For each com.android.support dependency or aar packaging, add a classpath dependency that points to the + * classes.jar inside that (exploded) aar. */ // IClasspathInterceptor override fun intercept(project: Project, dependencies: List): List { val result = arrayListOf() dependencies.forEach { - if (it is MavenDependency && (it.groupId == "com.android.support" || it.mavenId.packaging == "aar")) { + if (it is MavenDependency && (isAar(it.mavenId) || it.mavenId.packaging == "aar")) { val newDep = FileDependency(AndroidFiles.classesJar(project, it.mavenId)) result.add(newDep) val id = MavenId.create(it.groupId, it.artifactId, "aar", it.version) @@ -397,6 +400,15 @@ public class AndroidPlugin @Inject constructor(val javaCompiler: JavaCompiler, return result } + // IMavenIdInterceptor + override fun intercept(mavenId: MavenId) : MavenId = + if (isAar(mavenId)) { + val version = mavenId.version ?: "" + MavenId.createNoInterceptors("${mavenId.groupId}:${mavenId.artifactId}:aar:$version") + } else { + mavenId + } + private val extraSourceDirectories = arrayListOf() // ISourceDirectoryContributor diff --git a/src/test/kotlin/com/beust/kobalt/maven/MavenIdTest.kt b/src/test/kotlin/com/beust/kobalt/maven/MavenIdTest.kt index fcc4999e..71b348f6 100644 --- a/src/test/kotlin/com/beust/kobalt/maven/MavenIdTest.kt +++ b/src/test/kotlin/com/beust/kobalt/maven/MavenIdTest.kt @@ -23,7 +23,7 @@ class MavenIdTest { @Test(dataProvider = "dp") fun parseVersions(id: String, groupId: String, artifactId: String, version: String?, packaging: String?, qualifier: String?) { - val mi = MavenId(id) + val mi = MavenId.create(id) Assert.assertEquals(mi.groupId, groupId) Assert.assertEquals(mi.artifactId, artifactId) Assert.assertEquals(mi.version, version)