packages feed

hpack 0.5.1 → 0.5.2

raw patch · 7 files changed

+407/−112 lines, 7 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Hpack.Run: renderPackage :: Int -> [String] -> Package -> String
+ Hpack.Run: renderPackage :: RenderSettings -> Int -> [String] -> Package -> String
- Hpack.Run: renderSourceRepository :: SourceRepository -> String
+ Hpack.Run: renderSourceRepository :: SourceRepository -> Stanza

Files

driver/Main.hs view
@@ -35,7 +35,11 @@       (warnings, name, new) <- run       forM_ warnings $ \warning -> hPutStrLn stderr ("WARNING: " ++ warning)       old <- force . either (const Nothing) (Just . stripHeader) <$> tryJust (guard . isDoesNotExistError) (readFile name)-      unless (old == Just (lines new)) (writeFile name $ header ++ new)+      if (old == Just (lines new)) then do+        putStrLn (name ++ " is up-to-date")+      else do+        (writeFile name $ header ++ new)+        putStrLn ("generated " ++ name)       where         stripHeader :: String -> [String]         stripHeader = dropWhile null . dropWhile ("--" `isPrefixOf`) . lines
hpack.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack  name:           hpack-version:        0.5.1+version:        0.5.2 synopsis:       An alternative format for Haskell packages homepage:       https://github.com/sol/hpack#readme bug-reports:    https://github.com/sol/hpack/issues@@ -18,7 +18,9 @@   location: https://github.com/sol/hpack  library-  hs-source-dirs: src+  hs-source-dirs:+      src+  ghc-options: -Wall   build-depends:       aeson >= 0.8     , base >= 4.7 && < 5@@ -30,17 +32,19 @@     , text     , unordered-containers     , yaml-  ghc-options: -Wall   exposed-modules:       Hpack.Config       Hpack.Run   other-modules:+      Hpack.Render       Hpack.Util   default-language: Haskell2010  executable hpack   main-is: Main.hs-  hs-source-dirs: driver+  hs-source-dirs:+      driver+  ghc-options: -Wall   build-depends:       aeson >= 0.8     , base >= 4.7 && < 5@@ -53,13 +57,15 @@     , unordered-containers     , yaml     , hpack-  ghc-options: -Wall   default-language: Haskell2010  test-suite spec   type: exitcode-stdio-1.0   main-is: Spec.hs-  hs-source-dirs: test, src+  hs-source-dirs:+      test+    , src+  ghc-options: -Wall   build-depends:       aeson >= 0.8     , base >= 4.7 && < 5@@ -75,13 +81,14 @@     , mockery >= 0.3     , interpolate     , aeson-qq-  ghc-options: -Wall   other-modules:       Helper       Hpack.ConfigSpec+      Hpack.RenderSpec       Hpack.RunSpec       Hpack.UtilSpec       Hpack.Config+      Hpack.Render       Hpack.Run       Hpack.Util   default-language: Haskell2010
src/Hpack/Config.hs view
@@ -258,7 +258,7 @@ } deriving (Eq, Show, Functor, Foldable, Traversable, Data, Typeable)  instance HasFieldNames a => HasFieldNames (Section a) where-  fieldNames section = (fieldNames (sectionData section) ++ fieldNames proxy) \\ ["config"] -- FIXME : test for removing "config"+  fieldNames section = (fieldNames (sectionData section) ++ fieldNames proxy)     where       proxy :: CommonOptions       proxy = CommonOptions Nothing Nothing Nothing Nothing Nothing@@ -420,8 +420,7 @@     defaultExtensions = sectionDefaultExtensions globalOptions ++ sectionDefaultExtensions options     ghcOptions = sectionGhcOptions globalOptions ++ sectionGhcOptions options     cppOptions = sectionCppOptions globalOptions ++ sectionCppOptions options-    getDependencies = sectionDependencies-    dependencies = getDependencies globalOptions ++ getDependencies options+    dependencies = sectionDependencies globalOptions ++ sectionDependencies options  toSection :: a -> CommonOptions -> Section a toSection a CommonOptions{..}
+ src/Hpack/Render.hs view
@@ -0,0 +1,118 @@+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ViewPatterns #-}+module Hpack.Render where++import           Prelude ()+import           Prelude.Compat++import           Control.Applicative+import           Data.Char+import           Data.List.Compat+import           Data.Maybe+import           Data.String++data Value =+    Literal String+  | CommaSeparatedList [String]+  | LineSeparatedList [String]+  | WordList [String]+  deriving (Eq, Show)++data Field = Field String Value+  deriving (Eq, Show)++data Stanza = Stanza String [Field] | Fields [Field]+  deriving (Eq, Show)++data Lines = SingleLine String | MultipleLines [String]+  deriving (Eq, Show)++data CommaStyle = LeadingCommas | TrailingCommas+  deriving (Eq, Show)++data RenderSettings = RenderSettings {+  renderSettingsIndentation :: Int+, renderSettingsCommaStyle :: CommaStyle+} deriving (Eq, Show)++defaultRenderSettings :: RenderSettings+defaultRenderSettings = RenderSettings 2 LeadingCommas++class Render a where+  render :: RenderSettings -> Int -> a -> [String]++instance Render Stanza where+  render settings nesting (Fields fields) = concatMap (render settings nesting) fields+  render settings nesting (Stanza name fields) = name : renderFields fields+    where+      renderFields :: [Field] -> [String]+      renderFields = concatMap (render settings $ succ nesting)++instance Render Field where+  render settings nesting (Field name v) = case renderValue settings v of+    SingleLine "" -> []+    SingleLine x -> [indent settings nesting (name ++ ": " ++ x)]+    MultipleLines [] -> []+    MultipleLines xs -> (indent settings nesting name ++ ":") : map (indent settings $ succ nesting) xs++renderValue :: RenderSettings -> Value -> Lines+renderValue RenderSettings{..} v = case v of+  Literal s -> SingleLine s+  WordList ws -> SingleLine $ unwords ws+  LineSeparatedList xs -> renderLineSeparatedList renderSettingsCommaStyle xs+  CommaSeparatedList xs -> renderCommaSeparatedList renderSettingsCommaStyle xs++renderLineSeparatedList :: CommaStyle -> [String] -> Lines+renderLineSeparatedList style = MultipleLines . map (padding ++)+  where+    padding = case style of+      LeadingCommas -> "  "+      TrailingCommas -> ""++renderCommaSeparatedList :: CommaStyle -> [String] -> Lines+renderCommaSeparatedList style = MultipleLines . case style of+  LeadingCommas -> map renderLeadingComma . zip (True : repeat False)+  TrailingCommas -> map renderTrailingComma . reverse . zip (True : repeat False) . reverse+  where+    renderLeadingComma :: (Bool, String) -> String+    renderLeadingComma (isFirst, x)+      | isFirst   = "  " ++ x+      | otherwise = ", " ++ x++    renderTrailingComma :: (Bool, String) -> String+    renderTrailingComma (isLast, x)+      | isLast    = x+      | otherwise = x ++ ","++instance IsString Value where+  fromString = Literal++indent :: RenderSettings -> Int -> String -> String+indent RenderSettings{..} nesting s = replicate (nesting * renderSettingsIndentation) ' ' ++ s++sniffIndentation :: String -> Maybe Int+sniffIndentation input = sniffFrom "library" <|> sniffFrom "executable"+  where+    sniffFrom :: String -> Maybe Int+    sniffFrom section = case findSection . removeEmptyLines $ lines input of+      _ : x : _ -> Just . length $ takeWhile isSpace x+      _ -> Nothing+      where+        findSection = dropWhile (not . isPrefixOf section)++    removeEmptyLines :: [String] -> [String]+    removeEmptyLines = filter $ any (not . isSpace)++sniffCommaStyle :: String -> Maybe CommaStyle+sniffCommaStyle (lines -> input)+  | any startsWithComma input = Just LeadingCommas+  | any (startsWithComma . reverse) input = Just TrailingCommas+  | otherwise = Nothing+  where+    startsWithComma = isPrefixOf "," . dropWhile isSpace++sniffRenderSettings :: String -> RenderSettings+sniffRenderSettings input = RenderSettings indentation trailingCommas+  where+    indentation = fromMaybe (renderSettingsIndentation defaultRenderSettings) (sniffIndentation input)+    trailingCommas = fromMaybe (renderSettingsCommaStyle defaultRenderSettings) (sniffCommaStyle input)
src/Hpack/Run.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ViewPatterns #-}@@ -20,6 +21,7 @@  import           Hpack.Util import           Hpack.Config+import           Hpack.Render  run :: IO ([String], FilePath, String) run = do@@ -31,31 +33,32 @@       old <- tryReadFile cabalFile        let alignment = fromMaybe 16 (old >>= sniffAlignment)-          output = renderPackage alignment (maybe [] extractFieldOrderHint old) package+          settings = maybe defaultRenderSettings sniffRenderSettings old+          output = renderPackage settings alignment (maybe [] extractFieldOrderHint old) package       return (warnings, cabalFile, output)     Left err -> die err -renderPackage :: Int -> [String] -> Package -> String-renderPackage alignment existingFieldOrder Package{..} = intercalate "\n" sections+renderPackage :: RenderSettings -> Int -> [String] -> Package -> String+renderPackage settings alignment existingFieldOrder Package{..} = intercalate "\n" (header : chunks)   where-    sections :: [String]-    sections = catMaybes [-        header-      , extraSourceFiles-      , dataFiles-      , sourceRepository-      , library-      ] ++ renderExecutables packageExecutables ++ renderTests packageTests+    chunks :: [String]+    chunks = map unlines . filter (not . null) . map (render settings 0) $ stanzas -    header = Just (unlines $ map formatField sortedFields)+    header = unlines $ map formatField sortedFields -    extraSourceFiles = guard (not . null $ packageExtraSourceFiles) >> Just (unlines $ "extra-source-files:" : map ("  " ++) packageExtraSourceFiles)-    dataFiles = guard (not . null $ packageDataFiles) >> Just (unlines $ "data-files:" : map ("  " ++) packageDataFiles)+    extraSourceFiles :: Field+    extraSourceFiles = Field "extra-source-files" (LineSeparatedList packageExtraSourceFiles) -    sourceRepository = renderSourceRepository <$> packageSourceRepository+    dataFiles :: Field+    dataFiles = Field "data-files" (LineSeparatedList packageDataFiles) -    library = renderLibrary <$> packageLibrary+    sourceRepository = maybe [] (return . renderSourceRepository) packageSourceRepository +    library = maybe [] (return . renderLibrary) packageLibrary++    stanzas :: [Stanza]+    stanzas = Fields [extraSourceFiles] : Fields [dataFiles] : sourceRepository ++ library ++ renderExecutables packageExecutables ++ renderTests packageTests+     padding name = replicate (alignment - length name - 2) ' '      formatField :: (String, String) -> String@@ -112,7 +115,7 @@   x : xs -> intercalate "\n" (x : map (indentation ++) xs)   [] -> ""   where-    n = max alignment (length "description: ")+    n = max alignment (length ("description: " :: String))     indentation = replicate n ' '      emptyLineToDot xs@@ -121,90 +124,72 @@      isEmptyLine = all isSpace -renderSourceRepository :: SourceRepository -> String-renderSourceRepository SourceRepository{..} = concat [-    "source-repository head\n"-  , "  type: git\n"-  , "  location: " ++ sourceRepositoryUrl ++ "\n"-  , maybe "" (("  subdir: " ++) . (++ "\n")) sourceRepositorySubdir+renderSourceRepository :: SourceRepository -> Stanza+renderSourceRepository SourceRepository{..} = Stanza "source-repository head" [+    Field "type" "git"+  , Field "location" (Literal sourceRepositoryUrl)+  , Field "subdir" (maybe "" Literal sourceRepositorySubdir)   ] -renderExecutables :: [Section Executable] -> [String]+renderExecutables :: [Section Executable] -> [Stanza] renderExecutables = map renderExecutable -renderExecutable :: Section Executable -> String+renderExecutable :: Section Executable -> Stanza renderExecutable section@(sectionData -> Executable{..}) =-     "executable "-  ++ executableName ++ "\n"-  ++ renderExecutableSection section+  Stanza ("executable " ++ executableName) (renderExecutableSection section) -renderTests :: [Section Executable] -> [String]+renderTests :: [Section Executable] -> [Stanza] renderTests = map renderTest -renderTest :: Section Executable -> String+renderTest :: Section Executable -> Stanza renderTest section@(sectionData -> Executable{..}) =-     "test-suite " ++ executableName ++ "\n"-  ++ "  type: exitcode-stdio-1.0\n"-  ++ renderExecutableSection section+  Stanza ("test-suite " ++ executableName)+    (Field "type" "exitcode-stdio-1.0" : renderExecutableSection section) -renderExecutableSection :: Section Executable -> String+renderExecutableSection :: Section Executable -> [Field] renderExecutableSection section@(sectionData -> Executable{..}) =-     "  main-is: " ++ executableMain ++ "\n"-  ++ renderSection section-  ++ renderOtherModules executableOtherModules-  ++ "  default-language: Haskell2010\n"+  mainIs : renderSection section ++ [otherModules, defaultLanguage]+  where+    mainIs = Field "main-is" (Literal executableMain)+    otherModules = renderOtherModules executableOtherModules -renderLibrary :: Section Library -> String-renderLibrary section@(sectionData -> Library{..}) =-    "library\n"-  ++ renderSection section-  ++ renderExposedModules libraryExposedModules-  ++ renderOtherModules libraryOtherModules-  ++ "  default-language: Haskell2010\n"+renderLibrary :: Section Library -> Stanza+renderLibrary section@(sectionData -> Library{..}) = Stanza "library" $+  renderSection section ++ [+    renderExposedModules libraryExposedModules+  , renderOtherModules libraryOtherModules+  , defaultLanguage+  ] -renderSection :: Section a -> String-renderSection Section{..} =-     renderSourceDirs sectionSourceDirs-  ++ unlines (renderDependencies sectionDependencies)-  ++ renderDefaultExtensions sectionDefaultExtensions-  ++ renderGhcOptions sectionGhcOptions-  ++ renderCppOptions sectionCppOptions+renderSection :: Section a -> [Field]+renderSection Section{..} = [+    renderSourceDirs sectionSourceDirs+  , renderDefaultExtensions sectionDefaultExtensions+  , renderGhcOptions sectionGhcOptions+  , renderCppOptions sectionCppOptions+  , renderDependencies sectionDependencies+  ] -renderSourceDirs :: [String] -> String-renderSourceDirs dirs-  | null dirs = ""-  | otherwise = "  hs-source-dirs: " ++ intercalate ", " dirs ++ "\n"+defaultLanguage :: Field+defaultLanguage = Field "default-language" "Haskell2010" -renderExposedModules :: [String] -> String-renderExposedModules modules-  | null modules = ""-  | otherwise = "  exposed-modules:\n" ++ (unlines $ map ("      " ++) modules)+renderSourceDirs :: [String] -> Field+renderSourceDirs dirs = Field "hs-source-dirs" (CommaSeparatedList dirs) -renderOtherModules :: [String] -> String-renderOtherModules modules-  | null modules = ""-  | otherwise = "  other-modules:\n" ++ (unlines $ map ("      " ++) modules)+renderExposedModules :: [String] -> Field+renderExposedModules modules = Field "exposed-modules" (LineSeparatedList modules) -renderDependencies :: [Dependency] -> [String]-renderDependencies dependencies-  | null dependencies = []-  | otherwise = "  build-depends:" : map render (zip (True : repeat False) dependencies)-  where-    render :: (Bool, Dependency) -> String-    render (isFirst, dependency)-      | isFirst   = "      " ++ dependencyName dependency-      | otherwise = "    , " ++ dependencyName dependency+renderOtherModules :: [String] -> Field+renderOtherModules modules = Field "other-modules" (LineSeparatedList modules) -renderGhcOptions :: [GhcOption] -> String-renderGhcOptions = renderOptions "ghc-options"+renderDependencies :: [Dependency] -> Field+renderDependencies dependencies = Field "build-depends" (CommaSeparatedList $ map dependencyName dependencies) -renderCppOptions :: [GhcOption] -> String-renderCppOptions = renderOptions "cpp-options"+renderGhcOptions :: [GhcOption] -> Field+renderGhcOptions = Field "ghc-options" . WordList -renderDefaultExtensions :: [String] -> String-renderDefaultExtensions = renderOptions "default-extensions"+renderCppOptions :: [GhcOption] -> Field+renderCppOptions = Field "cpp-options" . WordList -renderOptions :: String -> [String] -> String-renderOptions field options-  | null options = ""-  | otherwise = "  " ++ field ++ ": " ++ unwords options ++ "\n"+renderDefaultExtensions :: [String] -> Field+renderDefaultExtensions = Field "default-extensions" . WordList
+ test/Hpack/RenderSpec.hs view
@@ -0,0 +1,167 @@+{-# LANGUAGE OverloadedStrings #-}++module Hpack.RenderSpec where++import Test.Hspec++import Hpack.Render++spec :: Spec+spec = do+  describe "render" $ do+    context "when rendering a Stanza" $ do+      it "renders stanza" $ do+        let stanza = Stanza "foo" [+                Field "bar" "23"+              , Field "baz" "42"+              ]+        render defaultRenderSettings 0 stanza `shouldBe` [+            "foo"+          , "  bar: 23"+          , "  baz: 42"+          ]++      it "omits empty fields" $ do+        let stanza = Stanza "foo" [+                Field "bar" "23"+              , Field "baz" (WordList [])+              ]+        render defaultRenderSettings 0 stanza `shouldBe` [+            "foo"+          , "  bar: 23"+          ]++      it "allows to customize indentation" $ do+        let stanza = Stanza "foo" [+                Field "bar" "23"+              , Field "baz" "42"+              ]+        render defaultRenderSettings{renderSettingsIndentation = 4} 0 stanza `shouldBe` [+            "foo"+          , "    bar: 23"+          , "    baz: 42"+          ]++    context "when rendering a Field" $ do+      context "when rendering a MultipleLines value" $ do+        it "takes nesting into account" $ do+          let field = Field "foo" (CommaSeparatedList ["bar", "baz"])+          render defaultRenderSettings 1 field `shouldBe` [+              "  foo:"+            , "      bar"+            , "    , baz"+            ]++        context "when value is empty" $ do+          it "returns an empty list" $ do+            let field = Field "foo" (CommaSeparatedList [])+            render defaultRenderSettings 0 field `shouldBe` []++      context "when rendering a SingleLine value" $ do+        it "returns a single line" $ do+          let field = Field "foo" (Literal "bar")+          render defaultRenderSettings 0 field `shouldBe` ["foo: bar"]++        it "takes nesting into account" $ do+          let field = Field "foo" (Literal "bar")+          render defaultRenderSettings 2 field `shouldBe` ["    foo: bar"]++        context "when value is empty" $ do+          it "returns an empty list" $ do+            let field = Field "foo" (Literal "")+            render defaultRenderSettings 0 field `shouldBe` []++  describe "renderValue" $ do+    it "renders WordList" $ do+      renderValue defaultRenderSettings (WordList ["foo", "bar", "baz"]) `shouldBe` SingleLine "foo bar baz"++    it "renders CommaSeparatedList" $ do+      renderValue defaultRenderSettings (CommaSeparatedList ["foo", "bar", "baz"]) `shouldBe` MultipleLines [+          "  foo"+        , ", bar"+        , ", baz"+        ]++    it "renders LineSeparatedList" $ do+      renderValue defaultRenderSettings (LineSeparatedList ["foo", "bar", "baz"]) `shouldBe` MultipleLines [+          "  foo"+        , "  bar"+        , "  baz"+        ]++    context "when renderSettingsCommaStyle is TrailingCommas" $ do+      let settings = defaultRenderSettings{renderSettingsCommaStyle = TrailingCommas}++      it "renders CommaSeparatedList with trailing commas" $ do+        renderValue settings (CommaSeparatedList ["foo", "bar", "baz"]) `shouldBe` MultipleLines [+            "foo,"+          , "bar,"+          , "baz"+          ]++      it "renders LineSeparatedList without padding" $ do+        renderValue settings (LineSeparatedList ["foo", "bar", "baz"]) `shouldBe` MultipleLines [+            "foo"+          , "bar"+          , "baz"+          ]++  describe "sniffIndentation" $ do+    it "sniff alignment from executable section" $ do+      let input = unlines [+              "name: foo"+            , "version: 0.0.0"+            , ""+            , "executable foo"+            , "    build-depends: bar"+            ]+      sniffIndentation input `shouldBe` Just 4++    it "sniff alignment from library section" $ do+      let input = unlines [+              "name: foo"+            , "version: 0.0.0"+            , ""+            , "library"+            , "    build-depends: bar"+            ]+      sniffIndentation input `shouldBe` Just 4++    it "ignores empty lines" $ do+      let input = unlines [+              "executable foo"+            , ""+            , "    build-depends: bar"+            ]+      sniffIndentation input `shouldBe` Just 4++    it "ignores whitespace lines" $ do+      let input = unlines [+              "executable foo"+            , "  "+            , "    build-depends: bar"+            ]+      sniffIndentation input `shouldBe` Just 4++  describe "sniffCommaStyle" $ do+    it "detects leading commas" $ do+      let input = unlines [+              "executable foo"+            , "  build-depends:"+            , "      bar"+            , "    , baz"+            ]+      sniffCommaStyle input `shouldBe` Just LeadingCommas++    it "detects trailing commas" $ do+      let input = unlines [+              "executable foo"+            , "  build-depends:"+            , "    bar,  "+            , "    baz"+            ]+      sniffCommaStyle input `shouldBe` Just TrailingCommas++    context "when detection fails" $ do+      it "returns Nothing" $ do+        sniffCommaStyle "" `shouldBe` Nothing
test/Hpack/RunSpec.hs view
@@ -6,13 +6,15 @@  import           Hpack.ConfigSpec hiding (spec) import           Hpack.Config+import           Hpack.Render import           Hpack.Run  spec :: Spec spec = do   describe "renderPackage" $ do+    let renderPackage_ = renderPackage defaultRenderSettings     it "renders a package" $ do-      renderPackage 0 [] package `shouldBe` unlines [+      renderPackage_ 0 [] package `shouldBe` unlines [           "name: foo"         , "version: 0.0.0"         , "build-type: Simple"@@ -20,7 +22,7 @@         ]      it "aligns fields" $ do-      renderPackage 16 [] package `shouldBe` unlines [+      renderPackage_ 16 [] package `shouldBe` unlines [           "name:           foo"         , "version:        0.0.0"         , "build-type:     Simple"@@ -28,7 +30,7 @@         ]      it "includes description" $ do-      renderPackage 0 [] package {packageDescription = Just "foo\n\nbar\n"} `shouldBe` unlines [+      renderPackage_ 0 [] package {packageDescription = Just "foo\n\nbar\n"} `shouldBe` unlines [           "name: foo"         , "version: 0.0.0"         , "description: foo"@@ -39,7 +41,7 @@         ]      it "aligns description" $ do-      renderPackage 16 [] package {packageDescription = Just "foo\n\nbar\n"} `shouldBe` unlines [+      renderPackage_ 16 [] package {packageDescription = Just "foo\n\nbar\n"} `shouldBe` unlines [           "name:           foo"         , "version:        0.0.0"         , "description:    foo"@@ -50,7 +52,7 @@         ]      it "includes stability" $ do-      renderPackage 0 [] package {packageStability = Just "experimental"} `shouldBe` unlines [+      renderPackage_ 0 [] package {packageStability = Just "experimental"} `shouldBe` unlines [           "name: foo"         , "version: 0.0.0"         , "stability: experimental"@@ -59,7 +61,7 @@         ]      it "includes copyright holder" $ do-      renderPackage 0 [] package {packageCopyright = ["(c) 2015 Simon Hengel"]} `shouldBe` unlines [+      renderPackage_ 0 [] package {packageCopyright = ["(c) 2015 Simon Hengel"]} `shouldBe` unlines [           "name: foo"         , "version: 0.0.0"         , "copyright: (c) 2015 Simon Hengel"@@ -68,7 +70,7 @@         ]      it "aligns copyright holders" $ do-      renderPackage 16 [] package {packageCopyright = ["(c) 2015 Foo", "(c) 2015 Bar"]} `shouldBe` unlines [+      renderPackage_ 16 [] package {packageCopyright = ["(c) 2015 Foo", "(c) 2015 Bar"]} `shouldBe` unlines [           "name:           foo"         , "version:        0.0.0"         , "copyright:      (c) 2015 Foo,"@@ -78,20 +80,31 @@         ]      it "includes extra-source-files" $ do-      renderPackage 0 [] package {packageExtraSourceFiles = ["foo", "bar"]} `shouldBe` unlines [+      renderPackage_ 0 [] package {packageExtraSourceFiles = ["foo", "bar"]} `shouldBe` unlines [           "name: foo"         , "version: 0.0.0"         , "build-type: Simple"         , "cabal-version: >= 1.10"         , ""         , "extra-source-files:"-        , "  foo"-        , "  bar"+        , "    foo"+        , "    bar"         ] +    it "renders libray section" $ do+      renderPackage_ 0 [] package {packageLibrary = Just $ section library} `shouldBe` unlines [+          "name: foo"+        , "version: 0.0.0"+        , "build-type: Simple"+        , "cabal-version: >= 1.10"+        , ""+        , "library"+        , "  default-language: Haskell2010"+        ]+     context "when given list of existing fields" $ do       it "retains field order" $ do-        renderPackage 16 ["cabal-version", "version", "name", "build-type"] package `shouldBe` unlines [+        renderPackage_ 16 ["cabal-version", "version", "name", "build-type"] package `shouldBe` unlines [             "cabal-version:  >= 1.10"           , "version:        0.0.0"           , "name:           foo"@@ -99,7 +112,7 @@           ]        it "uses default field order for new fields" $ do-        renderPackage 16 ["name", "version", "cabal-version"] package `shouldBe` unlines [+        renderPackage_ 16 ["name", "version", "cabal-version"] package `shouldBe` unlines [             "name:           foo"           , "version:        0.0.0"           , "build-type:     Simple"@@ -108,7 +121,7 @@      context "when rendering executable section" $ do       it "includes dependencies" $ do-        renderPackage 0 [] package {packageExecutables = [(section $ executable "foo" "Main.hs") {sectionDependencies = ["foo", "bar", "foo", "baz"]}]} `shouldBe` unlines [+        renderPackage_ 0 [] package {packageExecutables = [(section $ executable "foo" "Main.hs") {sectionDependencies = ["foo", "bar", "foo", "baz"]}]} `shouldBe` unlines [             "name: foo"           , "version: 0.0.0"           , "build-type: Simple"@@ -125,7 +138,7 @@           ]        it "includes GHC options" $ do-        renderPackage 0 [] package {packageExecutables = [(section $ executable "foo" "Main.hs") {sectionGhcOptions = ["-Wall", "-Werror"]}]} `shouldBe` unlines [+        renderPackage_ 0 [] package {packageExecutables = [(section $ executable "foo" "Main.hs") {sectionGhcOptions = ["-Wall", "-Werror"]}]} `shouldBe` unlines [             "name: foo"           , "version: 0.0.0"           , "build-type: Simple"@@ -174,16 +187,18 @@    describe "renderSourceRepository" $ do     it "renders source-repository without subdir correctly" $ do-      renderSourceRepository (SourceRepository "https://github.com/hspec/hspec" Nothing)-        `shouldBe` unlines [+      let repository = SourceRepository "https://github.com/hspec/hspec" Nothing+      (render defaultRenderSettings 0 $ renderSourceRepository repository)+        `shouldBe` [             "source-repository head"           , "  type: git"           , "  location: https://github.com/hspec/hspec"           ]      it "renders source-repository with subdir" $ do-      renderSourceRepository (SourceRepository "https://github.com/hspec/hspec" (Just "hspec-core"))-        `shouldBe` unlines [+      let repository = SourceRepository "https://github.com/hspec/hspec" (Just "hspec-core")+      (render defaultRenderSettings 0 $ renderSourceRepository repository)+        `shouldBe` [             "source-repository head"           , "  type: git"           , "  location: https://github.com/hspec/hspec"