Skip to content

Commit 80d789a

Browse files
authored
Merge pull request #21 from olafurpg/sourcegraphEnable
Add sbt v0.13 support and `sourcegraphEnable` command
2 parents 10174ab + c063cc5 commit 80d789a

File tree

10 files changed

+516
-103
lines changed

10 files changed

+516
-103
lines changed

.jvmopts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-Xss4m
2+
-Xms1G
3+
-Xmx4G
4+
-XX:ReservedCodeCacheSize=1024m
5+
-XX:+TieredCompilation
6+
-XX:+CMSClassUnloadingEnabled
7+
-Dfile.encoding=UTF-8

build.sbt

Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,66 @@
1-
inThisBuild(
2-
List(
3-
scalaVersion := "2.12.12",
4-
scalacOptions ++= List(
5-
"-Xlint:unused"
6-
),
7-
scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.5.0-alpha.1",
8-
semanticdbEnabled := true,
9-
organization := "com.sourcegraph",
10-
homepage := Some(url("https://github.com/sourcegraph/sbt-sourcegraph")),
11-
licenses := List(
12-
"Apache-2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0")
13-
),
14-
developers := List(
15-
Developer(
16-
"olafurpg",
17-
"Ólafur Páll Geirsson",
18-
19-
url("https://sourcegraph.com")
20-
)
21-
)
1+
import scala.jdk.CollectionConverters._
2+
import java.util.Properties
3+
import com.sourcegraph.sbtsourcegraph.Versions
4+
5+
val V = new {
6+
def scala212 = "2.12.12"
7+
def scalameta = "4.4.25"
8+
}
9+
10+
scalaVersion := V.scala212
11+
ThisBuild / scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.5.0-alpha.1"
12+
organization := "com.sourcegraph"
13+
semanticdbEnabled := true
14+
semanticdbVersion := "4.4.26"
15+
homepage := Some(url("https://github.com/sourcegraph/sbt-sourcegraph"))
16+
licenses := List(
17+
"Apache-2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0")
18+
)
19+
developers := List(
20+
Developer(
21+
"olafurpg",
22+
"Ólafur Páll Geirsson",
23+
24+
url("https://sourcegraph.com")
2225
)
2326
)
2427

25-
publish / skip := true
28+
// Cross-building settings (see https://github.com/sbt/sbt/issues/3473#issuecomment-325729747)
29+
def scala212 = "2.12.13"
30+
def scala210 = "2.10.7"
2631

27-
lazy val plugin = project
28-
.settings(
29-
sbtPlugin := true,
30-
moduleName := "sbt-sourcegraph"
31-
)
32+
sbtPlugin := true
33+
moduleName := "sbt-sourcegraph"
34+
pluginCrossBuild / sbtVersion := "1.2.1"
35+
Compile / resourceGenerators += Def.task {
36+
val out =
37+
(Compile / managedResourceDirectories).value.head / "sbt-sourcegraph" / "semanticdb.properties"
38+
if (!out.exists()) {
39+
val versions = Versions.semanticdbVersionsByScalaVersion()
40+
val props = new Properties()
41+
props.putAll(versions.asJava)
42+
IO.write(props, "SemanticDB versions grouped by Scala version.", out)
43+
}
44+
List(out)
45+
}
46+
crossScalaVersions := Seq(scala212, scala210)
47+
scalacOptions ++= {
48+
if (scalaVersion.value == scala210) List()
49+
else List("-Xlint:unused")
50+
}
51+
52+
pluginCrossBuild / sbtVersion := {
53+
// keep this as low as possible to avoid running into binary incompatibility such as https://github.com/sbt/sbt/issues/5049
54+
scalaBinaryVersion.value match {
55+
case "2.10" => "0.13.17"
56+
case "2.12" => "1.2.1"
57+
}
58+
}
59+
60+
buildInfoKeys := List[BuildInfoKey](
61+
version
62+
)
63+
buildInfoPackage := "com.sourcegraph.sbtsourcegraph"
64+
enablePlugins(BuildInfoPlugin)
65+
66+
def isCI = "true" == System.getenv("CI")

project/plugins.sbt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@ addSbtPlugin("com.geirsson" % "sbt-ci-release" % "1.5.5")
22
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.10.0")
33
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.3")
44
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.29")
5+
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.4.8-94-1cfdf0bd")
56

