Skip to content

Commit c652dbf

Browse files
Merge pull request #282 from ua-parser/scalafmt
Remove scalastyle and adopt scalafix and scalafmt
2 parents 341f186 + 8adcf11 commit c652dbf

File tree

14 files changed

+206
-190
lines changed

14 files changed

+206
-190
lines changed

Diff for: .github/workflows/scala.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,7 @@ jobs:
2323
cache: sbt
2424
- name: Setup sbt
2525
uses: sbt/setup-sbt@v1
26+
- name: Check formatting
27+
run: sbt -v "scalafixAll --check; scalafmtCheck"
2628
- name: Run tests
27-
run: sbt -v "++${{ matrix.scala-version }} clean; test; scalastyle;"
29+
run: sbt -v "++${{ matrix.scala-version }} clean; test;"

Diff for: .scalafix.conf

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
rules = [OrganizeImports, LeakingImplicitClassVal, ProcedureSyntax, RedundantSyntax, ExplicitResultTypes]
2+
3+
OrganizeImports {
4+
targetDialect = Scala3
5+
coalesceToWildcardImportThreshold = 2147483647 # Int.MaxValue
6+
expandRelative = true
7+
groupExplicitlyImportedImplicitsSeparately = false
8+
groupedImports = AggressiveMerge
9+
groups = ["re:javax?\\.", "scala.", "*", "org.uaparser."]
10+
importSelectorsOrder = Ascii
11+
importsOrder = Ascii
12+
removeUnused = false
13+
}
14+
15+
ExplicitResultTypes {
16+
memberVisibility = [Public]
17+
memberKind = [Def]
18+
skipSimpleDefinitions = false
19+
}

Diff for: .scalafmt.conf

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version = 3.9.4
2+
3+
runner.dialect = scala3
4+
maxColumn = 120
5+
newlines.topLevelStatementBlankLines = [
6+
{ blanks: { after: 0 } }
7+
]
8+
fileOverride {
9+
"glob:**/*.sbt" {
10+
runner.dialect = sbt1
11+
align.preset = most
12+
}
13+
}

Diff for: build.sbt

+26-22
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import ReleaseTransformations._
22

3-
name := "uap-scala"
3+
name := "uap-scala"
44
organization := "org.uaparser"
55

6-
scalaVersion := "2.13.14"
6+
scalaVersion := "2.13.14"
77
crossScalaVersions := Seq("2.12.20", "2.13.16", "3.3.5")
88

99
scalacOptions ++= Seq(
1010
"-Xfatal-warnings",
1111
"-deprecation",
12-
"-encoding", "UTF-8",
12+
"-encoding",
13+
"UTF-8",
1314
"-feature",
1415
"-unchecked"
1516
)
@@ -23,43 +24,47 @@ val scala2Flags = Seq(
2324
)
2425

2526
scalacOptions := {
26-
CrossVersion.partialVersion(scalaVersion.value) match {
27-
case Some((3, _)) =>
28-
scalacOptions.value :+ "-language:implicitConversions"
29-
case Some((2, _)) =>
30-
scalacOptions.value ++ scala2Flags
31-
case _ =>
32-
scalacOptions.value
33-
}
27+
CrossVersion.partialVersion(scalaVersion.value) match {
28+
case Some((3, _)) =>
29+
scalacOptions.value :+ "-language:implicitConversions"
30+
case Some((2, _)) =>
31+
scalacOptions.value ++ scala2Flags
32+
case _ =>
33+
scalacOptions.value
34+
}
3435
}
3536

36-
libraryDependencies += "org.yaml" % "snakeyaml" % "2.4"
37+
// Enable scalafix
38+
semanticdbEnabled := true
39+
semanticdbVersion := scalafixSemanticdb.revision
40+
41+
libraryDependencies += "org.yaml" % "snakeyaml" % "2.4"
3742

