Skip to content

Commit

Permalink
SBT: sbt-strucutre plugin in now bundled
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelfatin committed Jul 7, 2014
1 parent 8ae2c2d commit 4cc8795
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 33 deletions.
2 changes: 2 additions & 0 deletions .idea/artifacts/ScalaPlugins.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added SBT/lib/sbt-structure-0.12.jar
Binary file not shown.
Binary file added SBT/lib/sbt-structure-0.13.jar
Binary file not shown.
Expand Up @@ -12,7 +12,6 @@ import org.jetbrains.sbt.settings.SbtApplicationSettings
import java.util
import java.net.URL
import com.intellij.openapi.options.Configurable
import com.intellij.openapi.application.PathManager

/**
* @author Pavel Fatin
Expand Down Expand Up @@ -65,8 +64,6 @@ object SbtExternalSystemManager {
def executionSettingsFor(project: Project, path: String) = {
val app = SbtApplicationSettings.instance

val ideaSystem = PathManager.getSystemPath.toFile

val customLauncher = app.customLauncherEnabled
.option(app.getCustomLauncherPath).map(_.toFile)

Expand All @@ -77,7 +74,7 @@ object SbtExternalSystemManager {
val customVm = app.customVMEnabled
.option(app.getCustomVMPath).map(_.toFile)

new SbtExecutionSettings(ideaSystem, vmOptions, customLauncher, customVm)
new SbtExecutionSettings(vmOptions, customLauncher, customVm)
}

private def proxyOptionsFor(http: HttpConfigurable): Seq[String] = {
Expand Down
Expand Up @@ -23,7 +23,7 @@ class SbtProjectResolver extends ExternalSystemProjectResolver[SbtExecutionSetti
if (file.isDirectory) file.getPath else file.getParent
}

val runner = new SbtRunner(settings.ideaSystem, settings.vmOptions, settings.customLauncher, settings.customVm)
val runner = new SbtRunner(settings.vmOptions, settings.customLauncher, settings.customVm)

var warnings = new StringBuilder()

Expand Down
Expand Up @@ -7,7 +7,6 @@ import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutio
/**
* @author Pavel Fatin
*/
class SbtExecutionSettings(val ideaSystem: File,
val vmOptions: Seq[String],
class SbtExecutionSettings(val vmOptions: Seq[String],
val customLauncher: Option[File],
val customVm: Option[File]) extends ExternalSystemExecutionSettings
@@ -1,45 +1,60 @@
package org.jetbrains.sbt
package project.structure

import java.io.{FileNotFoundException, PrintWriter, File}
import java.io._
import scala.xml.{Elem, XML}
import com.intellij.execution.process.OSProcessHandler
import java.util.jar.{JarEntry, JarFile}
import java.util.Properties
import SbtRunner._

/**
* @author Pavel Fatin
*/
class SbtRunner(ideaSystem: File, vmOptions: Seq[String], customLauncher: Option[File], customVM: Option[File]) {
class SbtRunner(vmOptions: Seq[String], customLauncher: Option[File], customVM: Option[File]) {
private val JavaHome = customVM.getOrElse(new File(System.getProperty("java.home")))
private val JavaVM = JavaHome / "bin" / "java"
private val LauncherDir = SbtRunner.getSbtLauncherDir
private val LauncherDir = getSbtLauncherDir
private val SbtLauncher = customLauncher.getOrElse(LauncherDir / "sbt-launch.jar")
private val DefaultSbtVersion = "0.13"

def read(directory: File, download: Boolean)(listener: (String) => Unit): Either[Exception, Elem] = {
checkFilePresence.fold(read0(directory, download)(listener))(it => Left(new FileNotFoundException(it)))
}

private def read0(directory: File, download: Boolean)(listener: (String) => Unit): Either[Exception, Elem] = {
val sbtVersion = sbtVersionIn(directory)
.orElse(implementationVersionOf(SbtLauncher))
.getOrElse(DefaultSbtVersion)

val majorSbtVersion = sbtVersion.split("\\.").take(2).mkString(".")

read1(directory, majorSbtVersion, download, listener)
}

private def checkFilePresence: Option[String] = {
val files = Stream("Java home" -> JavaHome, "SBT launcher" -> SbtLauncher)
val problem = files.map((check _).tupled).flatten.headOption
problem.fold(read0(directory, download, listener))(it => Left(new FileNotFoundException(it)))
files.map((check _).tupled).flatten.headOption
}

private def check(entity: String, file: File) = (!file.exists()).option(s"$entity does not exist: $file")

private def read0(directory: File, download: Boolean, listener: (String) => Unit) = {
val sbtBase = ideaSystem / "SBT"

createGlobalConfigurationWithin(sbtBase)
private def read1(directory: File, sbtVersion: String, download: Boolean, listener: (String) => Unit) = {
val pluginFile = LauncherDir / s"sbt-structure-$sbtVersion.jar"
val className = if (download) "ReadProjectAndRepository" else "ReadProject"

usingTempFile("sbt-structure", Some(".xml")) { structureFile =>
usingTempFile("sbt-commands", Some(".lst")) { commandsFile =>

commandsFile.write(
s"""set artifactPath := file("${path(structureFile)}")""",
if (download) "read-project-and-repository" else "read-project")
s"""apply -cp ${path(pluginFile)} org.jetbrains.sbt.$className""")

val processCommands =
path(JavaVM) +:
// "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005" +:
"-Djline.terminal=jline.UnsupportedTerminal" +:
"-Dsbt.log.noformat=true" +:
s"-Dsbt.global.base=${sbtBase.canonicalPath}" +:
vmOptions :+
"-jar" :+
path(SbtLauncher) :+
Expand All @@ -56,20 +71,6 @@ class SbtRunner(ideaSystem: File, vmOptions: Seq[String], customLauncher: Option
}}
}

private def createGlobalConfigurationWithin(base: File) {
val lines = Seq(
"""resolvers += "sbt-releases" at "http://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/"""",
"",
s"""addSbtPlugin("org.jetbrains" % "sbt-structure" % "${Sbt.StructurePluginVersion}")""")

val pluginsFiles = Seq(base / "plugins" / "build.sbt", base / "0.13" / "plugins" / "build.sbt")

pluginsFiles.foreach { file =>
file.getParentFile.mkdirs()
file.write(lines: _*)
}
}

private def handle(process: Process, listener: (String) => Unit): String = {
val output = new StringBuilder()

Expand Down Expand Up @@ -108,4 +109,31 @@ object SbtRunner {
}

def getDefaultLauncher = getSbtLauncherDir / "sbt-launch.jar"

private def implementationVersionOf(jar: File): Option[String] = {
readManifestAttributeFrom(jar, "Implementation-Version")
}

private def readManifestAttributeFrom(file: File, name: String): Option[String] = {
using(new JarFile(file)) { jar =>
using(new BufferedInputStream(jar.getInputStream(new JarEntry("META-INF/MANIFEST.MF")))) { input =>
val manifest = new java.util.jar.Manifest(input)
val attributes = manifest.getMainAttributes
Option(attributes.getValue(name))
}
}
}

private def sbtVersionIn(directory: File): Option[String] = {
val propertiesFile = directory / "project" / "build.properties"
if (propertiesFile.exists()) readPropertyFrom(propertiesFile, "sbt.version") else None
}

private def readPropertyFrom(file: File, name: String): Option[String] = {
using(new BufferedInputStream(new FileInputStream(file))) { input =>
val properties = new Properties()
properties.load(input)
Option(properties.getProperty(name))
}
}
}

0 comments on commit 4cc8795

Please sign in to comment.