From 57441d9bd0529c6294078f43ddacfa845c60e63a Mon Sep 17 00:00:00 2001 From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com> Date: Thu, 13 Jan 2022 09:31:42 -0800 Subject: [PATCH] FileOps: support symlinked files or directories Otherwise, the formatter won't be able to use a symlinked configuration file. --- .../org/scalafmt/sysops/AbsoluteFile.scala | 1 + .../scala/org/scalafmt/sysops/FileOps.scala | 22 ++++++++++++++++--- .../scala/org/scalafmt/sysops/GitOps.scala | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/scalafmt-sysops/shared/src/main/scala/org/scalafmt/sysops/AbsoluteFile.scala b/scalafmt-sysops/shared/src/main/scala/org/scalafmt/sysops/AbsoluteFile.scala index 2e7bd930ab..8aab39d0fd 100644 --- a/scalafmt-sysops/shared/src/main/scala/org/scalafmt/sysops/AbsoluteFile.scala +++ b/scalafmt-sysops/shared/src/main/scala/org/scalafmt/sysops/AbsoluteFile.scala @@ -22,6 +22,7 @@ final class AbsoluteFile(val path: Path) extends AnyVal { @inline def isDirectory: Boolean = FileOps.isDirectory(path) @inline def isRegularFile: Boolean = FileOps.isRegularFile(path) + @inline def isRegularFileNoLinks: Boolean = FileOps.isRegularFileNoLinks(path) @inline def attributes: BasicFileAttributes = FileOps.getAttributes(path) @inline def listFiles: Seq[AbsoluteFile] = join(FileOps.listFiles(path)) diff --git a/scalafmt-sysops/shared/src/main/scala/org/scalafmt/sysops/FileOps.scala b/scalafmt-sysops/shared/src/main/scala/org/scalafmt/sysops/FileOps.scala index 6719a83f6e..1ed3ceb296 100644 --- a/scalafmt-sysops/shared/src/main/scala/org/scalafmt/sysops/FileOps.scala +++ b/scalafmt-sysops/shared/src/main/scala/org/scalafmt/sysops/FileOps.scala @@ -11,20 +11,36 @@ import org.scalafmt.CompatCollections.JavaConverters._ object FileOps { - @inline - def getLastModifiedMsec(file: Path): Long = - Files.getLastModifiedTime(file, LinkOption.NOFOLLOW_LINKS).toMillis + def getLastModifiedMsec(file: Path): Long = { + val attributes = getAttributesNoLinks(file) + val mtime = attributes.lastModifiedTime().toMillis + if (attributes.isSymbolicLink) + math.max(mtime, Files.getLastModifiedTime(file).toMillis) + else mtime + } @inline def isDirectory(file: Path): Boolean = + Files.isDirectory(file) + + @inline + def isDirectoryNoLinks(file: Path): Boolean = Files.isDirectory(file, LinkOption.NOFOLLOW_LINKS) @inline def isRegularFile(file: Path): Boolean = + Files.isRegularFile(file) + + @inline + def isRegularFileNoLinks(file: Path): Boolean = Files.isRegularFile(file, LinkOption.NOFOLLOW_LINKS) @inline def getAttributes(file: Path): BasicFileAttributes = + Files.readAttributes(file, classOf[BasicFileAttributes]) + + @inline + def getAttributesNoLinks(file: Path): BasicFileAttributes = Files.readAttributes( file, classOf[BasicFileAttributes], diff --git a/scalafmt-sysops/shared/src/main/scala/org/scalafmt/sysops/GitOps.scala b/scalafmt-sysops/shared/src/main/scala/org/scalafmt/sysops/GitOps.scala index 5d1e9e8072..03cfbaa686 100644 --- a/scalafmt-sysops/shared/src/main/scala/org/scalafmt/sysops/GitOps.scala +++ b/scalafmt-sysops/shared/src/main/scala/org/scalafmt/sysops/GitOps.scala @@ -59,7 +59,7 @@ private class GitOpsImpl(val workingDirectory: AbsoluteFile) extends GitOps { override def lsTree(dir: AbsoluteFile*): Seq[AbsoluteFile] = { val cmd = Seq("git", "ls-files", "--full-name") ++ dir.map(_.toString()) - withRoot(exec(cmd)).filter(_.isRegularFile) + withRoot(exec(cmd)).filter(_.isRegularFileNoLinks) } override def rootDir: Option[AbsoluteFile] = tryRoot.toOption