aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Kirillov <darthorimar@users.noreply.github.com>2017-06-14 17:34:08 +0300
committerJan Christopher Vogt <oss.nsp@cvogt.org>2017-06-14 10:34:08 -0400
commit3df15ef7c9c5a48516c06cf7b598acf298d8b8c0 (patch)
treee602f3425bf791e1c5503642af2c42293b9af1e7
parent7a6894fca68f97a542e698772c8bda9faa08eec1 (diff)
downloadcbt-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
-rw-r--r--examples/export-build-information/Main.scala6
-rw-r--r--examples/export-build-information/build/build.scala3
-rw-r--r--examples/export-build-information/build/build/build.scala9
-rw-r--r--stage2/BasicBuild.scala2
-rw-r--r--stage2/plugins/ExportBuildInformation.scala170
5 files changed, 189 insertions, 1 deletions
diff --git a/examples/export-build-information/Main.scala b/examples/export-build-information/Main.scala
new file mode 100644
index 0000000..586aa1d
--- /dev/null
+++ b/examples/export-build-information/Main.scala
@@ -0,0 +1,6 @@
+package export_build_information
+object Main{
+ def main( args: Array[String] ): Unit = {
+ println( Console.GREEN ++ "Hello World" ++ Console.RESET )
+ }
+}
diff --git a/examples/export-build-information/build/build.scala b/examples/export-build-information/build/build.scala
new file mode 100644
index 0000000..23b3f2d
--- /dev/null
+++ b/examples/export-build-information/build/build.scala
@@ -0,0 +1,3 @@
+import cbt._
+
+class Build(val context: Context) extends BaseBuild
diff --git a/examples/export-build-information/build/build/build.scala b/examples/export-build-information/build/build/build.scala
new file mode 100644
index 0000000..c7d5d82
--- /dev/null
+++ b/examples/export-build-information/build/build/build.scala
@@ -0,0 +1,9 @@
+import cbt._
+
+class Build(val context: Context) extends BuildBuild {
+ override def dependencies =
+ super.dependencies ++
+ Resolver(mavenCentral, sonatypeReleases).bind(
+ ScalaDependency( "org.scala-lang.modules", "scala-xml", "1.0.6" )
+ )
+}
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>
+}