Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend behaviour for Maven classifiers and types #53

Merged
merged 3 commits into from
Aug 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 40 additions & 13 deletions src/main/scala/com/typesafe/sbt/pom/MavenHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -190,37 +190,64 @@ object MavenHelper {

def convertDep(dep: PomDependency): sbt.ModuleID = {
// TODO - Handle mapping all the maven oddities into sbt's DSL.
val scopeString: Option[String] =
for {
scope <- Option(dep.getScope)
} yield scope

def fixScope(m: ModuleID): ModuleID =
scopeString match {
case Some(scope) => m % scope
case None => m
}

// See https://maven.apache.org/ref/3.6.3/maven-core/artifact-handlers.html for
// matrix on Maven side of attributes
def addExclusions(mod: ModuleID): ModuleID = {
val exclusions = dep.getExclusions.asScala
exclusions.foldLeft(mod) { (mod, exclude) =>
mod.exclude(exclude.getGroupId, exclude.getArtifactId)
}
}

def addClassifier(mod: ModuleID): ModuleID = {
Option(dep.getClassifier) match {
case Some(_classifier) => mod classifier _classifier
case None => mod
}
}
addExclusions(addClassifier(fixScope(dep.getGroupId % dep.getArtifactId % dep.getVersion)))

def addConfiguration(mod: ModuleID): ModuleID = {
val mvnScope = Option(dep.getScope)
val mvnType = Option(dep.getType)
val mvnClassifier = Option(dep.getClassifier)

(mvnScope, mvnType) match {
// <type>test-jar</type>
// <scope>SCOPE</scope>
case (Some(mScope), Some(mType)) if ("test-jar".equalsIgnoreCase(mType)) =>
mod
.withConfigurations(Some(s"${mScope}->test"))
.intransitive
// <classifier>tests</classifier>
// <scope>SCOPE</scope>
case (Some(mScope), _) if (mvnClassifier.getOrElse("").equalsIgnoreCase("tests")) =>
mod
.withConfigurations(Some(s"${mScope}->test"))
// <scope>SCOPE</scope>
case (Some(mScope), _) =>
mod % mScope
case _ => mod
}
}

// order does not matter
def conversion = addExclusions _ andThen addClassifier andThen addConfiguration

conversion(ModuleID(dep.getGroupId, dep.getArtifactId, dep.getVersion))
}

def getDependencies(pom: PomModel): Seq[ModuleID] = {
for {
dep <- pom.getDependencies.asScala
} yield convertDep(dep)
}

/** Filters module dependencies within same group id, which results in list
* of modules this one depends on. */
def getModuleDependencies(pom: PomModel): Seq[ModuleID] = {
val allDependencies = getDependencies(pom)
allDependencies.filter { dep => dep.organization == pom.getGroupId }
}

def getPomResolvers(pom: PomModel): Seq[Resolver] = {
for {
Expand Down
42 changes: 29 additions & 13 deletions src/main/scala/com/typesafe/sbt/pom/MavenProjectHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ object MavenProjectHelper {
// Next flatten the list of all projects.
val projects = allProjectsInTree(tree)
// Create a mapping of all dependencies between projects.
val depMap = makeDependencyMap(projects)
val depMap: Map[ProjectTree, Seq[ProjectTree]] = makeDependencyMap(projects)
// Helper to look up dependencies in the presence of absences.
def getDepsFor(project: ProjectTree): Seq[ProjectTree] =
depMap.getOrElse(project, Nil)
Expand All @@ -62,11 +62,11 @@ object MavenProjectHelper {
val deps = getDepsFor(project)
aggregates ++ deps
}
def makeProjects(toMake: Seq[ProjectTree], made: Map[ProjectTree, Project] = Map.empty): Seq[Project] =
def makeProjects(toMake: Seq[ProjectTree], made: Map[ProjectTree, (Project, ModuleID)] = Map.empty): Seq[Project] =
toMake match {
case current :: rest =>
// Make a project, and add it to the stack
val depProjects: Seq[Project] =
val depProjects: Seq[(Project, ModuleID)] =
for {
dep <- getDepsFor(current)
depProject <- made.get(dep)
Expand All @@ -77,16 +77,32 @@ object MavenProjectHelper {
for {
child <- children
depProject <- made.get(child)
} yield depProject
} yield depProject._1
case _ => Nil
}
// Prepare data:
// list of projects and their moduleIds with correct configurations,
// according to current node in POM we are processing now
val modulesMap: Map[String, Seq[ModuleID]] =
MavenHelper
.getModuleDependencies(current.model)
.groupBy { m => makeId(m.organization, m.name, m.revision) }
val projectsMap: Map[String, Seq[(Project, ModuleID)]] = depProjects.groupBy { case (p, m) => makeId(m.organization, m.name, m.revision) }
val projectsWithModules: Seq[(Project, ModuleID)] = modulesMap.keySet.map { id =>
val mwc: Seq[ModuleID] = modulesMap.get(id).getOrElse(Seq.empty)
val projects: Seq[Project] = projectsMap.get(id).getOrElse(Seq.empty).map(_._1)
projects.zip(mwc)
}
.flatten
.toSeq

// TODO - Configure debugging output....
val currentProject = (
Project(makeProjectName(current.model,overrideRootProjectName),current.dir)
val currentProject: Project = (
Project(makeProjectName(current.model,overrideRootProjectName), current.dir)
// First pull in settings from pom
settings(useMavenPom:_*)
// Now update depends on relationships
dependsOn(depProjects.map(x =>x: ClasspathDep[ProjectReference]):_*)
// Now update depends on relationships with actual configurations
dependsOn( projectsWithModules.map { case (p, m) => new ClasspathDependency(p, m.configurations) }: _* )
// Now fix aggregate relationships
aggregate(aggregates.map(x => x:ProjectReference):_*)
// Now remove any inter-project dependencies we pulled in from the maven pom.
Expand All @@ -98,13 +114,13 @@ object MavenProjectHelper {
Keys.libraryDependencies.value.filterNot { dep =>
val id = makeId(dep.organization, dep.name, dep.revision)
depIds contains id
}
}
}
}
)

)
makeProjects(rest, made + (current -> currentProject))
case Nil => made.values.toSeq
val currentModule = ModuleID(current.model.getGroupId, current.model.getArtifactId, current.model.getVersion)
makeProjects(rest, made + (current -> (currentProject, currentModule)))
case Nil => made.values.map(_._1).toSeq
}
makeProjects(sorted)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.gemelen.example</groupId>
<artifactId>module1_2.12</artifactId>
<version>1.0</version>
<packaging>jar</packaging>

<parent>
<groupId>net.gemelen.example</groupId>
<artifactId>example-parent_2.12</artifactId>
<version>1.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>

<properties>
<sbt.project.name>module1</sbt.project.name>
</properties>

<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
</dependencies>

<build>
<outputDirectory>target/scala-${scala.binary.version}/classes</outputDirectory>
<testOutputDirectory>target/scala-${scala.binary.version}/test-classes</testOutputDirectory>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package net.gemelen.example.annotation;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER,
ElementType.CONSTRUCTOR, ElementType.LOCAL_VARIABLE, ElementType.PACKAGE})
public @interface ExampleAnnotation1 {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package net.gemelen.example.annotation

import scala.annotation.StaticAnnotation
import scala.annotation.meta._

@param @field @getter @setter @beanGetter @beanSetter
class ExampleAnnotation2(version: String) extends StaticAnnotation
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package net.gemelen.example.annotation;

import org.scalatest.TagAnnotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@TagAnnotation
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface MarkerTest { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.gemelen.example</groupId>
<artifactId>core_2.12</artifactId>
<version>1.0</version>
<packaging>jar</packaging>

<parent>
<groupId>net.gemelen.example</groupId>
<artifactId>example-parent_2.12</artifactId>
<version>1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>

<properties>
<sbt.project.name>core</sbt.project.name>
</properties>

<dependencies>
<dependency>
<groupId>net.gemelen.example</groupId>
<artifactId>other_${scala.binary.version}</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>net.gemelen.example</groupId>
<artifactId>other_${scala.binary.version}</artifactId>
<version>${project.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>

<dependency>
<groupId>net.gemelen.example</groupId>
<artifactId>module1_${scala.binary.version}</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>net.gemelen.example</groupId>
<artifactId>module1_${scala.binary.version}</artifactId>
<version>${project.version}</version>
<classifier>tests</classifier>
<type>test-jar</type>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
</dependencies>

<build>
<outputDirectory>target/scala-${scala.binary.version}/classes</outputDirectory>
<testOutputDirectory>target/scala-${scala.binary.version}/test-classes</testOutputDirectory>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package net.gemelen.example.core;

import net.gemelen.example.annotation.ExampleAnnotation1;

public class Core {

@ExampleAnnotation1
public void method() {}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package net.gemelen.example.core;

import net.gemelen.example.annotation.MarkerTest;

public class JavaCoreTest {

@MarkerTest
public void method() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package net.gemelen.example.core

import net.gemelen.example.annotation.ExampleAnnotation1
import net.gemelen.example.annotation.ExampleAnnotation2

class CoreTest {

@ExampleAnnotation1
@ExampleAnnotation2(version = "something")
def f(): Unit = {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.gemelen.example</groupId>
<artifactId>other_2.12</artifactId>
<version>1.0</version>
<packaging>jar</packaging>

<parent>
<groupId>net.gemelen.example</groupId>
<artifactId>example-parent_2.12</artifactId>
<version>1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>

<properties>
<sbt.project.name>other</sbt.project.name>
</properties>

<dependencies>
<dependency>
<groupId>net.gemelen.example</groupId>
<artifactId>module1_${scala.binary.version}</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>net.gemelen.example</groupId>
<artifactId>module1_${scala.binary.version}</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
</dependencies>

<build>
<outputDirectory>target/scala-${scala.binary.version}/classes</outputDirectory>
<testOutputDirectory>target/scala-${scala.binary.version}/test-classes</testOutputDirectory>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package net.gemelen.example.other;

import net.gemelen.example.annotation.ExampleAnnotation1;

public class Other {

@ExampleAnnotation1
public void method() {}
}
Loading