From ca9c8975ed671112fdfce94f2e9e2ad3de480c9a Mon Sep 17 00:00:00 2001 From: piegames Date: Mon, 25 Sep 2023 17:32:43 +0200 Subject: [PATCH] Don't touch files if they don't need changing Fixes #88 --- CHANGELOG.md | 1 + main/Main.hs | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b1f3b6a..a04cd703 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. diff --git a/main/Main.hs b/main/Main.hs index 5b1a3cef..018ff5d1 100644 --- a/main/Main.hs +++ b/main/Main.hs @@ -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 @@ -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 -- | Return an error if target could not be parsed or was not formatted -- correctly. @@ -99,17 +100,19 @@ checkTarget format Target{tDoRead, tPath} = do | otherwise -> Left $ tPath ++ ": not formatted" stdioTarget :: Target -stdioTarget = Target TextIO.getContents "" TextIO.putStr +stdioTarget = Target TextIO.getContents "" (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]