3843
libraryDependencies := {
3944
CrossVersion.partialVersion(scalaVersion.value) match {
40-
case Some((3, _)) =>
45+
case Some((3, _)) =>
4146
libraryDependencies.value ++ Seq("org.specs2" %% "specs2-core" % "5.5.8" % "test")
4247
case Some((2, scalaMajor)) if scalaMajor >= 11 =>
4348
libraryDependencies.value ++ Seq("org.specs2" %% "specs2-core" % "4.20.9" % "test")
44-
case _ =>
49+
case _ =>
4550
libraryDependencies.value ++ Seq("org.specs2" %% "specs2-core" % "3.10.0" % "test")
46-
}
4751
}
52+
}
4853

4954
mimaPreviousArtifacts := Set("org.uaparser" %% "uap-scala" % "0.3.0")
5055

5156
Compile / unmanagedResourceDirectories += baseDirectory.value / "core"
5257
Compile / unmanagedResources / includeFilter := "regexes.yaml"
5358
Test / unmanagedResourceDirectories += baseDirectory.value / "core"
54-
Test / unmanagedResources / includeFilter := "*.yaml"
59+
Test / unmanagedResources / includeFilter := "*.yaml"
5560

5661
// Publishing
57-
publishMavenStyle := true
58-
publishTo := sonatypePublishToBundle.value
62+
publishMavenStyle := true
63+
publishTo := sonatypePublishToBundle.value
5964
Test / publishArtifact := false
6065

61-
releaseCrossBuild := true
62-
releaseTagComment := s"Release ${(ThisBuild / version).value}"
66+
releaseCrossBuild := true
67+
releaseTagComment := s"Release ${(ThisBuild / version).value}"
6368
releaseCommitMessage := s"Set version to ${(ThisBuild / version).value}"
6469

