New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add the CLI option to fetch only recently changed files for formating. #1416
Changes from all commits
e59260d
01716d8
ddb7702
0ca1c28
dfd1407
e4774c0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,8 @@ object CliArgParser { | |
| # 2. .scalafmt.conf inside root directory of current git repo | ||
| # 3. no configuration, default style | ||
|scalafmt --test # throw exception on mis-formatted files, won't write to files. | ||
|scalafmt --diff # Format all files that were edited in git diff against master branch. | ||
|scalafmt --mode diff # Format all files that were edited in git diff against master branch. | ||
|scalafmt --mode changed # Format files listed in `git status` (latest changes against previous commit. | ||
|scalafmt --diff-branch 2.x # same as --diff, except against branch 2.x | ||
|scalafmt --stdin # read from stdin and print to stdout | ||
|scalafmt --stdin --assume-filename foo.sbt < foo.sbt # required when using --stdin to format .sbt files. | ||
|
@@ -135,12 +136,23 @@ object CliArgParser { | |
"""migrate .scalafmt CLI style configuration to hocon style configuration in .scalafmt.conf""" | ||
) | ||
opt[Unit]("diff") | ||
.action((_, c) => c.copy(diff = Some("master"))) | ||
.text("If set, only format edited files in git diff against master.") | ||
.action((_, c) => c.copy(mode = Option(DiffFiles("master")))) | ||
.text( | ||
s"""Format files listed in `git diff` against master. | ||
|Deprecated: use --mode diff instead""".stripMargin | ||
) | ||
opt[FileFetchMode]("mode") | ||
.action((m, c) => c.copy(mode = Option(m))) | ||
.text( | ||
s"""Sets the files to be formatted fetching mode. | ||
|Options: | ||
| diff - format files listed in `git diff` against master | ||
| changed - format files listed in `git status` (latest changes against previous commit)""".stripMargin | ||
) | ||
opt[String]("diff-branch") | ||
.action((branch, c) => c.copy(diff = Some(branch))) | ||
.text( | ||
"If set, only format edited files in git diff against provided branch." | ||
"If set, only format edited files in git diff against provided branch. Has no effect if mode set to `changed`." | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
) | ||
opt[Unit]("build-info") | ||
.action({ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,12 @@ | ||
package org.scalafmt.util | ||
|
||
import scala.sys.process.ProcessLogger | ||
import scala.util.Try | ||
import scala.util.{Failure, Success, Try} | ||
import scala.util.control.NonFatal | ||
|
||
import java.io.File | ||
|
||
trait GitOps { | ||
def status: Seq[AbsoluteFile] | ||
def diff(branch: String): Seq[AbsoluteFile] | ||
def lsTree(dir: AbsoluteFile): Seq[AbsoluteFile] | ||
def rootDir: Option[AbsoluteFile] | ||
|
@@ -50,7 +50,7 @@ class GitOpsImpl(private[util] val workingDirectory: AbsoluteFile) | |
"--full-name", | ||
dir.path | ||
) | ||
).toOption.toSeq.flatten.map(f => rtDir / f) | ||
).getOrElse(Seq.empty).map(f => rtDir / f) | ||
} | ||
|
||
override def rootDir: Option[AbsoluteFile] = { | ||
|
@@ -76,7 +76,48 @@ class GitOpsImpl(private[util] val workingDirectory: AbsoluteFile) | |
) | ||
for { | ||
root <- rootDir.toSeq | ||
path <- exec(cmd).toOption.toSeq.flatten | ||
path <- exec(cmd).getOrElse(Seq.empty) | ||
} yield AbsoluteFile.fromFile(new File(path), root) | ||
} | ||
|
||
override def status: Seq[AbsoluteFile] = { | ||
val cmd = Seq( | ||
"git", | ||
"status", | ||
"--porcelain" | ||
) | ||
for { | ||
root <- rootDir.toSeq | ||
statusLine <- exec(cmd).getOrElse(Seq.empty) | ||
file <- getFileFromGitStatusLine(statusLine).toOption.toSeq | ||
} yield AbsoluteFile.fromFile(file, root) | ||
}.filter(_.exists) | ||
|
||
private final val renameStatusCode = "R" | ||
private final val renameStatusArrowDelimiter = "-> " | ||
|
||
/* | ||
Method extracts path to changed file from the singular line of the `git status --porcelain` output. | ||
(see https://git-scm.com/docs/git-status#_short_format) | ||
*/ | ||
private def extractPathPart(s: String): Try[String] = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you add some comments that explain the behavior (and include a reference to https://git-scm.com/docs/git-status#_short_format)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure 👍 |
||
Try( | ||
Option(s) | ||
// Checks if the line status states the file was renamed (E.g: `R ORIG_PATH -> PATH`) | ||
.filter(_.substring(0, 2).contains(renameStatusCode)) | ||
// takes the part of the string after the `-> ` character sequence | ||
.map(_.split(renameStatusArrowDelimiter).last) | ||
// fallback for the regular status line (E.g.: `XY PATH`) | ||
// Drops the status codes by splitting on white spaces then taking the tail of the result | ||
// Restores spaces in the path by merging the tail back with white space separator | ||
.getOrElse(s.trim.split(' ').tail.mkString(" ")) | ||
.trim | ||
) | ||
|
||
private def trimQuotes(s: String): String = | ||
s.replaceAll("^\"|\"$", "") | ||
|
||
private def getFileFromGitStatusLine(s: String): Try[File] = | ||
extractPathPart(s) | ||
.map(pathRaw => new File(trimQuotes(pathRaw))) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you keep
--diff
option available (as an alias of--mode diff
) to avoid breaking changes?In that case, the description of
--diff
would be sufficient with something likeAlias to "--mode diff"
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. Makes sense.