Skip to content
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

Don't touch files if they don't need changing #133

Merged
merged 1 commit into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

* Fix escaping of interpolations after dollar signs.
* Fix nixfmt trying to allocate temp files that aren't used.
* Don't write if files didn't change, fixing treefmt compatibility
* Nixfmt now accepts the '-' argument to read from stdin.
* `nixfmt [dir]` now recursively formats nix files in that directory.
* Float and int literal parsing now matches nix.
Expand Down
15 changes: 9 additions & 6 deletions main/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ options =
data Target = Target
{ tDoRead :: IO Text
, tPath :: FilePath
, tDoWrite :: Text -> IO ()
-- The bool is true when the formatted file differs from the input
, tDoWrite :: Bool -> Text -> IO ()
}

-- | Recursively collect nix files in a directory
Expand All @@ -84,8 +85,8 @@ collectAllNixFiles paths = concat <$> mapM collectNixFiles paths
formatTarget :: Formatter -> Target -> IO Result
formatTarget format Target{tDoRead, tPath, tDoWrite} = do
contents <- tDoRead
let formatted = format tPath contents
mapM tDoWrite formatted
let formatResult = format tPath contents
mapM (\formatted -> tDoWrite (formatted /= contents) formatted) formatResult
piegamesde marked this conversation as resolved.
Show resolved Hide resolved

-- | Return an error if target could not be parsed or was not formatted
-- correctly.
Expand All @@ -99,17 +100,19 @@ checkTarget format Target{tDoRead, tPath} = do
| otherwise -> Left $ tPath ++ ": not formatted"

stdioTarget :: Target
stdioTarget = Target TextIO.getContents "<stdin>" TextIO.putStr
stdioTarget = Target TextIO.getContents "<stdin>" (const $ TextIO.putStr)

fileTarget :: FilePath -> Target
fileTarget path = Target (readFileUtf8 path) path atomicWriteFile
where
atomicWriteFile t = withOutputFile path $ \h -> do
atomicWriteFile True t = withOutputFile path $ \h -> do
hSetEncoding h utf8
TextIO.hPutStr h t
-- Don't do anything if the file is already formatted
atomicWriteFile False _ = mempty

checkFileTarget :: FilePath -> Target
checkFileTarget path = Target (readFileUtf8 path) path (const $ pure ())
checkFileTarget path = Target (readFileUtf8 path) path (const $ const $ pure ())

toTargets :: Nixfmt -> IO [Target]
toTargets Nixfmt{ files = [] } = pure [stdioTarget]
Expand Down