From 932234eb13f39a1d17b338310fb5f41997f35b7f Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Fri, 23 Jun 2017 14:55:55 +0300 Subject: BuildInfo extensions --- stage2/plugins/ExportBuildInformation.scala | 215 +++++++++++++++++----------- 1 file 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 = - + def serialize(project: BuildInformation.Project): Node = + {project.modules.map(serialize)} {project.libraries.map(serialize)} + + {project.cbtLibraries.map(serialize)} + + + {project.scalaCompilers.map(serialize)} + - private def serialize(module: BuildInformation.Module): Node = + private def serialize(module: BuildInformation.Module): Node = {module.sources.map(s => {s})} + + {module.scalacOptions.map(o => )} + - {module.binaryDependencies.map(serialize)} + {module.binaryDependencies.map(serialize)} {module.moduleDependencies.map(serialize)} - {module.classpaths.map(serialize)} + {module.classpath.map(c => {c.toString})} {module.parentBuild.map(p => {p}).getOrElse(NodeSeq.Empty)} - private def serialize(binaryDependency: BuildInformation.BinaryDependency): Node = + private def serialize(binaryDependency: BuildInformation.BinaryDependency): Node = {binaryDependency.name} - private def serialize(library: BuildInformation.Library): Node = - + private def serialize(library: BuildInformation.Library): Node = + {library.jars.map(j => {j})} - private def serialize(moduleDependency: BuildInformation.ModuleDependency): Node = - {moduleDependency.name} + private def serialize(compiler: BuildInformation.ScalaCompiler): Node = + + {compiler.jars.map(j => {j})} + - private def serialize(targetLibrary: BuildInformation.ClassPathItem): Node = - {targetLibrary.path.toString} -} + private def serialize(moduleDependency: BuildInformation.ModuleDependency): Node = + {moduleDependency.name} +} \ No newline at end of file -- cgit v1.2.3