diff options
author | Ilya Kirillov <darthorimar@users.noreply.github.com> | 2017-06-14 17:34:08 +0300 |
---|---|---|
committer | Jan Christopher Vogt <oss.nsp@cvogt.org> | 2017-06-14 10:34:08 -0400 |
commit | 3df15ef7c9c5a48516c06cf7b598acf298d8b8c0 (patch) | |
tree | e602f3425bf791e1c5503642af2c42293b9af1e7 /stage2 | |
parent | 7a6894fca68f97a542e698772c8bda9faa08eec1 (diff) | |
download | cbt-3df15ef7c9c5a48516c06cf7b598acf298d8b8c0.tar.gz cbt-3df15ef7c9c5a48516c06cf7b598acf298d8b8c0.tar.bz2 cbt-3df15ef7c9c5a48516c06cf7b598acf298d8b8c0.zip |
Export build information (#511)
* ExportBuildInformation plugin
* Add targetLibraries
* Add ExportBuildInformation to the BaseBuild trait
* Add target, library jars
* fixing mixed tabs and spaces
* fixing indentation
Diffstat (limited to 'stage2')
-rw-r--r-- | stage2/BasicBuild.scala | 2 | ||||
-rw-r--r-- | stage2/plugins/ExportBuildInformation.scala | 170 |
2 files changed, 171 insertions, 1 deletions
diff --git a/stage2/BasicBuild.scala b/stage2/BasicBuild.scala index 05e3c41..0bdbad7 100644 --- a/stage2/BasicBuild.scala +++ b/stage2/BasicBuild.scala @@ -5,7 +5,7 @@ import java.net._ import java.nio.file._ class BasicBuild(final val context: Context) extends BaseBuild -trait BaseBuild extends BuildInterface with DependencyImplementation with SbtDependencyDsl{ +trait BaseBuild extends BuildInterface with DependencyImplementation with SbtDependencyDsl with ExportBuildInformation{ override def equals(other: Any) = { other match { case b: BaseBuild => projectDirectory === b.projectDirectory diff --git a/stage2/plugins/ExportBuildInformation.scala b/stage2/plugins/ExportBuildInformation.scala new file mode 100644 index 0000000..0d33d75 --- /dev/null +++ b/stage2/plugins/ExportBuildInformation.scala @@ -0,0 +1,170 @@ +package cbt + +import cbt._ +import scala.xml._ +import java.io._ + +trait ExportBuildInformation { self: BaseBuild => + lazy val printer = new scala.xml.PrettyPrinter(200, 2) + + def buildInfoXml = + printer.format(BuildInformationSerializer.serialize(BuildInformation.Project(self))) +} + +object BuildInformation { + case class Project( + name: String, + root: File, + rootModule: Module, + modules: Seq[Module], + libraries: Seq[Library] + ) + + case class Module( + name: String, + root: File, + sources: Seq[File], + target: File, + mavenDependencies: Seq[MavenDependency], + moduleDependencies: Seq[ModuleDependency], + classpaths: Seq[ClassPathItem], + parentBuild: Option[String] + ) + + case class Library( name: String, jars: Seq[File] ) + + case class MavenDependency( name: String ) + + case class ModuleDependency( name: String ) + + case class ClassPathItem( path: File ) + + object Project { + def apply(build: BaseBuild) = + new BuildInformationExporter(build).exportBuildInformation + + private class BuildInformationExporter(rootBuild: BaseBuild) { + def exportBuildInformation(): Project = { + val rootModule = exportModule(rootBuild) + val modules = (rootBuild +: rootBuild.transitiveDependencies) + .collect { case d: BaseBuild => d +: collectParentBuilds(d)} + .flatten + .map(exportModule) + .distinct + val libraries = rootBuild.transitiveDependencies + .collect { case d: BoundMavenDependency => exportLibrary(d)} + .distinct + + Project( + rootModule.name, + rootModule.root, + rootModule, + modules, + libraries + ) + } + + private def exportLibrary(mavenDependency: BoundMavenDependency) = + Library(fomatMavenDependency(mavenDependency.mavenDependency), mavenDependency.exportedJars) + + private def collectParentBuilds(build: BaseBuild): Seq[BaseBuild] = + build.context.parentBuild + .map(_.asInstanceOf[BaseBuild]) + .map(b => b +: collectParentBuilds(b)) + .toSeq + .flatten + + private def exportModule(build: BaseBuild): Module = { + val moduleDependencies = build.dependencies + .collect { case d: BaseBuild => ModuleDependency(moduleName(d)) } + val mavenDependencies = build.dependencies + .collect { case d: BoundMavenDependency => MavenDependency(fomatMavenDependency(d.mavenDependency))} + val classpaths = build.dependencyClasspath.files + .filter(_.isFile) + .map(t => ClassPathItem(t)) + val sources = { + val s = build.sources + .filter(s => s.exists && s.isDirectory) + if (s.isEmpty) + Seq(build.projectDirectory) + else + s + } + Module( + name = moduleName(build), + root = build.projectDirectory, + sources = sources, + target = build.target, + mavenDependencies = mavenDependencies, + moduleDependencies = moduleDependencies, + classpaths = classpaths, + parentBuild = build.context.parentBuild.map(b => moduleName(b.asInstanceOf[BaseBuild])) + ) + } + + private def fomatMavenDependency(dependency: cbt.MavenDependency) = + s"${dependency.groupId}:${dependency.artifactId}:${dependency.version}" + + private def moduleName(build: BaseBuild) = + if (rootBuild.projectDirectory == build.projectDirectory) + rootBuild.projectDirectory.getName + else + build.projectDirectory.getPath + .drop(rootBuild.projectDirectory.getPath.length) + .stripPrefix("/") + .replace("/", "-") + } + } +} + +object BuildInformationSerializer { + def serialize(project: BuildInformation.Project): Node = + <project> + <name>{project.name}</name> + <root>{project.root.toString}</root> + <rootModule>{project.rootModule.name}</rootModule> + <modules> + {project.modules.map(serialize)} + </modules> + <libraries> + {project.libraries.map(serialize)} + </libraries> + </project> + + private def serialize(module: BuildInformation.Module): Node = + <module> + <name>{module.name}</name> + <root>{module.root}</root> + <target>{module.target}</target> + <sources> + {module.sources.map(s => <source>{s}</source>)} + </sources> + <mavenDependencies> + {module.mavenDependencies.map(serialize)} + </mavenDependencies> + <moduleDependencies> + {module.moduleDependencies.map(serialize)} + </moduleDependencies> + <classpaths> + {module.classpaths.map(serialize)} + </classpaths> + {module.parentBuild.map(p => <parentBuild>{p}</parentBuild>).getOrElse(NodeSeq.Empty)} + </module> + + private def serialize(mavenDependency: BuildInformation.MavenDependency): Node = + <mavenDependency>{mavenDependency.name}</mavenDependency> + + private def serialize(library: BuildInformation.Library): Node = + <library> + <name>{library.name}</name> + <jars> + {library.jars.map(j => <jar>{j}</jar>)} + </jars> + </library> + + private def serialize(moduleDependency: BuildInformation.ModuleDependency): Node = + <moduleDependency>{moduleDependency.name}</moduleDependency> + + private def serialize(targetLibrary: BuildInformation.ClassPathItem): Node = + <classpathItem>{targetLibrary.path.toString}</classpathItem> +} |