diff --git a/Changelog.md b/Changelog.md index a7b040d..676b56a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,9 @@ +# 0.1.11 + +- Change how dependencies on (multiple) sublibraries are output: + Always print each sublibrary on individual line, + with the first one having the version range. + # 0.1.10 - Fix removal of empty lines in free text fields (like `description`) diff --git a/cabal-fmt.cabal b/cabal-fmt.cabal index 00d907c..4dc4a1f 100644 --- a/cabal-fmt.cabal +++ b/cabal-fmt.cabal @@ -1,6 +1,6 @@ cabal-version: 2.2 name: cabal-fmt -version: 0.1.10 +version: 0.1.11 synopsis: Format .cabal files category: Development description: diff --git a/fixtures/sublib.cabal b/fixtures/sublib.cabal new file mode 100644 index 0000000..1b39d63 --- /dev/null +++ b/fixtures/sublib.cabal @@ -0,0 +1,23 @@ +cabal-version: 3.0 +name: sublib +version: 0 + +library + default-language: Haskell2010 + hs-source-dirs: src + + -- the anotherlib case tests case insensitivity. + build-depends: + base >=4.3 && <4.18 + , megalib + , megalib:sublib-a >=0.1 + , megalib:sublib-b <0.3 + , megalib:sublib-c <0.2 + + , anotherlib:sublib-B <0.3 + , anotherlib:sublib-a >=0.1 + , anotherlib:sublib-C <0.2 + + exposed-modules: + Data.ExampleA + Data.ExampleB diff --git a/fixtures/sublib.format b/fixtures/sublib.format new file mode 100644 index 0000000..0caf00a --- /dev/null +++ b/fixtures/sublib.format @@ -0,0 +1,22 @@ +cabal-version: 3.0 +name: sublib +version: 0 + +library + default-language: Haskell2010 + hs-source-dirs: src + + -- the anotherlib case tests case insensitivity. + build-depends: + , anotherlib:sublib-a >=0.1 && <0.2 + , anotherlib:sublib-B + , anotherlib:sublib-C + , base >=4.3 && <4.18 + , megalib >=0.1 && <0.2 + , megalib:sublib-a + , megalib:sublib-b + , megalib:sublib-c + + exposed-modules: + Data.ExampleA + Data.ExampleB diff --git a/fixtures/with-sublibs.format b/fixtures/with-sublibs.format index 3182c26..be766e2 100644 --- a/fixtures/with-sublibs.format +++ b/fixtures/with-sublibs.format @@ -1,4 +1,3 @@ -Up to date cabal-version: 3.0 name: with-sublibs version: 1 @@ -7,14 +6,21 @@ library hs-source-dirs: src default-language: Haskell2010 build-depends: - , test1:{test1, sub} - , test2:{test2, sub} >=2 && <3 + , test1 + , test1:sub + , test2 >=2 && <3 + , test2:sub build-depends: test1 build-depends: test2 >=1 build-depends: test2:sub build-depends: test2:sub - build-depends: test2:{sub1, sub2} + build-depends: + , test2:sub1 + , test2:sub2 + build-depends: test2:sub >=1 && <3 build-depends: test2:sub >=2 && <3 - build-depends: test2:{sub1, sub2} >=3 && <4 + build-depends: + , test2:sub1 >=3 && <4 + , test2:sub2 diff --git a/src/CabalFmt/Fields/BuildDepends.hs b/src/CabalFmt/Fields/BuildDepends.hs index 61acf5c..bda2f53 100644 --- a/src/CabalFmt/Fields/BuildDepends.hs +++ b/src/CabalFmt/Fields/BuildDepends.hs @@ -11,20 +11,22 @@ module CabalFmt.Fields.BuildDepends ( import Data.List (dropWhileEnd) +import CabalFmt.Fields +import CabalFmt.Options +import CabalFmt.Prelude import qualified Distribution.CabalSpecVersion as C +import qualified Distribution.Compat.NonEmptySet as NES import qualified Distribution.FieldGrammar as C import qualified Distribution.Parsec as C import qualified Distribution.Pretty as C import qualified Distribution.Types.Dependency as C import qualified Distribution.Types.DependencyMap as C import qualified Distribution.Types.ExeDependency as C +import qualified Distribution.Types.LibraryName as C import qualified Distribution.Types.VersionRange as C import qualified Text.PrettyPrint as PP - -import CabalFmt.Fields -import CabalFmt.Options -import CabalFmt.Prelude -import VersionInterval (normaliseVersionRange, ConversionProblem (..)) +import VersionInterval + (ConversionProblem (..), normaliseVersionRange) setupDependsF :: Options -> FieldDescrs () () setupDependsF opts = singletonF "setup-depends" (pretty opts) parse @@ -48,7 +50,7 @@ normaliseVersionRange' vr = either fromConversionProblem id (normaliseVersionRan fromConversionProblem OtherConversionProblem = vr pretty :: Options -> [C.Dependency] -> PP.Doc -pretty opts deps = case deps of +pretty opts deps = case deps' of [] -> PP.empty [dep] -> PP.text (prettyDepNoVersion dep) PP.<+> prettyVR vr' where @@ -58,18 +60,33 @@ pretty opts deps = case deps of | vr == C.noVersion = PP.text "<0" | otherwise = C.pretty vr - _ -> prettyMany opts deps' + _ -> prettyMany opts deps'' where - deps' :: [(String, C.VersionRange)] - deps' = sortOn (map toLower . fst) - $ map (prettyDepNoVersion &&& C.depVerRange) - $ C.fromDepMap . C.toDepMap -- this combines duplicate packages - $ deps + deps'' :: [(String, C.VersionRange)] + deps'' = + sortOn (map toLower . fst) $ + map (prettyDepNoVersion &&& C.depVerRange) deps' where + -- combined and expanded dependencies + deps' :: [C.Dependency] + deps' = concatMap expandDep $ C.fromDepMap $ C.toDepMap deps + prettyDepNoVersion :: C.Dependency -> String prettyDepNoVersion (C.Dependency pkg _ libs) = C.prettyShow (C.Dependency pkg C.anyVersion libs) + expandDep :: C.Dependency -> [C.Dependency] + expandDep (C.Dependency pkg vr libs) = makeDep $ sortOn f (NES.toList libs) + where + f C.LMainLibName = Nothing + f (C.LSubLibName n) = Just (map toLower (C.prettyShow n)) + + -- attach version range to the first dependency of the group. + makeDep :: [C.LibraryName] -> [C.Dependency] + makeDep [] = [] + makeDep (ln : lns) = + C.Dependency pkg vr (NES.singleton ln) : + map (\ln' -> C.Dependency pkg C.anyVersion (NES.singleton ln')) lns prettyExe :: Options -> [C.ExeDependency] -> PP.Doc prettyExe opts deps = case deps of diff --git a/tests/golden.hs b/tests/golden.hs index 52945a2..227ee19 100644 --- a/tests/golden.hs +++ b/tests/golden.hs @@ -33,6 +33,9 @@ main = defaultMain $ testGroup "tests" , goldenTest' "issue69" , goldenTest' "issue29" + + , goldenTest' "sublib" + , goldenTest' "with-sublibs" ] goldenTest' :: String -> TestTree