diff options
-rw-r--r-- | stage2/plugins/ExportBuildInformation.scala | 215 |
1 files changed, 130 insertions, 85 deletions
diff --git a/stage2/plugins/ExportBuildInformation.scala b/stage2/plugins/ExportBuildInformation.scala index 8884ed4..8896d86 100644 --- a/stage2/plugins/ExportBuildInformation.scala +++ b/stage2/plugins/ExportBuildInformation.scala @@ -1,16 +1,12 @@ package cbt import cbt._ -import scala.xml._ -import scala.util._ import java.io._ -import scala.collection.JavaConverters._ +import scala.xml._ trait ExportBuildInformation { self: BaseBuild => - lazy val printer = new scala.xml.PrettyPrinter(200, 2) - - def buildInfoXml = - printer.format(BuildInformationSerializer.serialize(BuildInformation.Project(self))) + def buildInfoXml: String = + BuildInformationSerializer.serialize(BuildInformation.Project(self)).toString } object BuildInformation { @@ -19,7 +15,9 @@ object BuildInformation { root: File, rootModule: Module, modules: Seq[Module], - libraries: Seq[Library] + libraries: Seq[Library], + cbtLibraries: Seq[Library], + scalaCompilers: Seq[ScalaCompiler] ) case class Module( @@ -30,8 +28,9 @@ object BuildInformation { target: File, binaryDependencies: Seq[BinaryDependency], moduleDependencies: Seq[ModuleDependency], - classpaths: Seq[ClassPathItem], - parentBuild: Option[String] + classpath: Seq[File], + parentBuild: Option[String], + scalacOptions: Seq[String] ) case class Library( name: String, jars: Seq[File] ) @@ -40,162 +39,208 @@ object BuildInformation { case class ModuleDependency( name: String ) - case class ClassPathItem( path: File ) + case class ScalaCompiler( version: String, jars: Seq[File] ) object Project { - def apply(build: BaseBuild) = - new BuildInformationExporter(build).exportBuildInformation + def apply(build: BaseBuild): Project = + new BuildInformationExporter(build).exportBuildInformation class BuildInformationExporter(rootBuild: BaseBuild) { - def exportBuildInformation(): Project = { + def exportBuildInformation: Project = { val moduleBuilds = transitiveBuilds(rootBuild) val libraries = moduleBuilds .flatMap(_.transitiveDependencies) .collect { case d: BoundMavenDependency => exportLibrary(d) } .distinct val cbtLibraries = convertCbtLibraries - val cbtbinaryDependencies = cbtLibraries - .map(l => BinaryDependency(l.name)) - val rootModule = exportModule(cbtbinaryDependencies)(rootBuild) - val modules = moduleBuilds.map(exportModule(cbtbinaryDependencies)) + val rootModule = exportModule(rootBuild) + val modules = moduleBuilds + .map(exportModule) + .distinct + + val scalaCompilers = modules + .map(_.scalaVersion) + .map(v => ScalaCompiler(v, scalaCompiler(rootBuild, v))) + Project( rootModule.name, rootModule.root, rootModule, modules, - libraries ++ cbtLibraries + libraries, + cbtLibraries, + scalaCompilers ) } - private def convertCbtLibraries() = + private def convertCbtLibraries = transitiveBuilds(DirectoryDependency(rootBuild.context.cbtHome)(rootBuild.context).dependenciesArray.head.asInstanceOf[BaseBuild]) - .collect { - case d: BoundMavenDependency => d.jar - case d: PackageJars => d.jar.get - } - .map(exportLibrary) - .distinct - - private def collectLazyBuilds(dependency: Dependency): Option[BaseBuild] = + .collect { + case d: BoundMavenDependency => d.jar + case d: PackageJars => d.jar.get + } + .map(exportLibrary) + .distinct + + private def collectLazyBuilds(dependency: Dependency): Option[BaseBuild] = dependency match { - case l: LazyDependency => + case l: LazyDependency => l.dependency match { - case d: BaseBuild => Some(d) - case d: LazyDependency => collectLazyBuilds(d.dependency) - case _ => None + case d: BaseBuild => Some(d) + case d: LazyDependency => collectLazyBuilds(d.dependency) + case _ => None } case d: BaseBuild => Some(d) case _ => None } - private def transitiveBuilds(build: BaseBuild): Seq[BaseBuild] = + private def transitiveBuilds(build: BaseBuild): Seq[BaseBuild] = (build +: build.transitiveDependencies) - .collect { - case d: BaseBuild => d +: collectParentBuilds(d).flatMap(transitiveBuilds) - case d: LazyDependency => - collectLazyBuilds(d.dependency) - .toSeq - .flatMap(transitiveBuilds) - } - .flatten - .distinct + .collect { + case d: BaseBuild => d +: collectParentBuilds(d).flatMap(transitiveBuilds) + case d: LazyDependency => + collectLazyBuilds(d.dependency) + .toSeq + .flatMap(transitiveBuilds) + } + .flatten + .distinct - private def exportLibrary(mavenDependency: BoundMavenDependency) = - Library(fomatMavenDependency(mavenDependency.mavenDependency), mavenDependency.exportedJars) + private def exportLibrary(mavenDependency: BoundMavenDependency) = { + val name = formatMavenDependency(mavenDependency.mavenDependency) + val jars = (mavenDependency +: mavenDependency.transitiveDependencies) + .map(_.asInstanceOf[BoundMavenDependency].jar) + Library(name, jars) + } - private def exportLibrary(file: File) = + private def exportLibrary(file: File) = Library("CBT:" + file.getName.stripSuffix(".jar"), Seq(file)) - private def collectParentBuilds(build: BaseBuild): Seq[BaseBuild] = + private def collectParentBuilds(build: BaseBuild): Seq[BaseBuild] = build.context.parentBuild - .map(_.asInstanceOf[BaseBuild]) - .map(b => b +: collectParentBuilds(b)) - .toSeq - .flatten - - private def exportModule(cbtbinaryDependencies: Seq[BinaryDependency])(build: BaseBuild): Module = { - def collectDependencies(dependencies: Seq[Dependency]): Seq[ModuleDependency] = - dependencies + .map(_.asInstanceOf[BaseBuild]) + .map(b => b +: collectParentBuilds(b)) + .toSeq + .flatten + + private def collectDependencies(dependencies: Seq[Dependency]): Seq[ModuleDependency] = + dependencies .collect { - case d: BaseBuild => Seq(ModuleDependency(moduleName(d))) - case d: LazyDependency => collectDependencies(Seq(d.dependency)) - } - .flatten + case d: BaseBuild => Seq(ModuleDependency(moduleName(d))) + case d: LazyDependency => collectDependencies(Seq(d.dependency)) + } + .flatten + + private def exportModule(build: BaseBuild): Module = { val moduleDependencies = collectDependencies(build.dependencies) val mavenDependencies = build.dependencies - .collect { case d: BoundMavenDependency => BinaryDependency(fomatMavenDependency(d.mavenDependency))} - val classpaths = build.dependencyClasspath.files + .collect { case d: BoundMavenDependency => BinaryDependency(formatMavenDependency(d.mavenDependency)) } + val classpath = build.dependencyClasspath.files .filter(_.isFile) - .map(t => ClassPathItem(t)) - val sources = build.sources - .filter(s => s.exists && s.isDirectory) :+ build.projectDirectory - + .distinct + val sources = { + val s = build.sources + .filter(_.exists) + .map(handleSource) + .filter(_.getName != "target") //Dirty hack for cbt's sources + .distinct + if (s.nonEmpty) + s + else + Seq(build.projectDirectory) + } + Module( name = moduleName(build), root = build.projectDirectory, scalaVersion = build.scalaVersion, sources = sources, target = build.target, - binaryDependencies = mavenDependencies ++ cbtbinaryDependencies, + binaryDependencies = mavenDependencies, moduleDependencies = moduleDependencies, - classpaths = classpaths, - parentBuild = build.context.parentBuild.map(b => moduleName(b.asInstanceOf[BaseBuild])) + classpath = classpath, + parentBuild = build.context.parentBuild.map(b => moduleName(b.asInstanceOf[BaseBuild])), + scalacOptions = build.scalacOptions ) } - private def fomatMavenDependency(dependency: cbt.MavenDependency) = + private def scalaCompiler(build: BaseBuild, scalaVersion: String) = + build.Resolver(mavenCentral, sonatypeReleases).bindOne( + MavenDependency("org.scala-lang", "scala-compiler", scalaVersion) + ).classpath.files + + + private def handleSource(source: File): File = + if (source.isDirectory) + source + else + source.getParentFile //Let's asume that for now + + + private def formatMavenDependency(dependency: cbt.MavenDependency) = s"${dependency.groupId}:${dependency.artifactId}:${dependency.version}" - private def moduleName(build: BaseBuild) = + private def moduleName(build: BaseBuild) = if (rootBuild.projectDirectory == build.projectDirectory) rootBuild.projectDirectory.getName else build.projectDirectory.getPath - .drop(rootBuild.projectDirectory.getPath.length) - .stripPrefix("/") - .replace("/", "-") + .drop(rootBuild.projectDirectory.getPath.length) + .stripPrefix("/") + .replace("/", "-") } } } object BuildInformationSerializer { - def serialize(project: BuildInformation.Project): Node = - <project name={project.name} root={project.root.toString} rootModule={project.rootModule.name}> + def serialize(project: BuildInformation.Project): Node = + <project name={project.name} root={project.root.toString} rootModule={project.rootModule.name}> <modules> {project.modules.map(serialize)} </modules> <libraries> {project.libraries.map(serialize)} </libraries> + <cbtLibraries> + {project.cbtLibraries.map(serialize)} + </cbtLibraries> + <scalaCompilers> + {project.scalaCompilers.map(serialize)} + </scalaCompilers> </project> - private def serialize(module: BuildInformation.Module): Node = + private def serialize(module: BuildInformation.Module): Node = <module name={module.name} root={module.root.toString} target={module.target.toString} scalaVersion={module.scalaVersion}> <sources> {module.sources.map(s => <source>{s}</source>)} </sources> + <scalacOptions> + {module.scalacOptions.map(o => <option>{o}</option>)} + </scalacOptions> <dependencies> - {module.binaryDependencies.map(serialize)} + {module.binaryDependencies.map(serialize)} {module.moduleDependencies.map(serialize)} </dependencies> <classpath> - {module.classpaths.map(serialize)} + {module.classpath.map(c => <classpathItem>{c.toString}</classpathItem>)} </classpath> {module.parentBuild.map(p => <parentBuild>{p}</parentBuild>).getOrElse(NodeSeq.Empty)} </module> - private def serialize(binaryDependency: BuildInformation.BinaryDependency): Node = + private def serialize(binaryDependency: BuildInformation.BinaryDependency): Node = <binaryDependency>{binaryDependency.name}</binaryDependency> - private def serialize(library: BuildInformation.Library): Node = - <library name = {library.name}> + private def serialize(library: BuildInformation.Library): Node = + <library name={library.name}> {library.jars.map(j => <jar>{j}</jar>)} </library> - private def serialize(moduleDependency: BuildInformation.ModuleDependency): Node = - <moduleDependency>{moduleDependency.name}</moduleDependency> + private def serialize(compiler: BuildInformation.ScalaCompiler): Node = + <compiler version={compiler.version}> + {compiler.jars.map(j => <jar>{j}</jar>)} + </compiler> - private def serialize(targetLibrary: BuildInformation.ClassPathItem): Node = - <classpathItem>{targetLibrary.path.toString}</classpathItem> -} + private def serialize(moduleDependency: BuildInformation.ModuleDependency): Node = + <moduleDependency>{moduleDependency.name}</moduleDependency> +}
\ No newline at end of file |