diff --git a/CHANGELOG.md b/CHANGELOG.md index b4f9424d..29787d78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Changes in 0.36.0 - Add `--canonical` + - Avoid unnecessary writes on `--force` (see #555) - When an existing `.cabal` does not align fields then do not align fields in the generated `.cabal` file. - Fix a bug related to git conflict markers in existing `.cabal` files: When a diff --git a/src/Hpack.hs b/src/Hpack.hs index f6b4398b..e9676943 100644 --- a/src/Hpack.hs +++ b/src/Hpack.hs @@ -267,7 +267,7 @@ writeCabalFile :: DecodeOptions -> Bool -> FilePath -> NewCabalFile -> IO () writeCabalFile options toStdout name cabalFile = do write . unlines $ renderCabalFile (decodeOptionsTarget options) cabalFile where - write = if toStdout then Utf8.putStr else Utf8.writeFile name + write = if toStdout then Utf8.putStr else Utf8.ensureFile name makeCabalFile :: OutputStrategy -> GenerateHashStrategy -> Maybe ExistingCabalFile -> [String] -> Version -> Package -> NewCabalFile makeCabalFile outputStrategy generateHashStrategy mExistingCabalFile cabalVersion v pkg = cabalFile diff --git a/src/Hpack/Utf8.hs b/src/Hpack/Utf8.hs index 0ac650ff..cb397541 100644 --- a/src/Hpack/Utf8.hs +++ b/src/Hpack/Utf8.hs @@ -1,7 +1,9 @@ +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE ScopedTypeVariables #-} module Hpack.Utf8 ( encodeUtf8 , readFile -, writeFile +, ensureFile , putStr , hPutStr , hPutStrLn @@ -9,6 +11,8 @@ module Hpack.Utf8 ( import Prelude hiding (readFile, writeFile, putStr) +import Control.Monad +import Control.Exception (try, IOException) import qualified Data.Text as T import qualified Data.Text.Encoding as Encoding import Data.Text.Encoding.Error (lenientDecode) @@ -48,8 +52,13 @@ decodeNewlines = go readFile :: FilePath -> IO String readFile = fmap decodeText . B.readFile -writeFile :: FilePath -> String -> IO () -writeFile name xs = withFile name WriteMode (`hPutStr` xs) +ensureFile :: FilePath -> String -> IO () +ensureFile name new = do + try (readFile name) >>= \ case + Left (_ :: IOException) -> do + withFile name WriteMode (`hPutStr` new) + Right old -> unless (old == new) $ do + withFile name WriteMode (`hPutStr` new) putStr :: String -> IO () putStr = hPutStr stdout diff --git a/test/Hpack/Utf8Spec.hs b/test/Hpack/Utf8Spec.hs index 187e8ab7..662dd939 100644 --- a/test/Hpack/Utf8Spec.hs +++ b/test/Hpack/Utf8Spec.hs @@ -18,7 +18,7 @@ spec = do B.writeFile name "foo\r\nbar" Utf8.readFile name `shouldReturn` "foo\nbar" - describe "writeFile" $ do + describe "ensureFile" $ do it "uses system specific newline encoding" $ do inTempDirectory $ do let @@ -28,5 +28,5 @@ spec = do writeFile name c systemSpecific <- B.readFile name - Utf8.writeFile name c + Utf8.ensureFile name c B.readFile name `shouldReturn` systemSpecific