Skip to content

Commit

Permalink
clean up deprecated methods in preparation of sbt 1.0, where these wi…
Browse files Browse the repository at this point in the history
…ll be removed.

This requires having separate sources for sbt 0.12 and 0.13. Code duplication, but that's okay, since we only need to maintain the basic functionality in sbt 0.12
  • Loading branch information
jastice committed Nov 10, 2016
1 parent eb64769 commit 5e3a320
Show file tree
Hide file tree
Showing 35 changed files with 4,795 additions and 54 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ project/target
actual.txt
expected.txt
sbt-global
structure-*-actual.xml
10 changes: 5 additions & 5 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import bintray.Keys._


def newProject(projectName: String): Project =
Project(projectName, file(projectName))
.settings(
Expand Down Expand Up @@ -34,7 +33,7 @@ lazy val core = newProject("core")
Seq.empty
}
},
crossScalaVersions := Seq("2.9.2", "2.10.4", "2.11.6")
crossScalaVersions := Seq("2.9.3", "2.10.6", "2.11.8", "2.12.0")
)

lazy val extractor = newProject("extractor")
Expand All @@ -51,9 +50,10 @@ lazy val extractor = newProject("extractor")
System.setProperty("structure.sbtversion.short", CrossBuilding.pluginSbtVersion.value.substring(0, 4))
System.setProperty("structure.scalaversion", scalaBinaryVersion.value)
},
test in Test <<= (test in Test).dependsOn(testSetup),
testOnly in Test <<= (testOnly in Test).dependsOn(testSetup),
name in bintray := "sbt-structure-extractor"
test in Test := (test in Test).dependsOn(testSetup).value,
testOnly in Test := (testOnly in Test).dependsOn(testSetup).evaluated,
name in bintray := "sbt-structure-extractor",
scalacOptions ++= Seq("-deprecation")
)

