hpack 0.35.3 → 0.35.4
raw patch · 15 files changed
+208/−75 lines, 15 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Hpack: CanonicalOutput :: OutputStrategy
+ Hpack: MinimizeDiffs :: OutputStrategy
+ Hpack: [optionsOutputStrategy] :: Options -> OutputStrategy
+ Hpack: data OutputStrategy
- Hpack: Options :: DecodeOptions -> Force -> GenerateHashStrategy -> Bool -> Options
+ Hpack: Options :: DecodeOptions -> Force -> GenerateHashStrategy -> Bool -> OutputStrategy -> Options
Files
- CHANGELOG.md +15/−0
- hpack.cabal +3/−2
- resources/test/hpack.cabal +3/−2
- src/Hpack.hs +37/−24
- src/Hpack/CabalFile.hs +40/−14
- src/Hpack/Options.hs +11/−3
- src/Hpack/Render.hs +2/−2
- src/Hpack/Render/Hints.hs +21/−5
- src/Hpack/Utf8.hs +12/−3
- test/Helper.hs +5/−0
- test/Hpack/CabalFileSpec.hs +2/−2
- test/Hpack/OptionsSpec.hs +10/−10
- test/Hpack/Render/HintsSpec.hs +20/−4
- test/Hpack/Utf8Spec.hs +2/−2
- test/HpackSpec.hs +25/−2
CHANGELOG.md view
@@ -1,3 +1,18 @@+## Changes in 0.35.4+ - Add `--canonical`, which can be used to produce canonical output instead of+ trying to produce minimal diffs+ - 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+ `.cabal` file was essentially unchanged, but contained git conflict markers+ then `hpack` did not write a new `.cabal` file at all. To address this+ `hpack` now unconditionally writes a new `.cabal` file when the existing+ `.cabal` file contains any git conflict markers.++## Changes in 0.35.3+ - Depend on `crypton` instead of `cryptonite`+ ## Changes in 0.35.2 - Add support for `ghc-shared-options`
hpack.cabal view
@@ -1,16 +1,17 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.35.2.+-- This file has been generated from package.yaml by hpack version 0.35.3. -- -- see: https://github.com/sol/hpack name: hpack-version: 0.35.3+version: 0.35.4 synopsis: A modern format for Haskell packages description: See README at <https://github.com/sol/hpack#readme> category: Development homepage: https://github.com/sol/hpack#readme bug-reports: https://github.com/sol/hpack/issues+author: Simon Hengel <sol@typeful.net> maintainer: Simon Hengel <sol@typeful.net> license: MIT license-file: LICENSE
resources/test/hpack.cabal view
@@ -1,16 +1,17 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.35.2.+-- This file has been generated from package.yaml by hpack version 0.35.3. -- -- see: https://github.com/sol/hpack name: hpack-version: 0.35.3+version: 0.35.4 synopsis: A modern format for Haskell packages description: See README at <https://github.com/sol/hpack#readme> category: Development homepage: https://github.com/sol/hpack#readme bug-reports: https://github.com/sol/hpack/issues+author: Simon Hengel <sol@typeful.net> maintainer: Simon Hengel <sol@typeful.net> license: MIT license-file: LICENSE
src/Hpack.hs view
@@ -37,6 +37,7 @@ , Options(..) , Force(..) , GenerateHashStrategy(..)+, OutputStrategy(..) #ifdef TEST , hpackResultWithVersion@@ -84,6 +85,7 @@ , optionsForce :: Force , optionsGenerateHashStrategy :: GenerateHashStrategy , optionsToStdout :: Bool+, optionsOutputStrategy :: OutputStrategy } data GenerateHashStrategy = ForceHash | ForceNoHash | PreferHash | PreferNoHash@@ -102,12 +104,12 @@ Help -> do printHelp return Nothing- Run (ParseOptions verbose force hash toStdout file) -> do+ Run (ParseOptions verbose force hash toStdout file outputStrategy) -> do let generateHash = case hash of Just True -> ForceHash Just False -> ForceNoHash Nothing -> PreferNoHash- return $ Just (verbose, Options defaultDecodeOptions {decodeOptionsTarget = file} force generateHash toStdout)+ return $ Just (verbose, Options defaultDecodeOptions {decodeOptionsTarget = file} force generateHash toStdout outputStrategy) ParseError -> do printHelp exitFailure@@ -116,7 +118,7 @@ printHelp = do name <- getProgName Utf8.hPutStrLn stderr $ unlines [- "Usage: " ++ name ++ " [ --silent ] [ --force | -f ] [ --[no-]hash ] [ PATH ] [ - ]"+ "Usage: " ++ name ++ " [ --silent ] [ --canonical ] [ --force | -f ] [ --[no-]hash ] [ PATH ] [ - ]" , " " ++ name ++ " --version" , " " ++ name ++ " --numeric-version" , " " ++ name ++ " --help"@@ -126,7 +128,7 @@ hpack verbose options = hpackResult options >>= printResult verbose defaultOptions :: Options-defaultOptions = Options defaultDecodeOptions NoForce PreferNoHash False+defaultOptions = Options defaultDecodeOptions NoForce PreferNoHash False MinimizeDiffs setTarget :: FilePath -> Options -> Options setTarget target options@Options{..} =@@ -206,8 +208,8 @@ printWarnings :: [String] -> IO () printWarnings = mapM_ $ Utf8.hPutStrLn stderr . ("WARNING: " ++) -mkStatus :: CabalFile -> CabalFile -> Status-mkStatus new@(CabalFile _ mNewVersion mNewHash _) existing@(CabalFile _ mExistingVersion _ _)+mkStatus :: NewCabalFile -> ExistingCabalFile -> Status+mkStatus new@(CabalFile _ mNewVersion mNewHash _ _) existing@(CabalFile _ mExistingVersion _ _ _) | new `hasSameContent` existing = OutputUnchanged | otherwise = case mExistingVersion of Nothing -> ExistingCabalFileWasModifiedManually@@ -216,16 +218,19 @@ | isJust mNewHash && hashMismatch existing -> ExistingCabalFileWasModifiedManually | otherwise -> Generated -hasSameContent :: CabalFile -> CabalFile -> Bool-hasSameContent (CabalFile cabalVersionA _ _ a) (CabalFile cabalVersionB _ _ b) = cabalVersionA == cabalVersionB && a == b+hasSameContent :: NewCabalFile -> ExistingCabalFile -> Bool+hasSameContent (CabalFile cabalVersionA _ _ a ()) (CabalFile cabalVersionB _ _ b gitConflictMarkers) =+ cabalVersionA == cabalVersionB+ && a == b+ && gitConflictMarkers == DoesNotHaveGitConflictMarkers -hashMismatch :: CabalFile -> Bool+hashMismatch :: ExistingCabalFile -> Bool hashMismatch cabalFile = case cabalFileHash cabalFile of Nothing -> False- Just hash -> hash /= calculateHash cabalFile+ Just hash -> cabalFileGitConflictMarkers cabalFile == HasGitConflictMarkers || hash /= calculateHash cabalFile -calculateHash :: CabalFile -> Hash-calculateHash (CabalFile cabalVersion _ _ body) = sha256 (unlines $ cabalVersion ++ body)+calculateHash :: CabalFile a -> Hash+calculateHash (CabalFile cabalVersion _ _ body _) = sha256 (unlines $ cabalVersion ++ body) hpackResult :: Options -> IO Result hpackResult opts = hpackResultWithError opts >>= either (die . formatHpackError programName) return@@ -236,12 +241,12 @@ hpackResultWithError = hpackResultWithVersion version hpackResultWithVersion :: Version -> Options -> IO (Either HpackError Result)-hpackResultWithVersion v (Options options force generateHashStrategy toStdout) = do+hpackResultWithVersion v (Options options force generateHashStrategy toStdout outputStrategy) = do readPackageConfigWithError options >>= \ case Right (DecodeResult pkg (lines -> cabalVersion) cabalFileName warnings) -> do mExistingCabalFile <- readCabalFile cabalFileName let- newCabalFile = makeCabalFile generateHashStrategy mExistingCabalFile cabalVersion v pkg+ newCabalFile = makeCabalFile outputStrategy generateHashStrategy mExistingCabalFile cabalVersion v pkg status = case force of Force -> Generated@@ -258,24 +263,32 @@ } Left err -> return $ Left err -writeCabalFile :: DecodeOptions -> Bool -> FilePath -> CabalFile -> IO ()+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 :: GenerateHashStrategy -> Maybe CabalFile -> [String] -> Version -> Package -> CabalFile-makeCabalFile strategy mExistingCabalFile cabalVersion v pkg = cabalFile+makeCabalFile :: OutputStrategy -> GenerateHashStrategy -> Maybe ExistingCabalFile -> [String] -> Version -> Package -> NewCabalFile+makeCabalFile outputStrategy generateHashStrategy mExistingCabalFile cabalVersion v pkg = cabalFile where- cabalFile = CabalFile cabalVersion (Just v) hash body+ hints :: [String]+ hints = case outputStrategy of+ CanonicalOutput -> []+ MinimizeDiffs -> maybe [] cabalFileContents mExistingCabalFile + cabalFile :: NewCabalFile+ cabalFile = CabalFile cabalVersion (Just v) hash body ()++ hash :: Maybe Hash hash- | shouldGenerateHash mExistingCabalFile strategy = Just $ calculateHash cabalFile+ | shouldGenerateHash mExistingCabalFile generateHashStrategy = Just $ calculateHash cabalFile | otherwise = Nothing - body = lines $ renderPackage (maybe [] cabalFileContents mExistingCabalFile) pkg+ body :: [String]+ body = lines $ renderPackage hints pkg -shouldGenerateHash :: Maybe CabalFile -> GenerateHashStrategy -> Bool+shouldGenerateHash :: Maybe ExistingCabalFile -> GenerateHashStrategy -> Bool shouldGenerateHash mExistingCabalFile strategy = case (strategy, mExistingCabalFile) of (ForceHash, _) -> True (ForceNoHash, _) -> False@@ -284,5 +297,5 @@ (_, Just CabalFile {cabalFileHash = Nothing}) -> False (_, Just CabalFile {cabalFileHash = Just _}) -> True -renderCabalFile :: FilePath -> CabalFile -> [String]-renderCabalFile file (CabalFile cabalVersion hpackVersion hash body) = cabalVersion ++ header file hpackVersion hash ++ body+renderCabalFile :: FilePath -> NewCabalFile -> [String]+renderCabalFile file (CabalFile cabalVersion hpackVersion hash body _) = cabalVersion ++ header file hpackVersion hash ++ body
src/Hpack/CabalFile.hs view
@@ -1,7 +1,19 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ViewPatterns #-}-module Hpack.CabalFile where+module Hpack.CabalFile (+ CabalFile(..)+, GitConflictMarkers(..)+, ExistingCabalFile+, NewCabalFile+, readCabalFile+, parseVersion+#ifdef TEST+, extractVersion+, removeGitConflictMarkers+#endif+) where import Imports @@ -12,28 +24,42 @@ import Hpack.Util -makeVersion :: [Int] -> Version-makeVersion v = Version v []--data CabalFile = CabalFile {+data CabalFile a = CabalFile { cabalFileCabalVersion :: [String] , cabalFileHpackVersion :: Maybe Version , cabalFileHash :: Maybe Hash , cabalFileContents :: [String]+, cabalFileGitConflictMarkers :: a } deriving (Eq, Show) -readCabalFile :: FilePath -> IO (Maybe CabalFile)-readCabalFile cabalFile = fmap parse <$> tryReadFile cabalFile+data GitConflictMarkers = HasGitConflictMarkers | DoesNotHaveGitConflictMarkers+ deriving (Show, Eq)++type ExistingCabalFile = CabalFile GitConflictMarkers+type NewCabalFile = CabalFile ()++readCabalFile :: FilePath -> IO (Maybe ExistingCabalFile)+readCabalFile cabalFile = fmap parseCabalFile <$> tryReadFile cabalFile++parseCabalFile :: String -> ExistingCabalFile+parseCabalFile (lines -> input) = case span isComment <$> span (not . isComment) clean of+ (cabalVersion, (header, body)) -> CabalFile {+ cabalFileCabalVersion = cabalVersion+ , cabalFileHpackVersion = extractVersion header+ , cabalFileHash = extractHash header+ , cabalFileContents = dropWhile null body+ , cabalFileGitConflictMarkers = gitConflictMarkers+ } where- parse :: String -> CabalFile- parse (splitHeader -> (cabalVersion, h, c)) = CabalFile cabalVersion (extractVersion h) (extractHash h) c+ clean :: [String]+ clean = removeGitConflictMarkers input - splitHeader :: String -> ([String], [String], [String])- splitHeader (removeGitConflictMarkers . lines -> c) =- case span (not . isComment) c of- (cabalVersion, xs) -> case span isComment xs of- (header, body) -> (cabalVersion, header, dropWhile null body)+ gitConflictMarkers :: GitConflictMarkers+ gitConflictMarkers+ | input == clean = DoesNotHaveGitConflictMarkers+ | otherwise = HasGitConflictMarkers + isComment :: String -> Bool isComment = ("--" `isPrefixOf`) extractHash :: [String] -> Maybe Hash
src/Hpack/Options.hs view
@@ -16,12 +16,16 @@ data Force = Force | NoForce deriving (Eq, Show) +data OutputStrategy = CanonicalOutput | MinimizeDiffs+ deriving (Eq, Show)+ data ParseOptions = ParseOptions { parseOptionsVerbose :: Verbose , parseOptionsForce :: Force , parseOptionsHash :: Maybe Bool , parseOptionsToStdout :: Bool , parseOptionsTarget :: FilePath+, parseOptionsOutputStrategy :: OutputStrategy } deriving (Eq, Show) parseOptions :: FilePath -> [String] -> IO ParseResult@@ -34,8 +38,8 @@ file <- expandTarget defaultTarget target let options- | toStdout = ParseOptions NoVerbose Force hash toStdout file- | otherwise = ParseOptions verbose force hash toStdout file+ | toStdout = ParseOptions NoVerbose Force hash toStdout file outputStrategy+ | otherwise = ParseOptions verbose force hash toStdout file outputStrategy return (Run options) Left err -> return err where@@ -43,11 +47,15 @@ forceFlags = ["--force", "-f"] hashFlag = "--hash" noHashFlag = "--no-hash"+ canonicalFlag = "--canonical" - flags = hashFlag : noHashFlag : silentFlag : forceFlags+ flags = canonicalFlag : hashFlag : noHashFlag : silentFlag : forceFlags verbose :: Verbose verbose = if silentFlag `elem` args then NoVerbose else Verbose++ outputStrategy :: OutputStrategy+ outputStrategy = if canonicalFlag `elem` args then CanonicalOutput else MinimizeDiffs force :: Force force = if any (`elem` args) forceFlags then Force else NoForce
src/Hpack/Render.hs view
@@ -48,10 +48,10 @@ import qualified Hpack.Render.Dsl as Dsl renderPackage :: [String] -> Package -> String-renderPackage oldCabalFile = renderPackageWith settings alignment formattingHintsFieldOrder formattingHintsSectionsFieldOrder+renderPackage oldCabalFile = renderPackageWith settings headerFieldsAlignment formattingHintsFieldOrder formattingHintsSectionsFieldOrder where FormattingHints{..} = sniffFormattingHints oldCabalFile- alignment = fromMaybe 16 formattingHintsAlignment+ headerFieldsAlignment = fromMaybe 16 formattingHintsAlignment settings = formattingHintsRenderSettings renderPackageWith :: RenderSettings -> Alignment -> [String] -> [(String, [String])] -> Package -> String
src/Hpack/Render/Hints.hs view
@@ -68,16 +68,32 @@ where indentation = minimum $ map (length . takeWhile isSpace) input +data Indentation = Indentation {+ indentationFieldNameLength :: Int+, indentationPadding :: Int+}++indentationTotal :: Indentation -> Int+indentationTotal (Indentation fieldName padding) = fieldName + padding+ sniffAlignment :: [String] -> Maybe Alignment-sniffAlignment input = case nub . catMaybes . map indentation . catMaybes . map splitField $ input of- [n] -> Just (Alignment n)- _ -> Nothing+sniffAlignment input = case indentations of+ [] -> Nothing+ _ | all (indentationPadding >>> (== 1)) indentations -> Just 0+ _ -> case nub (map indentationTotal indentations) of+ [n] -> Just (Alignment n)+ _ -> Nothing where+ indentations :: [Indentation]+ indentations = catMaybes . map (splitField >=> indentation) $ input - indentation :: (String, String) -> Maybe Int+ indentation :: (String, String) -> Maybe Indentation indentation (name, value) = case span isSpace value of (_, "") -> Nothing- (xs, _) -> (Just . succ . length $ name ++ xs)+ (padding, _) -> Just Indentation {+ indentationFieldNameLength = succ $ length name+ , indentationPadding = length padding+ } splitField :: String -> Maybe (String, String) splitField field = case span isNameChar field of
src/Hpack/Utf8.hs view
@@ -1,7 +1,9 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE ScopedTypeVariables #-} module Hpack.Utf8 ( encodeUtf8 , readFile-, writeFile+, ensureFile , putStr , hPutStr , hPutStrLn@@ -9,6 +11,8 @@ 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 @@ 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
test/Helper.hs view
@@ -11,6 +11,7 @@ , module System.FilePath , withCurrentDirectory , yaml+, makeVersion ) where import Imports@@ -19,6 +20,7 @@ import Test.Mockery.Directory import Control.Monad import Control.Applicative+import Data.Version (Version(..)) import System.Directory (getCurrentDirectory, setCurrentDirectory, canonicalizePath) import Control.Exception import qualified System.IO.Temp as Temp@@ -44,3 +46,6 @@ yaml :: Language.Haskell.TH.Quote.QuasiQuoter yaml = yamlQQ++makeVersion :: [Int] -> Version+makeVersion v = Version v []
test/Hpack/CabalFileSpec.hs view
@@ -28,12 +28,12 @@ it "includes hash" $ do inTempDirectory $ do writeFile file $ mkHeader "package.yaml" version hash- readCabalFile file `shouldReturn` Just (CabalFile [] (Just version) (Just hash) [])+ readCabalFile file `shouldReturn` Just (CabalFile [] (Just version) (Just hash) [] DoesNotHaveGitConflictMarkers) it "accepts cabal-version at the beginning of the file" $ do inTempDirectory $ do writeFile file $ ("cabal-version: 2.2\n" ++ mkHeader "package.yaml" version hash)- readCabalFile file `shouldReturn` Just (CabalFile ["cabal-version: 2.2"] (Just version) (Just hash) [])+ readCabalFile file `shouldReturn` Just (CabalFile ["cabal-version: 2.2"] (Just version) (Just hash) [] DoesNotHaveGitConflictMarkers) describe "extractVersion" $ do it "extracts Hpack version from a cabal file" $ do
test/Hpack/OptionsSpec.hs view
@@ -18,10 +18,10 @@ context "by default" $ do it "returns Run" $ do- parseOptions defaultTarget [] `shouldReturn` Run (ParseOptions Verbose NoForce Nothing False defaultTarget)+ parseOptions defaultTarget [] `shouldReturn` Run (ParseOptions Verbose NoForce Nothing False defaultTarget MinimizeDiffs) it "includes target" $ do- parseOptions defaultTarget ["foo.yaml"] `shouldReturn` Run (ParseOptions Verbose NoForce Nothing False "foo.yaml")+ parseOptions defaultTarget ["foo.yaml"] `shouldReturn` Run (ParseOptions Verbose NoForce Nothing False "foo.yaml" MinimizeDiffs) context "with superfluous arguments" $ do it "returns ParseError" $ do@@ -29,31 +29,31 @@ context "with --silent" $ do it "sets optionsVerbose to NoVerbose" $ do- parseOptions defaultTarget ["--silent"] `shouldReturn` Run (ParseOptions NoVerbose NoForce Nothing False defaultTarget)+ parseOptions defaultTarget ["--silent"] `shouldReturn` Run (ParseOptions NoVerbose NoForce Nothing False defaultTarget MinimizeDiffs) context "with --force" $ do it "sets optionsForce to Force" $ do- parseOptions defaultTarget ["--force"] `shouldReturn` Run (ParseOptions Verbose Force Nothing False defaultTarget)+ parseOptions defaultTarget ["--force"] `shouldReturn` Run (ParseOptions Verbose Force Nothing False defaultTarget MinimizeDiffs) context "with -f" $ do it "sets optionsForce to Force" $ do- parseOptions defaultTarget ["-f"] `shouldReturn` Run (ParseOptions Verbose Force Nothing False defaultTarget)+ parseOptions defaultTarget ["-f"] `shouldReturn` Run (ParseOptions Verbose Force Nothing False defaultTarget MinimizeDiffs) context "when determining parseOptionsHash" $ do it "assumes True on --hash" $ do- parseOptions defaultTarget ["--hash"] `shouldReturn` Run (ParseOptions Verbose NoForce (Just True) False defaultTarget)+ parseOptions defaultTarget ["--hash"] `shouldReturn` Run (ParseOptions Verbose NoForce (Just True) False defaultTarget MinimizeDiffs) it "assumes False on --no-hash" $ do- parseOptions defaultTarget ["--no-hash"] `shouldReturn` Run (ParseOptions Verbose NoForce (Just False) False defaultTarget)+ parseOptions defaultTarget ["--no-hash"] `shouldReturn` Run (ParseOptions Verbose NoForce (Just False) False defaultTarget MinimizeDiffs) it "gives last occurrence precedence" $ do- parseOptions defaultTarget ["--no-hash", "--hash"] `shouldReturn` Run (ParseOptions Verbose NoForce (Just True) False defaultTarget)- parseOptions defaultTarget ["--hash", "--no-hash"] `shouldReturn` Run (ParseOptions Verbose NoForce (Just False) False defaultTarget)+ parseOptions defaultTarget ["--no-hash", "--hash"] `shouldReturn` Run (ParseOptions Verbose NoForce (Just True) False defaultTarget MinimizeDiffs)+ parseOptions defaultTarget ["--hash", "--no-hash"] `shouldReturn` Run (ParseOptions Verbose NoForce (Just False) False defaultTarget MinimizeDiffs) context "with -" $ do it "sets optionsToStdout to True, implies Force and NoVerbose" $ do- parseOptions defaultTarget ["-"] `shouldReturn` Run (ParseOptions NoVerbose Force Nothing True defaultTarget)+ parseOptions defaultTarget ["-"] `shouldReturn` Run (ParseOptions NoVerbose Force Nothing True defaultTarget MinimizeDiffs) it "rejects - for target" $ do parseOptions defaultTarget ["-", "-"] `shouldReturn` ParseError
test/Hpack/Render/HintsSpec.hs view
@@ -21,7 +21,7 @@ describe "extractFieldOrder" $ do it "extracts field order hints" $ do let input = [- "name: cabalize"+ "name: hpack" , "version: 0.0.0" , "license:" , "license-file: "@@ -38,7 +38,7 @@ describe "extractSectionsFieldOrder" $ do it "splits input into sections" $ do let input = [- "name: cabalize"+ "name: hpack" , "version: 0.0.0" , "" , "library"@@ -88,7 +88,7 @@ describe "sniffAlignment" $ do it "sniffs field alignment from given cabal file" $ do let input = [- "name: cabalize"+ "name: hpack" , "version: 0.0.0" , "license: MIT" , "license-file: LICENSE"@@ -98,13 +98,29 @@ it "ignores fields without a value on the same line" $ do let input = [- "name: cabalize"+ "name: hpack" , "version: 0.0.0" , "description: " , " foo" , " bar" ] sniffAlignment input `shouldBe` Just 16++ context "when all fields are padded with exactly one space" $ do+ it "returns 0" $ do+ let input = [+ "name: hpack"+ , "version: 0.0.0"+ , "license: MIT"+ , "license-file: LICENSE"+ , "build-type: Simple"+ ]+ sniffAlignment input `shouldBe` Just 0++ context "with an empty input list" $ do+ it "returns Nothing" $ do+ let input = []+ sniffAlignment input `shouldBe` Nothing describe "splitField" $ do it "splits fields" $ do
test/Hpack/Utf8Spec.hs view
@@ -18,7 +18,7 @@ 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 @@ writeFile name c systemSpecific <- B.readFile name - Utf8.writeFile name c+ Utf8.ensureFile name c B.readFile name `shouldReturn` systemSpecific
test/HpackSpec.hs view
@@ -12,7 +12,7 @@ import Hpack.Config import Hpack.CabalFile import Hpack.Error (formatHpackError)-import Hpack hiding (hpack)+import Hpack readFile :: FilePath -> IO String readFile name = Prelude.readFile name >>= (return $!!)@@ -52,7 +52,7 @@ it "is inverse to readCabalFile" $ do expected <- lines <$> readFile "resources/test/hpack.cabal" Just c <- readCabalFile "resources/test/hpack.cabal"- renderCabalFile "package.yaml" c `shouldBe` expected+ renderCabalFile "package.yaml" c {cabalFileGitConflictMarkers = ()} `shouldBe` expected describe "hpackResult" $ around_ inTempDirectory $ before_ (writeFile packageConfig "name: foo") $ do let@@ -155,3 +155,26 @@ old <- readFile file hpackWithVersion [0,20,0] `shouldReturn` outputUnchanged readFile file `shouldReturn` old++ context "with git conflict markers" $ do+ context "when the new and the existing .cabal file are essentially the same" $ do+ it "still removes the conflict markers" $ do+ writeFile file $ unlines [+ "--"+ , "name: foo"+ ]+ hpack NoVerbose defaultOptions {optionsForce = Force}+ old <- readFile file+ let+ modified :: String+ modified = unlines $ case break (== "version: 0.0.0") $ lines old of+ (xs, v : ys) -> xs +++ "<<<<<<< ours" :+ v :+ "=======" :+ "version: 0.1.0" :+ ">>>>>>> theirs" : ys+ _ -> undefined+ writeFile file modified+ hpack NoVerbose defaultOptions+ readFile file `shouldReturn` old