Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

New version of generate ecosystem tool

Added support for Scala IDE version staging.
It is using cleaner structure to hold information about the computed data
The tool generates a build report.
  • Loading branch information...
commit 5001dea470e0d543085751839b7bbfeaee3b29e5 1 parent 1a58782
@skyluc skyluc authored skyluc committed
Showing with 901 additions and 468 deletions.
  1. +27 −0 src/main/scala/org/scalaide/buildtools/AddOn.scala
  2. +3 −2 src/main/scala/org/scalaide/buildtools/Ecosystem.scala
  3. +50 −0 src/main/scala/org/scalaide/buildtools/EcosystemBuild.scala
  4. +37 −0 src/main/scala/org/scalaide/buildtools/EcosystemBuilds.scala
  5. +260 −0 src/main/scala/org/scalaide/buildtools/EcosystemBuildsMavenProjects.scala
  6. +133 −0 src/main/scala/org/scalaide/buildtools/EcosystemBuildsReport.scala
  7. +11 −5 src/main/scala/org/scalaide/buildtools/EcosystemsDescriptor.scala
  8. +23 −18 src/main/scala/org/scalaide/buildtools/FileUtils.scala
  9. +27 −215 src/main/scala/org/scalaide/buildtools/GenerateEcosystemBuilds.scala
  10. +215 −0 src/main/scala/org/scalaide/buildtools/GenerateEcosystemBuildsTake1.scala
  11. +0 −190 src/main/scala/org/scalaide/buildtools/MavenProject.scala
  12. +6 −10 src/main/scala/org/scalaide/buildtools/MavenProject2.scala
  13. +56 −14 src/main/scala/org/scalaide/buildtools/P2Repository.scala
  14. +33 −0 src/main/scala/org/scalaide/buildtools/ScalaIDEVersion.scala
  15. +6 −1 src/main/scala/org/scalaide/buildtools/UpdateAddonManifests.scala
  16. +4 −4 src/test/scala/org/scalaide/buildtools/EcosystemsDescriptorTests.scala
  17. +2 −5 src/test/scala/org/scalaide/buildtools/RemoteRepositoryTest.scala
  18. +8 −4 src/test/scala/org/scalaide/buildtools/ecosystems.conf
