packages feed

cabal-fmt 0.1.5.1 → 0.1.6

raw patch · 29 files changed

+2822/−178 lines, 29 filesdep +Cabal-syntaxdep +QuickCheckdep +integer-logarithmsdep −Cabaldep ~basedep ~bytestringdep ~optparse-applicativePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: Cabal-syntax, QuickCheck, integer-logarithms, tasty-hunit, tasty-quickcheck, temporary

Dependencies removed: Cabal

Dependency ranges changed: base, bytestring, optparse-applicative

API changes (from Hackage documentation)

- CabalFmt.Fields: instance Distribution.FieldGrammar.Class.FieldGrammar CabalFmt.Fields.FieldDescrs
+ CabalFmt.Fields: instance (Distribution.Pretty.Pretty a, Distribution.Parsec.Parsec a) => CabalFmt.Fields.PrettyParsec a
+ CabalFmt.Fields: instance Distribution.FieldGrammar.Class.FieldGrammar CabalFmt.Fields.PrettyParsec CabalFmt.Fields.FieldDescrs
+ CabalFmt.Fields.BuildDepends: buildToolDependsF :: Options -> FieldDescrs () ()
+ CabalFmt.Prelude: for_ :: (Foldable t, Applicative f) => t a -> (a -> f b) -> f ()

Files

