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 +8/−0
- cabal-fmt.cabal +49/−13
- cli/Main.hs +0/−2
- fixtures/Cabal-notab.cabal +653/−0
- fixtures/Cabal-notab.format +675/−0
- fixtures/cabal-fmt.format +2/−2
- fixtures/simple-example.cabal +5/−0
- fixtures/simple-example.format +9/−3
- fixtures/tree-diff.cabal +190/−0
- fixtures/tree-diff.format +190/−0
- fixtures/with-sublibs.cabal +12/−0
- fixtures/with-sublibs.format +11/−0
- src-interval/VersionInterval.hs +444/−0
- src/CabalFmt.hs +12/−14
- src/CabalFmt/Error.hs +1/−1
- src/CabalFmt/Fields.hs +7/−1
- src/CabalFmt/Fields/BuildDepends.hs +107/−93
- src/CabalFmt/Fields/Extensions.hs +6/−6
- src/CabalFmt/Fields/Modules.hs +6/−6
- src/CabalFmt/Fields/SourceFiles.hs +9/−7
- src/CabalFmt/Fields/TestedWith.hs +3/−3
- src/CabalFmt/Glob.hs +7/−6
- src/CabalFmt/Monad.hs +7/−4
- src/CabalFmt/Prelude.hs +3/−3
- src/CabalFmt/Refactoring/ExpandExposedModules.hs +2/−1
- src/CabalFmt/Refactoring/Fragments.hs +2/−2
- src/CabalFmt/Refactoring/GlobFiles.hs +10/−5
- tests-interval/version-interval-tests.hs +367/−0
- tests/Golden.hs +25/−6
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)