View
27 src/main/scala/org/scalaide/buildtools/AddOn.scala
@@ -0,0 +1,27 @@
+package org.scalaide.buildtools
+
+import org.osgi.framework.Version
+
+case class AddOn(conf: PluginDescriptor, iu: InstallableUnit, repository: P2Repository) {
+ import Ecosystem._
+
+ // TODO: need to check for missing information
+
+ lazy val scalaIDEVersion: Version = findStrictVersion(findDependency(ScalaIDEFeatureIdOsgi).get.range)
+
+ val version = iu.version
+
+ def id= conf.featureId
+
+ private def findDependency(id: String) = iu.dependencies.find(_.id == id)
+
+ private def findStrictVersion(range: String) = {
+ range match {
+ case RangeRegex(low, high) if (low == high) =>
+ new Version(low)
+ case _ =>
+ UndefinedVersion
+ }
+ }
+
+}
View
5 src/main/scala/org/scalaide/buildtools/Ecosystem.scala
@@ -34,8 +34,9 @@ object Ecosystem {
/** regex to find the root option in the command line */
val RootOption = "--root=(.*)".r
- // regex for the config file
- val ConfigComment = "#.*".r
+ val RangeRegex = "\\[([^,]*),([^\\]]*)\\]".r
+
+ val UndefinedVersion = new Version(0, 0, 0)
/** regex to find the given bundle id dependency in a manifest file */
def idInManifest(id: String) = ("(.*" + id + ")(,?.*)").r
View
50 src/main/scala/org/scalaide/buildtools/EcosystemBuild.scala
@@ -0,0 +1,50 @@
+package org.scalaide.buildtools
+
+object EcosystemBuild {
+
+ import Ecosystem._
+
+ def apply(ecosystemConf: EcosystemDescriptor, availableAddOns: Map[PluginDescriptor, Seq[AddOn]], featureConfs: Seq[PluginDescriptor]): EcosystemBuild = {
+
+ val siteRepo = Repositories(ecosystemConf.site)
+ val nextSiteRepo = Repositories(ecosystemConf.nextSite)
+ val existingAddOns = EcosystemBuilds.findAvailableFeaturesFrom(featureConfs, siteRepo)
+ val nextExistingAddOns = EcosystemBuilds.findAvailableFeaturesFrom(featureConfs, nextSiteRepo)
+ val baseRepo = Repositories(ecosystemConf.base)
+ val baseScalaIDEVersions = findScalaIDEVersions(baseRepo, existingAddOns, availableAddOns, siteRepo, featureConfs)
+ val nextBaseRepo = Repositories(ecosystemConf.nextBase)
+ val nextScalaIDEVersions = findScalaIDEVersions(nextBaseRepo, nextExistingAddOns, availableAddOns, nextSiteRepo, featureConfs)
+
+ EcosystemBuild(
+ ecosystemConf.id,
+ baseRepo,
+ baseScalaIDEVersions,
+ nextBaseRepo,
+ nextScalaIDEVersions,
+ siteRepo,
+ nextSiteRepo,
+ existingAddOns,
+ nextExistingAddOns)
+ }
+
+ private def findScalaIDEVersions(baseRepo: P2Repository, existingAddOns: Map[PluginDescriptor, Seq[AddOn]], availableAddOns: Map[PluginDescriptor, Seq[AddOn]], siteRepo: P2Repository, featureConfs: Seq[PluginDescriptor]): Seq[ScalaIDEVersion] = {
+ baseRepo.findIU(ScalaIDEFeatureIdOsgi).toSeq.map(ScalaIDEVersion(_, baseRepo, existingAddOns, availableAddOns, siteRepo))
+ }
+
+}
+
+case class EcosystemBuild(
+ id: String,
+ baseRepo: P2Repository,
+ baseScalaIDEVersions: Seq[ScalaIDEVersion],
+ nextRepo: P2Repository,
+ nextScalaIDEVersions: Seq[ScalaIDEVersion],
+ siteRepo: P2Repository,
+ nextSiteRepo: P2Repository,
+ existingAddOns: Map[PluginDescriptor, Seq[AddOn]],
+ nextExistingAddOns: Map[PluginDescriptor, Seq[AddOn]]) {
+
+ val regenerateEcosystem: Boolean = !baseScalaIDEVersions.forall(_.associatedAvailableAddOns.isEmpty)
+
+ val regenerateNextEcosystem: Boolean = !nextScalaIDEVersions.forall(_.associatedAvailableAddOns.isEmpty)
+}
View
37 src/main/scala/org/scalaide/buildtools/EcosystemBuilds.scala
@@ -0,0 +1,37 @@
+package org.scalaide.buildtools
+
+object EcosystemBuilds {
+
+ import Ecosystem._
+
+ def apply(ecosystemConfs: Seq[EcosystemDescriptor], featureConfs: Seq[PluginDescriptor]): EcosystemBuilds = {
+ val availableAddOns = findAvailableFeatures(featureConfs)
+ new EcosystemBuilds(ecosystemConfs.map(c => EcosystemBuild(c, availableAddOns, featureConfs)), availableAddOns)
+ }
+
+ def findAvailableFeatures(featureConfs: Seq[PluginDescriptor]): Map[PluginDescriptor, Seq[AddOn]] = {
+ featureConfs.map {
+ f =>
+ (f -> f.updateSites.flatMap(r => findAvailableFeatureVersionsFrom(f, Repositories(r))))
+ }.toMap
+ }
+
+ def findAvailableFeaturesFrom(featureConfs: Seq[PluginDescriptor], repo: P2Repository): Map[PluginDescriptor, Seq[AddOn]] = {
+ featureConfs.flatMap {
+ f =>
+ findAvailableFeatureVersionsFrom(f, repo) match {
+ case Nil =>
+ None
+ case l: Seq[AddOn] =>
+ Some((f -> l))
+ }
+ }.toMap
+ }
+
+ def findAvailableFeatureVersionsFrom(featureConf: PluginDescriptor, repository: P2Repository): Seq[AddOn] = {
+ repository.findIU(featureConf.featureId + FeatureSuffix).toSeq.map(AddOn(featureConf, _, repository))
+ }
+
+}
+
+case class EcosystemBuilds(ecosystems: Seq[EcosystemBuild], availableAddOns: Map[PluginDescriptor, Seq[AddOn]]) {}
View
260 src/main/scala/org/scalaide/buildtools/EcosystemBuildsMavenProjects.scala
@@ -0,0 +1,260 @@
+package org.scalaide.buildtools
+
+import java.io.File
+
+object EcosystemBuildsMavenProjects {
+
+ private val artifactIdSuffix = Iterator.from(1)
+
+ def generate(builds: EcosystemBuilds, targetFolder: File) {
+ val buildFolder= new File(targetFolder, "builds")
+
+ if (buildFolder.exists) {
+ FileUtils.deleteFull(buildFolder)
+ }
+ buildFolder.mkdirs()
+
+ val ecosystemFolders = builds.ecosystems.flatMap(generateEcosystemProjects(_, buildFolder))
+
+ if (ecosystemFolders.isEmpty) {
+ println("Nothing to do")
+ } else {
+ FileUtils.saveXml(new File(buildFolder, "pom.xml"), createTopPomXml(ecosystemFolders))
+ }
+
+ }
+
+ def generateEcosystemProjects(ecosystemBuild: EcosystemBuild, buildFolder: File): Seq[File]= {
+ val ecosystemFolder= new File(buildFolder, ecosystemBuild.id)
+
+ val siteFolder = if (ecosystemBuild.regenerateEcosystem) {
+ Some(generateEcosystemProject(ecosystemBuild.baseScalaIDEVersions, "%s-base".format(ecosystemBuild.id), ecosystemBuild.baseRepo, buildFolder))
+ } else {
+ None
+ }
+
+ val nextFolder = if (ecosystemBuild.regenerateNextEcosystem) {
+ Some(generateEcosystemProject(ecosystemBuild.nextScalaIDEVersions, "%s-next".format(ecosystemBuild.id), ecosystemBuild.nextRepo, buildFolder))
+ } else {
+ None
+ }
+
+ Seq(siteFolder, nextFolder).flatten
+ }
+
+ def generateEcosystemProject(scalaIDEVersions: Seq[org.scalaide.buildtools.ScalaIDEVersion], tag: String, baseRepository: P2Repository, buildFolder: File): File = {
+ val siteFolder= new File(buildFolder, tag)
+ siteFolder.mkdirs()
+
+ val artifactId = "ecosystem.%s".format(tag)
+
+ val featureFolders = scalaIDEVersions.flatMap(generateScalaIDEProjects(_, artifactId, siteFolder))
+
+ FileUtils.saveXml(new File(siteFolder, "pom.xml"), createEcosystemPomXml(artifactId, baseRepository, featureFolders))
+
+ siteFolder
+ }
+
+ def generateScalaIDEProjects(scalaIDEVersion: ScalaIDEVersion, parentId: String, siteFolder: File): Seq[File] = {
+ val scalaIDEFolder= new File(siteFolder, scalaIDEVersion.version.toString)
+ scalaIDEFolder.mkdir()
+
+ (scalaIDEVersion.associatedExistingAddOns ++ scalaIDEVersion.associatedAvailableAddOns).map {
+ case (_, addOn) =>
+ generateAddOnProject(addOn, scalaIDEVersion, parentId, scalaIDEFolder)
+ }.toSeq
+ }
+
+ def generateAddOnProject(addOn: AddOn, scalaIDEVersion: ScalaIDEVersion, parentId: String, scalaIDEFolder: File): File = {
+ val addOnFolder= new File(scalaIDEFolder, addOn.id)
+ addOnFolder.mkdir()
+
+ FileUtils.saveXml(new File(addOnFolder, "pom.xml"), createAddOnPomXml(addOn, scalaIDEVersion, parentId))
+ FileUtils.saveXml(new File(addOnFolder, "site.xml"), createAddOnSiteXml(addOn))
+
+ addOnFolder
+ }
+
+ def createTopPomXml(ecosystemFolders: Seq[File]) = {
+ <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+ <groupId>org.scalaide</groupId>
+ <artifactId>ecosystem.build</artifactId>
+ <version>0.1.0-SNAPSHOT</version>
+ <description>Build a repository containing multiple versions</description>
+ <packaging>pom</packaging>
+ <properties>
+ <encoding>UTF-8</encoding>
+ <tycho.version>0.15.0</tycho.version>
+ </properties>
+ <modules>
+ {
+ ecosystemFolders.map { f =>
+ <module>{ f.getName }</module>
+ }
+ }
+ </modules>
+ </project>
+ }
+
+
+
+ def createEcosystemPomXml(artifactId: String, baseRepository: P2Repository, featureFolders: Seq[File]) = {
+ <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+ <parent>
+ <groupId>org.scalaide</groupId>
+ <artifactId>ecosystem.build</artifactId>
+ <version>0.1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>{ artifactId }</artifactId>
+ <version>0.1.0-SNAPSHOT</version>
+ <description>Build a repository containing multiple versions</description>
+ <packaging>pom</packaging>
+ <properties>
+ <encoding>UTF-8</encoding>
+ <tycho.version>0.15.0</tycho.version>
+ </properties>
+ <profiles>
+ <profile>
+ <id>package</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho.extras</groupId>
+ <artifactId>tycho-p2-extras-plugin</artifactId>
+ <version>${{tycho.version}}</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>mirror</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <source>
+ <repository>
+ <url>{ baseRepository.location }</url>
+ <layout>p2</layout>
+ </repository>
+ {
+ featureFolders.map { f =>
+ <repository>
+ <url>{ new File(f, "target/site").toURI() }</url>
+ <layout>p2</layout>
+ </repository>
+
+ }
+ }
+ </source>
+ <destination>${{project.build.directory}}/site</destination>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>build</id>
+ <modules>
+ {
+ featureFolders.map { f =>
+ <module>{ "%s/%s".format(f.getParentFile.getName, f.getName) }</module>
+ }
+ }
+ </modules>
+ </profile>
+ </profiles>
+ </project>
+ }
+
+
+ def createAddOnPomXml(addOn: AddOn, scalaIDEVersion: ScalaIDEVersion, parentId: String) = {
+ // TODO: support for non-indigo build
+ <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+ <parent>
+ <groupId>org.scalaide</groupId>
+ <artifactId>{ parentId }</artifactId>
+ <version>0.1.0-SNAPSHOT</version>
+ <relativePath>../..</relativePath>
+ </parent>
+ <artifactId>org.scala-ide.ecosystem.generated{ artifactIdSuffix.next }</artifactId>
+ <version>0.1.0-SNAPSHOT</version>
+ <description>Build project for the scalatest support in Scala IDE</description>
+ <packaging>eclipse-update-site</packaging>
+ <properties>
+ <encoding>UTF-8</encoding>
+ <tycho.version>0.15.0</tycho.version>
+ <!-- p2 repositories location -->
+ <repo.eclipse.indigo>http://download.eclipse.org/releases/indigo/</repo.eclipse.indigo>
+ <!-- dependencies repos -->
+ <eclipse.codename>indigo</eclipse.codename>
+ </properties>
+ <repositories>
+ <repository>
+ <id>eclipse.indigo</id>
+ <name>Eclipse p2 repository</name>
+ <layout>p2</layout>
+ <url>http://download.eclipse.org/releases/indigo/</url>
+ </repository>
+ <repository>
+ <id>scalaide.repo</id>
+ <layout>p2</layout>
+ <url>{ scalaIDEVersion.repository.location }</url>
+ </repository>
+ <repository>
+ <id>feature.repo</id>
+ <layout>p2</layout>
+ <url>{ addOn.repository.location }</url>
+ </repository>
+ </repositories>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-maven-plugin</artifactId>
+ <version>${{tycho.version}}</version>
+ <extensions>true</extensions>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-packaging-plugin</artifactId>
+ <version>${{tycho.version}}</version>
+ <configuration>
+ <archiveSite>true</archiveSite>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </project>
+ }
+
+ def createAddOnSiteXml(addOn: AddOn) = {
+ // TODO: fix category
+ // TODO: fix sourceFeatureId, should be option
+ <site>
+ { featureXml(addOn.conf.featureId, addOn.version.toString, "incubation") }
+ { featureXml(addOn.conf.sourceFeatureId, addOn.version.toString, "source") }
+ <category-def name="stable" label="Scala IDE plugins"/>
+ <category-def name="incubation" label="Scala IDE plugins (incubation)"/>
+ <category-def name="source" label="Sources"/>
+ </site>
+ }
+
+ private def featureXml(id: String, version: String, category: String) = {
+ <feature url={ "features/" + id + "_0.0.0.jar" } id={ id } version={ version }>
+ <category name={ category }/>
+ </feature>
+ }
+
+}
View
133 src/main/scala/org/scalaide/buildtools/EcosystemBuildsReport.scala
@@ -0,0 +1,133 @@
+package org.scalaide.buildtools
+
+import java.io.File
+import scala.xml.Elem
+
+object EcosystemBuildsReport {
+
+ def generate(builds: EcosystemBuilds, targeFolder: File) {
+ new EcosystemBuildsReport(builds, targeFolder).generate()
+ }
+
+}
+
+private class EcosystemBuildsReport(builds: EcosystemBuilds, targetFolder: File) {
+
+ def generate() {
+
+ val content =
+ <html>
+ <head>
+ <style type="text/css">
+ div.ecosystem {{border-width: 1px; border: solid; border-color: gray;}}
+ div.availableAddOns {{border-width: 1px; border: solid; border-color: gray;}}
+ .red {{color: red;}}
+ .blue {{color: blue;}}
+ </style>
+ </head>
+ <body>
+ <div class="availableAddOns">
+ <h1>Available add-ons</h1>
+ { availableAddOns(builds.availableAddOns) }
+ </div>
+ { builds.ecosystems.map(generate(_)) }
+ </body>
+ </html>
+
+ FileUtils.saveXml(new File(targetFolder, "builds.html"), content)
+ }
+
+ def generate(build: EcosystemBuild) = {
+ <div class="ecosystem">
+ <h1>{ build.id }</h1>
+ <div>
+ <h2>Available Scala IDE versions:</h2>
+ { availableScalaIDEVersions(build.baseRepo, build.baseScalaIDEVersions) }
+ { availableScalaIDEVersions(build.nextRepo, build.nextScalaIDEVersions) }
+ </div>
+ <div>
+ <h2>Existing add-ons</h2>
+ { existingAddOns(build.siteRepo, build.existingAddOns) }
+ { existingAddOns(build.nextSiteRepo, build.nextExistingAddOns) }
+ </div>
+ <div>
+ <h2>Updated ecosystem { rebuiltComment(build.regenerateEcosystem) }</h2>
+ { build.baseScalaIDEVersions.map(scalaIDEVersionWithAddOns(_)) }
+ </div>
+ <div>
+ <h2>Next ecosystem { rebuiltComment(build.regenerateNextEcosystem) }</h2>
+ { build.nextScalaIDEVersions.map(scalaIDEVersionWithAddOns(_)) }
+ </div>
+ </div>
+ }
+
+ def rebuiltComment(rebuilt: Boolean) = {
+ if (rebuilt)
+ <span class="blue">- rebuilt</span>
+ else
+ <span class="red">- not rebuilt</span>
+ }
+
+ def availableScalaIDEVersions(repo: P2Repository, scalaIDEVersions: Seq[ScalaIDEVersion]) = {
+ repo match {
+ case p: ValidP2Repository =>
+ <div>
+ <h3>{ repo.location }:</h3>
+ { scalaIDEVersions.map(s => <div>{ s.version }</div>) }
+ </div>
+ case e: ErrorP2Repository =>
+ <div><h3>{ repo.location }:</h3>Not available.</div>
+ }
+ }
+
+ def existingAddOns(repo: P2Repository, addOns: Map[PluginDescriptor, Seq[AddOn]]) = {
+ repo match {
+ case p: ValidP2Repository =>
+ <div>
+ <h3>{ repo.location }:</h3>
+ { availableAddOns(addOns) }
+ </div>
+ case e: ErrorP2Repository =>
+ <div><h3>{ repo.location }:</h3>Not available.</div>
+ }
+ }
+
+ def availableAddOns(addOns: Map[PluginDescriptor, Seq[AddOn]]) = {
+ addOns.map { p =>
+ <div>
+ <h4> { p._1.featureId }</h4>
+ { p._2.map { a => <div>{ a.iu.version }</div> } }
+ </div>
+ }
+ }
+
+ def scalaIDEVersionWithAddOns(scalaIDEVersion: ScalaIDEVersion) = {
+ <div>
+ <h3>{ scalaIDEVersion.version }</h3>
+ <div>
+ <h4>Existing add-ons</h4>
+ {
+ scalaIDEVersion.associatedExistingAddOns.map {
+ case (p, a) => usedAddOns(p, a)
+ }
+ }
+ </div>
+ <div>
+ <h4>Updated add-ons</h4>
+ {
+ scalaIDEVersion.associatedAvailableAddOns.map {
+ case (p, a) => usedAddOns(p, a)
+ }
+ }
+ </div>
+ </div>
+ }
+
+ def usedAddOns(pluginDescriptor: PluginDescriptor, addon: AddOn) = {
+ <div>
+ <b>{ pluginDescriptor.featureId }</b>
+ -&nbsp;{ addon.version }
+ </div>
+ }
+
+}
View
16 src/main/scala/org/scalaide/buildtools/EcosystemsDescriptor.scala
@@ -40,9 +40,13 @@ class EcosystemsDescriptor(config: Config) {
for(ecosystemId <- ids) yield {
val site = config.getString(EcosystemsDescriptor.Keys.site(ecosystemId))
val siteUrl = new URL(site)
- val baseSite = config.getString(EcosystemsDescriptor.Keys.baseSite(ecosystemId))
- val baseSiteUrl = new URL(baseSite)
- EcosystemDescriptor(ecosystemId, siteUrl, baseSiteUrl)
+ val base = config.getString(EcosystemsDescriptor.Keys.base(ecosystemId))
+ val baseUrl = new URL(base)
+ val nextSite = config.getString(EcosystemsDescriptor.Keys.nextSite(ecosystemId))
+ val nextSiteUrl = new URL(nextSite)
+ val nextBase = config.getString(EcosystemsDescriptor.Keys.nextBase(ecosystemId))
+ val nextBaseUrl = new URL(nextBase)
+ EcosystemDescriptor(ecosystemId, siteUrl, baseUrl, nextSiteUrl, nextBaseUrl)
}
}
}
@@ -52,7 +56,9 @@ object EcosystemsDescriptor {
val root = "ecosystems-descriptor"
val idsKey = root + ".ids"
def site(ecosystemId: String): String = root + "." + ecosystemId + ".site"
- def baseSite(ecosystemId: String): String = root + "." + ecosystemId + ".baseSite"
+ def base(ecosystemId: String): String = root + "." + ecosystemId + ".base"
+ def nextSite(ecosystemId: String): String = root + "." + ecosystemId + ".nextSite"
+ def nextBase(ecosystemId: String): String = root + "." + ecosystemId + ".nextBase"
}
def load(file: File): EcosystemsDescriptor = {
@@ -60,4 +66,4 @@ object EcosystemsDescriptor {
}
}
-final case class EcosystemDescriptor(id: String, site: URL, baseSite: URL)
+final case class EcosystemDescriptor(id: String, site: URL, base: URL, nextSite: URL, nextBase: URL)
View
41 src/main/scala/org/scalaide/buildtools/FileUtils.scala
@@ -3,27 +3,32 @@ package org.scalaide.buildtools
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
+import scala.xml.XML
+import scala.xml.Elem
object FileUtils {
- def copyFile(in: File, out: File)
- {
- val inChannel = new FileInputStream(in).getChannel();
- val outChannel = new FileOutputStream(out).getChannel();
- try {
- inChannel.transferTo(0, inChannel.size(),
- outChannel);
- }
- finally {
- if (inChannel != null) inChannel.close();
- if (outChannel != null) outChannel.close();
- }
+ def copyFile(in: File, out: File) {
+ val inChannel = new FileInputStream(in).getChannel();
+ val outChannel = new FileOutputStream(out).getChannel();
+ try {
+ inChannel.transferTo(0, inChannel.size(),
+ outChannel);
+ } finally {
+ if (inChannel != null) inChannel.close();
+ if (outChannel != null) outChannel.close();
}
-
- def deleteFull(file: File) {
- if (file.isDirectory()) {
- file.listFiles().foreach(deleteFull(_))
- }
- file.delete()
+ }
+
+ def deleteFull(file: File) {
+ if (file.isDirectory()) {
+ file.listFiles().foreach(deleteFull(_))
}
+ file.delete()
+ }
+
+ def saveXml(file: File, xml: Elem) {
+ XML.save(file.getAbsolutePath(), xml, "UTF-8", true)
+ }
+
}
View
242 src/main/scala/org/scalaide/buildtools/GenerateEcosystemBuilds.scala
@@ -1,33 +1,13 @@
package org.scalaide.buildtools
import java.io.File
-import scala.annotation.tailrec
-import scala.collection.mutable.HashMap
-import java.net.URL
-import org.osgi.framework.Version
-import scala.collection.immutable.TreeSet
+import scala.Option.option2Iterable
+import Ecosystem.EcosystemConfigFile
+import Ecosystem.RootOption
import dispatch.Http
-/**
- * !!! This object not thread safe !!! It was used in a single threaded system when implemented.
- */
-object Repositories {
-
- val repos = HashMap[URL, Either[String, P2Repository]]()
-
- def apply(location: URL): Either[String, P2Repository] = {
- repos.get(location) match {
- case Some(repo) =>
- repo
- case None =>
- val repo = P2Repository.fromUrl(location)
- repos.put(location, repo)
- repo
- }
- }
-}
-
object GenerateEcosystemBuilds {
+
import Ecosystem._
def main(args: Array[String]) {
@@ -38,209 +18,41 @@ object GenerateEcosystemBuilds {
root
}.getOrElse(System.getProperty("user.dir"))
- new GenerateEcosystemBuilds(rootFolder)()
+ new GenerateEcosystemBuilds(new File(rootFolder))()
}
-
}
-class GenerateEcosystemBuilds(rootFolder: String) {
- import Ecosystem._
-
- def apply(): Either[String, AnyRef] = {
-
- val ecosystems = EcosystemsDescriptor.load(new File(rootFolder, EcosystemConfigFile)).ecosystems
- val requestedFeatures = PluginDescriptor.loadAll(new File(rootFolder, "features")).flatMap(_ match {
- case Right(conf) =>
- Some(conf)
- case Left(_) =>
- None
- })
-
- val res= for {
- availableFeatures <- findFeatures(requestedFeatures.toList).right
- ecosystemToScalaIDEToAvailableFeatures <- getAvailableScalaIDEs(ecosystems, requestedFeatures.toList, availableFeatures).right
- } yield MavenProject2.generateEcosystemsProjects(ecosystemToScalaIDEToAvailableFeatures, new File(rootFolder, "target/builds"))
+class GenerateEcosystemBuilds(rootFolder: File) {
-
- // need to stop Dispatch in any cases
- Http.shutdown()
- res
-
- }
-
- private def getAvailableScalaIDEs(ecosystems: List[EcosystemDescriptor], requestedFeatures: List[PluginDescriptor], availableFeatures: List[FeatureDefinition]): Either[String, Map[EcosystemDescriptor, Map[ScalaIDEDefinition, Features]]] = {
- @tailrec
- def loop(repositories: List[EcosystemDescriptor], definitions: Map[EcosystemDescriptor, Map[ScalaIDEDefinition, Features]]): Either[String, Map[EcosystemDescriptor, Map[ScalaIDEDefinition, Features]]] = {
- repositories match {
- case Nil =>
- Right(definitions)
- case head :: tail =>
- findScalaIDEsAndResolvedAvailableFeatures(head, requestedFeatures, availableFeatures) match {
- case Left(error) =>
- Left(error)
- case Right(scalaIDEs) =>
- loop(tail, definitions + (head -> scalaIDEs))
- }
- }
- }
- loop(ecosystems, Map())
- }
-
- private def findScalaIDEsAndResolvedAvailableFeatures(ecosystem: EcosystemDescriptor, requestedFeatures: List[PluginDescriptor], availableFeatures: List[FeatureDefinition]): Either[String, Map[ScalaIDEDefinition, Features]] = {
- for {
- repository <- Repositories(ecosystem.site).right
- baseRepository <- Repositories(ecosystem.baseSite).right
- } yield findScalaIDEsAndResolvedAvailableFeatures(repository, baseRepository, requestedFeatures, availableFeatures)
- }
-
- private def findScalaIDEsAndResolvedAvailableFeatures(repository: P2Repository, baseRepository: P2Repository, requestedFeatures: List[PluginDescriptor], availableFeatures: List[FeatureDefinition]): Map[ScalaIDEDefinition, Features] = {
- val allAvailableFeatures = mergeFeatureList(findExistingFeatures(requestedFeatures, repository), availableFeatures)
-
- baseRepository.findIU(ScalaIDEFeatureIdOsgi).foldLeft(Map[ScalaIDEDefinition, Features]())((m, ui) =>
- // TODO: might be a nice place to check versions
- m + (ScalaIDEDefinition(ui, baseRepository) -> filterFeaturesFor(ui, allAvailableFeatures, repository)))
- }
-
- private def filterFeaturesFor(scalaIDE: InstallableUnit, availableFeatures: List[FeatureDefinition], baseRepository: P2Repository): Features = {
- val lists= availableFeatures.filter(f => ScalaIDEDefinition.matches(scalaIDE.version, f.sdtFeatureRange.range)).groupBy(_.details.featureId).map(t => TreeSet(t._2: _*)(FeatureDefinition.DescendingOrdering).head).toList.partition(_.repository == baseRepository)
- Features(lists._2, lists._1)
- }
+ import Ecosystem._
- private def findFeatures(requestedFeatures: List[PluginDescriptor]): Either[String, List[FeatureDefinition]] = {
- Right(requestedFeatures.flatMap(findFeatures(_)))
- }
+ def apply() {
+ try {
+ println("Generating ecosystem builds")
- private def findFeatures(requestedFeature: PluginDescriptor): List[FeatureDefinition] = {
- requestedFeature.updateSites.flatMap { location =>
- Repositories(location) match {
- case Right(p2repo) =>
- findFeatures(requestedFeature, p2repo)
+ val ecosystemConfs = EcosystemsDescriptor.load(new File(rootFolder, EcosystemConfigFile)).ecosystems
+ val featureConfs = PluginDescriptor.loadAll(new File(rootFolder, "features")).flatMap(_ match {
+ case Right(conf) =>
+ Some(conf)
case Left(_) =>
- Nil
- }
- }
- }
-
- private def findFeatures(feature: PluginDescriptor, repository: P2Repository): List[FeatureDefinition] = {
- repository.findIU(feature.featureId + FeatureSuffix).toList.map(FeatureDefinition(feature, _, repository))
- }
+ None
+ })
- private def mergeFeatureList(base: List[FeatureDefinition], toMerge: List[FeatureDefinition]): List[FeatureDefinition] = {
+ val builds = EcosystemBuilds(ecosystemConfs, featureConfs)
- def loop(toProcess: List[FeatureDefinition]): List[FeatureDefinition] = {
- toProcess match {
- case Nil =>
- base
- case head :: tail =>
- if (base.exists(f => f.details == head.details && f.version == head.version)) {
- loop(tail)
- } else {
- loop(tail) :+ head
- }
+ val targetFolder = new File(rootFolder, "target")
+ if (!targetFolder.exists()) {
+ targetFolder.mkdirs()
}
- }
- val res = loop(toMerge)
- res
- }
- private def findExistingFeatures(requestedFeatures: List[PluginDescriptor], repository: P2Repository): List[FeatureDefinition] = {
- requestedFeatures.flatMap(findFeatures(_, repository))
- }
+ EcosystemBuildsReport.generate(builds, targetFolder)
+ EcosystemBuildsMavenProjects.generate(builds, targetFolder)
- private def findAssociatedFeatures() {
-
- }
-
-}
-
-case class ScalaIDEDefinition(
- sdtFeatureVersion: Version,
- sdtCoreVersion: Option[DependencyUnit],
- scalaLibraryVersion: Option[DependencyUnit],
- scalaCompilerVersion: Option[DependencyUnit], repository: P2Repository)
-
-object ScalaIDEDefinition {
- import Ecosystem._
-
- private val RangeRegex = "\\[([^,]*),([^\\]]*)\\]".r
-
- def apply(feature: InstallableUnit, repository: P2Repository): ScalaIDEDefinition = {
-
- val dependencies = allDependencies(feature, repository)
-
- val sdtCore = dependencies.find(_.id == ScalaIDEId)
- val scalaLibrary = dependencies.find(_.id == ScalaLibraryId)
- val scalaCompiler = dependencies.find(_.id == ScalaCompilerId)
-
- new ScalaIDEDefinition(feature.version, sdtCore, scalaLibrary, scalaCompiler, repository)
- }
-
- def allDependencies(iu: InstallableUnit, repository: P2Repository): List[DependencyUnit] = {
- iu.dependencies ++ iu.dependencies.flatMap(allDependencies(_, repository))
- }
-
- def allDependencies(du: DependencyUnit, repository: P2Repository): List[DependencyUnit] = {
- repository.findIU(du.id).toList.filter(iu => matches(iu.version, du.range)) match {
- case Nil =>
- // not part of this repository, fine
- Nil
- case List(iu) =>
- // this is the one we are looking for
- val dep = allDependencies(iu, repository)
- dep
- case _ =>
- // more than one?
- Nil // TODO: better return value?
- }
- }
-
- def matches(version: Version, range: String): Boolean = {
- range match {
- case RangeRegex(low, high) if (low == high) =>
- // we care only about strict versions so far
- // TODO: may need to improve that
- version.equals(new Version(low))
- case _ =>
- false
+ println("Generating ecosystem builds - Done")
+ } finally {
+ // need to stop Dispatch in any cases
+ Http.shutdown()
}
}
-}
-
-case class FeatureDefinition(
- details: PluginDescriptor,
- version: Version,
- sdtFeatureRange: DependencyUnit,
- sdtCoreRange: DependencyUnit,
- scalaLibraryRange: DependencyUnit,
- scalaCompilerRange: DependencyUnit,
- repository: P2Repository)
-
-object FeatureDefinition {
- import Ecosystem._
-
- def apply(details: PluginDescriptor, iu: InstallableUnit, repository: P2Repository): FeatureDefinition = {
- val dependencies = ScalaIDEDefinition.allDependencies(iu, repository)
-
- val sdtCore = dependencies.find(_.id == ScalaIDEId)
- val scalaLibrary = dependencies.find(_.id == ScalaLibraryId)
- val scalaCompiler = dependencies.find(_.id == ScalaCompilerId)
- val sdtFeature = dependencies.find(_.id == ScalaIDEFeatureIdOsgi)
-
- // TODO: add support for source features
-
- // TODO: need to handle error cases, and check versions ...
-
- new FeatureDefinition(details, iu.version, sdtFeature.get, sdtCore.get, scalaLibrary.get, scalaCompiler.get, repository)
- }
-
- implicit object DescendingOrdering extends Ordering[FeatureDefinition] {
- override def compare(x: FeatureDefinition, y: FeatureDefinition): Int = {
- val diffId = x.details.featureId.compareTo(y.details.featureId)
- if (diffId == 0) -1 * x.version.compareTo(y.version) // same bundle name, compare versions
- else diffId
- }
- }
-
-}
-case class Features(available: List[FeatureDefinition], existing: List[FeatureDefinition])
+}
View
215 src/main/scala/org/scalaide/buildtools/GenerateEcosystemBuildsTake1.scala
@@ -0,0 +1,215 @@
+package org.scalaide.buildtools
+
+import java.io.File
+import scala.annotation.tailrec
+import scala.collection.mutable.HashMap
+import java.net.URL
+import org.osgi.framework.Version
+import scala.collection.immutable.TreeSet
+import dispatch.Http
+
+object GenerateEcosystemBuildsTake1 {
+ import Ecosystem._
+
+ def main(args: Array[String]) {
+ // parse arguments
+
+ val rootFolder = args.collectFirst {
+ case RootOption(root) =>
+ root
+ }.getOrElse(System.getProperty("user.dir"))
+
+ new GenerateEcosystemBuildsTake1(rootFolder)()
+ }
+
+}
+
+class GenerateEcosystemBuildsTake1(rootFolder: String) {
+ import Ecosystem._
+
+ def apply(): Either[String, AnyRef] = {
+
+ val ecosystems = EcosystemsDescriptor.load(new File(rootFolder, EcosystemConfigFile)).ecosystems
+ val requestedFeatures = PluginDescriptor.loadAll(new File(rootFolder, "features")).flatMap(_ match {
+ case Right(conf) =>
+ Some(conf)
+ case Left(_) =>
+ None
+ })
+
+ val res = for {
+ availableFeatures <- findFeatures(requestedFeatures.toList).right
+ ecosystemToScalaIDEToAvailableFeatures <- getAvailableScalaIDEs(ecosystems, requestedFeatures.toList, availableFeatures).right
+ } yield MavenProject2.generateEcosystemsProjects(ecosystemToScalaIDEToAvailableFeatures, new File(rootFolder, "target/builds"))
+
+ // need to stop Dispatch in any cases
+ Http.shutdown()
+ res
+
+ }
+
+ private def getAvailableScalaIDEs(ecosystems: List[EcosystemDescriptor], requestedFeatures: List[PluginDescriptor], availableFeatures: List[FeatureDefinition]): Either[String, Map[EcosystemDescriptor, Map[ScalaIDEDefinition, Features]]] = {
+ @tailrec
+ def loop(repositories: List[EcosystemDescriptor], definitions: Map[EcosystemDescriptor, Map[ScalaIDEDefinition, Features]]): Either[String, Map[EcosystemDescriptor, Map[ScalaIDEDefinition, Features]]] = {
+ repositories match {
+ case Nil =>
+ Right(definitions)
+ case head :: tail =>
+ loop(tail, definitions + (head -> findScalaIDEsAndResolvedAvailableFeatures(head, requestedFeatures, availableFeatures)))
+ }
+ }
+ loop(ecosystems, Map())
+ }
+
+ private def findScalaIDEsAndResolvedAvailableFeatures(ecosystem: EcosystemDescriptor, requestedFeatures: List[PluginDescriptor], availableFeatures: List[FeatureDefinition]): Map[ScalaIDEDefinition, Features] = {
+ val repository = Repositories(ecosystem.site)
+ val baseRepository = Repositories(ecosystem.base)
+ findScalaIDEsAndResolvedAvailableFeatures(repository, baseRepository, requestedFeatures, availableFeatures)
+ }
+
+ private def findScalaIDEsAndResolvedAvailableFeatures(repository: P2Repository, baseRepository: P2Repository, requestedFeatures: List[PluginDescriptor], availableFeatures: List[FeatureDefinition]): Map[ScalaIDEDefinition, Features] = {
+ val allAvailableFeatures = mergeFeatureList(findExistingFeatures(requestedFeatures, repository), availableFeatures)
+
+ baseRepository.findIU(ScalaIDEFeatureIdOsgi).foldLeft(Map[ScalaIDEDefinition, Features]())((m, ui) =>
+ // TODO: might be a nice place to check versions
+ m + (ScalaIDEDefinition(ui, baseRepository) -> filterFeaturesFor(ui, allAvailableFeatures, repository)))
+ }
+
+ private def filterFeaturesFor(scalaIDE: InstallableUnit, availableFeatures: List[FeatureDefinition], baseRepository: P2Repository): Features = {
+ val lists = availableFeatures.filter(f => ScalaIDEDefinition.matches(scalaIDE.version, f.sdtFeatureRange.range)).groupBy(_.details.featureId).map(t => TreeSet(t._2: _*)(FeatureDefinition.DescendingOrdering).head).toList.partition(_.repository == baseRepository)
+ Features(lists._2, lists._1)
+ }
+
+ private def findFeatures(requestedFeatures: List[PluginDescriptor]): Either[String, List[FeatureDefinition]] = {
+ Right(requestedFeatures.flatMap(findFeatures(_)))
+ }
+
+ private def findFeatures(requestedFeature: PluginDescriptor): List[FeatureDefinition] = {
+ requestedFeature.updateSites.flatMap { location =>
+ findFeatures(requestedFeature, Repositories(location))
+ }
+ }
+
+ private def findFeatures(feature: PluginDescriptor, repository: P2Repository): List[FeatureDefinition] = {
+ repository.findIU(feature.featureId + FeatureSuffix).toList.map(FeatureDefinition(feature, _, repository))
+ }
+
+ private def mergeFeatureList(base: List[FeatureDefinition], toMerge: List[FeatureDefinition]): List[FeatureDefinition] = {
+
+ def loop(toProcess: List[FeatureDefinition]): List[FeatureDefinition] = {
+ toProcess match {
+ case Nil =>
+ base
+ case head :: tail =>
+ if (base.exists(f => f.details == head.details && f.version == head.version)) {
+ loop(tail)
+ } else {
+ loop(tail) :+ head
+ }
+ }
+ }
+ val res = loop(toMerge)
+ res
+ }
+
+ private def findExistingFeatures(requestedFeatures: List[PluginDescriptor], repository: P2Repository): List[FeatureDefinition] = {
+ requestedFeatures.flatMap(findFeatures(_, repository))
+ }
+
+ private def findAssociatedFeatures() {
+
+ }
+
+}
+
+case class ScalaIDEDefinition(
+ sdtFeatureVersion: Version,
+ sdtCoreVersion: Option[DependencyUnit],
+ scalaLibraryVersion: Option[DependencyUnit],
+ scalaCompilerVersion: Option[DependencyUnit], repository: P2Repository)
+
+object ScalaIDEDefinition {
+ import Ecosystem._
+
+ private val RangeRegex = "\\[([^,]*),([^\\]]*)\\]".r
+
+ def apply(feature: InstallableUnit, repository: P2Repository): ScalaIDEDefinition = {
+
+ val dependencies = allDependencies(feature, repository)
+
+ val sdtCore = dependencies.find(_.id == ScalaIDEId)
+ val scalaLibrary = dependencies.find(_.id == ScalaLibraryId)
+ val scalaCompiler = dependencies.find(_.id == ScalaCompilerId)
+
+ new ScalaIDEDefinition(feature.version, sdtCore, scalaLibrary, scalaCompiler, repository)
+ }
+
+ def allDependencies(iu: InstallableUnit, repository: P2Repository): List[DependencyUnit] = {
+ iu.dependencies ++ iu.dependencies.flatMap(allDependencies(_, repository))
+ }
+
+ def allDependencies(du: DependencyUnit, repository: P2Repository): List[DependencyUnit] = {
+ repository.findIU(du.id).toList.filter(iu => matches(iu.version, du.range)) match {
+ case Nil =>
+ // not part of this repository, fine
+ Nil
+ case List(iu) =>
+ // this is the one we are looking for
+ val dep = allDependencies(iu, repository)
+ dep
+ case _ =>
+ // more than one?
+ Nil // TODO: better return value?
+ }
+ }
+
+ def matches(version: Version, range: String): Boolean = {
+ range match {
+ case RangeRegex(low, high) if (low == high) =>
+ // we care only about strict versions so far
+ // TODO: may need to improve that
+ version.equals(new Version(low))
+ case _ =>
+ false
+ }
+ }
+}
+
+case class FeatureDefinition(
+ details: PluginDescriptor,
+ version: Version,
+ sdtFeatureRange: DependencyUnit,
+ sdtCoreRange: DependencyUnit,
+ scalaLibraryRange: DependencyUnit,
+ scalaCompilerRange: DependencyUnit,
+ repository: P2Repository)
+
+object FeatureDefinition {
+ import Ecosystem._
+
+ def apply(details: PluginDescriptor, iu: InstallableUnit, repository: P2Repository): FeatureDefinition = {
+ val dependencies = ScalaIDEDefinition.allDependencies(iu, repository)
+
+ val sdtCore = dependencies.find(_.id == ScalaIDEId)
+ val scalaLibrary = dependencies.find(_.id == ScalaLibraryId)
+ val scalaCompiler = dependencies.find(_.id == ScalaCompilerId)
+ val sdtFeature = dependencies.find(_.id == ScalaIDEFeatureIdOsgi)
+
+ // TODO: add support for source features
+
+ // TODO: need to handle error cases, and check versions ...
+
+ new FeatureDefinition(details, iu.version, sdtFeature.get, sdtCore.get, scalaLibrary.get, scalaCompiler.get, repository)
+ }
+
+ implicit object DescendingOrdering extends Ordering[FeatureDefinition] {
+ override def compare(x: FeatureDefinition, y: FeatureDefinition): Int = {
+ val diffId = x.details.featureId.compareTo(y.details.featureId)
+ if (diffId == 0) -1 * x.version.compareTo(y.version) // same bundle name, compare versions
+ else diffId
+ }
+ }
+
+}
+
+case class Features(available: List[FeatureDefinition], existing: List[FeatureDefinition])
View
190 src/main/scala/org/scalaide/buildtools/MavenProject.scala
@@ -1,190 +0,0 @@
-package org.scalaide.buildtools
-
-import java.io.File
-import scala.xml.Elem
-import scala.xml.XML
-import org.osgi.framework.Version
-
-object MavenProject {
- import Ecosystem._
-/*
- def generateEcosystemsProjects(ecosystemToScalaIDEToAvailableFeatures: Map[EcosystemRepository, Map[ScalaIDEDefinition, List[FeatureDefinition]]], location: File): String = {
-
- val baseFolder = new File(location, "target/build")
-
- println("Generating build: %s".format(ecosystemToScalaIDEToAvailableFeatures))
-
- if (baseFolder.exists()) {
- FileUtils.deleteFull(baseFolder)
- }
- baseFolder.mkdirs()
-
- ecosystemToScalaIDEToAvailableFeatures.foreach(e => generateEcosystemProjects(e._1, e._2, baseFolder))
-
- "OK"
- }
-
- private def generateEcosystemProjects(ecosystem: EcosystemRepository, scalaIDEToAvailableFeatures: Map[ScalaIDEDefinition, List[FeatureDefinition]], baseFolder: File) {
- val ecosystemFolder = new File(baseFolder, "ecosystem-" + ecosystem.id)
- ecosystemFolder.mkdir()
-
- val c = Iterator.from(1)
-
- scalaIDEToAvailableFeatures.foreach(s => generateScalaIDEProject(ecosystem, s._1, s._2, ecosystemFolder, c.next))
-
- generateRepositoryBuilder(ecosystemFolder, c.next - 1)
- }
-
- private def generateRepositoryBuilder(ecosystemFolder: File, nbSubProject: Int) {
- XML.save(new File(ecosystemFolder, "pom.xml").getAbsolutePath(), createBuilderPomXml(ecosystemFolder, nbSubProject), "UTF-8", true)
- }
-
- private def generateScalaIDEProject(ecosystem: EcosystemRepository, scalaIDE: ScalaIDEDefinition, features: List[FeatureDefinition], ecosystemFolder: File, id: Int) {
- val projectFolder = new File(ecosystemFolder, "v" + id)
- projectFolder.mkdir()
-
- XML.save(new File(projectFolder, "site.xml").getAbsolutePath(), createSiteXml(scalaIDE, features), "UTF-8", true)
-
- XML.save(new File(projectFolder, "pom.xml").getAbsolutePath(), createPomXml(ecosystem.getRepository.right.get, features), "UTF-8", true)
- }
-
- private def createBuilderPomXml(ecosystemFolder: File, nbSubProject: Int) = {
- <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <modelVersion>4.0.0</modelVersion>
- <prerequisites>
- <maven>3.0</maven>
- </prerequisites>
- <groupId>org.scala-ide</groupId>
- <artifactId>org.scala-ide.composite.generated</artifactId>
- <version>0.1.0-SNAPSHOT</version>
- <description>Build a repository containing multiple versions</description>
- <packaging>pom</packaging>
- <properties>
- <encoding>UTF-8</encoding>
- <tycho.version>0.15.0</tycho.version>
- </properties>
- <build>
- <plugins>
- <plugin>
- <groupId>org.eclipse.tycho.extras</groupId>
- <artifactId>tycho-p2-extras-plugin</artifactId>
- <version>${{tycho.version}}</version>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>mirror</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <source>
- <!-- source repositories to mirror from -->
- {
- 1 to nbSubProject map (i =>
- <repository>
- <url>file://{ new File(ecosystemFolder, "v" + i + "/target/site") }</url>
- <layout>p2</layout>
- </repository>)
- }
- </source>
- <destination>${{project.build.directory}}/site</destination>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </project>
- }
-
- private def createSiteXml(scalaIDE: ScalaIDEDefinition, features: List[FeatureDefinition]) = {
- <site>
- { featureXml(scalaIDE) }
- { features.flatMap(featureXml(_)) }
- <category-def name="sdt" label="Scala IDE for Eclipse"/>
- <category-def name="stable" label="Scala IDE plugins"/>
- <category-def name="incubation" label="Scala IDE plugins (incubation)"/>
- <category-def name="dev" label="Scala IDE for Eclipse development support"/>
- <category-def name="source" label="Sources"/>
- </site>
- }
-
- private def featureXml(scalaIDE: ScalaIDEDefinition): List[Elem] =
- List(featureXml(ScalaIDEFeatureId, scalaIDE.sdtFeatureVersion, "sdt"),
- featureXml(ScalaIDESourceFeatureId, scalaIDE.sdtFeatureVersion, "source"),
- featureXml(ScalaIDEDevFeatureId, scalaIDE.sdtFeatureVersion, "dev"))
-
- private def featureXml(feature: FeatureDefinition): List[Elem] =
- List(featureXml(feature.details.id, feature.version, feature.details.category)) ++ feature.details.source.map(featureXml(_, feature.version, "source"))
-
- private def featureXml(id: String, version: Version, category: String): Elem = {
- <feature url={ "features/" + id + "_0.0.0.jar" } id={ id } version={ version.toString }>
- <category name={ category }/>
- </feature>
- }
-
- private def createPomXml(repository: P2Repository, features: List[FeatureDefinition]) = {
-
- // TODO: add support for Juno
-
- val repositories = features.map(_.repository) :+ repository distinct
-
- <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <modelVersion>4.0.0</modelVersion>
- <prerequisites>
- <maven>3.0</maven>
- </prerequisites>
- <groupId>org.scala-ide</groupId>
- <artifactId>org.scala-ide.ecosystem.generated</artifactId>
- <version>0.1.0-SNAPSHOT</version>
- <description>Build project for the scalatest support in Scala IDE</description>
- <packaging>eclipse-update-site</packaging>
- <properties>
- <encoding>UTF-8</encoding>
- <tycho.version>0.15.0</tycho.version>
- <!-- p2 repositories location -->
- <repo.eclipse.indigo>http://download.eclipse.org/releases/indigo/</repo.eclipse.indigo>
- <!-- dependencies repos -->
- <eclipse.codename>indigo</eclipse.codename>
- </properties>
- <repositories>
- <repository>
- <id>eclipse.indigo</id>
- <name>Eclipse p2 repository</name>
- <layout>p2</layout>
- <url>http://download.eclipse.org/releases/indigo/</url>
- </repository>
- {
- val counter = Iterator.from(1)
- repositories.map(repositoryXml(_, counter.next))
- }
- </repositories>
- <build>
- <plugins>
- <plugin>
- <groupId>org.eclipse.tycho</groupId>
- <artifactId>tycho-maven-plugin</artifactId>
- <version>${{tycho.version}}</version>
- <extensions>true</extensions>
- </plugin>
- <plugin>
- <groupId>org.eclipse.tycho</groupId>
- <artifactId>tycho-packaging-plugin</artifactId>
- <version>${{tycho.version}}</version>
- <configuration>
- <archiveSite>true</archiveSite>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </project>
- }
-
- private def repositoryXml(repository: P2Repository, id: Int) = {
- <repository>
- <id>{ "repo-" + id }</id>
- <layout>p2</layout>
- <url>{ repository.location }</url>
- </repository>
- }
-*/
-}
View
16 src/main/scala/org/scalaide/buildtools/MavenProject2.scala
@@ -10,10 +10,6 @@ object MavenProject2 {
val artifactIdSuffix = Iterator.from(1)
- private def saveXml(file: File, xml: Elem) {
- XML.save(file.getAbsolutePath(), xml, "UTF-8", true)
- }
-
def generateEcosystemsProjects(ecosystemToScalaIDEToAvailableFeatures: Map[EcosystemDescriptor, Map[ScalaIDEDefinition, Features]], baseFolder: File): String = {
println(ecosystemToScalaIDEToAvailableFeatures)
@@ -28,7 +24,7 @@ object MavenProject2 {
if (ecosystemFolders isEmpty) {
"Nothing to do"
} else {
- saveXml(new File(baseFolder, "pom.xml"), createTopPomXml(ecosystemFolders))
+ FileUtils.saveXml(new File(baseFolder, "pom.xml"), createTopPomXml(ecosystemFolders))
"OK"
}
@@ -44,7 +40,7 @@ object MavenProject2 {
val artifactId = "ecosystem.%s".format(ecosystem.id)
val featureFolders: Seq[File] = scalaIDEToAvailableFeatures.flatMap(s => generateScalaIDEProjects(s._1, s._2, artifactId, ecosystemFolder)).toSeq
- saveXml(new File(ecosystemFolder, "pom.xml"), createEcosystemPomXml(artifactId, ecosystem.baseSite, ecosystemFolder, featureFolders))
+ FileUtils.saveXml(new File(ecosystemFolder, "pom.xml"), createEcosystemPomXml(artifactId, ecosystem.base, ecosystemFolder, featureFolders))
Some(ecosystemFolder)
@@ -56,8 +52,8 @@ object MavenProject2 {
private def hasNewContent(ecosystem: EcosystemDescriptor, scalaIDEToAvailableFeatures: Map[ScalaIDEDefinition, Features]): Boolean = {
// at this point, the sites exist
- val siteRepo = Repositories(ecosystem.site).right.get
- val stagingRepo = Repositories(ecosystem.baseSite).right.get
+ val siteRepo = Repositories(ecosystem.site)
+ val stagingRepo = Repositories(ecosystem.base)
existsMissing(stagingRepo.uis, siteRepo.uis) || existsMissing(scalaIDEToAvailableFeatures)
}
@@ -99,8 +95,8 @@ object MavenProject2 {
val featureFolder = new File(baseFolder, feature.details.featureId)
featureFolder.mkdir()
- saveXml(new File(featureFolder, "pom.xml"), createFeaturePomXml(feature.repository, scalaIDERepository, parentId))
- saveXml(new File(featureFolder, "site.xml"), createSiteXml(feature))
+ FileUtils.saveXml(new File(featureFolder, "pom.xml"), createFeaturePomXml(feature.repository, scalaIDERepository, parentId))
+ FileUtils.saveXml(new File(featureFolder, "site.xml"), createSiteXml(feature))
featureFolder
}
View
70 src/main/scala/org/scalaide/buildtools/P2Repository.scala
@@ -13,6 +13,27 @@ import java.net.{ URL => jURL }
import scala.xml.Node
import org.osgi.framework.Version
import scala.collection.immutable.TreeSet
+import java.net.URL
+import scala.collection.mutable.HashMap
+
+/**
+ * !!! This object not thread safe !!! It was used in a single threaded system when implemented.
+ */
+object Repositories {
+
+ val cache = HashMap[URL, P2Repository]()
+
+ def apply(location: URL): P2Repository = {
+ cache.get(location) match {
+ case Some(repo) =>
+ repo
+ case None =>
+ val repo = P2Repository.fromUrl(location)
+ cache.put(location, repo)
+ repo
+ }
+ }
+}
case class DependencyUnit(id: String, range: String)
@@ -55,16 +76,22 @@ object InstallableUnit {
private def isFeature(unit: Node) = unit \ "properties" \ "property" exists (e => (e \ "@name" text) == "org.eclipse.equinox.p2.type.group" && (e \ "@value" text) == "true")
}
-case class P2Repository private (uis: Map[String, TreeSet[InstallableUnit]], location: String) {
+trait P2Repository {
+ def uis: Map[String, TreeSet[InstallableUnit]]
+ def findIU(unitId: String): TreeSet[InstallableUnit]
+ def location: String
+}
+
+case class ValidP2Repository (uis: Map[String, TreeSet[InstallableUnit]], location: String) extends P2Repository {
- def findIU(unitId: String): TreeSet[InstallableUnit] =
+ override def findIU(unitId: String): TreeSet[InstallableUnit] =
uis get (unitId) getOrElse (TreeSet.empty[InstallableUnit])
override def toString = "P2Repository(%s)".format(location)
override def equals(o: Any): Boolean = {
o match {
- case P2Repository(_, `location`) => true
+ case ValidP2Repository(_, `location`) => true
case _ => false
}
}
@@ -73,6 +100,11 @@ case class P2Repository private (uis: Map[String, TreeSet[InstallableUnit]], loc
}
+case class ErrorP2Repository (errorMessage: String, location: String) extends P2Repository {
+ override def findIU(unitId: String): TreeSet[InstallableUnit] = TreeSet()
+ override def uis: Map[String, TreeSet[InstallableUnit]] = Map()
+}
+
object P2Repository {
final val CompressedContentFile = "content.jar"
@@ -82,7 +114,7 @@ object P2Repository {
val units = unitsXML.flatMap(InstallableUnit(_))
val grouped = units.groupBy(_.id)
val sorted = for ((key, values) <- grouped) yield (key, TreeSet(values: _*))
- P2Repository(sorted, location)
+ ValidP2Repository(sorted, location)
}
def fromString(content: String): P2Repository = {
@@ -100,11 +132,11 @@ object P2Repository {
* before exiting the application, otherwise threads may hang on
* to the current process.
*/
- def fromUrl(repoUrl: String): Either[String, P2Repository] = {
+ def fromUrl(repoUrl: String): P2Repository = {
fromUrl(new jURL(repoUrl))
}
- def fromUrl(repoUrl: jURL): Either[String, P2Repository] = {
+ def fromUrl(repoUrl: jURL): P2Repository = {
repoUrl.getProtocol() match {
case "file" =>
fromLocalFolder(repoUrl.getFile())
@@ -113,18 +145,22 @@ object P2Repository {
}
}
- def fromLocalFolder(repoFolder: String): Either[String, P2Repository] = {
+ def fromLocalFolder(repoFolder: String): P2Repository = {
val contentFile = new File(repoFolder, CompressedContentFile)
+ val folderUrl = "file://" + repoFolder
if (contentFile.exists && contentFile.isFile) {
- for {
- xml <- getContentsFromZipFile(contentFile).right
- } yield fromXML(xml, "file://" + repoFolder)
+ getContentsFromZipFile(contentFile) match {
+ case Right(xml) =>
+ fromXML(xml, folderUrl)
+ case Left(msg) =>
+ ErrorP2Repository(msg, folderUrl)
+ }
} else {
- Left("%s doesn't exist, or is not a file".format(contentFile.getAbsolutePath()))
+ ErrorP2Repository("%s doesn't exist, or is not a file".format(contentFile.getAbsolutePath()), folderUrl)
}
}
- def fromHttpUrl(repoUrl: String): Either[String, P2Repository] = {
+ def fromHttpUrl(repoUrl: String): P2Repository = {
val tmpFile = File.createTempFile("downloaded-content", ".jar")
val svc = url(repoUrl) / CompressedContentFile
@@ -133,11 +169,17 @@ object P2Repository {
// get rid of the exception
val stringExceptionHandle = for (ex <- downloadHandle.left) yield "Error downloading file " + ex.getMessage()
- for {
+ val res= for {
d <- stringExceptionHandle().right
xml <- getContentsFromZipFile(tmpFile).right
} yield fromXML(xml, repoUrl)
- // } finally Http.shutdown()
+
+ res match {
+ case Right(p2Repository) =>
+ p2Repository
+ case Left(msg) =>
+ ErrorP2Repository(msg, repoUrl)
+ }
}
def getContentsFromZipFile(file: File): Either[String, Elem] = {
View
33 src/main/scala/org/scalaide/buildtools/ScalaIDEVersion.scala
@@ -0,0 +1,33 @@
+package org.scalaide.buildtools
+
+import org.osgi.framework.Version
+
+object ScalaIDEVersion {
+
+ def apply(iu: InstallableUnit, repository: P2Repository, existingAddOns: Map[PluginDescriptor, Seq[AddOn]], availableAddOns: Map[PluginDescriptor, Seq[AddOn]], siteRepo: P2Repository): ScalaIDEVersion = {
+ val (associatedExistingAddOns, associatedAvailableAddOns) = latestAssociated(availableAddOns, iu.version).foldLeft(latestAssociated(existingAddOns, iu.version)) {
+ (acc, availableAddOn) =>
+ acc.get(availableAddOn._1) match {
+ case Some(existingAddOn) if (existingAddOn.version.compareTo(availableAddOn._2.version) >= 0) =>
+ acc
+ case _ =>
+ acc + availableAddOn
+ }
+ }.partition(_._2.repository == siteRepo)
+
+ new ScalaIDEVersion(iu, repository, associatedExistingAddOns, associatedAvailableAddOns)
+ }
+
+ private def latestAssociated(addOns: Map[PluginDescriptor, Seq[AddOn]], version: Version): Map[PluginDescriptor, AddOn] = {
+ addOns.flatMap {
+ case (conf, addOns) =>
+ addOns.filter(_.scalaIDEVersion == version).headOption.map(conf -> _)
+ }
+ }
+}
+
+case class ScalaIDEVersion private (iu: InstallableUnit, repository: P2Repository, associatedExistingAddOns: Map[PluginDescriptor, AddOn], associatedAvailableAddOns: Map[PluginDescriptor, AddOn]) {
+
+ def version = iu.version
+
+}
View
7 src/main/scala/org/scalaide/buildtools/UpdateAddonManifests.scala
@@ -49,7 +49,12 @@ class UpdateAddonManifests(repoURL: String, rootFolder: String) {
import Ecosystem._
def apply(): Either[String, String] = {
- val res= P2Repository.fromUrl(repoURL).right.flatMap(updateVersions(_))
+ val res= P2Repository.fromUrl(repoURL) match {
+ case r: ValidP2Repository =>
+ updateVersions(r)
+ case ErrorP2Repository(msg, _) =>
+ Left(msg)
+ }
// need to stop Dispatch in any cases
Http.shutdown()
View
8 src/test/scala/org/scalaide/buildtools/EcosystemsDescriptorTests.scala
@@ -13,10 +13,10 @@ class EcosystemsDescriptorTests {
@Test
def ecosystemsDescriptorIsCorrectlyLoaded() {
- val expected = List(EcosystemDescriptor("stable-scala29", new URL("http://download.scala-ide.org/ecosystem/scala29/stable/site"), new URL("http://download.scala-ide.org/ecosystem/scala29/stable/base/site")),
- EcosystemDescriptor("stable-scala210", new URL("http://download.scala-ide.org/ecosystem/scala210/stable/site"), new URL("http://download.scala-ide.org/ecosystem/scala210/stable/base/site")),
- EcosystemDescriptor("dev-scala29", new URL("http://download.scala-ide.org/ecosystem/scala29/dev/site"), new URL("http://download.scala-ide.org/ecosystem/scala29/dev/base/site")),
- EcosystemDescriptor("dev-scala210", new URL("http://download.scala-ide.org/ecosystem/scala210/dev/site"), new URL("http://download.scala-ide.org/ecosystem/scala210/dev/base/site")))
+ val expected = List(EcosystemDescriptor("stable-scala29", new URL("http://download.scala-ide.org/ecosystem/scala29/stable/site"), new URL("http://download.scala-ide.org/ecosystem/scala29/stable/base"), new URL("http://download.scala-ide.org/ecosystem/next/scala29/stable/site"), new URL("http://download.scala-ide.org/ecosystem/next/scala29/stable/base")),
+ EcosystemDescriptor("stable-scala210", new URL("http://download.scala-ide.org/ecosystem/scala210/stable/site"), new URL("http://download.scala-ide.org/ecosystem/scala210/stable/base"), new URL("http://download.scala-ide.org/ecosystem/next/scala210/stable/site"), new URL("http://download.scala-ide.org/ecosystem/next/scala210/stable/base")),
+ EcosystemDescriptor("dev-scala29", new URL("http://download.scala-ide.org/ecosystem/scala29/dev/site"), new URL("http://download.scala-ide.org/ecosystem/scala29/dev/base"), new URL("http://download.scala-ide.org/ecosystem/next/scala29/dev/site"), new URL("http://download.scala-ide.org/ecosystem/next/scala29/dev/base")),
+ EcosystemDescriptor("dev-scala210", new URL("http://download.scala-ide.org/ecosystem/scala210/dev/site"), new URL("http://download.scala-ide.org/ecosystem/scala210/dev/base"), new URL("http://download.scala-ide.org/ecosystem/next/scala210/dev/site"), new URL("http://download.scala-ide.org/ecosystem/next/scala210/dev/base")))
val resource = EcosystemsDescriptor.getClass().getResource("ecosystems.conf")
val file = new java.io.File(resource.toURI())
View
7 src/test/scala/org/scalaide/buildtools/RemoteRepositoryTest.scala
@@ -11,12 +11,9 @@ class RemoteRepositoryTest {
"org.scala-ide.sdt.core" -> new Version("2.1.0.m2-2_10-201209130850-f6ab297"))
@Test def milestonesTest {
- val maybeRepo = P2Repository.fromUrl("http://download.scala-ide.org/ecosystem/dev-milestone-milestone/site/")
-
- Assert.assertTrue("Error downloading contents: " + maybeRepo, maybeRepo.isRight)
+ val p2repo = P2Repository.fromUrl("http://download.scala-ide.org/ecosystem/dev-milestone-milestone/site/")
for {
- p2repo <- maybeRepo.right
(id, version) <- expectedIds
found <- p2repo.findIU(id)
} {
@@ -27,7 +24,7 @@ class RemoteRepositoryTest {
@Test def httpErrorTest {
val maybeRepo = P2Repository.fromUrl("http://download.scala-ide.org/nosuchrepository")
- Assert.assertTrue("Error downloading contents: " + maybeRepo, maybeRepo.isLeft)
+ Assert.assertTrue("Error downloading contents: " + maybeRepo, maybeRepo.isInstanceOf[ErrorP2Repository])
}
}
View
12 src/test/scala/org/scalaide/buildtools/ecosystems.conf
@@ -3,18 +3,22 @@ ecosystems-descriptor {
stable-scala29 {
site = "http://download.scala-ide.org/ecosystem/scala29/stable/site"
- baseSite = "http://download.scala-ide.org/ecosystem/scala29/stable/base/site"
+ base = "http://download.scala-ide.org/ecosystem/scala29/stable/base"
+ next = "http://download.scala-ide.org/ecosystem/next/scala29/stable/base"
}
stable-scala210 {
site = "http://download.scala-ide.org/ecosystem/scala210/stable/site"
- baseSite = "http://download.scala-ide.org/ecosystem/scala210/stable/base/site"
+ base = "http://download.scala-ide.org/ecosystem/scala210/stable/base"
+ next = "http://download.scala-ide.org/ecosystem/next/scala210/stable/base"
}
dev-scala29 {
site = "http://download.scala-ide.org/ecosystem/scala29/dev/site"
- baseSite = "http://download.scala-ide.org/ecosystem/scala29/dev/base/site"
+ base = "http://download.scala-ide.org/ecosystem/scala29/dev/base"
+ next = "http://download.scala-ide.org/ecosystem/next/scala29/dev/base"
}
dev-scala210 {
site = "http://download.scala-ide.org/ecosystem/scala210/dev/site"
- baseSite = "http://download.scala-ide.org/ecosystem/scala210/dev/base/site"
+ base = "http://download.scala-ide.org/ecosystem/scala210/dev/base"
+ next = "http://download.scala-ide.org/ecosystem/next/scala210/dev/base"
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.