lazy val sbtStructure = project.in(file(".")).aggregate(core, extractor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ package extractors

import java.io.File

import org.jetbrains.sbt.structure.{Aar, ApkLib, AndroidData, BuildData, ConfigurationData, DependencyData, DirectoryData, ProjectData}
import sbt._
import org.jetbrains.sbt.structure.{Aar, AndroidData, ApkLib, BuildData, ConfigurationData, DependencyData, DirectoryData, ProjectData}
import sbt.Project.Initialize
import sbt._


object AndroidSdkPluginExtractor extends SbtStateOps with TaskOps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ package extractors
import java.io.File

import org.jetbrains.sbt.structure.BuildData
import sbt._
import sbt.Project.Initialize
import sbt._

/**
* @author Nikolay Obedin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package org.jetbrains.sbt
package extractors

import org.jetbrains.sbt.structure._
import org.jetbrains.sbt.{structure => jb}
import sbt._
import org.jetbrains.sbt.{ModulesOps, SbtStateOps, StructureKeys, TaskOps, structure => jb}
import sbt.Project.Initialize
import sbt._

/**
* @author Nikolay Obedin
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.jetbrains.sbt
package extractors
package org.jetbrains.sbt.extractors

import org.jetbrains.sbt.{SbtStateOps, TaskOps}
import org.jetbrains.sbt.structure._
import sbt._
import sbt.Project.Initialize
import sbt._

/**
* @author Dmitry Naydanov
Expand Down Expand Up @@ -40,12 +40,12 @@ object Play2Extractor extends SbtStateOps with TaskOps {
}

private object Keys {
val playPlugin_prior_to_2_4_0 = SettingKey[Boolean]("play-plugin")
val playPlugin = SettingKey[Boolean]("playPlugin")
val playVersion = SettingKey[String]("play-version")
val templateImports = SettingKey[Seq[String]]("twirl-template-imports")
val routesImports_prior_to_2_4_0 = SettingKey[Seq[String]]("play-routes-imports")
val routesImports = SettingKey[Seq[String]]("playRoutesImports")
val confDirectory = SettingKey[File]("play-conf")
val playPlugin_prior_to_2_4_0: SettingKey[Boolean] = SettingKey[Boolean]("play-plugin")
val playPlugin: SettingKey[Boolean] = SettingKey[Boolean]("playPlugin")
val playVersion: SettingKey[String] = SettingKey[String]("play-version")
val templateImports: SettingKey[Seq[String]] = SettingKey[Seq[String]]("twirl-template-imports")
val routesImports_prior_to_2_4_0: SettingKey[Seq[String]] = SettingKey[Seq[String]]("play-routes-imports")
val routesImports: SettingKey[Seq[String]] = SettingKey[Seq[String]]("playRoutesImports")
val confDirectory: SettingKey[File] = SettingKey[File]("play-conf")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,11 @@ class ProjectExtractor(projectRef: ProjectRef,
if (testConfigurations.contains(configuration)) Test else configuration

private def extractScala: Option[ScalaData] = scalaInstance.map { instance =>
val extraJars = instance.extraJars.filter(_.getName.contains("reflect"))
ScalaData(instance.version, instance.libraryJar, instance.compilerJar, extraJars, scalacOptions)
val jars =
instance.libraryJar +:
instance.compilerJar +:
instance.extraJars.filter(_.getName.contains("reflect"))
ScalaData(instance.version, jars, scalacOptions)
}

private def extractJava: Option[JavaData] =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package org.jetbrains.sbt
package extractors
package org.jetbrains.sbt.extractors

import org.jetbrains.sbt.StructureKeys
import org.jetbrains.sbt.structure.StructureData
import sbt.Project.Initialize
import sbt._
import Project.Initialize

//import scala.language.reflectiveCalls

object StructureExtractor {

Expand Down
31 changes: 31 additions & 0 deletions extractor/src/main/scala-sbt-0.13/org/jetbrains/sbt/adapters.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.jetbrains.sbt

import sbt._

case class LoadedBuildUnitAdapter(delegate: LoadedBuildUnit) {
def imports: Seq[String] =
delegate.imports

def pluginsClasspath: Seq[Attributed[File]] =
delegate.unit.plugins.pluginData.dependencyClasspath
}

case class UpdateReportAdapter(configurationToModule: Map[String, Seq[ModuleReportAdapter]]) {
def this(delegate: UpdateReport) {
this(delegate.configurations.map { report =>
(report.configuration, report.modules.map(new ModuleReportAdapter(_)))
}.toMap)
}

def allModules: Seq[ModuleReportAdapter] =
configurationToModule.values.toSeq.flatten

def modulesFrom(configuration: String): Seq[ModuleReportAdapter] =
configurationToModule.getOrElse(configuration, Seq.empty)
}

case class ModuleReportAdapter(moduleId: ModuleID, artifacts: Seq[(Artifact, File)]) {
def this(delegate: ModuleReport) {
this(delegate.module, delegate.artifacts)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package org.jetbrains.sbt.extractors

import java.io.File

import org.jetbrains.sbt.structure.{Aar, AndroidData, ApkLib, BuildData, ConfigurationData, DependencyData, DirectoryData, ProjectData}
import org.jetbrains.sbt.{SbtStateOps, TaskOps}
import sbt._

import scala.language.reflectiveCalls


object AndroidSdkPluginExtractor extends SbtStateOps with TaskOps {

def taskDef: Def.Initialize[Task[Option[AndroidData]]] =
(sbt.Keys.state, sbt.Keys.thisProjectRef) flatMap { (state, projectRef) =>
val keys = state.attributes.get(sbt.Keys.sessionSettings) match {
case Some(SessionSettings(_, _, settings, _, _, _)) => settings map { _.key }
case _ => Seq.empty
}

val manifestFileTaskOpt = Keys.processManifest.in(projectRef).find(state)
.orElse(Keys.manifestPath.in(projectRef).find(state).map(_.toTask))
val layoutAsAnyOpt = findSettingKeyIn(keys, "projectLayout")
.flatMap(_.in(projectRef).find(state))
val apklibsAsAnyTaskOpt = findTaskKeyIn(keys, "apklibs")
.flatMap(_.in(projectRef).find(state))
val aarsAsAnyTaskOpt = findTaskKeyIn(keys, "aars")
.flatMap(_.in(projectRef).find(state))

val androidTaskOpt = for {
manifestTask <- manifestFileTaskOpt
apk <- Keys.apkFile.in(projectRef).find(state)
isLibrary <- Keys.libraryProject.in(projectRef).find(state)
layoutAsAny <- layoutAsAnyOpt
apklibsAsAnyTask <- apklibsAsAnyTaskOpt
targetVersionTask <- Keys.settingOrTask[String](Keys.targetSdkVersionKey, projectRef, state)
aarsAsAnyTask <- aarsAsAnyTaskOpt
proguardConfigTask <- Keys.proguardConfig.in(projectRef).find(state)
proguardOptionsTask <- Keys.settingOrTask[Seq[String]](Keys.proguardOptionsKey, projectRef, state)
} yield {
for {
manifest <- manifestTask
targetVersion <- targetVersionTask
proguardConfig <- proguardConfigTask
proguardOptions <- proguardOptionsTask
apklibsAsAny <- apklibsAsAnyTask
aarsAsAny <- aarsAsAnyTask
} yield {
try {
val layout = layoutAsAny.asInstanceOf[ProjectLayout]
val apklibs = apklibsAsAny.asInstanceOf[Seq[LibraryDependency]]
val aars = aarsAsAny.asInstanceOf[Seq[LibraryDependency]].map(libraryDepToAar(targetVersion))
Some(AndroidData(targetVersion, manifest, apk,
layout.res, layout.assets, layout.gen, layout.libs,
isLibrary, proguardConfig ++ proguardOptions,
apklibs.map(libraryDepToApkLib), aars))
} catch {
case _ : NoSuchMethodException => None
}
}
}

androidTaskOpt.getOrElse(None.toTask)
}

private val Android = config("android")

private object Keys {
val targetSdkVersionKey = "target-sdk-version"
val manifestPath: SettingKey[File] = SettingKey[File]("manifest-path").in(Android)
val processManifest: TaskKey[File] = TaskKey[File]("process-manifest").in(Android)
val apkFile: SettingKey[File] = SettingKey[File]("apk-file").in(Android)
val libraryProject: SettingKey[Boolean] = SettingKey[Boolean]("library-project").in(Android)
val proguardConfig: TaskKey[Seq[String]] = TaskKey[Seq[String]]("proguard-config").in(Android)
val proguardOptionsKey = "proguard-options"

def settingOrTask[A : Manifest](key: String, projectRef: ProjectRef, state: State): Option[Task[A]] = {
TaskKey[A](key).in(Android).in(projectRef).find(state)
.orElse(SettingKey[A](key).in(Android).in(projectRef).find(state).map(_.toTask))
}
}

private type ProjectLayout = {
def base: File
def res: File
def assets: File
def gen: File
def bin: File
def libs: File
def sources: File
def resources: File
def manifest: File
}

private type LibraryDependency = {
def layout: ProjectLayout
def getName: String
def getJarFile: File
}

private def findSettingKeyIn(keys: Seq[sbt.ScopedKey[_]], label: String): Option[SettingKey[Any]] =
keys.find(k => k.key.label == label && isInAndroidScope(k))
.map(k => SettingKey(k.key.asInstanceOf[AttributeKey[Any]]).in(k.scope))

private def findTaskKeyIn(keys: Seq[sbt.ScopedKey[_]], label: String): Option[TaskKey[Any]] =
keys.find(k => k.key.label == label && isInAndroidScope(k))
.map(k => TaskKey(k.key.asInstanceOf[AttributeKey[Task[Any]]]).in(k.scope))

private def libraryDepToApkLib(lib: LibraryDependency): ApkLib = {
// As for version 1.5.0 android-sdk-plugin uses canonical path to library as its name
val fixedLibName = lib.getName.split(File.separatorChar).last
ApkLib(fixedLibName, lib.layout.base, lib.layout.manifest, lib.layout.sources, lib.layout.res, lib.layout.libs, lib.layout.gen)
}

private def libraryDepToAar(targetSdkVersion: String)(lib: LibraryDependency): Aar = {
val fixedLibName = lib.getName.split(File.separatorChar).last
val android = AndroidData(targetSdkVersion, lib.layout.manifest, lib.layout.base,
lib.layout.res, lib.layout.assets, lib.layout.gen, lib.layout.libs,
isLibrary = true, Nil, Nil, Nil)
val project = ProjectData(
fixedLibName, fixedLibName, "sbt-android-synthetic-organization", "0.1-SNAPSHOT-sbt-android",
lib.layout.base, Nil, lib.layout.bin, BuildData(Nil, Nil, Nil, Nil),
ConfigurationData("compile",
Seq(DirectoryData(lib.layout.sources, managed = true)),
Seq(DirectoryData(lib.layout.resources, managed = true)), Nil, lib.getJarFile) :: Nil, None, None, Some(android),
DependencyData(Nil, Nil, Nil), Set.empty, None)
Aar(fixedLibName, project)
}

private def isInAndroidScope(key: ScopedKey[_]) = key.scope.config match {
case Select(k) => k.name == Android.name
case _ => false
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.jetbrains.sbt.extractors

import java.io.File

import org.jetbrains.sbt.{LoadedBuildUnitAdapter, SbtStateOps, StructureKeys, TaskOps, UpdateReportAdapter}
import org.jetbrains.sbt.structure.BuildData
import sbt._

/**
* @author Nikolay Obedin
* @since 4/10/15.
*/
class BuildExtractor(unit: LoadedBuildUnitAdapter, updateSbtClassifiers: Option[UpdateReportAdapter]) {
private[extractors] def extract: BuildData = {
val (docs, sources) = extractSbtClassifiers
BuildData(unit.imports, unit.pluginsClasspath.map(_.data), docs, sources)
}

private def extractSbtClassifiers: (Seq[File], Seq[File]) =
updateSbtClassifiers.map { updateReport =>
val allArtifacts = updateReport.allModules.flatMap(_.artifacts)
def artifacts(kind: String) = allArtifacts.filter(_._1.`type` == kind).map(_._2).distinct
(artifacts(Artifact.DocType), artifacts(Artifact.SourceType))
}.getOrElse((Seq.empty, Seq.empty))
}

object BuildExtractor extends SbtStateOps with TaskOps {
def taskDef: Def.Initialize[Task[BuildData]] =
(sbt.Keys.state, sbt.Keys.thisProjectRef, StructureKeys.sbtStructureOpts) flatMap {
(state, projectRef, options) =>
val unit = LoadedBuildUnitAdapter(structure(state).units(projectRef.build))
Keys.updateSbtClassifiers.in(projectRef).get(state)
.onlyIf(options.download && options.resolveSbtClassifiers)
.map { updateClassifiersOpt =>
new BuildExtractor(unit, updateClassifiersOpt.map(new UpdateReportAdapter(_))).extract
}
}
}
Loading

0 comments on commit 5e3a320

Please sign in to comment.