Skip to content

Commit 03aeb37

Browse files
authored
Add in scalafmt and scalafix. (#333)
I was going to wait to do this, but I was starting on something else in here and I kept hitting format by habit since I'm honestly just used to always having it. I think it's safe to say that most Scala developers will be used to the default style that scalafmt gives you, so I'd like to propose that we add this in along with scalafix to organize imports. One huge concern is always that changes like this make it hard to get a good `git blame`, however with modern git, this really isn't an issue anymore. You can read more about his here: https://www.moxio.com/blog/43/ignoring-bulk-change-commits-with-git-blame I recently used the strategy outlined in that article in the sbt-scoverage plugin: scoverage/sbt-scoverage#351 and it seems to work quite well.
1 parent 3a02728 commit 03aeb37

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1989
-1005
lines changed

Diff for: .github/workflows/ci.yml

+24-5
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ on:
1111
pull_request:
1212

1313
jobs:
14-
scala:
14+
test:
1515
runs-on: ubuntu-latest
1616
strategy:
1717
fail-fast: false
1818
matrix:
19-
java: [ '1.8', '1.11' ]
19+
java: [ '8', '11' ]
2020
scala: [
2121
{ version: '2.12.13' },
2222
{ version: '2.12.12' },
@@ -37,10 +37,29 @@ jobs:
3737
with:
3838
fetch-depth: 0
3939

40-
- name: Set up Scala env
41-
uses: olafurpg/setup-scala@v10
40+
- name: Set up JVM
41+
uses: actions/setup-java@v2
4242
with:
43-
java-version: adopt@${{ matrix.java }}
43+
distribution: 'adopt'
44+
java-version: ${{ matrix.java }}
4445

4546
- name: run tests
4647
run: sbt ++${{ matrix.scala.version }} test
48+
49+
style-check:
50+
runs-on: ubuntu-latest
51+
52+
steps:
53+
- name: checkout the repo
54+
uses: actions/checkout@v2
55+
with:
56+
fetch-depth: 0
57+
58+
- name: Set up JVM
59+
uses: actions/setup-java@v2
60+
with:
61+
distribution: 'adopt'
62+
java-version: '8'
63+
64+
- name: styleCheck
65+
run: sbt styleCheck

Diff for: .scalafix.conf

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
rules = [
2+
OrganizeImports
3+
]
4+
5+
OrganizeImports.groupedImports = Explode
6+
OrganizeImports.expandRelative = true
7+
OrganizeImports.removeUnused = true
8+
OrganizeImports.groups = [
9+
"re:javax?\\."
10+
"scala."
11+
"*"
12+
]

Diff for: .scalafmt.conf

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
version = "2.7.5"
2+
project.git = true
3+
assumeStandardLibraryStripMargin = true
4+
xmlLiterals.assumeFormatted = true

Diff for: build.sbt

+34-7
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import sbtcrossproject.CrossProject
22
import sbtcrossproject.CrossType
33

44
val scalatestVersion = "3.2.8"
5-
5+
val defaultScala213 = "2.13.5"
66
val bin212 = Seq("2.12.13", "2.12.12", "2.12.11", "2.12.10", "2.12.9", "2.12.8")
7-
val bin213 = Seq("2.13.5", "2.13.4", "2.13.3", "2.13.2", "2.13.1", "2.13.0")
7+
val bin213 =
8+
Seq(defaultScala213, "2.13.4", "2.13.3", "2.13.2", "2.13.1", "2.13.0")
89

910
inThisBuild(
1011
List(
@@ -27,23 +28,37 @@ inThisBuild(
2728
licenses := Seq(
2829
"Apache-2.0" -> url("http://www.apache.org/license/LICENSE-2.0")
2930
),
30-
scalaVersion := bin213.head,
31-
crossScalaVersions := bin212 ++ bin213,
31+
scalaVersion := defaultScala213,
3232
versionScheme := Some("early-semver"),
3333
Test / fork := false,
3434
Test / publishArtifact := false,
3535
Test / parallelExecution := false,
36+
Global / concurrentRestrictions += Tags.limit(Tags.Test, 1),
3637
scalacOptions := Seq(
3738
"-unchecked",
3839
"-deprecation",
3940
"-feature",
4041
"-encoding",
4142
"utf8"
4243
),
43-
Global / concurrentRestrictions += Tags.limit(Tags.Test, 1)
44+
scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.5.0",
45+
semanticdbEnabled := true,
46+
semanticdbVersion := scalafixSemanticdb.revision,
47+
scalafixScalaBinaryVersion := scalaBinaryVersion.value
4448
)
4549
)
4650

51+
lazy val sharedSettings = List(
52+
scalacOptions := {
53+
if (scalaVersion.value == defaultScala213) {
54+
scalacOptions.value :+ "-Wunused:imports"
55+
} else {
56+
scalacOptions.value
57+
}
58+
},
59+
crossScalaVersions := bin212 ++ bin213
60+
)
61+
4762
lazy val root = Project("scalac-scoverage", file("."))
4863
.settings(
4964
name := "scalac-scoverage",
@@ -63,7 +78,8 @@ lazy val runtime = CrossProject(
6378
crossTarget := target.value / s"scala-${scalaVersion.value}",
6479
libraryDependencies ++= Seq(
6580
"org.scalatest" %%% "scalatest" % scalatestVersion % Test
66-
)
81+
),
82+
sharedSettings
6783
)
6884
.jvmSettings(
6985
Test / fork := true
@@ -86,8 +102,19 @@ lazy val plugin =
86102
"org.scala-lang.modules" %% "scala-xml" % "1.3.0",
87103
"org.scalatest" %% "scalatest" % scalatestVersion % Test,
88104
"org.scala-lang" % "scala-compiler" % scalaVersion.value % Provided
89-
)
105+
),
106+
sharedSettings
90107
)
91108
.settings(
92109
(Test / unmanagedSourceDirectories) += (Test / sourceDirectory).value / "scala-2.12+"
93110
)
111+
112+
addCommandAlias(
113+
"styleFix",
114+
"scalafixAll ; scalafmtAll ; scalafmtSbt"
115+
)
116+
117+
addCommandAlias(
118+
"styleCheck",
119+
"scalafmtCheckAll ; scalafmtSbtCheck ; scalafix --check"
120+
)

Diff for: project/plugins.sbt

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.5.1")
22
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.0.0")
33
addSbtPlugin("com.geirsson" % "sbt-ci-release" % "1.5.7")
4+
5+
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2")
6+
7+
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.27")

Diff for: scalac-scoverage-plugin/src/main/scala/scoverage/CoverageFilter.scala

+51-39
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package scoverage
22

33
import scala.collection.mutable
4-
import scala.reflect.internal.util.{Position, SourceFile}
4+
import scala.reflect.internal.util.Position
5+
import scala.reflect.internal.util.SourceFile
56
import scala.util.matching.Regex
67

7-
/**
8-
* Methods related to filtering the instrumentation and coverage.
9-
*
10-
* @author Stephen Samuel
11-
*/
8+
/** Methods related to filtering the instrumentation and coverage.
9+
*
10+
* @author Stephen Samuel
11+
*/
1212
trait CoverageFilter {
1313
def isClassIncluded(className: String): Boolean
1414
def isFileIncluded(file: SourceFile): Boolean
@@ -25,40 +25,44 @@ object AllCoverageFilter extends CoverageFilter {
2525
override def isSymbolIncluded(symbolName: String): Boolean = true
2626
}
2727

28-
class RegexCoverageFilter(excludedPackages: Seq[String],
29-
excludedFiles: Seq[String],
30-
excludedSymbols: Seq[String]) extends CoverageFilter {
28+
class RegexCoverageFilter(
29+
excludedPackages: Seq[String],
30+
excludedFiles: Seq[String],
31+
excludedSymbols: Seq[String]
32+
) extends CoverageFilter {
3133

3234
val excludedClassNamePatterns = excludedPackages.map(_.r.pattern)
3335
val excludedFilePatterns = excludedFiles.map(_.r.pattern)
3436
val excludedSymbolPatterns = excludedSymbols.map(_.r.pattern)
3537

36-
/**
37-
* We cache the excluded ranges to avoid scanning the source code files
38-
* repeatedly. For a large project there might be a lot of source code
39-
* data, so we only hold a weak reference.
40-
*/
41-
val linesExcludedByScoverageCommentsCache: mutable.Map[SourceFile, List[Range]] = mutable.WeakHashMap.empty
38+
/** We cache the excluded ranges to avoid scanning the source code files
39+
* repeatedly. For a large project there might be a lot of source code
40+
* data, so we only hold a weak reference.
41+
*/
42+
val linesExcludedByScoverageCommentsCache
43+
: mutable.Map[SourceFile, List[Range]] = mutable.WeakHashMap.empty
4244

4345
final val scoverageExclusionCommentsRegex =
4446
"""(?ms)^\s*//\s*(\$COVERAGE-OFF\$).*?(^\s*//\s*\$COVERAGE-ON\$|\Z)""".r
4547

46-
/**
47-
* True if the given className has not been excluded by the
48-
* `excludedPackages` option.
49-
*/
48+
/** True if the given className has not been excluded by the
49+
* `excludedPackages` option.
50+
*/
5051
override def isClassIncluded(className: String): Boolean = {
51-
excludedClassNamePatterns.isEmpty || !excludedClassNamePatterns.exists(_.matcher(className).matches)
52+
excludedClassNamePatterns.isEmpty || !excludedClassNamePatterns.exists(
53+
_.matcher(className).matches
54+
)
5255
}
5356

5457
override def isFileIncluded(file: SourceFile): Boolean = {
55-
def isFileMatch(file: SourceFile) = excludedFilePatterns.exists(_.matcher(file.path.replace(".scala", "")).matches)
58+
def isFileMatch(file: SourceFile) = excludedFilePatterns.exists(
59+
_.matcher(file.path.replace(".scala", "")).matches
60+
)
5661
excludedFilePatterns.isEmpty || !isFileMatch(file)
5762
}
5863

59-
/**
60-
* True if the line containing `position` has not been excluded by a magic comment.
61-
*/
64+
/** True if the line containing `position` has not been excluded by a magic comment.
65+
*/
6266
def isLineIncluded(position: Position): Boolean = {
6367
if (position.isDefined) {
6468
val excludedLineNumbers = getExcludedLineNumbers(position.source)
@@ -70,27 +74,34 @@ class RegexCoverageFilter(excludedPackages: Seq[String],
7074
}
7175

7276
override def isSymbolIncluded(symbolName: String): Boolean = {
73-
excludedSymbolPatterns.isEmpty || !excludedSymbolPatterns.exists(_.matcher(symbolName).matches)
77+
excludedSymbolPatterns.isEmpty || !excludedSymbolPatterns.exists(
78+
_.matcher(symbolName).matches
79+
)
7480
}
7581

76-
/**
77-
* Provides overloads to paper over 2.12.13+ SourceFile incompatibility
78-
*/
79-
def compatFindAllIn(regexp: Regex, pattern: Array[Char]): Regex.MatchIterator = regexp.findAllIn(new String(pattern))
80-
def compatFindAllIn(regexp: Regex, pattern: String): Regex.MatchIterator = regexp.findAllIn(pattern)
82+
/** Provides overloads to paper over 2.12.13+ SourceFile incompatibility
83+
*/
84+
def compatFindAllIn(
85+
regexp: Regex,
86+
pattern: Array[Char]
87+
): Regex.MatchIterator = regexp.findAllIn(new String(pattern))
88+
def compatFindAllIn(regexp: Regex, pattern: String): Regex.MatchIterator =
89+
regexp.findAllIn(pattern)
8190

82-
/**
83-
* Checks the given sourceFile for any magic comments which exclude lines
84-
* from coverage. Returns a list of Ranges of lines that should be excluded.
85-
*
86-
* The line numbers returned are conventional 1-based line numbers (i.e. the
87-
* first line is line number 1)
88-
*/
91+
/** Checks the given sourceFile for any magic comments which exclude lines
92+
* from coverage. Returns a list of Ranges of lines that should be excluded.
93+
*
94+
* The line numbers returned are conventional 1-based line numbers (i.e. the
95+
* first line is line number 1)
96+
*/
8997
def getExcludedLineNumbers(sourceFile: SourceFile): List[Range] = {
9098
linesExcludedByScoverageCommentsCache.get(sourceFile) match {
9199
case Some(lineNumbers) => lineNumbers
92100
case None =>
93-
val lineNumbers = compatFindAllIn(scoverageExclusionCommentsRegex, sourceFile.content).matchData.map { m =>
101+
val lineNumbers = compatFindAllIn(
102+
scoverageExclusionCommentsRegex,
103+
sourceFile.content
104+
).matchData.map { m =>
94105
// Asking a SourceFile for the line number of the char after
95106
// the end of the file gives an exception
96107
val endChar = math.min(m.end(2), sourceFile.content.length - 1)
@@ -100,7 +111,8 @@ class RegexCoverageFilter(excludedPackages: Seq[String],
100111
// line numbers
101112
Range(
102113
1 + sourceFile.offsetToLine(m.start(1)),
103-
1 + sourceFile.offsetToLine(endChar))
114+
1 + sourceFile.offsetToLine(endChar)
115+
)
104116
}.toList
105117
linesExcludedByScoverageCommentsCache.put(sourceFile, lineNumbers)
106118
lineNumbers

Diff for: scalac-scoverage-plugin/src/main/scala/scoverage/DoubleFormat.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package scoverage
22

3-
import java.text.{DecimalFormat, DecimalFormatSymbols}
3+
import java.text.DecimalFormat
4+
import java.text.DecimalFormatSymbols
45
import java.util.Locale
56

67
object DoubleFormat {

0 commit comments

Comments
 (0)