Skip to content

Commit f41b9c4

Browse files
Albert Meltzerkitbellew
Albert Meltzer
authored andcommitted
FormatSession: recognize git parameters and filter
1 parent 58f3509 commit f41b9c4

File tree

3 files changed

+71
-2
lines changed

3 files changed

+71
-2
lines changed

build.sbt

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ lazy val plugin = project
4040
.settings(
4141
moduleName := "sbt-scalafmt",
4242
libraryDependencies ++= List(
43+
"org.scalameta" %% "scalafmt-sysops" % scalafmtVersion,
4344
"org.scalameta" %% "scalafmt-dynamic" % scalafmtVersion
4445
),
4546
scriptedBufferLog := false,

plugin/src/main/scala/org/scalafmt/sbt/ScalafmtPlugin.scala

+36-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ import scala.util.Success
1515
import scala.util.Try
1616

1717
import org.scalafmt.interfaces.Scalafmt
18+
import org.scalafmt.sysops.AbsoluteFile
19+
import org.scalafmt.sysops.FileOps
20+
import org.scalafmt.sysops.GitOps
1821

1922
import complete.DefaultParsers._
2023

@@ -64,6 +67,9 @@ object ScalafmtPlugin extends AutoPlugin {
6467
settingKey[Boolean](
6568
"Enables logging of detailed errors with stacktraces, disabled by default"
6669
)
70+
val scalafmtFilter = settingKey[String](
71+
"File filtering mode when running scalafmt."
72+
)
6773
}
6874

6975
import autoImport._
@@ -102,10 +108,17 @@ object ScalafmtPlugin extends AutoPlugin {
102108
.create(this.getClass.getClassLoader)
103109
.withRespectProjectFilters(true)
104110

111+
private object FilterMode {
112+
val diffDirty = "diff-dirty"
113+
val diffRefPrefix = "diff-ref="
114+
}
115+
105116
private class FormatSession(
106117
config: Path,
107118
taskStreams: TaskStreams,
108119
resolvers: Seq[Resolver],
120+
currentProject: ResolvedProject,
121+
filterMode: String,
109122
detailedErrorEnabled: Boolean
110123
) {
111124
private val log = taskStreams.log
@@ -134,11 +147,27 @@ object ScalafmtPlugin extends AutoPlugin {
134147
scalafmtSession
135148
}
136149

137-
private def filterFiles(sources: Seq[File]): Seq[File] =
150+
private def filterFiles(sources: Seq[File]): Seq[File] = {
151+
val filter = getFileFilter()
138152
sources.distinct.filter { file =>
139153
val path = file.toPath.toAbsolutePath
140-
scalafmtSession.matchesProjectFilters(path)
154+
scalafmtSession.matchesProjectFilters(path) && filter(path)
141155
}
156+
}
157+
158+
private def getFileFilter(): Path => Boolean = {
159+
def gitOps = GitOps.FactoryImpl(AbsoluteFile(currentProject.base.toPath))
160+
val files =
161+
if (filterMode == FilterMode.diffDirty)
162+
gitOps.status()
163+
else if (filterMode.startsWith(FilterMode.diffRefPrefix))
164+
gitOps.diff(filterMode.substring(FilterMode.diffRefPrefix.length))
165+
else if (scalafmtSession.isGitOnly)
166+
gitOps.lsTree()
167+
else null
168+
if (files eq null) _ => true
169+
else FileOps.getFileMatcher(files.map(_.path))
170+
}
142171

143172
private def withFormattedSources[T](sources: Seq[File])(
144173
onFormat: (File, Input, Output) => T
@@ -374,6 +403,8 @@ object ScalafmtPlugin extends AutoPlugin {
374403
config,
375404
streams.value,
376405
fullResolvers.value,
406+
thisProject.value,
407+
scalafmtFilter.value,
377408
scalafmtDetailedError.value
378409
)
379410
func(files, session)
@@ -412,6 +443,8 @@ object ScalafmtPlugin extends AutoPlugin {
412443
scalaConfig.value,
413444
streams.value,
414445
fullResolvers.value,
446+
thisProject.value,
447+
"",
415448
scalafmtDetailedError.value
416449
).formatSources(absFiles)
417450
}
@@ -437,6 +470,7 @@ object ScalafmtPlugin extends AutoPlugin {
437470

438471
override def globalSettings: Seq[Def.Setting[_]] =
439472
Seq(
473+
scalafmtFilter := "",
440474
scalafmtOnCompile := false,
441475
scalafmtDetailedError := false
442476
)

plugin/src/sbt-test/scalafmt-sbt/sbt/test

+34
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,40 @@ $ delete p17/src/main/scala/Test2.scala
142142
$ copy-file changes/good.scala p17/src/main/scala/Test2.scala
143143
> p17/scalafmtCheck
144144
> p17/scalafmt
145+
$ delete p17/src/main/scala/Test.scala
146+
147+
# set up git
148+
$ exec git init -b main p17
149+
# filter dirty files
150+
> set p17/scalafmtFilter := ("diff-dirty")
151+
# dirty but should succeed
152+
$ copy-file changes/good.scala p17/src/main/scala/TestGood.scala
153+
> p17/scalafmtCheck
154+
# dirty and should fail
155+
$ copy-file changes/bad.scala p17/src/main/scala/TestBad.scala
156+
-> p17/scalafmtCheck
157+
# tracked yet still fail
158+
$ exec git -C p17 add "src/main/scala/TestBad.scala"
159+
-> p17/scalafmtCheck
160+
# no longer dirty, should succeed
161+
$ exec git -C p17 commit -m 'added TestBad.scala'
162+
> p17/scalafmtCheck
163+
# filter tracked modifications since branch=main
164+
> set p17/scalafmtFilter := ("diff-ref=main")
165+
# TestBad is checked in, TestGood not tracked
166+
> p17/scalafmtCheck
167+
# copy but unchanged
168+
$ copy-file changes/bad.scala p17/src/main/scala/TestBad.scala
169+
> p17/scalafmtCheck
170+
# copy to new file but untracked
171+
$ copy-file changes/bad.scala p17/src/main/scala/TestBad2.scala
172+
> p17/scalafmtCheck
173+
# now track it
174+
$ exec git -C p17 add "src/main/scala/TestBad2.scala"
175+
-> p17/scalafmtCheck
176+
# now commit it, no longer modified
177+
$ exec git -C p17 commit -m 'added TestBad2.scala'
178+
> p17/scalafmtCheck
145179

146180
$ copy-file changes/target/managed.scala project/target/managed.scala
147181
$ copy-file changes/x/Something.scala project/x/Something.scala

0 commit comments

Comments
 (0)