Changelog.md view
@@ -1,3 +1,11 @@+# 0.1.6++- Fix filepath issues on Windows+- Add support for sublibraries+- Format `build-tool-depends`+- Use Cabal-syntax-3.8.1.0+- Smarter version range normaliser+ # 0.1.5.1  - Fix bug in pretty printing empty version ranges.
cabal-fmt.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.2 name:               cabal-fmt-version:            0.1.5.1+version:            0.1.6 synopsis:           Format .cabal files category:           Development description:@@ -12,7 +12,15 @@ license-file:       LICENSE author:             Oleg Grenrus <oleg.grenrus@iki.fi> maintainer:         Oleg Grenrus <oleg.grenrus@iki.fi>-tested-with:        GHC ==8.4.4 || ==8.6.5 || ==8.8.4 || ==8.10.2+tested-with:+  GHC ==8.4.4+   || ==8.6.5+   || ==8.8.4+   || ==8.10.7+   || ==9.0.2+   || ==9.2.4+   || ==9.4.1+ extra-source-files:   Changelog.md   fixtures/*.cabal@@ -22,22 +30,34 @@   type:     git   location: https://github.com/phadej/cabal-fmt.git +library version-interval+  default-language: Haskell2010+  hs-source-dirs:   src-interval+  build-depends:+    , base          ^>=4.11.1.0 || ^>=4.12.0.0 || ^>=4.13.0.0 || ^>=4.14.0.0 || ^>=4.15.0.0 || ^>=4.16.0.0 || ^>=4.17.0.0+    , Cabal-syntax  ^>=3.8.1.0++  exposed-modules:  VersionInterval+ library cabal-fmt-internal   default-language: Haskell2010   hs-source-dirs:   src    -- GHC boot libraries   build-depends:-    , base        ^>=4.11.1.0 || ^>=4.12.0.0 || ^>=4.13.0.0 || ^>=4.14.0.0-    , bytestring  ^>=0.10.8.2-    , Cabal       ^>=3.2.0.0-    , containers  ^>=0.5.11.0 || ^>=0.6.0.1-    , directory   ^>=1.3.1.5-    , filepath    ^>=1.4.2-    , mtl         ^>=2.2.2-    , parsec      ^>=3.1.13.0-    , pretty      ^>=1.1.3.6+    , base          ^>=4.11.1.0 || ^>=4.12.0.0 || ^>=4.13.0.0 || ^>=4.14.0.0 || ^>=4.15.0.0 || ^>=4.16.0.0 || ^>=4.17.0.0+    , bytestring    ^>=0.10.8.2 || ^>=0.11.3.1+    , Cabal-syntax  ^>=3.8.1.0+    , containers    ^>=0.5.11.0 || ^>=0.6.0.1+    , directory     ^>=1.3.1.5+    , filepath      ^>=1.4.2+    , mtl           ^>=2.2.2+    , parsec        ^>=3.1.13.0+    , pretty        ^>=1.1.3.6 +  -- our version interval normalisation+  build-depends:    version-interval+   -- cabal-fmt: expand src   exposed-modules:     CabalFmt@@ -87,7 +107,7 @@     , filepath    -- extra dependencies-  build-depends:    optparse-applicative >=0.14.3.0 && <0.17+  build-depends:    optparse-applicative >=0.14.3.0 && <0.18  test-suite golden   type:             exitcode-stdio-1.0@@ -99,8 +119,8 @@   build-depends:     , base     , bytestring-    , Cabal     , cabal-fmt-internal+    , Cabal-syntax     , containers    -- test dependencies@@ -109,5 +129,21 @@     , process     , tasty     , tasty-golden+    , temporary++test-suite version-interval-tests+  type:             exitcode-stdio-1.0+  default-language: Haskell2010+  hs-source-dirs:   tests-interval+  main-is:          version-interval-tests.hs+  build-depends:+    , base+    , Cabal-syntax+    , integer-logarithms  ^>=1.0.3.1+    , QuickCheck+    , tasty+    , tasty-hunit+    , tasty-quickcheck+    , version-interval  -- end file comment
cli/Main.hs view
@@ -4,8 +4,6 @@ module Main (main) where  import Control.Applicative (many, (<**>))-import Control.Monad       (unless, when)-import Data.Foldable       (asum, for_) import Data.Traversable    (for) import Data.Version        (showVersion) import System.Exit         (exitFailure)
+ fixtures/Cabal-notab.cabal view
@@ -0,0 +1,653 @@+name:          Cabal+version:       2.5.0.0+-- cabal-fmt: no-tabular+copyright:     2003-2018, Cabal Development Team (see AUTHORS file)+license:       BSD3+license-file:  LICENSE+author:        Cabal Development Team <cabal-devel@haskell.org>+maintainer:    cabal-devel@haskell.org+homepage:      http://www.haskell.org/cabal/+bug-reports:   https://github.com/haskell/cabal/issues+synopsis:      A framework for packaging Haskell software+description:+  The Haskell Common Architecture for Building Applications and+  Libraries: a framework defining a common interface for authors to more+  easily build their Haskell applications in a portable way.+  .+  The Haskell Cabal is part of a larger infrastructure for distributing,+  organizing, and cataloging Haskell libraries and tools.+category:       Distribution+cabal-version:  >=1.10+build-type:     Simple+-- If we use a new Cabal feature, this needs to be changed to Custom so+-- we can bootstrap.++extra-source-files:+  README.md tests/README.md ChangeLog.md+  doc/bugs-and-stability.rst doc/concepts-and-development.rst+  doc/conf.py doc/config-and-install.rst doc/developing-packages.rst+  doc/images/Cabal-dark.png doc/index.rst doc/installing-packages.rst+  doc/intro.rst doc/misc.rst doc/nix-local-build-overview.rst+  doc/nix-local-build.rst doc/file-format-changelog.rst doc/README.md+  doc/references.inc++  -- Generated with 'make gen-extra-source-files'+  -- Do NOT edit this section manually; instead, run the script.+  -- BEGIN gen-extra-source-files+  tests/ParserTests/errors/common1.cabal+  tests/ParserTests/errors/common1.errors+  tests/ParserTests/errors/common2.cabal+  tests/ParserTests/errors/common2.errors+  tests/ParserTests/errors/common3.cabal+  tests/ParserTests/errors/common3.errors+  tests/ParserTests/errors/forward-compat.cabal+  tests/ParserTests/errors/forward-compat.errors+  tests/ParserTests/errors/forward-compat2.cabal+  tests/ParserTests/errors/forward-compat2.errors+  tests/ParserTests/errors/forward-compat3.cabal+  tests/ParserTests/errors/forward-compat3.errors+  tests/ParserTests/errors/issue-5055-2.cabal+  tests/ParserTests/errors/issue-5055-2.errors+  tests/ParserTests/errors/issue-5055.cabal+  tests/ParserTests/errors/issue-5055.errors+  tests/ParserTests/errors/leading-comma-2.cabal+  tests/ParserTests/errors/leading-comma-2.errors+  tests/ParserTests/errors/leading-comma-2b.cabal+  tests/ParserTests/errors/leading-comma-2b.errors+  tests/ParserTests/errors/leading-comma-2c.cabal+  tests/ParserTests/errors/leading-comma-2c.errors+  tests/ParserTests/errors/leading-comma.cabal+  tests/ParserTests/errors/leading-comma.errors+  tests/ParserTests/errors/multiple-libs.cabal+  tests/ParserTests/errors/multiple-libs.errors+  tests/ParserTests/errors/noVersion.cabal+  tests/ParserTests/errors/noVersion.errors+  tests/ParserTests/errors/noVersion2.cabal+  tests/ParserTests/errors/noVersion2.errors+  tests/ParserTests/errors/range-ge-wild.cabal+  tests/ParserTests/errors/range-ge-wild.errors+  tests/ParserTests/errors/removed-fields.cabal+  tests/ParserTests/errors/removed-fields.errors+  tests/ParserTests/errors/spdx-1.cabal+  tests/ParserTests/errors/spdx-1.errors+  tests/ParserTests/errors/spdx-2.cabal+  tests/ParserTests/errors/spdx-2.errors+  tests/ParserTests/errors/spdx-3.cabal+  tests/ParserTests/errors/spdx-3.errors+  tests/ParserTests/ipi/Includes2.cabal+  tests/ParserTests/ipi/Includes2.expr+  tests/ParserTests/ipi/Includes2.format+  tests/ParserTests/ipi/internal-preprocessor-test.cabal+  tests/ParserTests/ipi/internal-preprocessor-test.expr+  tests/ParserTests/ipi/internal-preprocessor-test.format+  tests/ParserTests/ipi/issue-2276-ghc-9885.cabal+  tests/ParserTests/ipi/issue-2276-ghc-9885.expr+  tests/ParserTests/ipi/issue-2276-ghc-9885.format+  tests/ParserTests/ipi/transformers.cabal+  tests/ParserTests/ipi/transformers.expr+  tests/ParserTests/ipi/transformers.format+  tests/ParserTests/regressions/MiniAgda.cabal+  tests/ParserTests/regressions/MiniAgda.check+  tests/ParserTests/regressions/Octree-0.5.cabal+  tests/ParserTests/regressions/Octree-0.5.expr+  tests/ParserTests/regressions/Octree-0.5.format+  tests/ParserTests/regressions/bad-glob-syntax.cabal+  tests/ParserTests/regressions/bad-glob-syntax.check+  tests/ParserTests/regressions/cc-options-with-optimization.cabal+  tests/ParserTests/regressions/cc-options-with-optimization.check+  tests/ParserTests/regressions/common-conditional.cabal+  tests/ParserTests/regressions/common-conditional.expr+  tests/ParserTests/regressions/common-conditional.format+  tests/ParserTests/regressions/common.cabal+  tests/ParserTests/regressions/common.expr+  tests/ParserTests/regressions/common.format+  tests/ParserTests/regressions/common2.cabal+  tests/ParserTests/regressions/common2.expr+  tests/ParserTests/regressions/common2.format+  tests/ParserTests/regressions/cxx-options-with-optimization.cabal+  tests/ParserTests/regressions/cxx-options-with-optimization.check+  tests/ParserTests/regressions/elif.cabal+  tests/ParserTests/regressions/elif.expr+  tests/ParserTests/regressions/elif.format+  tests/ParserTests/regressions/elif2.cabal+  tests/ParserTests/regressions/elif2.expr+  tests/ParserTests/regressions/elif2.format+  tests/ParserTests/regressions/encoding-0.8.cabal+  tests/ParserTests/regressions/encoding-0.8.expr+  tests/ParserTests/regressions/encoding-0.8.format+  tests/ParserTests/regressions/extensions-paths-5054.cabal+  tests/ParserTests/regressions/extensions-paths-5054.check+  tests/ParserTests/regressions/generics-sop.cabal+  tests/ParserTests/regressions/generics-sop.expr+  tests/ParserTests/regressions/generics-sop.format+  tests/ParserTests/regressions/ghc-option-j.cabal+  tests/ParserTests/regressions/ghc-option-j.check+  tests/ParserTests/regressions/haddock-api-2.18.1-check.cabal+  tests/ParserTests/regressions/haddock-api-2.18.1-check.check+  tests/ParserTests/regressions/hidden-main-lib.cabal+  tests/ParserTests/regressions/hidden-main-lib.expr+  tests/ParserTests/regressions/hidden-main-lib.format+  tests/ParserTests/regressions/issue-5055.cabal+  tests/ParserTests/regressions/issue-5055.expr+  tests/ParserTests/regressions/issue-5055.format+  tests/ParserTests/regressions/issue-774.cabal+  tests/ParserTests/regressions/issue-774.check+  tests/ParserTests/regressions/issue-774.expr+  tests/ParserTests/regressions/issue-774.format+  tests/ParserTests/regressions/jaeger-flamegraph.cabal+  tests/ParserTests/regressions/jaeger-flamegraph.expr+  tests/ParserTests/regressions/jaeger-flamegraph.format+  tests/ParserTests/regressions/leading-comma-2.cabal+  tests/ParserTests/regressions/leading-comma-2.expr+  tests/ParserTests/regressions/leading-comma-2.format+  tests/ParserTests/regressions/leading-comma.cabal+  tests/ParserTests/regressions/leading-comma.expr+  tests/ParserTests/regressions/leading-comma.format+  tests/ParserTests/regressions/multiple-libs-2.cabal+  tests/ParserTests/regressions/multiple-libs-2.check+  tests/ParserTests/regressions/multiple-libs-2.expr+  tests/ParserTests/regressions/multiple-libs-2.format+  tests/ParserTests/regressions/noVersion.cabal+  tests/ParserTests/regressions/noVersion.expr+  tests/ParserTests/regressions/noVersion.format+  tests/ParserTests/regressions/nothing-unicode.cabal+  tests/ParserTests/regressions/nothing-unicode.check+  tests/ParserTests/regressions/nothing-unicode.expr+  tests/ParserTests/regressions/nothing-unicode.format+  tests/ParserTests/regressions/pre-1.6-glob.cabal+  tests/ParserTests/regressions/pre-1.6-glob.check+  tests/ParserTests/regressions/pre-2.4-globstar.cabal+  tests/ParserTests/regressions/pre-2.4-globstar.check+  tests/ParserTests/regressions/shake.cabal+  tests/ParserTests/regressions/shake.expr+  tests/ParserTests/regressions/shake.format+  tests/ParserTests/regressions/spdx-1.cabal+  tests/ParserTests/regressions/spdx-1.expr+  tests/ParserTests/regressions/spdx-1.format+  tests/ParserTests/regressions/spdx-2.cabal+  tests/ParserTests/regressions/spdx-2.expr+  tests/ParserTests/regressions/spdx-2.format+  tests/ParserTests/regressions/spdx-3.cabal+  tests/ParserTests/regressions/spdx-3.expr+  tests/ParserTests/regressions/spdx-3.format+  tests/ParserTests/regressions/th-lift-instances.cabal+  tests/ParserTests/regressions/th-lift-instances.expr+  tests/ParserTests/regressions/th-lift-instances.format+  tests/ParserTests/regressions/wl-pprint-indef.cabal+  tests/ParserTests/regressions/wl-pprint-indef.expr+  tests/ParserTests/regressions/wl-pprint-indef.format+  tests/ParserTests/warnings/bom.cabal+  tests/ParserTests/warnings/bool.cabal+  tests/ParserTests/warnings/deprecatedfield.cabal+  tests/ParserTests/warnings/doubledash.cabal+  tests/ParserTests/warnings/extratestmodule.cabal+  tests/ParserTests/warnings/gluedop.cabal+  tests/ParserTests/warnings/multiplesingular.cabal+  tests/ParserTests/warnings/nbsp.cabal+  tests/ParserTests/warnings/newsyntax.cabal+  tests/ParserTests/warnings/oldsyntax.cabal+  tests/ParserTests/warnings/subsection.cabal+  tests/ParserTests/warnings/tab.cabal+  tests/ParserTests/warnings/trailingfield.cabal+  tests/ParserTests/warnings/unknownfield.cabal+  tests/ParserTests/warnings/unknownsection.cabal+  tests/ParserTests/warnings/utf8.cabal+  tests/ParserTests/warnings/versiontag.cabal+  tests/hackage/check.sh+  tests/hackage/download.sh+  tests/hackage/unpack.sh+  tests/misc/ghc-supported-languages.hs+  -- END gen-extra-source-files++source-repository head+  type:     git+  location: https://github.com/haskell/cabal/+  subdir:   Cabal++flag bundled-binary-generic+  default: False++library+  build-depends:+    array      >= 0.4.0.1  && < 0.6,+    base       >= 4.6      && < 5,+    bytestring >= 0.10.0.0 && < 0.11,+    containers >= 0.5.0.0  && < 0.7,+    deepseq    >= 1.3.0.1  && < 1.5,+    directory  >= 1.2      && < 1.4,+    filepath   >= 1.3.0.1  && < 1.5,+    pretty     >= 1.1.1    && < 1.2,+    process    >= 1.1.0.2  && < 1.7,+    time       >= 1.4.0.1  && < 1.10++  if flag(bundled-binary-generic)+    build-depends: binary >= 0.5.1.1 && < 0.7+  else+    build-depends: binary >= 0.7 && < 0.9++  if os(windows)+    build-depends: Win32 >= 2.3.0.0 && < 2.9+  else+    build-depends: unix  >= 2.6.0.0 && < 2.8++  ghc-options: -Wall -fno-ignore-asserts -fwarn-tabs+  if impl(ghc >= 8.0)+    ghc-options: -Wcompat -Wnoncanonical-monad-instances+                 -Wnoncanonical-monadfail-instances++  exposed-modules:+    Distribution.Backpack+    Distribution.Backpack.Configure+    Distribution.Backpack.ComponentsGraph+    Distribution.Backpack.ConfiguredComponent+    Distribution.Backpack.DescribeUnitId+    Distribution.Backpack.FullUnitId+    Distribution.Backpack.LinkedComponent+    Distribution.Backpack.ModSubst+    Distribution.Backpack.ModuleShape+    Distribution.Backpack.PreModuleShape+    Distribution.CabalSpecVersion+    Distribution.Utils.IOData+    Distribution.Utils.LogProgress+    Distribution.Utils.MapAccum+    Distribution.Compat.CreatePipe+    Distribution.Compat.Directory+    Distribution.Compat.Environment+    Distribution.Compat.Exception+    Distribution.Compat.Graph+    Distribution.Compat.Internal.TempFile+    Distribution.Compat.Newtype+    Distribution.Compat.Prelude.Internal+    Distribution.Compat.Semigroup+    Distribution.Compat.Stack+    Distribution.Compat.Time+    Distribution.Compat.DList+    Distribution.Compiler+    Distribution.InstalledPackageInfo+    Distribution.Types.AbiDependency+    Distribution.Types.ExposedModule+    Distribution.Types.InstalledPackageInfo+    Distribution.Types.InstalledPackageInfo.FieldGrammar+    Distribution.License+    Distribution.Make+    Distribution.ModuleName+    Distribution.Package+    Distribution.PackageDescription+    Distribution.PackageDescription.Check+    Distribution.PackageDescription.Configuration+    Distribution.PackageDescription.PrettyPrint+    Distribution.PackageDescription.Utils+    Distribution.ReadE+    Distribution.Simple+    Distribution.Simple.Bench+    Distribution.Simple.Build+    Distribution.Simple.Build.Macros+    Distribution.Simple.Build.PathsModule+    Distribution.Simple.BuildPaths+    Distribution.Simple.BuildTarget+    Distribution.Simple.BuildToolDepends+    Distribution.Simple.CCompiler+    Distribution.Simple.Command+    Distribution.Simple.Compiler+    Distribution.Simple.Configure+    Distribution.Simple.Flag+    Distribution.Simple.GHC+    Distribution.Simple.GHCJS+    Distribution.Simple.Haddock+    Distribution.Simple.Doctest+    Distribution.Simple.Glob+    Distribution.Simple.HaskellSuite+    Distribution.Simple.Hpc+    Distribution.Simple.Install+    Distribution.Simple.InstallDirs+    Distribution.Simple.LocalBuildInfo+    Distribution.Simple.PackageIndex+    Distribution.Simple.PreProcess+    Distribution.Simple.PreProcess.Unlit+    Distribution.Simple.Program+    Distribution.Simple.Program.Ar+    Distribution.Simple.Program.Builtin+    Distribution.Simple.Program.Db+    Distribution.Simple.Program.Find+    Distribution.Simple.Program.GHC+    Distribution.Simple.Program.HcPkg+    Distribution.Simple.Program.Hpc+    Distribution.Simple.Program.Internal+    Distribution.Simple.Program.Ld+    Distribution.Simple.Program.ResponseFile+    Distribution.Simple.Program.Run+    Distribution.Simple.Program.Script+    Distribution.Simple.Program.Strip+    Distribution.Simple.Program.Types+    Distribution.Simple.Register+    Distribution.Simple.Setup+    Distribution.Simple.SrcDist+    Distribution.Simple.Test+    Distribution.Simple.Test.ExeV10+    Distribution.Simple.Test.LibV09+    Distribution.Simple.Test.Log+    Distribution.Simple.UHC+    Distribution.Simple.UserHooks+    Distribution.Simple.Utils+    Distribution.SPDX+    Distribution.SPDX.License+    Distribution.SPDX.LicenseId+    Distribution.SPDX.LicenseExceptionId+    Distribution.SPDX.LicenseExpression+    Distribution.SPDX.LicenseListVersion+    Distribution.SPDX.LicenseReference+    Distribution.System+    Distribution.TestSuite+    Distribution.Text+    Distribution.Pretty+    Distribution.Types.AbiHash+    Distribution.Types.AnnotatedId+    Distribution.Types.Benchmark+    Distribution.Types.BenchmarkInterface+    Distribution.Types.BenchmarkType+    Distribution.Types.BuildInfo+    Distribution.Types.BuildType+    Distribution.Types.ComponentInclude+    Distribution.Types.Dependency+    Distribution.Types.ExeDependency+    Distribution.Types.LegacyExeDependency+    Distribution.Types.PkgconfigDependency+    Distribution.Types.DependencyMap+    Distribution.Types.ComponentId+    Distribution.Types.MungedPackageId+    Distribution.Types.PackageId+    Distribution.Types.UnitId+    Distribution.Types.Executable+    Distribution.Types.ExecutableScope+    Distribution.Types.Library+    Distribution.Types.LibraryVisibility+    Distribution.Types.ForeignLib+    Distribution.Types.ForeignLibType+    Distribution.Types.ForeignLibOption+    Distribution.Types.Module+    Distribution.Types.ModuleReexport+    Distribution.Types.ModuleRenaming+    Distribution.Types.ComponentName+    Distribution.Types.LibraryName+    Distribution.Types.MungedPackageName+    Distribution.Types.PackageName+    Distribution.Types.PkgconfigName+    Distribution.Types.UnqualComponentName+    Distribution.Types.IncludeRenaming+    Distribution.Types.Mixin+    Distribution.Types.SetupBuildInfo+    Distribution.Types.TestSuite+    Distribution.Types.TestSuiteInterface+    Distribution.Types.TestType+    Distribution.Types.GenericPackageDescription+    Distribution.Types.Condition+    Distribution.Types.CondTree+    Distribution.Types.HookedBuildInfo+    Distribution.Types.PackageDescription+    Distribution.Types.SourceRepo+    Distribution.Types.Component+    Distribution.Types.ComponentLocalBuildInfo+    Distribution.Types.LocalBuildInfo+    Distribution.Types.ComponentRequestedSpec+    Distribution.Types.TargetInfo+    Distribution.Types.Version+    Distribution.Types.VersionRange+    Distribution.Types.VersionInterval+    Distribution.Types.GivenComponent+    Distribution.Types.PackageVersionConstraint+    Distribution.Utils.Generic+    Distribution.Utils.NubList+    Distribution.Utils.ShortText+    Distribution.Utils.Progress+    Distribution.Verbosity+    Distribution.Version+    Language.Haskell.Extension+    Distribution.Compat.Binary++  -- Parsec parser-related modules+  build-depends:+    -- transformers-0.4.0.0 doesn't have record syntax e.g. for Identity+    -- See also https://github.com/ekmett/transformers-compat/issues/35+    transformers (>= 0.3      && < 0.4) || (>=0.4.1.0 && <0.6),+    mtl           >= 2.1      && < 2.3,+    text          >= 1.2.3.0  && < 1.3,+    parsec        >= 3.1.13.0 && < 3.2+  exposed-modules:+    Distribution.Compat.Parsing+    Distribution.Compat.CharParsing+    Distribution.FieldGrammar+    Distribution.FieldGrammar.Class+    Distribution.FieldGrammar.FieldDescrs+    Distribution.FieldGrammar.Parsec+    Distribution.FieldGrammar.Pretty+    Distribution.PackageDescription.FieldGrammar+    Distribution.PackageDescription.Parsec+    Distribution.PackageDescription.Quirks+    Distribution.Parsec+    Distribution.Parsec.Error+    Distribution.Parsec.Newtypes+    Distribution.Parsec.Position+    Distribution.Parsec.Warning+    Distribution.Parsec.FieldLineStream+    Distribution.Fields+    Distribution.Fields.ConfVar+    Distribution.Fields.Field+    Distribution.Fields.Lexer+    Distribution.Fields.LexerMonad+    Distribution.Fields.ParseResult+    Distribution.Fields.Parser+    Distribution.Fields.Pretty++  -- Lens functionality+  exposed-modules:+    Distribution.Compat.Lens+    Distribution.Types.Lens+    Distribution.Types.Benchmark.Lens+    Distribution.Types.BuildInfo.Lens+    Distribution.Types.Executable.Lens+    Distribution.Types.ForeignLib.Lens+    Distribution.Types.GenericPackageDescription.Lens+    Distribution.Types.InstalledPackageInfo.Lens+    Distribution.Types.Library.Lens+    Distribution.Types.PackageDescription.Lens+    Distribution.Types.PackageId.Lens+    Distribution.Types.SetupBuildInfo.Lens+    Distribution.Types.SourceRepo.Lens+    Distribution.Types.TestSuite.Lens++  other-modules:+    Distribution.Backpack.PreExistingComponent+    Distribution.Backpack.ReadyComponent+    Distribution.Backpack.MixLink+    Distribution.Backpack.ModuleScope+    Distribution.Backpack.UnifyM+    Distribution.Backpack.Id+    Distribution.Utils.UnionFind+    Distribution.Utils.Base62+    Distribution.Compat.CopyFile+    Distribution.Compat.GetShortPathName+    Distribution.Compat.MonadFail+    Distribution.Compat.Prelude+    Distribution.Compat.SnocList+    Distribution.GetOpt+    Distribution.Lex+    Distribution.Utils.String+    Distribution.Simple.GHC.EnvironmentParser+    Distribution.Simple.GHC.Internal+    Distribution.Simple.GHC.ImplInfo+    Paths_Cabal++  if flag(bundled-binary-generic)+    other-modules:+      Distribution.Compat.Binary.Class+      Distribution.Compat.Binary.Generic++  default-language: Haskell2010+  other-extensions:+    BangPatterns+    CPP+    DefaultSignatures+    DeriveDataTypeable+    DeriveFoldable+    DeriveFunctor+    DeriveGeneric+    DeriveTraversable+    ExistentialQuantification+    FlexibleContexts+    FlexibleInstances+    GeneralizedNewtypeDeriving+    ImplicitParams+    KindSignatures+    NondecreasingIndentation+    OverloadedStrings+    RankNTypes+    RecordWildCards+    ScopedTypeVariables+    StandaloneDeriving+    Trustworthy+    TypeFamilies+    TypeOperators+    TypeSynonymInstances+    UndecidableInstances++  if impl(ghc >= 7.11)+    other-extensions: PatternSynonyms++-- Small, fast running tests.+test-suite unit-tests+  type: exitcode-stdio-1.0+  hs-source-dirs: tests+  other-modules:+    Test.Laws+    Test.QuickCheck.Utils+    UnitTests.Distribution.Compat.CreatePipe+    UnitTests.Distribution.Compat.Time+    UnitTests.Distribution.Compat.Graph+    UnitTests.Distribution.Simple.Glob+    UnitTests.Distribution.Simple.Program.Internal+    UnitTests.Distribution.Simple.Utils+    UnitTests.Distribution.SPDX+    UnitTests.Distribution.System+    UnitTests.Distribution.Types.GenericPackageDescription+    UnitTests.Distribution.Utils.Generic+    UnitTests.Distribution.Utils.NubList+    UnitTests.Distribution.Utils.ShortText+    UnitTests.Distribution.Version+  main-is: UnitTests.hs+  build-depends:+    array,+    base,+    bytestring,+    containers,+    directory,+    filepath,+    integer-logarithms >= 1.0.2 && <1.1,+    tasty >= 1.1.0.3 && < 1.2,+    tasty-hunit,+    tasty-quickcheck,+    tagged,+    temporary,+    text,+    pretty,+    QuickCheck >= 2.11.3 && < 2.12,+    Cabal+  ghc-options: -Wall+  default-language: Haskell2010++test-suite parser-tests+  type: exitcode-stdio-1.0+  hs-source-dirs: tests+  main-is: ParserTests.hs+  build-depends:+    base,+    base-compat >=0.10.4 && <0.11,+    bytestring,+    directory,+    filepath,+    tasty >= 1.1.0.3 && < 1.2,+    tasty-hunit,+    tasty-quickcheck,+    tasty-golden >=2.3.1.1 && <2.4,+    Diff >=0.3.4 && <0.4,+    Cabal+  ghc-options: -Wall+  default-language: Haskell2010++  if impl(ghc >= 7.8)+    build-depends:+      tree-diff      >= 0.0.1 && <0.1+    other-modules:+      Instances.TreeDiff+      Instances.TreeDiff.Language+      Instances.TreeDiff.SPDX+      Instances.TreeDiff.Version++test-suite check-tests+  type: exitcode-stdio-1.0+  hs-source-dirs: tests+  main-is: CheckTests.hs+  build-depends:+    base,+    bytestring,+    directory,+    filepath,+    tasty >= 1.1.0.3 && < 1.2,+    tasty-golden >=2.3.1.1 && <2.4,+    Diff >=0.3.4 && <0.4,+    Cabal+  ghc-options: -Wall+  default-language: Haskell2010++test-suite custom-setup-tests+  type: exitcode-stdio-1.0+  hs-source-dirs: tests/custom-setup+  main-is: CustomSetupTests.hs+  other-modules:+    CabalDoctestSetup+    IdrisSetup+  build-depends:+    Cabal,+    base,+    directory,+    filepath,+    process+  default-language: Haskell2010++test-suite hackage-tests+  type: exitcode-stdio-1.0+  main-is: HackageTests.hs++  -- TODO: need to get 01-index.tar on appveyor+  if os(windows)+    buildable: False++  hs-source-dirs: tests++  build-depends:+    base,+    Cabal,+    bytestring,+    deepseq,+    containers,+    directory,+    filepath++  build-depends:+    base-compat          >=0.10.4   && <0.11,+    base-orphans         >=0.6      && <0.9,+    optparse-applicative >=0.13.2.0 && <0.15,+    stm                  >=2.4.5.0  && <2.6,+    tar                  >=0.5.0.3  && <0.6++  if impl(ghc >= 7.8)+    build-depends:+      tree-diff      >= 0.0.1 && <0.1+    other-modules:+      Instances.TreeDiff+      Instances.TreeDiff.Language+      Instances.TreeDiff.SPDX+      Instances.TreeDiff.Version++  ghc-options: -Wall -rtsopts -threaded+  default-extensions: CPP+  default-language: Haskell2010
+ fixtures/Cabal-notab.format view
@@ -0,0 +1,675 @@+name:               Cabal+version:            2.5.0.0++-- cabal-fmt: no-tabular+copyright:          2003-2018, Cabal Development Team (see AUTHORS file)+license:            BSD3+license-file:       LICENSE+author:             Cabal Development Team <cabal-devel@haskell.org>+maintainer:         cabal-devel@haskell.org+homepage:           http://www.haskell.org/cabal/+bug-reports:        https://github.com/haskell/cabal/issues+synopsis:           A framework for packaging Haskell software+description:+  The Haskell Common Architecture for Building Applications and+  Libraries: a framework defining a common interface for authors to more+  easily build their Haskell applications in a portable way.+  .+  The Haskell Cabal is part of a larger infrastructure for distributing,+  organizing, and cataloging Haskell libraries and tools.++category:           Distribution+cabal-version:      >=1.10+build-type:         Simple++-- If we use a new Cabal feature, this needs to be changed to Custom so+-- we can bootstrap.++extra-source-files:+  ChangeLog.md+  doc/bugs-and-stability.rst+  doc/concepts-and-development.rst+  doc/conf.py+  doc/config-and-install.rst+  doc/developing-packages.rst+  doc/file-format-changelog.rst+  doc/images/Cabal-dark.png+  doc/index.rst+  doc/installing-packages.rst+  doc/intro.rst+  doc/misc.rst+  doc/nix-local-build-overview.rst+  doc/nix-local-build.rst+  doc/README.md+  doc/references.inc+  README.md+  tests/hackage/check.sh+  tests/hackage/download.sh+  tests/hackage/unpack.sh+  tests/misc/ghc-supported-languages.hs+  tests/ParserTests/errors/common1.cabal+  tests/ParserTests/errors/common1.errors+  tests/ParserTests/errors/common2.cabal+  tests/ParserTests/errors/common2.errors+  tests/ParserTests/errors/common3.cabal+  tests/ParserTests/errors/common3.errors+  tests/ParserTests/errors/forward-compat.cabal+  tests/ParserTests/errors/forward-compat.errors+  tests/ParserTests/errors/forward-compat2.cabal+  tests/ParserTests/errors/forward-compat2.errors+  tests/ParserTests/errors/forward-compat3.cabal+  tests/ParserTests/errors/forward-compat3.errors+  tests/ParserTests/errors/issue-5055-2.cabal+  tests/ParserTests/errors/issue-5055-2.errors+  tests/ParserTests/errors/issue-5055.cabal+  tests/ParserTests/errors/issue-5055.errors+  tests/ParserTests/errors/leading-comma-2.cabal+  tests/ParserTests/errors/leading-comma-2.errors+  tests/ParserTests/errors/leading-comma-2b.cabal+  tests/ParserTests/errors/leading-comma-2b.errors+  tests/ParserTests/errors/leading-comma-2c.cabal+  tests/ParserTests/errors/leading-comma-2c.errors+  tests/ParserTests/errors/leading-comma.cabal+  tests/ParserTests/errors/leading-comma.errors+  tests/ParserTests/errors/multiple-libs.cabal+  tests/ParserTests/errors/multiple-libs.errors+  tests/ParserTests/errors/noVersion.cabal+  tests/ParserTests/errors/noVersion.errors+  tests/ParserTests/errors/noVersion2.cabal+  tests/ParserTests/errors/noVersion2.errors+  tests/ParserTests/errors/range-ge-wild.cabal+  tests/ParserTests/errors/range-ge-wild.errors+  tests/ParserTests/errors/removed-fields.cabal+  tests/ParserTests/errors/removed-fields.errors+  tests/ParserTests/errors/spdx-1.cabal+  tests/ParserTests/errors/spdx-1.errors+  tests/ParserTests/errors/spdx-2.cabal+  tests/ParserTests/errors/spdx-2.errors+  tests/ParserTests/errors/spdx-3.cabal+  tests/ParserTests/errors/spdx-3.errors+  tests/ParserTests/ipi/Includes2.cabal+  tests/ParserTests/ipi/Includes2.expr+  tests/ParserTests/ipi/Includes2.format+  tests/ParserTests/ipi/internal-preprocessor-test.cabal+  tests/ParserTests/ipi/internal-preprocessor-test.expr+  tests/ParserTests/ipi/internal-preprocessor-test.format+  tests/ParserTests/ipi/issue-2276-ghc-9885.cabal+  tests/ParserTests/ipi/issue-2276-ghc-9885.expr+  tests/ParserTests/ipi/issue-2276-ghc-9885.format+  tests/ParserTests/ipi/transformers.cabal+  tests/ParserTests/ipi/transformers.expr+  tests/ParserTests/ipi/transformers.format+  tests/ParserTests/regressions/bad-glob-syntax.cabal+  tests/ParserTests/regressions/bad-glob-syntax.check+  tests/ParserTests/regressions/cc-options-with-optimization.cabal+  tests/ParserTests/regressions/cc-options-with-optimization.check+  tests/ParserTests/regressions/common-conditional.cabal+  tests/ParserTests/regressions/common-conditional.expr+  tests/ParserTests/regressions/common-conditional.format+  tests/ParserTests/regressions/common.cabal+  tests/ParserTests/regressions/common.expr+  tests/ParserTests/regressions/common.format+  tests/ParserTests/regressions/common2.cabal+  tests/ParserTests/regressions/common2.expr+  tests/ParserTests/regressions/common2.format+  tests/ParserTests/regressions/cxx-options-with-optimization.cabal+  tests/ParserTests/regressions/cxx-options-with-optimization.check+  tests/ParserTests/regressions/elif.cabal+  tests/ParserTests/regressions/elif.expr+  tests/ParserTests/regressions/elif.format+  tests/ParserTests/regressions/elif2.cabal+  tests/ParserTests/regressions/elif2.expr+  tests/ParserTests/regressions/elif2.format+  tests/ParserTests/regressions/encoding-0.8.cabal+  tests/ParserTests/regressions/encoding-0.8.expr+  tests/ParserTests/regressions/encoding-0.8.format+  tests/ParserTests/regressions/extensions-paths-5054.cabal+  tests/ParserTests/regressions/extensions-paths-5054.check+  tests/ParserTests/regressions/generics-sop.cabal+  tests/ParserTests/regressions/generics-sop.expr+  tests/ParserTests/regressions/generics-sop.format+  tests/ParserTests/regressions/ghc-option-j.cabal+  tests/ParserTests/regressions/ghc-option-j.check+  tests/ParserTests/regressions/haddock-api-2.18.1-check.cabal+  tests/ParserTests/regressions/haddock-api-2.18.1-check.check+  tests/ParserTests/regressions/hidden-main-lib.cabal+  tests/ParserTests/regressions/hidden-main-lib.expr+  tests/ParserTests/regressions/hidden-main-lib.format+  tests/ParserTests/regressions/issue-5055.cabal+  tests/ParserTests/regressions/issue-5055.expr+  tests/ParserTests/regressions/issue-5055.format+  tests/ParserTests/regressions/issue-774.cabal+  tests/ParserTests/regressions/issue-774.check+  tests/ParserTests/regressions/issue-774.expr+  tests/ParserTests/regressions/issue-774.format+  tests/ParserTests/regressions/jaeger-flamegraph.cabal+  tests/ParserTests/regressions/jaeger-flamegraph.expr+  tests/ParserTests/regressions/jaeger-flamegraph.format+  tests/ParserTests/regressions/leading-comma-2.cabal+  tests/ParserTests/regressions/leading-comma-2.expr+  tests/ParserTests/regressions/leading-comma-2.format+  tests/ParserTests/regressions/leading-comma.cabal+  tests/ParserTests/regressions/leading-comma.expr+  tests/ParserTests/regressions/leading-comma.format+  tests/ParserTests/regressions/MiniAgda.cabal+  tests/ParserTests/regressions/MiniAgda.check+  tests/ParserTests/regressions/multiple-libs-2.cabal+  tests/ParserTests/regressions/multiple-libs-2.check+  tests/ParserTests/regressions/multiple-libs-2.expr+  tests/ParserTests/regressions/multiple-libs-2.format+  tests/ParserTests/regressions/nothing-unicode.cabal+  tests/ParserTests/regressions/nothing-unicode.check+  tests/ParserTests/regressions/nothing-unicode.expr+  tests/ParserTests/regressions/nothing-unicode.format+  tests/ParserTests/regressions/noVersion.cabal+  tests/ParserTests/regressions/noVersion.expr+  tests/ParserTests/regressions/noVersion.format+  tests/ParserTests/regressions/Octree-0.5.cabal+  tests/ParserTests/regressions/Octree-0.5.expr+  tests/ParserTests/regressions/Octree-0.5.format+  tests/ParserTests/regressions/pre-1.6-glob.cabal+  tests/ParserTests/regressions/pre-1.6-glob.check+  tests/ParserTests/regressions/pre-2.4-globstar.cabal+  tests/ParserTests/regressions/pre-2.4-globstar.check+  tests/ParserTests/regressions/shake.cabal+  tests/ParserTests/regressions/shake.expr+  tests/ParserTests/regressions/shake.format+  tests/ParserTests/regressions/spdx-1.cabal+  tests/ParserTests/regressions/spdx-1.expr+  tests/ParserTests/regressions/spdx-1.format+  tests/ParserTests/regressions/spdx-2.cabal+  tests/ParserTests/regressions/spdx-2.expr+  tests/ParserTests/regressions/spdx-2.format+  tests/ParserTests/regressions/spdx-3.cabal+  tests/ParserTests/regressions/spdx-3.expr+  tests/ParserTests/regressions/spdx-3.format+  tests/ParserTests/regressions/th-lift-instances.cabal+  tests/ParserTests/regressions/th-lift-instances.expr+  tests/ParserTests/regressions/th-lift-instances.format+  tests/ParserTests/regressions/wl-pprint-indef.cabal+  tests/ParserTests/regressions/wl-pprint-indef.expr+  tests/ParserTests/regressions/wl-pprint-indef.format+  tests/ParserTests/warnings/bom.cabal+  tests/ParserTests/warnings/bool.cabal+  tests/ParserTests/warnings/deprecatedfield.cabal+  tests/ParserTests/warnings/doubledash.cabal+  tests/ParserTests/warnings/extratestmodule.cabal+  tests/ParserTests/warnings/gluedop.cabal+  tests/ParserTests/warnings/multiplesingular.cabal+  tests/ParserTests/warnings/nbsp.cabal+  tests/ParserTests/warnings/newsyntax.cabal+  tests/ParserTests/warnings/oldsyntax.cabal+  tests/ParserTests/warnings/subsection.cabal+  tests/ParserTests/warnings/tab.cabal+  tests/ParserTests/warnings/trailingfield.cabal+  tests/ParserTests/warnings/unknownfield.cabal+  tests/ParserTests/warnings/unknownsection.cabal+  tests/ParserTests/warnings/utf8.cabal+  tests/ParserTests/warnings/versiontag.cabal+  tests/README.md++-- Generated with 'make gen-extra-source-files'+-- Do NOT edit this section manually; instead, run the script.+-- BEGIN gen-extra-source-files+-- END gen-extra-source-files++source-repository head+  type:     git+  location: https://github.com/haskell/cabal/+  subdir:   Cabal++flag bundled-binary-generic+  default: False++library+  build-depends:+      array >=0.4.0.1 && <0.6+    , base >=4.6 && <5+    , bytestring >=0.10.0.0 && <0.11+    , containers >=0.5.0.0 && <0.7+    , deepseq >=1.3.0.1 && <1.5+    , directory >=1.2 && <1.4+    , filepath >=1.3.0.1 && <1.5+    , pretty >=1.1.1 && <1.2+    , process >=1.1.0.2 && <1.7+    , time >=1.4.0.1 && <1.10++  if flag(bundled-binary-generic)+    build-depends: binary >=0.5.1.1 && <0.7++  else+    build-depends: binary >=0.7 && <0.9++  if os(windows)+    build-depends: Win32 >=2.3.0.0 && <2.9++  else+    build-depends: unix >=2.6.0.0 && <2.8++  ghc-options:      -Wall -fno-ignore-asserts -fwarn-tabs++  if impl(ghc >=8.0)+    ghc-options:+      -Wcompat -Wnoncanonical-monad-instances+      -Wnoncanonical-monadfail-instances++  exposed-modules:+    Distribution.Backpack+    Distribution.Backpack.ComponentsGraph+    Distribution.Backpack.Configure+    Distribution.Backpack.ConfiguredComponent+    Distribution.Backpack.DescribeUnitId+    Distribution.Backpack.FullUnitId+    Distribution.Backpack.LinkedComponent+    Distribution.Backpack.ModSubst+    Distribution.Backpack.ModuleShape+    Distribution.Backpack.PreModuleShape+    Distribution.CabalSpecVersion+    Distribution.Compat.Binary+    Distribution.Compat.CreatePipe+    Distribution.Compat.Directory+    Distribution.Compat.DList+    Distribution.Compat.Environment+    Distribution.Compat.Exception+    Distribution.Compat.Graph+    Distribution.Compat.Internal.TempFile+    Distribution.Compat.Newtype+    Distribution.Compat.Prelude.Internal+    Distribution.Compat.Semigroup+    Distribution.Compat.Stack+    Distribution.Compat.Time+    Distribution.Compiler+    Distribution.InstalledPackageInfo+    Distribution.License+    Distribution.Make+    Distribution.ModuleName+    Distribution.Package+    Distribution.PackageDescription+    Distribution.PackageDescription.Check+    Distribution.PackageDescription.Configuration+    Distribution.PackageDescription.PrettyPrint+    Distribution.PackageDescription.Utils+    Distribution.Pretty+    Distribution.ReadE+    Distribution.Simple+    Distribution.Simple.Bench+    Distribution.Simple.Build+    Distribution.Simple.Build.Macros+    Distribution.Simple.Build.PathsModule+    Distribution.Simple.BuildPaths+    Distribution.Simple.BuildTarget+    Distribution.Simple.BuildToolDepends+    Distribution.Simple.CCompiler+    Distribution.Simple.Command+    Distribution.Simple.Compiler+    Distribution.Simple.Configure+    Distribution.Simple.Doctest+    Distribution.Simple.Flag+    Distribution.Simple.GHC+    Distribution.Simple.GHCJS+    Distribution.Simple.Glob+    Distribution.Simple.Haddock+    Distribution.Simple.HaskellSuite+    Distribution.Simple.Hpc+    Distribution.Simple.Install+    Distribution.Simple.InstallDirs+    Distribution.Simple.LocalBuildInfo+    Distribution.Simple.PackageIndex+    Distribution.Simple.PreProcess+    Distribution.Simple.PreProcess.Unlit+    Distribution.Simple.Program+    Distribution.Simple.Program.Ar+    Distribution.Simple.Program.Builtin+    Distribution.Simple.Program.Db+    Distribution.Simple.Program.Find+    Distribution.Simple.Program.GHC+    Distribution.Simple.Program.HcPkg+    Distribution.Simple.Program.Hpc+    Distribution.Simple.Program.Internal+    Distribution.Simple.Program.Ld+    Distribution.Simple.Program.ResponseFile+    Distribution.Simple.Program.Run+    Distribution.Simple.Program.Script+    Distribution.Simple.Program.Strip+    Distribution.Simple.Program.Types+    Distribution.Simple.Register+    Distribution.Simple.Setup+    Distribution.Simple.SrcDist+    Distribution.Simple.Test+    Distribution.Simple.Test.ExeV10+    Distribution.Simple.Test.LibV09+    Distribution.Simple.Test.Log+    Distribution.Simple.UHC+    Distribution.Simple.UserHooks+    Distribution.Simple.Utils+    Distribution.SPDX+    Distribution.SPDX.License+    Distribution.SPDX.LicenseExceptionId+    Distribution.SPDX.LicenseExpression+    Distribution.SPDX.LicenseId+    Distribution.SPDX.LicenseListVersion+    Distribution.SPDX.LicenseReference+    Distribution.System+    Distribution.TestSuite+    Distribution.Text+    Distribution.Types.AbiDependency+    Distribution.Types.AbiHash+    Distribution.Types.AnnotatedId+    Distribution.Types.Benchmark+    Distribution.Types.BenchmarkInterface+    Distribution.Types.BenchmarkType+    Distribution.Types.BuildInfo+    Distribution.Types.BuildType+    Distribution.Types.Component+    Distribution.Types.ComponentId+    Distribution.Types.ComponentInclude+    Distribution.Types.ComponentLocalBuildInfo+    Distribution.Types.ComponentName+    Distribution.Types.ComponentRequestedSpec+    Distribution.Types.Condition+    Distribution.Types.CondTree+    Distribution.Types.Dependency+    Distribution.Types.DependencyMap+    Distribution.Types.Executable+    Distribution.Types.ExecutableScope+    Distribution.Types.ExeDependency+    Distribution.Types.ExposedModule+    Distribution.Types.ForeignLib+    Distribution.Types.ForeignLibOption+    Distribution.Types.ForeignLibType+    Distribution.Types.GenericPackageDescription+    Distribution.Types.GivenComponent+    Distribution.Types.HookedBuildInfo+    Distribution.Types.IncludeRenaming+    Distribution.Types.InstalledPackageInfo+    Distribution.Types.InstalledPackageInfo.FieldGrammar+    Distribution.Types.LegacyExeDependency+    Distribution.Types.Library+    Distribution.Types.LibraryName+    Distribution.Types.LibraryVisibility+    Distribution.Types.LocalBuildInfo+    Distribution.Types.Mixin+    Distribution.Types.Module+    Distribution.Types.ModuleReexport+    Distribution.Types.ModuleRenaming+    Distribution.Types.MungedPackageId+    Distribution.Types.MungedPackageName+    Distribution.Types.PackageDescription+    Distribution.Types.PackageId+    Distribution.Types.PackageName+    Distribution.Types.PackageVersionConstraint+    Distribution.Types.PkgconfigDependency+    Distribution.Types.PkgconfigName+    Distribution.Types.SetupBuildInfo+    Distribution.Types.SourceRepo+    Distribution.Types.TargetInfo+    Distribution.Types.TestSuite+    Distribution.Types.TestSuiteInterface+    Distribution.Types.TestType+    Distribution.Types.UnitId+    Distribution.Types.UnqualComponentName+    Distribution.Types.Version+    Distribution.Types.VersionInterval+    Distribution.Types.VersionRange+    Distribution.Utils.Generic+    Distribution.Utils.IOData+    Distribution.Utils.LogProgress+    Distribution.Utils.MapAccum+    Distribution.Utils.NubList+    Distribution.Utils.Progress+    Distribution.Utils.ShortText+    Distribution.Verbosity+    Distribution.Version+    Language.Haskell.Extension++  -- Parsec parser-related modules+  build-depends:+      mtl >=2.1 && <2.3+    , parsec >=3.1.13.0 && <3.2+    , text >=1.2.3.0 && <1.3+    , transformers >=0.3 && <0.4 || >=0.4.1.0 && <0.6++  -- transformers-0.4.0.0 doesn't have record syntax e.g. for Identity+  -- See also https://github.com/ekmett/transformers-compat/issues/35+  exposed-modules:+    Distribution.Compat.CharParsing+    Distribution.Compat.Parsing+    Distribution.FieldGrammar+    Distribution.FieldGrammar.Class+    Distribution.FieldGrammar.FieldDescrs+    Distribution.FieldGrammar.Parsec+    Distribution.FieldGrammar.Pretty+    Distribution.Fields+    Distribution.Fields.ConfVar+    Distribution.Fields.Field+    Distribution.Fields.Lexer+    Distribution.Fields.LexerMonad+    Distribution.Fields.Parser+    Distribution.Fields.ParseResult+    Distribution.Fields.Pretty+    Distribution.PackageDescription.FieldGrammar+    Distribution.PackageDescription.Parsec+    Distribution.PackageDescription.Quirks+    Distribution.Parsec+    Distribution.Parsec.Error+    Distribution.Parsec.FieldLineStream+    Distribution.Parsec.Newtypes+    Distribution.Parsec.Position+    Distribution.Parsec.Warning++  -- Lens functionality+  exposed-modules:+    Distribution.Compat.Lens+    Distribution.Types.Benchmark.Lens+    Distribution.Types.BuildInfo.Lens+    Distribution.Types.Executable.Lens+    Distribution.Types.ForeignLib.Lens+    Distribution.Types.GenericPackageDescription.Lens+    Distribution.Types.InstalledPackageInfo.Lens+    Distribution.Types.Lens+    Distribution.Types.Library.Lens+    Distribution.Types.PackageDescription.Lens+    Distribution.Types.PackageId.Lens+    Distribution.Types.SetupBuildInfo.Lens+    Distribution.Types.SourceRepo.Lens+    Distribution.Types.TestSuite.Lens++  other-modules:+    Distribution.Backpack.Id+    Distribution.Backpack.MixLink+    Distribution.Backpack.ModuleScope+    Distribution.Backpack.PreExistingComponent+    Distribution.Backpack.ReadyComponent+    Distribution.Backpack.UnifyM+    Distribution.Compat.CopyFile+    Distribution.Compat.GetShortPathName+    Distribution.Compat.MonadFail+    Distribution.Compat.Prelude+    Distribution.Compat.SnocList+    Distribution.GetOpt+    Distribution.Lex+    Distribution.Simple.GHC.EnvironmentParser+    Distribution.Simple.GHC.ImplInfo+    Distribution.Simple.GHC.Internal+    Distribution.Utils.Base62+    Distribution.Utils.String+    Distribution.Utils.UnionFind+    Paths_Cabal++  if flag(bundled-binary-generic)+    other-modules:+      Distribution.Compat.Binary.Class+      Distribution.Compat.Binary.Generic++  default-language: Haskell2010+  other-extensions:+    BangPatterns+    CPP+    DefaultSignatures+    DeriveDataTypeable+    DeriveFoldable+    DeriveFunctor+    DeriveGeneric+    DeriveTraversable+    ExistentialQuantification+    FlexibleContexts+    FlexibleInstances+    GeneralizedNewtypeDeriving+    ImplicitParams+    KindSignatures+    NondecreasingIndentation+    OverloadedStrings+    RankNTypes+    RecordWildCards+    ScopedTypeVariables+    StandaloneDeriving+    Trustworthy+    TypeFamilies+    TypeOperators+    TypeSynonymInstances+    UndecidableInstances++  if impl(ghc >=7.11)+    other-extensions: PatternSynonyms++-- Small, fast running tests.+test-suite unit-tests+  type:             exitcode-stdio-1.0+  hs-source-dirs:   tests+  other-modules:+    Test.Laws+    Test.QuickCheck.Utils+    UnitTests.Distribution.Compat.CreatePipe+    UnitTests.Distribution.Compat.Graph+    UnitTests.Distribution.Compat.Time+    UnitTests.Distribution.Simple.Glob+    UnitTests.Distribution.Simple.Program.Internal+    UnitTests.Distribution.Simple.Utils+    UnitTests.Distribution.SPDX+    UnitTests.Distribution.System+    UnitTests.Distribution.Types.GenericPackageDescription+    UnitTests.Distribution.Utils.Generic+    UnitTests.Distribution.Utils.NubList+    UnitTests.Distribution.Utils.ShortText+    UnitTests.Distribution.Version++  main-is:          UnitTests.hs+  build-depends:+      array+    , base+    , bytestring+    , Cabal+    , containers+    , directory+    , filepath+    , integer-logarithms >=1.0.2 && <1.1+    , pretty+    , QuickCheck >=2.11.3 && <2.12+    , tagged+    , tasty >=1.1.0.3 && <1.2+    , tasty-hunit+    , tasty-quickcheck+    , temporary+    , text++  ghc-options:      -Wall+  default-language: Haskell2010++test-suite parser-tests+  type:             exitcode-stdio-1.0+  hs-source-dirs:   tests+  main-is:          ParserTests.hs+  build-depends:+      base+    , base-compat >=0.10.4 && <0.11+    , bytestring+    , Cabal+    , Diff >=0.3.4 && <0.4+    , directory+    , filepath+    , tasty >=1.1.0.3 && <1.2+    , tasty-golden >=2.3.1.1 && <2.4+    , tasty-hunit+    , tasty-quickcheck++  ghc-options:      -Wall+  default-language: Haskell2010++  if impl(ghc >=7.8)+    build-depends: tree-diff >=0.0.1 && <0.1+    other-modules:+      Instances.TreeDiff+      Instances.TreeDiff.Language+      Instances.TreeDiff.SPDX+      Instances.TreeDiff.Version++test-suite check-tests+  type:             exitcode-stdio-1.0+  hs-source-dirs:   tests+  main-is:          CheckTests.hs+  build-depends:+      base+    , bytestring+    , Cabal+    , Diff >=0.3.4 && <0.4+    , directory+    , filepath+    , tasty >=1.1.0.3 && <1.2+    , tasty-golden >=2.3.1.1 && <2.4++  ghc-options:      -Wall+  default-language: Haskell2010++test-suite custom-setup-tests+  type:             exitcode-stdio-1.0+  hs-source-dirs:   tests/custom-setup+  main-is:          CustomSetupTests.hs+  other-modules:+    CabalDoctestSetup+    IdrisSetup++  build-depends:+      base+    , Cabal+    , directory+    , filepath+    , process++  default-language: Haskell2010++test-suite hackage-tests+  type:               exitcode-stdio-1.0+  main-is:            HackageTests.hs++  -- TODO: need to get 01-index.tar on appveyor+  if os(windows)+    buildable: False++  hs-source-dirs:     tests+  build-depends:+      base+    , bytestring+    , Cabal+    , containers+    , deepseq+    , directory+    , filepath++  build-depends:+      base-compat >=0.10.4 && <0.11+    , base-orphans >=0.6 && <0.9+    , optparse-applicative >=0.13.2.0 && <0.15+    , stm >=2.4.5.0 && <2.6+    , tar >=0.5.0.3 && <0.6++  if impl(ghc >=7.8)+    build-depends: tree-diff >=0.0.1 && <0.1+    other-modules:+      Instances.TreeDiff+      Instances.TreeDiff.Language+      Instances.TreeDiff.SPDX+      Instances.TreeDiff.Version++  ghc-options:        -Wall -rtsopts -threaded+  default-extensions: CPP+  default-language:   Haskell2010
fixtures/cabal-fmt.format view
@@ -11,11 +11,11 @@   -- build depends will be in   -- a nice tabular format   build-depends:-    , base        >=4.11     && <4.13+    , base        >=4.11      && <4.13     , bytestring     , Cabal       ^>=2.5     , containers  ^>=0.5.11.0 || ^>=0.6.0.1-    , pretty      ^>=1.1.3.6+    , pretty      >=1.1.3.6   && <1.2    -- extensions will be sorted   other-extensions:
fixtures/simple-example.cabal view
@@ -57,6 +57,11 @@   build-depends: foo <2   build-depends: abc <1, def <1, ghj <2 +  -- build-tool-depends are formatted like build-depends+  build-tool-depends: happy:happy++  build-tool-depends: happy:happy >=1, alex:alex >=1+ test-suite doctests   type:                exitcode-stdio-1.0   main-is:             doctests.hs
fixtures/simple-example.format view
@@ -56,8 +56,8 @@   if impl(hugs)     build-depends: unbuildable <0     build-depends:-        unbuildable <0-      , unbuildable2 <0+        unbuildable   <0+      , unbuildable2  <0    -- full interval   build-depends:      text@@ -66,12 +66,18 @@     , pretty    -- only upper bound-  build-depends:      foo ==0.*+  build-depends:      foo <1   build-depends:      foo <2   build-depends:       abc  <1     , def  <1     , ghj  <2++  -- build-tool-depends are formatted like build-depends+  build-tool-depends: happy:happy+  build-tool-depends:+      alex:alex    >=1+    , happy:happy  >=1  test-suite doctests   type:             exitcode-stdio-1.0
+ fixtures/tree-diff.cabal view
@@ -0,0 +1,190 @@+cabal-version:      2.2+name:               tree-diff+version:            0.2.2+synopsis:           Diffing of (expression) trees.+category:           Data, Testing+description:+  Common diff algorithm works on list structures:+  .+  @+  diff :: Eq a => [a] -> [a] -> [Edit a]+  @+  .+  This package works on trees.+  .+  @+  treeDiff :: Eq a => Tree a -> Tree a -> Edit (EditTree a)+  @+  .+  This package also provides a way to diff arbitrary ADTs,+  using @Generics@-derivable helpers.+  .+  This package differs from <http://hackage.haskell.org/package/gdiff gdiff>,+  in a two ways: @tree-diff@ doesn't have patch function,+  and the "edit-script" is a tree itself, which is useful for pretty-printing.+  .+  @+  >>> prettyEditExpr $ ediff (Foo 42 [True, False] "old") (Foo 42 [False, False, True] "new")+  Foo+  \  {fooBool = [-True, +False, False, +True],+  \   fooInt = 42,+  \   fooString = -"old" +"new"}+  @++homepage:           https://github.com/phadej/tree-diff+bug-reports:        https://github.com/phadej/tree-diff/issues+license:            GPL-2.0-or-later+license-file:       LICENSE+author:             Oleg Grenrus <oleg.grenrus@iki.fi>+maintainer:         Oleg.Grenrus <oleg.grenrus@iki.fi>+copyright:          (c) 2017-2021 Oleg Grenrus+build-type:         Simple+extra-source-files:+  ChangeLog.md+  README.md++tested-with:+    GHC ==7.4.2+     || ==7.6.3+     || ==7.8.4+     || ==7.10.3+     || ==8.0.2+     || ==8.2.2+     || ==8.4.4+     || ==8.6.5+     || ==8.8.4+     || ==8.10.4+     || ==9.0.2+     || ==9.2.4+     || ==9.4.1+  , GHCJS ==8.4++extra-source-files:+  fixtures/exfoo.expr+  fixtures/MyInt1.expr+  fixtures/MyInt2.expr+  fixtures/MyInt3.expr+  fixtures/Positional.expr++source-repository head+  type:     git+  location: https://github.com/phadej/tree-diff.git++library+  exposed-modules:+    Data.TreeDiff+    Data.TreeDiff.Class+    Data.TreeDiff.Expr+    Data.TreeDiff.Golden+    Data.TreeDiff.List+    Data.TreeDiff.OMap+    Data.TreeDiff.Parser+    Data.TreeDiff.Pretty+    Data.TreeDiff.QuickCheck+    Data.TreeDiff.Tree++  -- GHC boot libraries+  build-depends:+    , base        >=4.5      && <4.18+    , bytestring  ^>=0.9.2.1 || ^>=0.10.0.2 || ^>=0.11.0.0+    , containers  ^>=0.4.2.1 || ^>=0.5.0.0 || ^>=0.6.0.1+    , deepseq     ^>=1.3.0.0 || ^>=1.4.0.0+    , parsec      ^>=3.1.13.0+    , pretty      ^>=1.1.1.0+    , text        ^>=1.2.3.0 || ^>=2.0+    , time        ^>=1.4      || ^>=1.5.0.1  || ^>=1.6.0.1  || ^>=1.8.0.2 || >=1.9.3 && <1.13++  build-depends:+    , aeson                 ^>=1.4.6.0 || ^>=1.5.6.0 || ^>=2.0.0.0 || ^>=2.1.0.0+    , ansi-terminal         >=0.10       && <0.12+    , ansi-wl-pprint        ^>=0.6.8.2+    , base-compat           ^>=0.10.5 || ^>=0.11.0 || ^>=0.12.0+    , bytestring-builder    ^>=0.10.8.2.0+    , hashable              ^>=1.2.7.0 || ^>=1.3.0.0 || ^>=1.4.0.1+    , parsers               ^>=0.12.10+    , primitive             ^>=0.7.1.0+    , QuickCheck            ^>=2.14.2+    , scientific            ^>=0.3.6.2+    , semialign             ^>=1.2.0.1+    , strict                ^>=0.4.0.1+    , tagged                ^>=0.8.6+    , these                 ^>=1.1.1.1+    , unordered-containers  ^>=0.2.8.0+    , uuid-types            ^>=1.0.3+    , vector                ^>=0.12.0.0 || ^>=0.13.0.0++  if impl(ghc <7.5)+    build-depends: ghc-prim++  if !impl(ghc >=8.0)+    build-depends: semigroups >=0.19.1 && <0.21++  if !impl(ghc >=7.8)+    build-depends: generic-deriving >=1.13.1 && <1.15++  if !impl(ghc >=7.10)+    build-depends:+      , nats          ^>=1.1.2+      , transformers  ^>=0.3.0.0 || ^>=0.4.2.0 || ^>=0.5.2.0+      , void          ^>=0.7.3++  other-extensions:+    CPP+    ConstraintKinds+    DefaultSignatures+    FlexibleContexts+    GADTs+    RankNTypes+    ScopedTypeVariables+    TypeOperators++  hs-source-dirs:   src+  default-language: Haskell2010++test-suite tree-diff-test+  default-language: Haskell2010+  type:             exitcode-stdio-1.0+  main-is:          Tests.hs+  hs-source-dirs:   tests src-diff+  ghc-options:      -Wall -threaded+  other-modules:    RefDiffBy++  -- dependencies from library+  build-depends:+    , ansi-terminal+    , ansi-wl-pprint+    , base+    , base-compat+    , parsec+    , primitive+    , QuickCheck+    , tagged+    , tree-diff++  if impl(ghc <7.5)+    build-depends: ghc-prim++  -- extra dependencies+  build-depends:+    , tasty             ^>=1.2 || ^>=1.3.1 || ^>=1.4.2+    , tasty-golden      ^>=2.3.1.1+    , tasty-quickcheck  ^>=0.10.1+    , trifecta          >=2       && <2.2++benchmark tree-diff-bench+  default-language: Haskell2010+  type:             exitcode-stdio-1.0+  main-is:          tree-diff-bench.hs+  hs-source-dirs:   bench+  ghc-options:      -Wall -threaded++  -- dependencies from library+  build-depends:+    , base+    , deepseq+    , tree-diff++  -- extra dependencies+  build-depends:+    , criterion  ^>=1.6.0.0+    , Diff       ^>=0.4.0
+ fixtures/tree-diff.format view
@@ -0,0 +1,190 @@+cabal-version:      2.2+name:               tree-diff+version:            0.2.2+synopsis:           Diffing of (expression) trees.+category:           Data, Testing+description:+  Common diff algorithm works on list structures:+  .+  @+  diff :: Eq a => [a] -> [a] -> [Edit a]+  @+  .+  This package works on trees.+  .+  @+  treeDiff :: Eq a => Tree a -> Tree a -> Edit (EditTree a)+  @+  .+  This package also provides a way to diff arbitrary ADTs,+  using @Generics@-derivable helpers.+  .+  This package differs from <http://hackage.haskell.org/package/gdiff gdiff>,+  in a two ways: @tree-diff@ doesn't have patch function,+  and the "edit-script" is a tree itself, which is useful for pretty-printing.+  .+  @+  >>> prettyEditExpr $ ediff (Foo 42 [True, False] "old") (Foo 42 [False, False, True] "new")+  Foo+  \  {fooBool = [-True, +False, False, +True],+  \   fooInt = 42,+  \   fooString = -"old" +"new"}+  @++homepage:           https://github.com/phadej/tree-diff+bug-reports:        https://github.com/phadej/tree-diff/issues+license:            GPL-2.0-or-later+license-file:       LICENSE+author:             Oleg Grenrus <oleg.grenrus@iki.fi>+maintainer:         Oleg.Grenrus <oleg.grenrus@iki.fi>+copyright:          (c) 2017-2021 Oleg Grenrus+build-type:         Simple+extra-source-files:+  ChangeLog.md+  README.md++tested-with:+    GHC ==7.4.2+     || ==7.6.3+     || ==7.8.4+     || ==7.10.3+     || ==8.0.2+     || ==8.2.2+     || ==8.4.4+     || ==8.6.5+     || ==8.8.4+     || ==8.10.4+     || ==9.0.2+     || ==9.2.4+     || ==9.4.1+  , GHCJS ==8.4++extra-source-files:+  fixtures/exfoo.expr+  fixtures/MyInt1.expr+  fixtures/MyInt2.expr+  fixtures/MyInt3.expr+  fixtures/Positional.expr++source-repository head+  type:     git+  location: https://github.com/phadej/tree-diff.git++library+  exposed-modules:+    Data.TreeDiff+    Data.TreeDiff.Class+    Data.TreeDiff.Expr+    Data.TreeDiff.Golden+    Data.TreeDiff.List+    Data.TreeDiff.OMap+    Data.TreeDiff.Parser+    Data.TreeDiff.Pretty+    Data.TreeDiff.QuickCheck+    Data.TreeDiff.Tree++  -- GHC boot libraries+  build-depends:+    , base        >=4.5       && <4.18+    , bytestring  ^>=0.9.2.1  || ^>=0.10.0.2 || ^>=0.11.0.0+    , containers  ^>=0.4.2.1  || ^>=0.5.0.0  || ^>=0.6.0.1+    , deepseq     ^>=1.3.0.0  || ^>=1.4.0.0+    , parsec      ^>=3.1.13.0+    , pretty      ^>=1.1.1.0+    , text        ^>=1.2.3.0  || ^>=2.0+    , time        ^>=1.4      || ^>=1.5.0.1  || ^>=1.6.0.1  || ^>=1.8.0.2 || >=1.9.3 && <1.12 || ^>=1.12++  build-depends:+    , aeson                 ^>=1.4.6.0    || ^>=1.5.6.0  || ^>=2.0.0.0 || ^>=2.1.0.0+    , ansi-terminal         >=0.10        && <0.12+    , ansi-wl-pprint        ^>=0.6.8.2+    , base-compat           ^>=0.10.5     || ^>=0.11.0   || ^>=0.12.0+    , bytestring-builder    ^>=0.10.8.2.0+    , hashable              ^>=1.2.7.0    || ^>=1.3.0.0  || ^>=1.4.0.1+    , parsers               ^>=0.12.10+    , primitive             ^>=0.7.1.0+    , QuickCheck            ^>=2.14.2+    , scientific            ^>=0.3.6.2+    , semialign             ^>=1.2.0.1+    , strict                ^>=0.4.0.1+    , tagged                ^>=0.8.6+    , these                 ^>=1.1.1.1+    , unordered-containers  ^>=0.2.8.0+    , uuid-types            ^>=1.0.3+    , vector                ^>=0.12.0.0   || ^>=0.13.0.0++  if impl(ghc <7.5)+    build-depends: ghc-prim++  if !impl(ghc >=8.0)+    build-depends: semigroups >=0.19.1 && <0.21++  if !impl(ghc >=7.8)+    build-depends: generic-deriving >=1.13.1 && <1.15++  if !impl(ghc >=7.10)+    build-depends:+      , nats          ^>=1.1.2+      , transformers  ^>=0.3.0.0 || ^>=0.4.2.0 || ^>=0.5.2.0+      , void          ^>=0.7.3++  other-extensions:+    CPP+    ConstraintKinds+    DefaultSignatures+    FlexibleContexts+    GADTs+    RankNTypes+    ScopedTypeVariables+    TypeOperators++  hs-source-dirs:   src+  default-language: Haskell2010++test-suite tree-diff-test+  default-language: Haskell2010+  type:             exitcode-stdio-1.0+  main-is:          Tests.hs+  hs-source-dirs:   tests src-diff+  ghc-options:      -Wall -threaded+  other-modules:    RefDiffBy++  -- dependencies from library+  build-depends:+    , ansi-terminal+    , ansi-wl-pprint+    , base+    , base-compat+    , parsec+    , primitive+    , QuickCheck+    , tagged+    , tree-diff++  if impl(ghc <7.5)+    build-depends: ghc-prim++  -- extra dependencies+  build-depends:+    , tasty             ^>=1.2     || ^>=1.3.1 || ^>=1.4.2+    , tasty-golden      ^>=2.3.1.1+    , tasty-quickcheck  ^>=0.10.1+    , trifecta          >=2        && <2.2++benchmark tree-diff-bench+  default-language: Haskell2010+  type:             exitcode-stdio-1.0+  main-is:          tree-diff-bench.hs+  hs-source-dirs:   bench+  ghc-options:      -Wall -threaded++  -- dependencies from library+  build-depends:+    , base+    , deepseq+    , tree-diff++  -- extra dependencies+  build-depends:+    , criterion  ^>=1.6.0.0+    , Diff       ^>=0.4.0
+ fixtures/with-sublibs.cabal view
@@ -0,0 +1,12 @@+cabal-version: 3.0+name:          with-sublibs+version:       1++library+  hs-source-dirs:     src+  default-language:   Haskell2010+  build-depends:+    test1,+    test1:sub,+    test2 >=1 && <3,+    test2:sub >=2 && <4
+ fixtures/with-sublibs.format view
@@ -0,0 +1,11 @@+Up to date+cabal-version: 3.0+name:          with-sublibs+version:       1++library+  hs-source-dirs:   src+  default-language: Haskell2010+  build-depends:+    , test1:{test1, sub}+    , test2:{test2, sub}  >=2 && <3
+ src-interval/VersionInterval.hs view
@@ -0,0 +1,444 @@+{-# LANGUAGE BangPatterns #-}++-- |+--+-- Author:          Oleg Grenrus <oleg.grenrus@iki.fi>+-- SPDX-License-Id: GPL-2.0-or-later+--+-- This module implements a view of a 'VersionRange' as a finite+-- list of separated version intervals.+--+-- In conversion from and to 'VersionRange' it makes some effort to+-- preserve the caret operator @^>=x.y@.  This constraint a priori+-- specifies the same interval as @==x.y.*@, but indicates that newer+-- versions could be acceptable (@allow-newer: ^@).+--+module VersionInterval (+    -- * Version intervals+    VersionIntervals,+    unVersionIntervals,++    -- * Conversions+    toVersionIntervals,+    fromVersionIntervals,+    ConversionProblem (..),++    -- ** Normalisation+    normaliseVersionRange,++    -- * Version intervals view+    VersionInterval (..),+    LB(..),+    MB(..),+    UB(..),+    Bound(..),++    -- * For testing+    validVersionInterval,+    validVersionIntervals,+    intersectInterval,+    stage1, stage2, stage3,+)  where++import Control.Applicative (liftA2)+import Control.Monad       (join)+import Data.List           (sortOn)+import Data.List.NonEmpty  (NonEmpty (..), cons)+import Data.Maybe          (catMaybes)++import Distribution.Types.Version+       (Version, mkVersion, validVersion, version0, versionNumbers)+import Distribution.Types.VersionRange.Internal+       (VersionRange, VersionRangeF (..), cataVersionRange, earlierVersion,+       intersectVersionRanges, majorBoundVersion, majorUpperBound, noVersion,+       orLaterVersion, thisVersion, unionVersionRanges)++singleton :: a -> NonEmpty a+singleton x = x :| []++-------------------------------------------------------------------------------+-- Data+-------------------------------------------------------------------------------++-- | A complementary representation of a 'VersionRange'. Instead of a boolean+-- version predicate it uses an increasing sequence of non-overlapping,+-- non-empty intervals.+--+-- This version is different than in @Cabal-3.8@ and previous,+-- as it tries to preserve @^>=@ version ranges under default and @transformCaretUpper@ semantics.+-- Slighly simplifying, 'normalizeVersionRange' shouldn't destroy @^>=@ in version range expressions.+--+newtype VersionIntervals = VersionIntervals [VersionInterval]+  deriving (Eq, Show)++-- | Inspect the list of version intervals.+--+unVersionIntervals :: VersionIntervals -> [VersionInterval]+unVersionIntervals (VersionIntervals is) = is++-- | Version interval.+--+-- Invariants:+--+-- * Interval is non-empty+-- * 'MB' is between 'LB' and 'UB'.+--+data VersionInterval = VI !LB !MB !UB+  deriving (Eq, Show)++-- | Lower bound. For intervals it always exist: 'zeroLB' i.e. @>= 0@.+--+-- All lower bound intervals are inclusive, i.e. @>=v@. @>x.y.z@ is converted into @>=x.y.z.0@.+--+data LB = LB !Version+  deriving (Eq, Ord, Show)++-- | Upper bound.+--+-- All upper bounds are exclusive, i.e. @<v@. @<=x.y.z@ is converted to @<x.y.z.0@.+--+--+data UB+    = UB !Version   -- ^ upper bound+    | NoUB          -- ^ no upper bound (i.e. infinite)+  deriving (Eq, Ord, Show)++-- | Bound variant.+data Bound+    = Incl  -- ^ inclusive: @>=@ or @<=@+    | Excl  -- ^ exclusive: @>@ or @<@+  deriving (Eq, Ord, Show)++-- | Middle bound.+data MB+    = MB !Version  -- ^ major bound.+    | NoMB         -- ^ no major bound (i.e. infinite)+  deriving (Eq, Ord, Show)++-- | @>=0@+zeroLB :: LB+zeroLB = LB version0++-- | Whether the version is @0@.+isVersion0 :: Version -> Bool+isVersion0 = (==) version0++-- | Versions are not separated type.+succVersion :: Version -> Version+succVersion v = mkVersion (versionNumbers v ++ [0])++-------------------------------------------------------------------------------+-- Stage1+-------------------------------------------------------------------------------++stage1 :: ([VersionInterval] -> [VersionInterval]) -> VersionRange -> [VersionInterval]+stage1 opt = cataVersionRange alg where+    -- version range leafs transform into singleton intervals+    alg (ThisVersionF v)                = [VI (LB v)                (MB (succVersion v))      (UB (succVersion v))]+    alg (LaterVersionF v)               = [VI (LB (succVersion v))  NoMB                      NoUB]+    alg (OrLaterVersionF v)             = [VI (LB v)                NoMB                      NoUB]+    alg (EarlierVersionF v)+        | isVersion0 v                  = []+        | otherwise                     = [VI zeroLB                (MB v)                    (UB v)]+    alg (OrEarlierVersionF v)           = [VI zeroLB                (MB (succVersion v))      (UB (succVersion v))]++    -- ^>= version-range's upper bound should be MajorBound+    alg (MajorBoundVersionF v)          = [VI (LB v)                (MB (majorUpperBound v))  NoUB]++    -- union: just merge the version intervals+    alg (UnionVersionRangesF v1 v2)     = v1 ++ v2++    -- intersection: pairwise intersect. Strip empty intervals. Sort to restore the invariant.+    alg (IntersectVersionRangesF v1 v2) = catMaybes $ liftA2 intersectInterval (opt v1) (opt v2)++-------------------------------------------------------------------------------+-- Stage2+-------------------------------------------------------------------------------++stage2 :: [VersionInterval] -> [VersionInterval]+stage2 = sortOn (\(VI l _ _) -> l)++-------------------------------------------------------------------------------+-- Postprocess+-------------------------------------------------------------------------------++stage2and3 :: [VersionInterval] -> [VersionInterval]+stage2and3 = stage3 . stage2++stage3 :: [VersionInterval] -> [VersionInterval]+stage3 []                = []+stage3 (VI l m u : rest) = stage3go l m u rest++stage3go :: LB -> MB -> UB -> [VersionInterval] -> [VersionInterval]+stage3go l m u []                 = [VI l m u]+stage3go l m u (VI l' m' u' : is)+    | l == l'   = stage3go l' (unionMB m m') (unionUB u u') is+    | otherwise = case overlap m u l' of+        NoOverlap -> VI l m u : stage3go l' m' u' is+        OverlapU  -> viCons (VI l m (trimLB u l')) (stage3go l' m' (unionUB u u') is)+        OverlapM  -> stage3go l (unionMB m m') (unionUB u u') is+  where+    viCons :: VersionInterval -> [VersionInterval] -> [VersionInterval]+    viCons i | nonEmptyVI i = (i :)+    viCons _                = id++trimLB :: UB -> LB -> UB+trimLB _    (LB l) = UB l++-------------------------------------------------------------------------------+-- Intersections+-------------------------------------------------------------------------------++intersectInterval :: VersionInterval -> VersionInterval -> Maybe VersionInterval+intersectInterval (VI xl xm xu) (VI yl ym yu)+    | nonEmptyVI xy = Just xy+    | otherwise     = Nothing+  where+    l = intersectLB xl yl+    m = intersectMB xm ym+    u = intersectUB xu yu++    -- make middle bound be between l and u+    m' = rtrimMB (ltrimMB l m) u++    xy = VI l m' u++ltrimMB :: LB -> MB -> MB+ltrimMB _         NoMB      = NoMB+ltrimMB (LB l) (MB m) = case compare l m of+    LT -> MB m+    EQ -> MB m+    GT -> MB l++rtrimMB :: MB -> UB -> MB+rtrimMB m      NoUB   = m+rtrimMB NoMB   (UB u) = MB u+rtrimMB (MB m) (UB u) = MB (min m u)++intersectLB :: LB -> LB -> LB+intersectLB (LB v) (LB u) = LB (max v u)++intersectMB :: MB -> MB -> MB+intersectMB NoMB   b      = b+intersectMB b      NoMB   = b+intersectMB (MB v) (MB u) = MB (min v u)++intersectUB :: UB -> UB -> UB+intersectUB NoUB   b      = b+intersectUB b      NoUB   = b+intersectUB (UB v) (UB u) = UB (min v u)++intersectMBandUB :: MB -> UB -> UB+intersectMBandUB NoMB   b      = b+intersectMBandUB (MB v) NoUB   = UB v+intersectMBandUB (MB v) (UB u) = UB (min v u)++-------------------------------------------------------------------------------+-- Unions+-------------------------------------------------------------------------------++unionMB :: MB -> MB -> MB+unionMB NoMB   _      = NoMB+unionMB _      NoMB   = NoMB+unionMB (MB v) (MB u) = MB (max v u)++unionUB :: UB -> UB -> UB+unionUB NoUB   _      = NoUB+unionUB _      NoUB   = NoUB+unionUB (UB v) (UB u) = UB (max v u)++-------------------------------------------------------------------------------+-- Helpers+-------------------------------------------------------------------------------++-- | Overlaps.+--+data Overlap+    = NoOverlap  -- ^ no overlap, next interval's @l@ is greater than @u@+    | OverlapM   -- ^ overlaps, next interval's @l@ is less than @m@+    | OverlapU   -- ^ overlaps, next interval's @l@ is less than @u@ (but greater than @m@)+  deriving (Eq, Show)++overlap :: MB -> UB -> LB -> Overlap+overlap _           (UB u ) (LB l) | u <  l = NoOverlap+overlap (MB m ) _           (LB l) | m <  l = OverlapU+overlap _           _           _           = OverlapM++-------------------------------------------------------------------------------+-- Invariants+-------------------------------------------------------------------------------++-- | 'VersionIntervals' invariant:+--+-- * all intervals are valid (lower bound is less then upper bound, middle bound is in between)+-- * intervals doesn't touch each other (distinct)+--+validVersionIntervals :: VersionIntervals -> Bool+validVersionIntervals (VersionIntervals intervals) =+    all validVersionInterval intervals &&+    all doesNotTouch' (pairs intervals)+  where+    doesNotTouch' :: (VersionInterval, VersionInterval) -> Bool+    doesNotTouch' (VI l m u, VI l' _ _) = l < l' && case overlap m u l' of+        NoOverlap -> True+        OverlapM  -> False+        OverlapU  -> case u of+            NoUB     -> True+            UB uv -> case l' of LB lv -> uv == lv++pairs :: [a] -> [(a,a)]+pairs xs = zip xs (tail xs)++validLB :: LB -> Bool+validLB (LB v) = validVersion v++validUB :: UB -> Bool+validUB NoUB   = True+validUB (UB v) = validVersion v++validMB :: MB -> Bool+validMB NoMB   = True+validMB (MB v) = validVersion v++validVersionInterval :: VersionInterval -> Bool+validVersionInterval i@(VI l m u) = validLB l && validMB m && validUB u && nonEmptyVI i && lbLessThanMB l m && mbLessThanUB m u++mbLessThanUB :: MB -> UB -> Bool+mbLessThanUB (MB m) (UB u) = m <= u+mbLessThanUB NoMB   (UB _) = False+mbLessThanUB _       NoUB  = True++lbLessThanMB :: LB -> MB -> Bool+lbLessThanMB _      NoMB   = True+lbLessThanMB (LB l) (MB m) = l <= m++-- Check an interval is non-empty+--+nonEmptyVI :: VersionInterval -> Bool+nonEmptyVI (VI (LB _) _ NoUB)   = True+nonEmptyVI (VI (LB l) _ (UB u)) = l < u++-------------------------------------------------------------------------------+-- Conversions+-------------------------------------------------------------------------------++-- | Convert a 'VersionRange' to a sequence of version intervals.+--+toVersionIntervals :: VersionRange -> VersionIntervals+toVersionIntervals = VersionIntervals . stage2and3 . stage1 stage2and3++data ConversionProblem+    = IntervalsEmpty+    | OtherConversionProblem+  deriving (Eq, Show)++-- | Convert a 'VersionIntervals' value back into a 'VersionRange' expression+-- representing the version intervals.+--+fromVersionIntervals :: VersionIntervals -> Either ConversionProblem VersionRange+fromVersionIntervals (VersionIntervals [])     = Right noVersion+fromVersionIntervals (VersionIntervals (x:xs)) =+    case join <$> traverse intervalToVersionRange (preprocess x xs) of+        Just vrs -> Right (foldr1 unionVersionRanges vrs)+        Nothing  -> Left $+            if all seemsEmpty (x:xs)+            then IntervalsEmpty+            else OtherConversionProblem+  where+    -- we can remove upper bounds, if they touch next interval, and the next interval doesn't have upper bound+    preprocess :: VersionInterval -> [VersionInterval] -> NonEmpty VersionInterval+    preprocess i [] = i :| []+    preprocess i@(VI l m u) (j:js) = case u' of+        NoUB | touchesUB u l' -> cons (VI l m NoUB) js'+        _                     -> cons i             js'+      where+        js'@(VI l' _ u' :| _)  = preprocess j js++    seemsEmpty :: VersionInterval -> Bool+    seemsEmpty (VI l m u) = not (nonEmptyVI (VI l NoMB (intersectMBandUB m u)))++touchesUB :: UB -> LB -> Bool+touchesUB NoUB   _      = True+touchesUB (UB u) (LB l) = u >= l++lbToVR :: LB -> VersionRange+lbToVR (LB l) = orLaterVersion l++ubToVR :: UB -> VersionRange -> VersionRange+ubToVR NoUB   vr = vr+ubToVR (UB u) vr = intersectVersionRanges vr (earlierVersion u)++mbEqUB :: MB -> UB -> Bool+mbEqUB NoMB   NoUB   = True+mbEqUB NoMB   (UB _) = False+mbEqUB (MB m) (UB u) = m == u+mbEqUB (MB _) NoUB   = False++-- return the unions of version ranges.+intervalToVersionRange :: VersionInterval -> Maybe (NonEmpty VersionRange)+intervalToVersionRange (VI l m u) | mbEqUB m u = Just (singleton (intervalToVersionRange1 l u))+intervalToVersionRange (VI l m u)              = fmap (fmap (ubToVR u)) (intervalToVersionRange2 l m)++intervalToVersionRange1 :: LB -> UB -> VersionRange+intervalToVersionRange1 (LB v) upper' = case upper' of+    NoUB+        -> lowerBound++    UB u+        | succVersion v == u+        -> thisVersion v++    UB u -> withLowerBound (makeUpperBound u)+  where+    lowerBound :: VersionRange+    lowerBound = lbToVR (LB v)++    withLowerBound :: VersionRange -> VersionRange+    withLowerBound vr+        | isVersion0 v = vr+        | otherwise    = intersectVersionRanges lowerBound vr++    makeUpperBound :: Version -> VersionRange+    makeUpperBound u = earlierVersion u++intervalToVersionRange2 :: LB -> MB -> Maybe (NonEmpty VersionRange)+intervalToVersionRange2 (LB l) major = case major of+    NoMB -> Just (singleton lowerBound)+    MB m+        | majorUpperBound l == m+        -> Just (singleton (majorBoundVersion l))++{-+    MB m+        | [a,b]  <- versionNumbers m+        , a' : _ <- versionNumbers l+        , a' == a+        , b >= 1+        , majorUpperBound l <= m+        -> Just $ go (majorBoundVersion l :|) (majorUpperBound l)+      where+        go acc v = if v >= m then acc [] else go (acc . (majorBoundVersion v :)) (majorUpperBound v)+-}++    MB m+        | [a,b] <- versionNumbers m+        , let m' = mkVersion [a,b-1]+        , b >= 1+        , m' > l+        -> Just $+            (ubToVR (UB m') (lbToVR (LB l)))+            :| [ majorBoundVersion (mkVersion [a, b-1]) ]++    _ -> Nothing+  where+    lowerBound :: VersionRange+    lowerBound = lbToVR (LB l)++-------------------------------------------------------------------------------+-- Normalisation+-------------------------------------------------------------------------------++-- | Convert 'VersionRange' to 'VersionIntervals' and back.+--+normaliseVersionRange :: VersionRange -> Either ConversionProblem VersionRange+normaliseVersionRange = fromVersionIntervals . toVersionIntervals
src/CabalFmt.hs view
@@ -11,7 +11,6 @@  import Control.Monad        (join) import Control.Monad.Reader (asks, local)-import Data.Either          (partitionEithers)  import qualified Data.ByteString                              as BS import qualified Distribution.CabalSpecVersion                as C@@ -22,13 +21,12 @@ import qualified Distribution.PackageDescription.FieldGrammar as C import qualified Distribution.Parsec                          as C import qualified Distribution.Pretty                          as C-import qualified Distribution.Simple.Utils                    as C import qualified Distribution.Types.Condition                 as C import qualified Distribution.Types.ConfVar                   as C import qualified Distribution.Types.GenericPackageDescription as C import qualified Distribution.Types.PackageDescription        as C-import qualified Distribution.Types.Version                   as C import qualified Distribution.Types.VersionRange              as C+import qualified Distribution.Utils.Generic                   as C import qualified Text.PrettyPrint                             as PP  import CabalFmt.Comments@@ -79,9 +77,7 @@         False -> return C.cabalSpecLatest         True  -> do             gpd <- parseGpd filepath contents-            return $ C.cabalSpecFromVersionDigits-              $ C.versionNumbers-              $ C.specVersion+            return $ C.specVersion               $ C.packageDescription gpd      local (over options $ \o -> runOptionsMorphism optsEndo $ o { optSpecVersion = csv }) $ do@@ -93,12 +89,13 @@             prettySectionArgs             inputFields -        return $ C.showFields' fromComments indentWith outputPrettyFields+        return $ C.showFields' fromComments (const id) indentWith outputPrettyFields             & if nullComments endComments then id else                 (++ unlines ("" : [ C.fromUTF8BS c | c <- unComments endComments ])) -fromComments :: Comments -> [String]-fromComments (Comments bss) = map C.fromUTF8BS bss+fromComments :: Comments -> C.CommentPosition+fromComments (Comments [])  = C.NoComment+fromComments (Comments bss) = C.CommentBefore (map C.fromUTF8BS bss)  ------------------------------------------------------------------------------- -- Field prettyfying@@ -120,6 +117,7 @@ fieldDescrs :: Options -> FieldDescrs () () fieldDescrs opts     =  buildDependsF opts+    <> buildToolDependsF opts     <> setupDependsF opts     <> defaultExtensionsF     <> otherExtensionsF@@ -158,12 +156,12 @@ ppCondition (C.CAnd c1 c2) = PP.parens (PP.hsep [ppCondition c1, PP.text "&&", ppCondition c2])  ppConfVar :: C.ConfVar -> PP.Doc-ppConfVar (C.OS os)     = PP.text "os"   PP.<> PP.parens (C.pretty os)-ppConfVar (C.Arch arch) = PP.text "arch" PP.<> PP.parens (C.pretty arch)-ppConfVar (C.Flag name) = PP.text "flag" PP.<> PP.parens (C.pretty name)+ppConfVar (C.OS os)            = PP.text "os"   PP.<> PP.parens (C.pretty os)+ppConfVar (C.Arch arch)        = PP.text "arch" PP.<> PP.parens (C.pretty arch)+ppConfVar (C.PackageFlag name) = PP.text "flag" PP.<> PP.parens (C.pretty name) ppConfVar (C.Impl c v)-    | v == C.anyVersion = PP.text "impl" PP.<> PP.parens (C.pretty c)-    | otherwise         = PP.text "impl" PP.<> PP.parens (C.pretty c PP.<+> C.pretty v)+    | v == C.anyVersion        = PP.text "impl" PP.<> PP.parens (C.pretty c)+    | otherwise                = PP.text "impl" PP.<> PP.parens (C.pretty c PP.<+> C.pretty v)  ------------------------------------------------------------------------------- -- Pragma to OM
src/CabalFmt/Error.hs view
@@ -12,8 +12,8 @@ import qualified Data.ByteString            as BS import qualified Data.ByteString.Char8      as BS8 import qualified Distribution.Parsec        as C-import qualified Distribution.Simple.Utils  as C (fromUTF8BS) import qualified Distribution.Types.Version as C+import qualified Distribution.Utils.Generic as C (fromUTF8BS)  data Error     = SomeError String
src/CabalFmt/Fields.hs view
@@ -3,7 +3,10 @@ -- Copyright: Oleg Grenrus {-# LANGUAGE DeriveFunctor             #-} {-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE FlexibleInstances         #-}+{-# LANGUAGE MultiParamTypeClasses     #-} {-# LANGUAGE RankNTypes                #-}+{-# LANGUAGE UndecidableInstances      #-} module CabalFmt.Fields (     FieldDescrs,     fieldDescrLookup,@@ -69,7 +72,7 @@     -> FieldDescrs s a singletonF fn f g = F $ Map.singleton fn (SP f g) -instance C.FieldGrammar FieldDescrs where+instance C.FieldGrammar PrettyParsec FieldDescrs where     blurFieldGrammar _ (F m) = F m      booleanFieldDef fn _ _def = singletonF fn f C.parsec where@@ -109,3 +112,6 @@     removedIn _ _ x        = x     availableSince _ _     = id     hiddenField _          = F mempty++class (C.Pretty a, C.Parsec a) => PrettyParsec a+instance (C.Pretty a, C.Parsec a) => PrettyParsec a
src/CabalFmt/Fields/BuildDepends.hs view
@@ -2,26 +2,29 @@ -- License: GPL-3.0-or-later -- Copyright: Oleg Grenrus {-# LANGUAGE OverloadedStrings #-}+{-# OPTIONS_GHC -Wno-deprecations #-} module CabalFmt.Fields.BuildDepends (     buildDependsF,     setupDependsF,-    ) where+    buildToolDependsF,+) where -import qualified Distribution.CabalSpecVersion      as C-import qualified Distribution.Parsec                as C-import qualified Distribution.Parsec.Newtypes       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.PackageName     as C-import qualified Distribution.Types.Version         as C-import qualified Distribution.Types.VersionInterval as C-import qualified Distribution.Types.VersionRange    as C-import qualified Text.PrettyPrint                   as PP+import Data.List (dropWhileEnd) -import CabalFmt.Prelude+import qualified Distribution.CabalSpecVersion    as C+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.VersionRange  as C+import qualified Text.PrettyPrint                 as PP+ import CabalFmt.Fields import CabalFmt.Options+import CabalFmt.Prelude+import VersionInterval  (normaliseVersionRange, ConversionProblem (..))  setupDependsF :: Options -> FieldDescrs () () setupDependsF opts = singletonF "setup-depends" (pretty opts) parse@@ -29,111 +32,122 @@ buildDependsF :: Options -> FieldDescrs () () buildDependsF opts = singletonF "build-depends" (pretty opts) parse +buildToolDependsF :: Options -> FieldDescrs () ()+buildToolDependsF opts = singletonF "build-tool-depends" (prettyExe opts) parseExe+ parse :: C.CabalParsing m => m [C.Dependency] parse = unpack' (C.alaList C.CommaVCat) <$> C.parsec +parseExe :: C.CabalParsing m => m [C.ExeDependency]+parseExe = unpack' (C.alaList C.CommaVCat) <$> C.parsec++normaliseVersionRange' :: C.VersionRange -> C.VersionRange+normaliseVersionRange' vr = either fromConversionProblem id (normaliseVersionRange vr) where+    fromConversionProblem :: ConversionProblem -> C.VersionRange+    fromConversionProblem IntervalsEmpty         = C.noVersion+    fromConversionProblem OtherConversionProblem = vr+ pretty :: Options -> [C.Dependency] -> PP.Doc-pretty Options { optSpecVersion = v, optTabular = tab } deps = case deps of+pretty opts deps = case deps of     []    -> PP.empty     [dep] -> C.pretty (C.depPkgName dep) PP.<+> prettyVR vr'       where-        vr' = either (C.fromVersionIntervals . C.mkVersionIntervals) id-            $ norm (C.asVersionIntervals $ C.depVerRange dep)+        vr' = normaliseVersionRange' (C.depVerRange dep)          prettyVR vr | vr == C.anyVersion = PP.empty                     | vr == C.noVersion  = PP.text "<0"                     | otherwise          = C.pretty vr -    _ -> PP.vcat (zipWith pretty' (True : repeat False) deps')+    _ -> prettyMany opts deps'       where-        deps' :: [(String, [C.VersionInterval])]+        deps' :: [(String, C.VersionRange)]         deps' = sortOn (map toLower . fst)-              $ map (C.unPackageName . C.depPkgName &&& C.asVersionIntervals . C.depVerRange)+              $ map (prettyDepNoVersion &&& C.depVerRange)               $ C.fromDepMap . C.toDepMap -- this combines duplicate packages               $ deps -        width = maximum (0 : map (length . fst) deps') + 1-        width' = maximum (0 : map (firstComponent . snd) deps')+        prettyDepNoVersion :: C.Dependency -> String+        prettyDepNoVersion (C.Dependency pkg _ libs) =+          C.prettyShow (C.Dependency pkg C.anyVersion libs) -        -- we assume cabal-version: 2.2 or higher-        pretty' :: Bool -> (String, [C.VersionInterval]) -> PP.Doc-        pretty' isFirst (name, vis)-            | empty vis = comma PP.<+> PP.text name PP.<+> PP.text "<0"-            | full  vis = comma PP.<+> PP.text name-            | otherwise = case norm vis of-                Left [] -> comma PP.<+> PP.text name-                Left (vi : vis') ->-                    comma PP.<+>-                    PP.text (lp width name) PP.<+>-                    PP.hsep-                        ( prettyVi vi-                        : map (\vi' -> PP.text "||" PP.<+> prettyVi' vi') vis'-                        )-                Right vr ->-                    comma PP.<+>-                    PP.text (lp width name) PP.<+>-                    C.pretty vr-          where-            comma | isFirst, v < C.CabalSpecV2_2 = PP.text " "-                  | otherwise = PP.comma -        -- indent first-        prettyVi (C.LowerBound l lb, C.NoUpperBound) =-            prettyLowerBound lb PP.<> C.pretty l-        prettyVi (C.LowerBound l C.InclusiveBound, C.UpperBound u C.InclusiveBound)-            | l == u = PP.text "==" PP.<> C.pretty l-        prettyVi (C.LowerBound l C.InclusiveBound, C.UpperBound u ub)-            | l == C.version0-            = prettyUpperBound ub PP.<> C.pretty u-        prettyVi (C.LowerBound l lb, C.UpperBound u ub) =-            prettyLowerBound lb PP.<> PP.text (lp width' l')-            PP.<+> PP.text "&&" PP.<+>-            prettyUpperBound ub PP.<> C.pretty u-          where-            l' = C.prettyShow l+prettyExe :: Options -> [C.ExeDependency] -> PP.Doc+prettyExe opts deps = case deps of+    []    -> PP.empty+    [dep] -> PP.text (exeDepExeName dep) PP.<+> prettyVR vr'+      where+        vr' = normaliseVersionRange' (exeDepVerRange dep) -        prettyVi' (C.LowerBound l lb, C.NoUpperBound) =-            prettyLowerBound lb PP.<> C.pretty l-        prettyVi' (C.LowerBound l C.InclusiveBound, C.UpperBound u C.InclusiveBound)-            | l == u = PP.text "==" PP.<> C.pretty l-        prettyVi' (C.LowerBound l lb, C.UpperBound u ub) =-            prettyLowerBound lb PP.<> C.pretty l PP.<+> PP.text "&&" PP.<+>-            prettyUpperBound ub PP.<> C.pretty u+        prettyVR vr | vr == C.anyVersion = PP.empty+                    | vr == C.noVersion  = PP.text "<0"+                    | otherwise          = C.pretty vr -        prettyLowerBound :: C.Bound -> PP.Doc-        prettyLowerBound C.InclusiveBound = PP.text ">="-        prettyLowerBound C.ExclusiveBound = PP.text ">"+    _ -> prettyMany opts deps'+      where+        deps' :: [(String, C.VersionRange)]+        deps' = sortOn (map toLower . fst)+              $ map (exeDepExeName &&& exeDepVerRange)+              -- C.fromDepMap . C.toDepMap -- this combines duplicate packages+              $ deps -        prettyUpperBound :: C.Bound -> PP.Doc-        prettyUpperBound C.InclusiveBound = PP.text "<="-        prettyUpperBound C.ExclusiveBound = PP.text "<"-  where-    full :: [C.VersionInterval] -> Bool-    full [(C.LowerBound l C.InclusiveBound, C.NoUpperBound)] = l == C.mkVersion [0]-    full _                                                   = False+exeDepExeName :: C.ExeDependency -> String+exeDepExeName (C.ExeDependency name exe _) =+    C.prettyShow name ++ ":" ++ C.prettyShow exe -    empty :: [C.VersionInterval] -> Bool-    empty [] = True-    empty _  = False+exeDepVerRange :: C.ExeDependency -> C.VersionRange+exeDepVerRange (C.ExeDependency _ _ vr) = vr -    norm :: [C.VersionInterval] -> Either [C.VersionInterval] C.VersionRange-    norm []                                                                    = Right C.noVersion-    norm [(C.LowerBound l C.InclusiveBound, C.NoUpperBound)] | l == C.version0 = Right C.anyVersion-    norm (i:is) = maybe (Left $ i:is) Right $-        foldr1 C.unionVersionRanges <$> traverse f (i : is)+prettyMany :: Options -> [(String, C.VersionRange)] -> PP.Doc+prettyMany Options { optSpecVersion = v, optTabular = tab } deps'+    = PP.vcat+    $ map PP.text+    $ tbl+    $ zipWith cols (True : repeat False) deps'+  where+    cols :: Bool -> (String, C.VersionRange) -> [String]+    cols isFirst (name, vr)+        | full vr'  = [comma, name]+        | otherwise = comma : name : "" : words (C.prettyShow vr')       where-        f :: C.VersionInterval -> Maybe C.VersionRange-        f (C.LowerBound l C.InclusiveBound, C.UpperBound u C.ExclusiveBound)-            | v >= C.CabalSpecV2_0, u == C.majorUpperBound l =-                Just (C.majorBoundVersion l)-        f _ = Nothing+        vr' = normaliseVersionRange' vr -    firstComponent :: [C.VersionInterval] -> Int-    firstComponent [] = 0-    firstComponent ((C.LowerBound l _, _) : _) = length (C.prettyShow l)+        comma | isFirst, v < C.CabalSpecV2_2 = " "+              | otherwise                    = "," -    lp | tab       = leftpad-       | otherwise = \_ x -> x+    full :: C.VersionRange -> Bool+    full vr = vr == C.anyVersion -leftpad :: Int -> String -> String-leftpad w s = s ++ replicate (w - length s) ' '+    tbl :: [[String]] -> [String]+    tbl = if tab then table else map (concatSpaces . unwords)++-- returns rows.+table :: [[String]] -> [String]+table cells = map strip rows+  where+    cols      :: Int+    rowWidths :: [Int]+    rows      :: [String]++    (cols, rowWidths, rows) = foldr go (0, repeat 0, []) cells++    go :: [String] -> (Int, [Int], [String]) -> (Int, [Int], [String])+    go xs (c, w, yss) =+        ( max c (length xs)+        , zipWith max w (map length xs ++ repeat 0)+        , unwords (take cols (zipWith fill xs rowWidths))+          : yss+        )++    fill :: String -> Int -> String+    fill s n = s ++ replicate (n - length s) ' '++strip :: String -> String+strip = dropWhileEnd (' ' ==)++concatSpaces :: String -> String+concatSpaces []        = []+concatSpaces (' ' : s) = ' ' : concatSpaces s+concatSpaces (c0 : s0)   = c0 : go s0 where+    go (' ' : ' ' : s) = go (' ' : s)+    go (c:s)           = c : go s+    go []              = []
src/CabalFmt/Fields/Extensions.hs view
@@ -7,14 +7,14 @@     defaultExtensionsF,     ) where -import qualified Distribution.Parsec          as C-import qualified Distribution.Parsec.Newtypes as C-import qualified Distribution.Pretty          as C-import qualified Language.Haskell.Extension   as C-import qualified Text.PrettyPrint             as PP+import qualified Distribution.FieldGrammar  as C+import qualified Distribution.Parsec        as C+import qualified Distribution.Pretty        as C+import qualified Language.Haskell.Extension as C+import qualified Text.PrettyPrint           as PP -import CabalFmt.Prelude import CabalFmt.Fields+import CabalFmt.Prelude  otherExtensionsF :: FieldDescrs () () otherExtensionsF = singletonF "other-extensions" pretty parse
src/CabalFmt/Fields/Modules.hs view
@@ -7,14 +7,14 @@     exposedModulesF,     ) where -import qualified Distribution.ModuleName      as C-import qualified Distribution.Parsec          as C-import qualified Distribution.Parsec.Newtypes as C-import qualified Distribution.Pretty          as C-import qualified Text.PrettyPrint             as PP+import qualified Distribution.FieldGrammar as C+import qualified Distribution.ModuleName   as C+import qualified Distribution.Parsec       as C+import qualified Distribution.Pretty       as C+import qualified Text.PrettyPrint          as PP -import CabalFmt.Prelude import CabalFmt.Fields+import CabalFmt.Prelude  exposedModulesF :: FieldDescrs () () exposedModulesF = singletonF "exposed-modules" pretty parse
src/CabalFmt/Fields/SourceFiles.hs view
@@ -7,13 +7,15 @@     fileFields,     ) where -import System.FilePath.Posix (splitDirectories)+-- Make sure we explicitly use Posix's splitDirectories+-- when parsing glob syntax since only `/` is valid, and not '\\'+import qualified System.FilePath.Posix     as Posix (splitDirectories) -import qualified Distribution.Fields          as C-import qualified Distribution.Parsec          as C-import qualified Distribution.Parsec.Newtypes as C-import qualified Distribution.Pretty          as C-import qualified Text.PrettyPrint             as PP+import qualified Distribution.FieldGrammar as C+import qualified Distribution.Fields       as C+import qualified Distribution.Parsec       as C+import qualified Distribution.Pretty       as C+import qualified Text.PrettyPrint          as PP  import CabalFmt.Fields import CabalFmt.Prelude@@ -46,7 +48,7 @@ pretty     = PP.vcat . map C.showFilePath     . nub-    . sortBy (cmp `on` map strToLower . splitDirectories)+    . sortBy (cmp `on` map strToLower . Posix.splitDirectories)   where     cmp a b = case dropCommonPrefix a b of         ([], [])  -> EQ
src/CabalFmt/Fields/TestedWith.hs view
@@ -11,15 +11,15 @@ import qualified Data.Set                      as Set import qualified Distribution.CabalSpecVersion as C import qualified Distribution.Compiler         as C+import qualified Distribution.FieldGrammar     as C import qualified Distribution.Parsec           as C-import qualified Distribution.Parsec.Newtypes  as C import qualified Distribution.Pretty           as C import qualified Distribution.Version          as C import qualified Text.PrettyPrint              as PP -import CabalFmt.Prelude import CabalFmt.Fields import CabalFmt.Options+import CabalFmt.Prelude  testedWithF :: Options -> FieldDescrs () () testedWithF Options { optSpecVersion = ver } = singletonF "tested-with" pretty parse where@@ -56,7 +56,7 @@ isVersionSet :: C.VersionRange -> Maybe (Set C.Version) isVersionSet vr = go Set.empty (C.asVersionIntervals vr) where     go !acc [] = Just acc-    go acc ((C.LowerBound v C.InclusiveBound, C.UpperBound u C.InclusiveBound) : vis)+    go acc (C.VersionInterval (C.LowerBound v C.InclusiveBound) (C.UpperBound u C.InclusiveBound) : vis)         | v == u    = go (Set.insert v acc) vis     go _ _ = Nothing 
src/CabalFmt/Glob.hs view
@@ -1,9 +1,11 @@ module CabalFmt.Glob where -import Data.List             (isInfixOf)-import Data.List.NonEmpty    (NonEmpty (..))-import System.FilePath.Posix (splitDirectories)+import Data.List          (isInfixOf)+import Data.List.NonEmpty (NonEmpty (..)) +import qualified System.FilePath       as Native (splitDirectories)+import qualified System.FilePath.Posix as Posix (splitDirectories)+ import CabalFmt.Prelude  data Glob = Glob FilePath [GlobPiece]@@ -27,7 +29,7 @@ -- [False,False,True,True] -- match :: Glob -> FilePath -> Bool-match (Glob g1 gs0) fp = go0 (splitDirectories fp) where+match (Glob g1 gs0) fp = go0 (Native.splitDirectories fp) where     go0 []     = False     go0 (p:ps) = if p == g1 then go ps gs0 else False @@ -38,7 +40,6 @@     go (s:ss) (GlobStarStar : gs) = go (s:ss) gs || go ss (GlobStarStar : gs)     go (s:ss) (GlobPiece cs : gs) = matches s (toList cs) && go ss gs -     matches :: FilePath -> [GlobChar] -> Bool     matches []     []                = True     matches (_:_)  []                = False@@ -47,7 +48,7 @@     matches (x:xs) (GlobChar c : cs) = if x == c then matches xs cs else False  parseGlob :: String -> Either String Glob-parseGlob input = case splitDirectories input of+parseGlob input = case Posix.splitDirectories input of     []     -> Left "empty path"     (x:xs) -> do         p <- parseFirstPiece x
src/CabalFmt/Monad.hs view
@@ -30,7 +30,7 @@ import Data.List              (isPrefixOf, stripPrefix) import Data.Maybe             (mapMaybe) import System.Exit            (exitFailure)-import System.FilePath        ((</>))+import System.FilePath        (pathSeparator, (</>)) import System.IO              (hPutStrLn, stderr)  import qualified Data.ByteString  as BS@@ -86,14 +86,17 @@       where         f :: FilePath -> Maybe FilePath         f fp = do-            rest <- stripPrefix (dir ++ "/") fp-            return $ takeWhile (/= '/') rest+            rest <- stripPrefix (dir ++ [pathSeparator]) fp+            return $ takeWhile (/= pathSeparator) rest+     doesDirectoryExist dir = CabalFmt $ do         files <- asks snd-        return (any (isPrefixOf (dir ++ "/")) (Map.keys files))+        return (any (isPrefixOf (dir ++ [pathSeparator])) (Map.keys files))+     readFileBS p         = CabalFmt $ do         files <- asks snd         return (maybe (IOError "doesn't exist") Contents $ Map.lookup p files)+     displayWarning w     = do         werror <- asks optError         if werror
src/CabalFmt/Prelude.hs view
@@ -15,7 +15,7 @@     -- * Data.Either     partitionEithers,     -- * Data.Foldable-    toList, traverse_, asum,+    toList, traverse_, asum, for_,     -- * Data.Function     on, (&),     -- * Data.List@@ -51,7 +51,7 @@ import Data.ByteString             (ByteString) import Data.Char                   (toLower) import Data.Either                 (partitionEithers)-import Data.Foldable               (asum, toList, traverse_)+import Data.Foldable               (asum, for_, toList, traverse_) import Data.Function               (on, (&)) import Data.List                   (intercalate, nub, sortBy, sortOn) import Data.Maybe                  (catMaybes, fromMaybe, isJust, isNothing)@@ -60,7 +60,7 @@ import Distribution.Compat.Newtype (pack', unpack') import System.FilePath             (dropExtension, splitDirectories) -import qualified Distribution.Simple.Utils as C+import qualified Distribution.Utils.Generic as C  traverseOf     :: Applicative f
src/CabalFmt/Refactoring/ExpandExposedModules.hs view
@@ -3,6 +3,7 @@ -- Copyright: Oleg Grenrus {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RankNTypes        #-}+{-# OPTIONS_GHC -Wno-deprecations #-} module CabalFmt.Refactoring.ExpandExposedModules (     refactoringExpandExposedModules,     ) where@@ -28,7 +29,7 @@             , file <- files'             , let parts = splitDirectories $ dropExtension file             , all C.validModuleComponent parts-            , let mn = C.fromComponents parts+            , let mn = C.fromComponents parts -- TODO: don't use fromComponents             , mn `notElem` mns             ] 
src/CabalFmt/Refactoring/Fragments.hs view
@@ -44,7 +44,7 @@                         displayWarning $ "Fragment " ++ p ++ " contains a section " ++ showSection name arg ++ ", expecting field " ++ show n ++ "."                         pure Nothing                     (C.Section name@(C.Name _ _) arg _, C.Field (C.Name _ n') _ : _) -> do-                        displayWarning $ "Fragment " ++ p ++ " contains a field " ++ show n' ++ ", expection section " ++ showSection name arg ++ "."+                        displayWarning $ "Fragment " ++ p ++ " contains a field " ++ show n' ++ ", expecting section " ++ showSection name arg ++ "."                         pure Nothing                      (C.Field name@(C.Name _ n) _, C.Field (C.Name _ n') fls' : rest) -> do@@ -66,7 +66,7 @@                         then do                             pure (Just (C.Section name arg (noCommentsPragmas fs')))                         else do-                            displayWarning $ "Fragment " ++ p ++ " contains a section " ++ showSection name arg ++ ", expection section " ++ showSection name' arg' ++ "."+                            displayWarning $ "Fragment " ++ p ++ " contains a section " ++ showSection name arg ++ ", expecting section " ++ showSection name' arg' ++ "."                             pure Nothing   where     noCommentsPragmas :: Functor f => [f ann] -> [f CommentsPragmas]
src/CabalFmt/Refactoring/GlobFiles.hs view
@@ -7,12 +7,14 @@     refactoringGlobFiles, ) where -import qualified Distribution.Fields     as C+import qualified Distribution.Fields   as C+import qualified System.FilePath       as Native+import qualified System.FilePath.Posix as Posix -import CabalFmt.Prelude-import CabalFmt.Monad import CabalFmt.Glob+import CabalFmt.Monad import CabalFmt.Pragma+import CabalFmt.Prelude import CabalFmt.Refactoring.Type  refactoringGlobFiles :: FieldRefactoring@@ -41,5 +43,8 @@      match' :: MonadCabalFmt r m => Glob -> m [FilePath]     match' g@(Glob dir _) = do-        files <- map (\fp -> dir ++ "/" ++ fp) <$> getFiles dir -        return $ filter (match g) files+        files <- map (\fp -> dir Native.</> fp) <$> getFiles dir+        return $ map toPosix $ filter (match g) files++    toPosix :: FilePath -> FilePath+    toPosix = Posix.joinPath . Native.splitDirectories
+ tests-interval/version-interval-tests.hs view
@@ -0,0 +1,367 @@+{-# OPTIONS_GHC -Wno-orphans #-}+module Main (main) where++import Control.Monad                   (replicateM)+import Distribution.Parsec             (eitherParsec)+import Distribution.Types.Version+       (Version, mkVersion, validVersion, versionNumbers)+import Distribution.Types.VersionRange+       (VersionRange, VersionRangeF (..), anyVersion, earlierVersion,+       intersectVersionRanges, laterVersion, majorBoundVersion, notThisVersion,+       orEarlierVersion, orLaterVersion, projectVersionRange, thisVersion,+       unionVersionRanges, withinRange, withinVersion)+import Distribution.Version            (transformCaretUpper)+import Math.NumberTheory.Logarithms    (intLog2)+import Test.QuickCheck                 (Arbitrary (..), (===))+import Test.Tasty                      (TestTree, defaultMain, testGroup)+import Test.Tasty.HUnit                (testCase, (@?=))+import Test.Tasty.QuickCheck           (testProperty)++import qualified Test.QuickCheck as QC++import VersionInterval++main :: IO ()+main = defaultMain $ testGroup "version-interval"+    [ testGroup "Validity"+        [ testProperty "validVersion" validVersion+        , testProperty "validVersionInterval" validVersionInterval+        , testProperty "validVersionIntervals" $ \vr ->+            let intervals = toVersionIntervals vr+            in QC.counterexample (show intervals) $ validVersionIntervals intervals+        ]++    , testGroup "VersionInterval"+        [ testProperty "intersect valid" $ \a b ->+            let ab = intersectInterval a b+            in maybe (QC.property True) (\ab' -> QC.counterexample ("intersection: " ++ show ab') $ validVersionInterval ab') ab++        , testProperty "intersect complete" intersect_complete+        , testProperty "intersect complete lax" intersect_complete_lax+        ]++    , testGroup "stage1"+        [ testProperty "valid" stage1_valid+        , testProperty "complete" stage1_complete+        , testProperty "complete lax" stage1_complete_lax++        , testProperty "valid ex1" $ stage1_valid+            (intersectVersionRanges (majorBoundVersion (mkVersion [0])) (thisVersion (mkVersion [1])))++        , testProperty "valid ex2" $ stage1_valid+            (intersectVersionRanges (majorBoundVersion (mkVersion [0])) (orLaterVersion (mkVersion [1])))++        , testProperty "complete ex1" $ stage1_complete+            (intersectVersionRanges (majorBoundVersion (mkVersion [0])) (thisVersion (mkVersion [6])))+            (mkVersion [6])++        , testProperty "complete ex2" $ stage1_complete+            (intersectVersionRanges (majorBoundVersion (mkVersion [0])) (orLaterVersion (mkVersion [1])))++        , testProperty "complete lax ex2" $ stage1_complete_lax+            (intersectVersionRanges (majorBoundVersion (mkVersion [0])) (orLaterVersion (mkVersion [1])))+        ]++    , testGroup "stage2"+        [ testProperty "valid" stage2_valid+        , testProperty "involutive" stage2_involutive+        , testProperty "complete" stage2_complete+        , testProperty "complete_lax" stage2_complete_lax+        ]++    , testGroup "stage3"+        [ testProperty "valid" stage3_valid+        , testProperty "involutive" stage3_involutive+        , testProperty "complete" stage3_complete+        , testProperty "complete_lax" stage3_complete_lax++        , testProperty "complete ex1" $ stage3_complete+           [VI (LB (mkVersion [0])) (MB (mkVersion [0])) NoUB,VI (LB (mkVersion [0,0])) NoMB NoUB]+           (mkVersion [0])++        , testProperty "complete lax ex1" $ stage3_complete_lax+            [VI (LB (mkVersion [0,0])) (MB (mkVersion [0])) (UB (mkVersion [1])),VI (LB (mkVersion [0,0,0])) (MB (mkVersion [1])) (UB (mkVersion [1]))]+            (mkVersion [1])++        , testProperty "valid ex2" $ stage3_valid+            (stage1 id (intersectVersionRanges (majorBoundVersion (mkVersion [0])) (orLaterVersion (mkVersion [1]))))++        , testProperty "complete ex2" $ stage3_complete+            (stage1 id (intersectVersionRanges (majorBoundVersion (mkVersion [0])) (orLaterVersion (mkVersion [1]))))++        , testProperty "complete lax ex2" $ stage3_complete_lax+            (stage1 id (intersectVersionRanges (majorBoundVersion (mkVersion [0])) (orLaterVersion (mkVersion [1]))))++        , testProperty "valid ex3" $ stage3_valid+            [VI (LB (mkVersion [0,0])) (MB (mkVersion [0])) NoUB,VI (LB (mkVersion [0,0])) NoMB NoUB]+        ]++    , testGroup "normalise"+        [ normaliseExample ">=1 && <2"                               ">=1 && <2"+        , normaliseExample "^>=1"                                    "^>=1"+        , normaliseExample "^>=1 || ^>=2"                            "^>=1 || ^>=2"+        , normaliseExample "^>=1.2 || ^>=1.3 || ^>=1.4"              ">=1.2 && <1.4 || ^>=1.4"+        , normaliseExample "^>=1.2 || ^>=2.0"                        "^>=1.2 || ^>=2.0"+        , normaliseExample ">=1.2 && <1.4 || ^>=1.4 || ^>=1.5"       ">=1.2 && <1.5 || ^>=1.5"+        , normaliseExample ">=1.2 && <2.4 || ^>=2.4 || ^>=2.5"       ">=1.2 && <2.5 || ^>=2.5"+        , normaliseExample "^>=1.2.0.0 || ^>=1.3.0.0 || ^>=1.4.0.0"  "^>=1.2.0.0 || ^>=1.3.0.0 || ^>=1.4.0.0"++        , normaliseExample "==3.1.4"           "==3.1.4"+        , normaliseExample "<3.1.4 || >3.1.4"  "<3.1.4 || >=3.1.4.0"++        , normaliseExample "^>=1.2 && <2.0 || ^>=2.0"                "^>=1.2 || ^>=2.0"+        , normaliseExample "^>=1.2 && <3.0 || ^>=2.0"                "^>=1.2 || ^>=2.0"+        , normaliseExample "^>=1.2 || ^>=2.0 && <3"                  "^>=1.2 || ^>=2.0"+        , normaliseExample "(^>=1.2 || ^>=2.0) && <3"                "^>=1.2 && <2.0 || ^>=2.0 && <3"+        , normaliseExample "(>=1.2 || >=2.0) && <3"                  ">=1.2 && <3"++        , normaliseExample "<1 || >=1.0"   "<1 || >=1.0"+        , normaliseExample "<=1 || >=1.0"  ">=0"+        , normaliseExample ">0 && <0.0"    "<0"++        , normaliseExample "^>=1.5.0.1 || ^>=1.6.0.1 || >=1.9 && <1.13"+                           "^>=1.5.0.1 || ^>=1.6.0.1 || >=1.9 && <1.12 || ^>=1.12"++        , cannotNormaliseExample "^>=0 && >=0.1" IntervalsEmpty++        , testProperty "involutive"   normalise_involutive++        , testProperty "complete"     normalise_complete+        , testProperty "complete_lax" normalise_complete_lax++        , testProperty "involutive ex1" $ normalise_involutive $+            intersectVersionRanges (majorBoundVersion (mkVersion [3])) (laterVersion (mkVersion [3]))+        ]+    ]++normaliseExample :: String -> String -> TestTree+normaliseExample input expected = testCase input $ do+    input'   <- either fail return $ eitherParsec input+    expected' <- either fail return $ eitherParsec expected++    VersionInterval.normaliseVersionRange input' @?= Right expected'++cannotNormaliseExample :: String -> ConversionProblem -> TestTree+cannotNormaliseExample input problem = testCase ("cannot " ++ input) $ do+    input'   <- either fail return $ eitherParsec input++    VersionInterval.normaliseVersionRange input' @?= Left problem++-------------------------------------------------------------------------------+-- Intersect+-------------------------------------------------------------------------------++intersect_complete :: VersionInterval -> VersionInterval -> Version -> QC.Property+intersect_complete a b v =+    QC.counterexample ("intersection: " ++ show (ab, inA, inB)) $ (inA && inB) === inAB+  where+    ab   = intersectInterval a b+    inA  = withinInterval v a+    inB  = withinInterval v b+    inAB = maybe False (withinInterval v) ab++intersect_complete_lax :: VersionInterval -> VersionInterval -> Version -> QC.Property+intersect_complete_lax a b v =+    QC.counterexample ("intersection: " ++ show (ab, inA, inB)) $ (inA && inB) === inAB+  where+    ab   = intersectInterval a b+    inA  = withinIntervalLax v a+    inB  = withinIntervalLax v b+    inAB = maybe False (withinIntervalLax v) ab++-------------------------------------------------------------------------------+-- Stage 1+-------------------------------------------------------------------------------++stage1_valid :: VersionRange -> QC.Property+stage1_valid vr = QC.counterexample ("stage1: " ++ show is) $ QC.property $ all validVersionInterval is+  where+    is = stage1 id vr++stage1_complete :: VersionRange -> Version -> QC.Property+stage1_complete vr v = QC.counterexample ("stage1: " ++ show is) $ withinRange v vr === any (withinInterval v) is+  where+    is = stage1 id vr++stage1_complete_lax :: VersionRange -> Version -> QC.Property+stage1_complete_lax vr v = QC.counterexample ("stage1: " ++ show is) $ withinRangeLax v vr === any (withinIntervalLax v) is+  where+    is = stage1 id vr++-------------------------------------------------------------------------------+-- Stage 2+-------------------------------------------------------------------------------++stage2_valid :: [VersionInterval] -> QC.Property+stage2_valid is' = QC.counterexample ("stage2: " ++ show is) $ QC.property $ all validVersionInterval is+  where+    is = stage2 is'++stage2_involutive :: [VersionInterval] -> QC.Property+stage2_involutive is' = is1 === is2+  where+    is1 = stage2 is'+    is2 = stage2 is1++stage2_complete :: [VersionInterval] -> Version -> QC.Property+stage2_complete is' v = QC.counterexample ("stage2: " ++ show is) $ any (withinInterval v) is' === any (withinInterval v) is+  where+    is = stage2 is'++stage2_complete_lax :: [VersionInterval] -> Version -> QC.Property+stage2_complete_lax is' v = QC.counterexample ("stage2: " ++ show is) $ any (withinIntervalLax v) is' === any (withinIntervalLax v) is+  where+    is = stage2 is'++-------------------------------------------------------------------------------+-- Stage 3+-------------------------------------------------------------------------------++stage3_valid :: [VersionInterval] -> QC.Property+stage3_valid is' = QC.counterexample ("stage3: " ++ show is) $ QC.property $ all validVersionInterval is+  where+    is = stage3 (stage2 is')++stage3_involutive :: [VersionInterval] -> QC.Property+stage3_involutive is' = is1 === is2+  where+    is1 = stage3 (stage2 is')+    is2 = stage3 is1++stage3_complete :: [VersionInterval] -> Version -> QC.Property+stage3_complete is' v = QC.counterexample ("stage3: " ++ show is) $ any (withinInterval v) is' === any (withinInterval v) is+  where+    is = stage3 (stage2 is')++stage3_complete_lax :: [VersionInterval] -> Version -> QC.Property+stage3_complete_lax is' v = QC.counterexample ("stage3: " ++ show is) $ any (withinIntervalLax v) is' === any (withinIntervalLax v) is+  where+    is = stage3 (stage2 is')++-------------------------------------------------------------------------------+-- Normalise+-------------------------------------------------------------------------------++normalise_involutive :: VersionRange -> QC.Property+normalise_involutive vr = vr1 === vr2 where+    vr1 = VersionInterval.normaliseVersionRange vr+    vr2 = VersionInterval.normaliseVersionRange =<< vr1++normalise_complete :: VersionRange -> Version -> QC.Property+normalise_complete vr v = case VersionInterval.normaliseVersionRange vr of+    Left _    -> QC.property True+    Right vr' -> QC.counterexample ("normalised: " ++ show vr') $ withinRange v vr === withinRange v vr'++normalise_complete_lax :: VersionRange -> Version -> QC.Property+normalise_complete_lax vr v = case VersionInterval.normaliseVersionRange vr of+    Left _    -> QC.property True+    Right vr' -> QC.counterexample ("normalised: " ++ show vr') $ withinRangeLax v vr === withinRangeLax v vr'++-------------------------------------------------------------------------------+-- Predicates+-------------------------------------------------------------------------------++withinInterval :: Version -> VersionInterval -> Bool+withinInterval v (VI l m u) = viGreater l && viLessM m && viLess u where+    viGreater (LB v') = v >= v'++    viLessM NoMB    = True+    viLessM (MB v') = v < v'++    viLess NoUB    = True+    viLess (UB v') = v < v'++withinIntervalLax :: Version -> VersionInterval -> Bool+withinIntervalLax v (VI l _ u) = viGreater l && viLess u where+    viGreater (LB v') = v >= v'++    viLess NoUB    = True+    viLess (UB v') = v < v'++withinRangeLax :: Version -> VersionRange -> Bool+withinRangeLax v vr = withinRange v (transformCaretUpper vr)++-------------------------------------------------------------------------------+-- QC instances+-------------------------------------------------------------------------------++instance Arbitrary Version where+    arbitrary = QC.oneof+        [ mkVersion <$> replicateM d vDigit+        | d <- [1..4]+        ]+      where+        vDigit :: QC.Gen Int+        vDigit = QC.elements [0..9]++    shrink v =+        [ mkVersion v'+        | v' <- shrink (versionNumbers v)+        , not (null v')+        ]++instance Arbitrary VersionRange where+    arbitrary = QC.sized $ \n -> genVersionRange (intLog2 (max 1 n))++    shrink vr = case projectVersionRange vr of+        LaterVersionF v -> laterVersion <$> shrink v+        OrLaterVersionF v -> orLaterVersion <$> shrink v+        EarlierVersionF v -> earlierVersion <$> shrink v+        OrEarlierVersionF v -> orEarlierVersion <$> shrink v+        ThisVersionF v -> thisVersion <$> shrink v+        MajorBoundVersionF v -> majorBoundVersion <$> shrink v+        UnionVersionRangesF l r -> l : r : fmap (uncurry unionVersionRanges) (shrink (l, r))+        IntersectVersionRangesF l r -> l : r : fmap (uncurry intersectVersionRanges) (shrink (l, r))++genVersionRange :: Int -> QC.Gen VersionRange+genVersionRange n+    | n <= 1 = QC.oneof+        [ pure anyVersion+        , thisVersion <$> arbitrary+        , notThisVersion <$> arbitrary+        , laterVersion <$> arbitrary+        , earlierVersion <$> arbitrary+        , orLaterVersion <$> arbitrary+        , orEarlierVersion <$> arbitrary+        , withinVersion  <$> arbitrary+        , majorBoundVersion <$> arbitrary+        ]+    | otherwise = do+        l <- QC.chooseInt (1, n - 1)+        let r = n - l+        QC.oneof+            [ unionVersionRanges <$> genVersionRange l <*> genVersionRange r+            , intersectVersionRanges <$> genVersionRange l <*> genVersionRange r+            ]++instance Arbitrary VersionInterval where+    arbitrary = QC.suchThat (VI <$> arbitrary <*> arbitrary <*> arbitrary) validVersionInterval++    shrink (VI l m u) =+        [ vi+        | (l', m', u') <- shrink (l, m, u)+        , let vi = VI l' m' u'+        , validVersionInterval vi+        ]++instance Arbitrary LB where+    arbitrary = LB <$> arbitrary+    shrink (LB v) = LB <$> shrink v++instance Arbitrary UB where+    arbitrary = QC.oneof+        [ pure NoUB+        , UB <$> arbitrary+        ]++    shrink NoUB     = []+    shrink (UB v) = NoUB : map UB (shrink v)++instance Arbitrary MB where+    arbitrary = QC.oneof+        [ pure NoMB+        , MB <$> arbitrary+        ]++    shrink NoMB     = []+    shrink (MB v) = NoMB : map MB (shrink v)
tests/Golden.hs view
@@ -1,6 +1,8 @@ module Main (main) where  import System.FilePath            ((-<.>), (</>))+import System.IO                  (hClose, hFlush)+import System.IO.Temp             (withSystemTempFile) import System.Process             (readProcessWithExitCode) import Test.Tasty                 (TestTree, defaultMain, testGroup) import Test.Tasty.Golden.Advanced (goldenTest)@@ -10,15 +12,17 @@ import qualified Data.Map              as Map  import CabalFmt         (cabalFmt)-import CabalFmt.Prelude import CabalFmt.Monad   (runCabalFmt) import CabalFmt.Options (defaultOptions)+import CabalFmt.Prelude  main :: IO () main = defaultMain $ testGroup "tests"     [ goldenTest' "cabal-fmt"     , goldenTest' "Cabal"+    , goldenTest' "Cabal-notab"     , goldenTest' "simple-example"+    , goldenTest' "tree-diff"      , goldenTest' "fragment-missing"     , goldenTest' "fragment-empty"@@ -50,8 +54,23 @@                         return (toUTF8BS $ unlines (map ("-- " ++) ws) ++ output')      cmp a b | a == b    = return Nothing-            | otherwise = Just <$> readProcess' "diff" ["-u", goldenPath, "-"] (fromUTF8BS b)+            | otherwise =+        withSystemTempFile "cabal-fmt-test.txt" $ \fpA hdlA ->+        withSystemTempFile "cabal-fmt-test.txt" $ \fpB hdlB -> do+            BS.hPutStr hdlA a+            BS.hPutStr hdlB b+            hFlush hdlA+            hFlush hdlB+            hClose hdlA+            hClose hdlB +            Just . postProcess <$> readProcess' "diff" ["-u", fpA, fpB] ""++    postProcess :: String -> String+    postProcess = unlines . (["======"] ++) . map (concatMap char) . (++ ["======"]). lines where+        char '\r' = "{CR}"+        char c    = [c]+     readProcess' proc args input = do         (_, out, _) <- readProcessWithExitCode proc args input         return out@@ -72,10 +91,10 @@     , p "multiple.fragment"         "build-depends: base\nghc-options: -Wall" -    , p "cbits/header.h" "..."-    , p "cbits/source1.c" "..."-    , p "cbits/source2.c" "..."-    , p "cbits/sub/source3.c" "..."+    , p ("cbits" </> "header.h") "..."+    , p ("cbits" </> "source1.c") "..."+    , p ("cbits" </> "source2.c") "..."+    , p ("cbits" </> "sub" </> "source3.c") "..."     ]   where     p x y = (x, BS8.pack y)