6570
releaseProcess := Seq[ReleaseStep](
@@ -77,8 +82,7 @@ releaseProcess := Seq[ReleaseStep](
7782
pushChanges
7883
)
7984

80-
pomExtra := (
81-
<url>https://github.com/ua-parser/uap-scala</url>
85+
pomExtra := (<url>https://github.com/ua-parser/uap-scala</url>
8286
<licenses>
8387
<license>
8488
<name>WTFPL</name>

Diff for: project/plugins.sbt

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.1")
2-
addSbtPlugin("com.github.sbt" % "sbt-release" % "1.4.0")
3-
addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.1.4")
4-
addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0")
5-
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.12.2")
1+
addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.1")
2+
addSbtPlugin("com.github.sbt" % "sbt-release" % "1.4.0")
3+
addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.1.4")
4+
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.12.2")
5+
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.14.2")
6+
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.4")

Diff for: scalastyle-config.xml

-85
This file was deleted.

Diff for: src/main/scala/org/uaparser/scala/CachingParser.scala

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package org.uaparser.scala
22

33
import java.io.InputStream
4-
import java.util.{ Collections, LinkedHashMap, Map => JMap }
4+
import java.util
5+
import java.util.{Collections, Map as JMap}
6+
57
import scala.util.Try
68

79
case class CachingParser(parser: Parser, maxEntries: Int) extends UserAgentStringParser {
810
lazy val clients: JMap[String, Client] = Collections.synchronizedMap(
9-
new LinkedHashMap[String, Client](maxEntries + 1, 1.0f, true) {
11+
new util.LinkedHashMap[String, Client](maxEntries + 1, 1.0f, true) {
1012
override protected def removeEldestEntry(eldest: JMap.Entry[String, Client]): Boolean =
1113
super.size > maxEntries
1214
}
@@ -19,7 +21,7 @@ case class CachingParser(parser: Parser, maxEntries: Int) extends UserAgentStrin
1921
}
2022

2123
object CachingParser {
22-
val defaultCacheSize: Int = 1000
24+
private val defaultCacheSize: Int = 1000
2325
def fromInputStream(source: InputStream, size: Int = defaultCacheSize): Try[CachingParser] =
2426
Parser.fromInputStream(source).map(CachingParser(_, size))
2527
def default(size: Int = defaultCacheSize): CachingParser = CachingParser(Parser.default, size)

Diff for: src/main/scala/org/uaparser/scala/Device.scala

+26-19
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,56 @@
11
package org.uaparser.scala
22

3-
import java.util.regex.{ Matcher, Pattern }
4-
import org.uaparser.scala.MatcherOps._
3+
import java.util.regex.{Matcher, Pattern}
4+
5+
import org.uaparser.scala.MatcherOps.*
56

67
case class Device(family: String, brand: Option[String] = None, model: Option[String] = None)
78

89
object Device {
910
private[scala] def fromMap(m: Map[String, String]) = m.get("family").map(Device(_, m.get("brand"), m.get("model")))
1011

11-
private[scala] case class DevicePattern(pattern: Pattern, familyReplacement: Option[String],
12-
brandReplacement: Option[String], modelReplacement: Option[String]) {
12+
private[scala] case class DevicePattern(
13+
pattern: Pattern,
14+
familyReplacement: Option[String],
15+
brandReplacement: Option[String],
16+
modelReplacement: Option[String]
17+
) {
1318
def process(agent: String): Option[Device] = {
1419
val matcher = pattern.matcher(agent)
15-
if (!matcher.find()) None else {
20+
if (!matcher.find()) None
21+
else {
1622
val family = familyReplacement.map(r => replace(r, matcher)).orElse(matcher.groupAt(1))
1723
val brand = brandReplacement.map(r => replace(r, matcher)).filterNot(s => s.isEmpty)
1824
val model = modelReplacement.map(r => replace(r, matcher)).orElse(matcher.groupAt(1)).filterNot(s => s.isEmpty)
1925
family.map(Device(_, brand, model))
2026
}
2127
}
2228

23-
def replace(replacement: String, matcher: Matcher): String = {
24-
(if (replacement.contains("$") && matcher.groupCount() >= 1) {
25-
(1 to matcher.groupCount()).foldLeft(replacement)((rep, i) => {
26-
val toInsert = if (matcher.group(i) ne null) matcher.group(i) else ""
27-
rep.replaceFirst("\\$" + i, Matcher.quoteReplacement(toInsert))
28-
})
29-
} else replacement).trim
29+
private def replace(replacement: String, matcher: Matcher): String = {
30+
(if (replacement.contains("$") && matcher.groupCount() >= 1) {
31+
(1 to matcher.groupCount()).foldLeft(replacement)((rep, i) => {
32+
val toInsert = if (matcher.group(i) ne null) matcher.group(i) else ""
33+
rep.replaceFirst("\\$" + i, Matcher.quoteReplacement(toInsert))
34+
})
35+
} else replacement).trim
3036
}
3137
}
3238

3339
private object DevicePattern {
3440
def fromMap(m: Map[String, String]): Option[DevicePattern] = m.get("regex").map { r =>
35-
val pattern = m.get("regex_flag").map(flag =>
36-
Pattern.compile(r, Pattern.CASE_INSENSITIVE)).getOrElse(Pattern.compile(r)
37-
)
41+
val pattern =
42+
m.get("regex_flag").map(flag => Pattern.compile(r, Pattern.CASE_INSENSITIVE)).getOrElse(Pattern.compile(r))
3843
DevicePattern(pattern, m.get("device_replacement"), m.get("brand_replacement"), m.get("model_replacement"))
3944
}
4045
}
4146

4247
case class DeviceParser(patterns: List[DevicePattern]) {
43-
def parse(agent: String): Device = patterns.foldLeft[Option[Device]](None) {
44-
case (None, pattern) => pattern.process(agent)
45-
case (result, _) => result
46-
}.getOrElse(Device("Other"))
48+
def parse(agent: String): Device = patterns
49+
.foldLeft[Option[Device]](None) {
50+
case (None, pattern) => pattern.process(agent)
51+
case (result, _) => result
52+
}
53+
.getOrElse(Device("Other"))
4754
}
4855

4956
object DeviceParser {

Diff for: src/main/scala/org/uaparser/scala/MatcherOps.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package org.uaparser.scala
33
import java.util.regex.Matcher
44

55
object MatcherOps {
6-
implicit class MatcherImprovements(val m: Matcher) extends AnyVal {
6+
implicit class MatcherImprovements(private val m: Matcher) extends AnyVal {
77
// Tries to safely return the matching group at index i wrapped in an Option.
88
// We also take care of converting empty strings to a None, because it seems possible in uap-core to define matching
99
// groups that capture empty strings. At the time, the semantics of None and empty strings seemed to match.

0 commit comments

Comments
 (0)