67
Compile / unmanagedSourceDirectories +=
78
(ThisBuild / baseDirectory).value.getParentFile /
8-
"plugin" / "src" / "main" / "scala"
9+
"src" / "main" / "scala"
10+
Compile / unmanagedSourceDirectories +=
11+
(ThisBuild / baseDirectory).value.getParentFile /
12+
"src" / "main" / "scala-sbt-1.0"
913
Compile / unmanagedResourceDirectories +=
1014
(ThisBuild / baseDirectory).value.getParentFile /
11-
"plugin" / "src" / "main" / "resources"
15+
"src" / "main" / "resources"
File renamed without changes.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package sbt.internal.sbtsourcegraph
2+
3+
import sbt.{Classpaths, Compiler, Extracted, Setting, State, UpdateReport}
4+
import sbt.inc.IncOptions
5+
6+
object Compat {
7+
type ConsoleLogger = sbt.ConsoleLogger
8+
val ConsoleLogger = sbt.ConsoleLogger
9+
10+
val Disabled = sbt.CrossVersion.Disabled
11+
12+
def append(
13+
project: Extracted,
14+
settings: Seq[Setting[_]],
15+
state: State
16+
): State =
17+
project.append(settings, state)
18+
19+
def addIgnoredScalacOptions(
20+
incOptions: IncOptions,
21+
ignoredScalacOptions: Seq[String]
22+
): IncOptions = {
23+
// ignoredScalacOptions was added in 1.2 https://github.com/sbt/zinc/commit/868182936686679b3e0c7569f69d843323b4d712
24+
incOptions
25+
}
26+
27+
def withHasModified(
28+
compileResult: Compiler.CompileResult,
29+
hasModified: Boolean
30+
): Compiler.CompileResult = {
31+
compileResult
32+
}
33+
34+
def autoPlugins(
35+
report: UpdateReport,
36+
scalaVersion: String
37+
): Seq[String] = {
38+
Classpaths.autoPlugins(
39+
report,
40+
Seq(),
41+
Set("jar", "bundle")
42+
)
43+
}
44+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package sbt.internal.sbtsourcegraph
2+
3+
import sbt.internal.inc.ScalaInstance
4+
import sbt.{Classpaths, Extracted, IncOptions, Setting, State, UpdateReport}
5+
import xsbti.compile.CompileResult
6+
import sbt.librarymanagement
7+
8+
object Compat {
9+
type ConsoleLogger = sbt.internal.util.ConsoleLogger
10+
val ConsoleLogger = sbt.internal.util.ConsoleLogger
11+
12+
// https://github.com/sbt/sbt/issues/4977
13+
val Disabled: librarymanagement.Disabled = sbt.librarymanagement.Disabled()
14+
15+
def append(
16+
project: Extracted,
17+
settings: Seq[Setting[_]],
18+
state: State
19+
): State =
20+
project.appendWithoutSession(settings, state)
21+
22+
def addIgnoredScalacOptions(
23+
incOptions: IncOptions,
24+
ignoredScalacOptions: Seq[String]
25+
): IncOptions = {
26+
incOptions.withIgnoredScalacOptions(
27+
incOptions.ignoredScalacOptions() ++ ignoredScalacOptions
28+
)
29+
}
30+
31+
def withHasModified(
32+
compileResult: CompileResult,
33+
hasModified: Boolean
34+
): CompileResult = {
35+
compileResult.withHasModified(hasModified)
36+
}
37+
38+
def autoPlugins(
39+
report: UpdateReport,
40+
scalaVersion: String
41+
): Seq[String] = {
42+
Classpaths.autoPlugins(
43+
report,
44+
Seq(),
45+
ScalaInstance.isDotty(scalaVersion)
46+
)
47+
}
48+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.sourcegraph.sbtsourcegraph
2+
3+
import sbt._
4+
import scala.util.control.NonFatal
5+
6+
/** Helper to use sbt 1.3+ SemanticdbPlugin features when available */
7+
object SemanticdbPlugin {
8+
9+
// Copied from https://github.com/scalacenter/sbt-scalafix/blob/cdee753f15bde75d84d93c26695d14fc3ec964f8/src/main/scala/scalafix/internal/sbt/SemanticdbPlugin.scala
10+
val semanticdbEnabled: SettingKey[Boolean] = settingKey[Boolean]("")
11+
val semanticdbVersion: SettingKey[String] = settingKey[String]("")
12+
val semanticdbTargetRoot: SettingKey[File] = settingKey[File]("")
13+
14+
def isAvailable(): Boolean = try {
15+
Class.forName("sbt.plugins.SemanticdbPlugin")
16+
true
17+
} catch {
18+
case NonFatal(_) =>
19+
false
20+
}
21+
22+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/**
2+
* Adaptation of the `scalafixEnable` command from sbt-scalafix with the following modifications:
3+
* - use older SemanticDB versions instead of upgrading the Scala version.
4+
* - configure the semanticdb-javac compiler plugin for Java projects.
5+
* Original license: Apache 2
6+
* Original source: https://github.com/scalacenter/sbt-scalafix/blob/cdee753f15bde75d84d93c26695d14fc3ec964f8/src/main/scala/scalafix/sbt/ScalafixEnable.scala
7+
*/
8+
package com.sourcegraph.sbtsourcegraph
9+
10+
import sbt._
11+
import sbt.Keys._
12+
import sbt.internal.sbtsourcegraph.Compat
13+
14+
object SourcegraphEnable {
15+
16+
lazy val command: Command =
17+
if (SemanticdbPlugin.isAvailable()) withSemanticdbPlugin
18+
else withSemanticdbScalac
19+
20+
private lazy val withSemanticdbPlugin = Command.command(
21+
"sourcegraphEnable",
22+
briefHelp = "Configure SemanticdbPlugin for Sourcegraph.",
23+
detail =
24+
"""1. set semanticdbEnabled where supported
25+
|2. conditionally sets semanticdbVersion & scalaVersion when support is not built-in in the compiler""".stripMargin
26+
) { s =>
27+
val extracted = Project.extract(s)
28+
val scalacOptionsSettings = Seq(Compile, Test).flatMap(
29+
inConfig(_)(SourcegraphPlugin.relaxScalacOptionsConfigSettings)
30+
)
31+
val settings = for {
32+
(p, semanticdbVersion, overriddenScalaVersion) <- collectProjects(
33+
extracted
34+
)
35+
enableSemanticdbPlugin <-
36+
List(
37+
Option(
38+
allDependencies.in(
39+
p
40+
) += "com.sourcegraph" % "semanticdb-javac" % Versions
41+
.semanticdbJavacVersion()
42+
),
43+
Option(
44+
javacOptions.in(p) += s"-Xplugin:semanticdb " +
45+
s"-build-tool:sbt " +
46+
s"-sourceroot:${baseDirectory.in(ThisBuild).value} " +
47+
s"-targetroot:${classDirectory.in(Compile).value.toPath().resolveSibling("semanticdb-classes")}"
48+
),
49+
overriddenScalaVersion.map(v => scalaVersion.in(p) := v),
50+
Option(SemanticdbPlugin.semanticdbEnabled := true),
51+
Option(SemanticdbPlugin.semanticdbVersion := semanticdbVersion)
52+
).flatten
53+
settings <-
54+
inScope(ThisScope.in(p))(
55+
scalacOptionsSettings
56+
) ++ enableSemanticdbPlugin
57+
} yield settings
58+
Compat.append(extracted, settings, s)
59+
}
60+
61+
private lazy val withSemanticdbScalac = Command.command(
62+
"sourcegraphEnable",
63+
briefHelp =
64+
"Configure libraryDependencies, scalaVersion and scalacOptions for sourcegraph.",
65+
detail =
66+
"""1. enables the semanticdb-scalac compiler plugin
67+
|2. sets scalaVersion to latest Scala version supported by sourcegraph
68+
|3. add -Yrangepos to Compile|Test / compile / scalacOptions""".stripMargin
69+
) { s =>
70+
val extracted = Project.extract(s)
71+
val scalacOptionsSettings = Seq(Compile, Test).flatMap(
72+
inConfig(_)(
73+
semanticdbConfigSettings ++
74+
SourcegraphPlugin.relaxScalacOptionsConfigSettings
75+
)
76+
)
77+
val settings: Seq[Setting[_]] = for {
78+
(p, semanticdbVersion, overriddenScalaVersion) <- collectProjects(
79+
extracted
80+
)
81+
isSemanticdbEnabled =
82+
libraryDependencies
83+
.in(p)
84+
.get(extracted.structure.data)
85+
.exists(_.exists(_.name == "semanticdb-scalac"))
86+
if !isSemanticdbEnabled
87+
addSemanticdbCompilerPlugin = List(
88+
overriddenScalaVersion.map { v =>
89+
scalaVersion.in(p) := v
90+
},
91+
Option(
92+
allDependencies.in(p) += compilerPlugin(
93+
SourcegraphPlugin.autoImport.sourcegraphSemanticdb(
94+
semanticdbVersion
95+
)
96+
)
97+
)
98+
).flatten
99+
settings <-
100+
inScope(ThisScope.in(p))(
101+
scalacOptionsSettings
102+
) ++ addSemanticdbCompilerPlugin
103+
} yield settings
104+
Compat.append(extracted, settings, s)
105+
}
106+
107+
private val semanticdbConfigSettings: Seq[Def.Setting[_]] =
108+
Seq(
109+
scalacOptions.in(compile) := {
110+
val old = scalacOptions.in(compile).value
111+
val options = List(
112+
"-Yrangepos",
113+
"-Xplugin-require:semanticdb"
114+
)
115+
// don't rely on autoCompilerPlugins to inject the plugin as it does not work if scalacOptions is overriden in the build
116+
val plugins = Compat.autoPlugins(update.value, scalaVersion.value)
117+
old ++ (plugins ++ options).diff(old)
118+
}
119+
)
120+
121+
private def collectProjects[U](
122+
extracted: Extracted
123+
): Seq[(ProjectRef, String, Option[String])] = for {
124+
p <- extracted.structure.allProjectRefs
125+
projectScalaVersion <- scalaVersion
126+
.in(p)
127+
.get(extracted.structure.data)
128+
.toList
129+
overriddenScalaVersion =
130+
if (
131+
projectScalaVersion.startsWith("2.11") &&
132+
Versions.semanticdbVersion(projectScalaVersion).isEmpty
133+
)
134+
Some("2.11.12")
135+
else None
136+
semanticdbVersion <- Versions
137+
.semanticdbVersion(overriddenScalaVersion.getOrElse(projectScalaVersion))
138+
.toList
139+
} yield (p, semanticdbVersion, overriddenScalaVersion)
140+
}

0 commit comments

Comments
 (0)