Skip to content

Commit

Permalink
Fixed #1000728. Modified classpath validator to accept multiple scala…
Browse files Browse the repository at this point in the history
… library jars of compatible version.

Extended tests for the new cases.
  • Loading branch information
Luc Bourlier committed Nov 7, 2011
1 parent 367d3a4 commit d713a83
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 46 deletions.
Expand Up @@ -53,7 +53,7 @@ class ClasspathTests {
/** /**
* No scala library defined in the classpath * No scala library defined in the classpath
*/ */
@Test @Ignore @Test
def noScalaLibrary() { def noScalaLibrary() {
setRawClasspathAndCheckMarkers(cleanRawClasspath, 0, 1) setRawClasspathAndCheckMarkers(cleanRawClasspath, 0, 1)
} }
Expand All @@ -63,15 +63,23 @@ class ClasspathTests {
*/ */
@Test @Test
def twoScalaLibraries() { def twoScalaLibraries() {
setRawClasspathAndCheckMarkers(baseRawClasspath :+ JavaCore.newLibraryEntry(new Path("/classpath/lib/2.10.x/scala-library.jar"), null, null), 0, 1) setRawClasspathAndCheckMarkers(baseRawClasspath :+ JavaCore.newLibraryEntry(new Path("/classpath/lib/" + ScalaPlugin.plugin.shortScalaVer + ".x/scala-library.jar"), null, null), 1, 0)
} }


/** /**
* Two scala library defined in the classpath, the eclipse container one, and one with a different name. * Two scala library defined in the classpath, the eclipse container one, and one with a different name.
*/ */
@Test @Test
def twoScalaLibrariesWithDifferentName() { def twoScalaLibrariesWithDifferentName() {
setRawClasspathAndCheckMarkers(baseRawClasspath :+ JavaCore.newLibraryEntry(new Path("/classpath/lib/2.10.x/my-scala-library.jar"), null, null), 0, 1) setRawClasspathAndCheckMarkers(baseRawClasspath :+ JavaCore.newLibraryEntry(new Path("/classpath/lib/" + ScalaPlugin.plugin.shortScalaVer + ".x/scala-library.jar"), null, null), 1, 0)
}

/**
* Two scala library defined in the classpath, the eclipse container one, and one incompatible.
*/
@Test
def twoScalaLibrariesWithOneIncompatbile() {
setRawClasspathAndCheckMarkers(baseRawClasspath :+ createIncompatibleScalaLibraryEntry(), 0, 1)
} }


/** /**
Expand Down Expand Up @@ -128,16 +136,8 @@ class ClasspathTests {
*/ */
@Test @Test
def differentAndIncompatibleVersion() { def differentAndIncompatibleVersion() {
val newRawClasspath= cleanRawClasspath :+ val newRawClasspath= cleanRawClasspath :+ createIncompatibleScalaLibraryEntry()
JavaCore.newLibraryEntry(new Path("/classpath/lib/" +
(ScalaPlugin.plugin.shortScalaVer match {
case "2.8" => "2.9"
case "2.9" => "2.10"
case "2.10" => "2.8"
case _ =>
fail("Unsupported embedded scala library version " + ScalaPlugin.plugin.scalaVer +". Please update the test.")
""
}) + ".x/scala-library.jar"), null, null)


setRawClasspathAndCheckMarkers(newRawClasspath, 0, 1) setRawClasspathAndCheckMarkers(newRawClasspath, 0, 1)
} }
Expand Down Expand Up @@ -171,16 +171,7 @@ class ClasspathTests {
*/ */
@Test @Test
def differentNameWithIncompatibleVersion() { def differentNameWithIncompatibleVersion() {
val newRawClasspath= cleanRawClasspath :+ val newRawClasspath= cleanRawClasspath :+ createIncompatibleScalaLibraryEntry()
JavaCore.newLibraryEntry(new Path("/classpath/lib/" +
(ScalaPlugin.plugin.shortScalaVer match {
case "2.8" => "2.9"
case "2.9" => "2.10"
case "2.10" => "2.8"
case _ =>
fail("Unsupported embedded scala library version " + ScalaPlugin.plugin.scalaVer +". Please update the test.")
""
}) + ".x/my-scala-library.jar"), null, null)


setRawClasspathAndCheckMarkers(newRawClasspath, 0, 1) setRawClasspathAndCheckMarkers(newRawClasspath, 0, 1)
} }
Expand Down Expand Up @@ -231,6 +222,20 @@ class ClasspathTests {
assertEquals("Unexpected number of scala problems in project", 1, markers.length) assertEquals("Unexpected number of scala problems in project", 1, markers.length)
} }


/**
* Generate library entry for an incompatible scala library
*/
private def createIncompatibleScalaLibraryEntry(): IClasspathEntry =
JavaCore.newLibraryEntry(new Path("/classpath/lib/" +
(ScalaPlugin.plugin.shortScalaVer match {
case "2.8" => "2.9"
case "2.9" => "2.10"
case "2.10" => "2.8"
case _ =>
fail("Unsupported embedded scala library version " + ScalaPlugin.plugin.scalaVer +". Please update the test.")
""
}) + ".x/scala-library.jar"), null, null)

/** /**
* Set the new classpath and check the number of errors and warnings attached to the project. * Set the new classpath and check the number of errors and warnings attached to the project.
*/ */
Expand Down
16 changes: 15 additions & 1 deletion org.scala-ide.sdt.core/src/scala/tools/eclipse/ScalaPlugin.scala
Expand Up @@ -84,7 +84,7 @@ class ScalaPlugin extends AbstractUIPlugin with IResourceChangeListener with IEl
val javaFileExtn = ".java" val javaFileExtn = ".java"
val jarFileExtn = ".jar" val jarFileExtn = ".jar"


def cutVersion(version: String): String = { private def cutVersion(version: String): String = {
val pattern = "(\\d)\\.(\\d+)\\..*".r val pattern = "(\\d)\\.(\\d+)\\..*".r
version match { version match {
case pattern(major, minor)=> case pattern(major, minor)=>
Expand All @@ -93,6 +93,20 @@ class ScalaPlugin extends AbstractUIPlugin with IResourceChangeListener with IEl
"(unknown)" "(unknown)"
} }
} }

/**
* Check if the given version is compatible with the current plug-in version.
* Check on the major/minor number, discard the maintenance number.
* 2.9.1 and 2.9.2-SNAPSHOT are compatible
* 2.8.1 and 2.9.0 are no compatible
*/
def isCompatibleVersion(version: Option[String]): Boolean =
version match {
case Some(v) =>
cutVersion(v) == shortScalaVer
case None =>
false
}


lazy val scalaVer = scala.util.Properties.scalaPropOrElse("version.number", "(unknown)") lazy val scalaVer = scala.util.Properties.scalaPropOrElse("version.number", "(unknown)")
lazy val shortScalaVer = cutVersion(scalaVer) lazy val shortScalaVer = cutVersion(scalaVer)
Expand Down
59 changes: 37 additions & 22 deletions org.scala-ide.sdt.core/src/scala/tools/eclipse/ScalaProject.scala
Expand Up @@ -441,30 +441,45 @@ class ScalaProject private (val underlying: IProject) extends HasLogger {
case 0 => // unable to find any trace of scala library case 0 => // unable to find any trace of scala library
setClasspathError(IMarker.SEVERITY_ERROR, "Unable to find a scala library. Please add the scala container or a scala library jar to the build path.") setClasspathError(IMarker.SEVERITY_ERROR, "Unable to find a scala library. Please add the scala container or a scala library jar to the build path.")
case 1 => // one and only one, now check if the version number is contained in library.properties case 1 => // one and only one, now check if the version number is contained in library.properties
for (resource <- fragmentRoots(0).getNonJavaResources()) getVersionNumber(fragmentRoots(0)) match {
resource match { case Some(v) if v == plugin.scalaVer =>
case jarEntry: IJarEntryResource if jarEntry.isFile() && "library.properties".equals(jarEntry.getName) => // exactly the same version, should be from the container. Perfect
val properties = new Properties() setClasspathError(0, null)
properties.load(jarEntry.getContents()) case v if plugin.isCompatibleVersion(v) =>
val version = properties.getProperty("version.number") // compatible version (major, minor are the same). Still, add warning message
if (version != null && version == plugin.scalaVer) { setClasspathError(IMarker.SEVERITY_WARNING, "The version of scala library found in the build path is different from the one provided by scala IDE: " + v.get + ". Expected: " + plugin.scalaVer + ". Make sure you know what you are doing.")
// exactly the same version, should be from the container. Perfect case Some(v) =>
setClasspathError(0, null) // incompatible version
} else if (version != null && plugin.cutVersion(version) == plugin.shortScalaVer) { setClasspathError(IMarker.SEVERITY_ERROR, "The version of scala library found in the build path is incompatible with the one provided by scala IDE: " + v + ". Expected: " + plugin.scalaVer + ". Please replace the scala library with the scala container or a compatible scala library jar.")
// compatible version (major, minor are the same). Still, add warning message case None =>
setClasspathError(IMarker.SEVERITY_WARNING, "The version of scala library found in the build path is different from the one provided by scala IDE: " + version + ". Expected: " + plugin.scalaVer + ". Make sure you know what you are doing.") // no version found
} else { setClasspathError(IMarker.SEVERITY_ERROR, "The scala library found in the build path doesn't expose its version. Please replace the scala library with the scala container or a valid scala library jar")
// incompatible version }
setClasspathError(IMarker.SEVERITY_ERROR, "The version of scala library found in the build path is incompatible with the one provided by scala IDE: " + version + ". Expected: " + plugin.scalaVer + ". Please replace the scala library with the scala container or a compatible scala library jar.") case _ => // 2 or more of them, not great
} if (fragmentRoots.exists(fragmentRoot => !plugin.isCompatibleVersion(getVersionNumber(fragmentRoot))))
return setClasspathError(IMarker.SEVERITY_ERROR, "More than one scala library found in the build path, including at least one with an incompatible version. Please update the project build path so it contains only compatible scala libraries")
case _ => else
setClasspathError(IMarker.SEVERITY_WARNING, "More than one scala library found in the build path, all with compatible versions. This is not an optimal configuration, try to limit to one scala library in the build path.")
}
}

/**
* Return the version number contained in library.properties if it exists.
*/
private def getVersionNumber(fragmentRoot: IPackageFragmentRoot): Option[String] = {
for (resource <- fragmentRoot.getNonJavaResources())
resource match {
case jarEntry: IJarEntryResource if jarEntry.isFile() && "library.properties".equals(jarEntry.getName) =>
val properties = new Properties()
properties.load(jarEntry.getContents())
val version = properties.getProperty("version.number")
if (version == null) {
return None
} }
// no library.properties, not good return Option(version)
setClasspathError(IMarker.SEVERITY_ERROR, "The scala library found in the build path doesn't contain a library.properties file. Please replace the scala library with the scala container or a valid scala library jar") case _ =>
case _ => // 2 or more of them, not good
setClasspathError(IMarker.SEVERITY_ERROR, "More than one scala library found in the build path. Please update the project build path so it contains only one scala library reference")
} }
None
} }


private def refreshOutput: Unit = { private def refreshOutput: Unit = {
Expand Down

0 comments on commit d713a83

Please sign in to comment.