sbt-idea
sbt-idea copied to clipboard
Attaching sources to dependencies
Hi
What is the best way to attach sources to the Intellij dependencies? After I run the "idea" command there does seem to be a source path attached for each dependency, e.g.: /Users/dev/scala/proj/lib_managed/scala_2.8.1/test/servlet-api-2.5.0.jar
Has source location:
/Users/dev/scala/proj/lib_managed/scala_2.8.1/test/servlet-api-2.5.0-sources.jar
Is it possible to tell sbt-idea to use a specific path format when it generates source attachment paths?
Alternatively is it possible to configure my sbt ivy retrieve pattern in such a way as to match the source locations generated by sbt-idea?
I am automatically retrieving the sources of my ivy.xml dependencies using sbt-sources(https://github.com/OlegYch/sbt-sources-plugin), so I would prefer to avoid copying source jars manually into the sbt-idea expected locations.
Thanks
Unfortunately I don't have an immediate answer for you. I haven't used sbt-sources-plugin, and have only used withSources() declarations in project definition which just work with sbt-idea, but obviously miss transitive dependencies.
So I would be interested in the answer to this too!
I have found a setup that I am happy with, sbt update is retrieving all my dependencies' sources transitively.
I have patched sbt-idea to be able to use a regular expression to distinguish between sources, jars, and javadocs and the relation between them. Using the patch I can now do the following in my project definition:
import java.io.File
import sbt._
import Process._
import FileUtilities._
import java.util.jar.Manifest
import scala.util.matching.Regex
class CustomProject(info: ProjectInfo) extends DefaultProject(info) with IdeaProject{
override val outputPattern = "[conf]/[type]s/[artifact](-[revision])(-[classifier]).[ext]"
override val JarsPattern:Regex = """.*/jars/(.*)\.jar""".r
override val SourcesPattern:Regex = """.*/sources/(.*)\.jar""".r
}
I ran the sbt-idea tests after the modifications and it seems the tests for issue-50 and issue-52 are failing. The failure seems to be that the "scope" attribute is no longer being added to order entries. I would be happy to track down the reason/fix if you think the changes are acceptable.
Here is the git patch:
---
.../src/main/scala/IdeaModuleDescriptor.scala | 40 ++++++++++++++------
sbt-idea-plugin/src/main/scala/IdeaProject.scala | 11 ++++-
.../src/main/scala/IdeaProcessor.scala | 8 +++-
3 files changed, 43 insertions(+), 16 deletions(-)
diff --git a/sbt-idea-core/src/main/scala/IdeaModuleDescriptor.scala b/sbt-idea-core/src/main/scala/IdeaModuleDescriptor.scala
index d17abe6..870748e 100644
--- a/sbt-idea-core/src/main/scala/IdeaModuleDescriptor.scala
+++ b/sbt-idea-core/src/main/scala/IdeaModuleDescriptor.scala
@@ -7,8 +7,23 @@
import sbt._
import java.io.File
import xml.{UnprefixedAttribute, NodeSeq, Node, NodeBuffer}
+import scala.util.matching.Regex
+
+class IdeaModuleDescriptor(val project: BasicDependencyProject,val JarsPattern:Regex,val SourcesPattern:Regex, val JavadocsPattern:Regex,val log: Logger) extends SaveableXml with ProjectPaths {
+
+
+ class RegexFilter(val Pattern:Regex) extends FileFilter{
+ override def accept(file:File):Boolean={
+ (Pattern findFirstIn file.getAbsolutePath) match{
+ case Some(_) => true
+ case None => false
+ }
+ }
+ }
+ val Jars = new RegexFilter(JarsPattern)
+ val Sources = new RegexFilter(SourcesPattern)
+ val JavaDocs = new RegexFilter(JavadocsPattern)
-class IdeaModuleDescriptor(val project: BasicDependencyProject, val log: Logger) extends SaveableXml with ProjectPaths {
val path = String.format("%s/%s.iml", projectPath, project.name)
val env = new IdeaProjectEnvironment(project.rootProject)
val userEnv = new IdeaUserEnvironment(project.rootProject)
@@ -95,13 +110,6 @@ class IdeaModuleDescriptor(val project: BasicDependencyProject, val log: Logger)
}
{
val Jar = ".jar"
- val Jars = GlobFilter("*" + Jar)
-
- val SourcesJar = "-sources" + Jar
- val Sources = GlobFilter("*" + SourcesJar)
-
- val JavaDocJar = "-javadoc" + Jar
- val JavaDocs = GlobFilter("*" + JavaDocJar)
val classpathJars = ideClasspath ** Jars
@@ -118,7 +126,7 @@ class IdeaModuleDescriptor(val project: BasicDependencyProject, val log: Logger)
case _ => List()
}.foldLeft(Set.empty[(String, Long)])(_++_)
- val sources = allJars ** Sources
+ val sources = ((project.unmanagedClasspath +++ project.managedDependencyPath) ** Sources)
val javadoc = allJars ** JavaDocs
val allClasses = classpathJars --- sources --- javadoc
val classes = allClasses.filter(p => !alreadyDeclared((nameWithScope(p.asFile), p.asFile.length)))
@@ -127,9 +135,17 @@ class IdeaModuleDescriptor(val project: BasicDependencyProject, val log: Logger)
def named(pf: PathFinder, suffix: String) = Map() ++ pf.getFiles.toList.sort(_.getAbsolutePath > _.getAbsolutePath).map(file =>
cut(file.getName, suffix) -> relativePath(file))
- val namedSources = named(sources, SourcesJar)
- val namedJavadoc = named(javadoc, JavaDocJar)
- val namedClasses = named(classes, Jar)
+ def namedRegex(pf: PathFinder, Pattern:Regex)={
+ Map() ++ pf.getFiles.toList.sort(_.getAbsolutePath > _.getAbsolutePath).map(file =>{ val name = file.getAbsolutePath match {
+ case Pattern(a) => a
+ case _ => throw new RuntimeException("Pattern %s did not match file path %s".format(Pattern,file.getAbsolutePath))
+ }
+ name -> relativePath(file)})
+ }
+
+ val namedSources = namedRegex(sources, SourcesPattern)
+ val namedJavadoc = namedRegex(javadoc, JavadocsPattern)
+ val namedClasses = namedRegex(classes, JarsPattern)
val defaultJars = defaultClasspath ** Jars
val defaultJarNames = defaultJars.get.map(_.name).toList
diff --git a/sbt-idea-plugin/src/main/scala/IdeaProject.scala b/sbt-idea-plugin/src/main/scala/IdeaProject.scala
index 6057732..ec95cfe 100644
--- a/sbt-idea-plugin/src/main/scala/IdeaProject.scala
+++ b/sbt-idea-plugin/src/main/scala/IdeaProject.scala
@@ -6,22 +6,27 @@
import sbt._
+import scala.util.matching.Regex
trait IdeaProject extends BasicDependencyProject {
lazy val env = new IdeaProjectEnvironment(this)
+ val JarsPattern:Regex = """(.*)\.jar""".r
+ val SourcesPattern:Regex = """(.*)-sources\.jar""".r
+ val JavadocsPattern:Regex = """(.*)-javadoc\.jar""".r
+
lazy val idea = task { createIdeaProject; None } describedAs("Creates IntelliJ IDEA project files.")
def createIdeaProject: Unit = {
if (this eq rootProject) {
- new IdeaProjectDescriptor(this, log).save
+ new IdeaProjectDescriptor(this,log).save
if (env.includeSbtProjectDefinitionModule.value) {
new SbtProjectDefinitionIdeaModuleDescriptor(this, log).save
}
}
this match {
case pp: ParentProject => new ParentProjectIdeaModuleDescriptor(pp, log).save
- case bdp: BasicDependencyProject => new IdeaModuleDescriptor(bdp, log).save
+ case bdp: BasicDependencyProject => new IdeaModuleDescriptor(bdp, JarsPattern, SourcesPattern, JavadocsPattern,log).save
}
}
-}
\ No newline at end of file
+}
diff --git a/sbt-idea-processor/src/main/scala/IdeaProcessor.scala b/sbt-idea-processor/src/main/scala/IdeaProcessor.scala
index 4512119..60bf94b 100644
--- a/sbt-idea-processor/src/main/scala/IdeaProcessor.scala
+++ b/sbt-idea-processor/src/main/scala/IdeaProcessor.scala
@@ -6,8 +6,14 @@
import sbt._
import processor._
+import scala.util.matching.Regex
class IdeaProcessor extends BasicProcessor {
+
+ val JarsPattern:Regex = """(.*)\.jar""".r
+ val SourcesPattern:Regex = """(.*)-sources\.jar""".r
+ val JavadocsPattern:Regex = """(.*)-javadoc\.jar""".r
+
def apply(project:Project, args:String){
attemptIdeaProject(project)
}
@@ -33,7 +39,7 @@ class IdeaProcessor extends BasicProcessor {
}
project match {
case pp: ParentProject => new ParentProjectIdeaModuleDescriptor(pp, project.log).save
- case bdp: BasicDependencyProject => new IdeaModuleDescriptor(bdp, project.log).save
+ case bdp: BasicDependencyProject => new IdeaModuleDescriptor(bdp,JarsPattern, SourcesPattern, JavadocsPattern, project.log).save
}
}
--
1.7.5
Note that this should work correctly with the sbt-0.10 branch.