From 10687555d3c8524d5f5f373128ee80ccd56322bb Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Tue, 4 May 2021 14:04:19 -0400 Subject: [PATCH 01/37] Rewrite `cabal init` command * Restructures the `cabal init` command to fix historical issues. All flags are preserved. * Codebases for interactive and non-interactive flags are disentangled. * Data structures now exploit relevant stanza structure and formatters only care about stanza data * Heuristics and prompts have a pure and impure implementation. * Sets default behavior to be `--interactive` as opposed to `--non-interactive`. * Rewrites tests to achieve 98% coverage * Golden files now test every stanza individually * Every flag is covered by a unit test * Interactive, simple, and non-interactive workflows are covered. --- Cabal/src/Distribution/Fields/Pretty.hs | 13 +- Cabal/src/Distribution/Simple/Test/ExeV10.hs | 4 +- Cabal/src/Distribution/Simple/Test/LibV09.hs | 11 +- cabal-install/cabal-install.cabal | 14 +- cabal-install/main/Main.hs | 44 +- .../src/Distribution/Client/Config.hs | 4 +- .../src/Distribution/Client/GenBounds.hs | 4 +- cabal-install/src/Distribution/Client/Init.hs | 56 +- .../src/Distribution/Client/Init/Command.hs | 749 ----------- .../src/Distribution/Client/Init/Defaults.hs | 182 ++- .../Distribution/Client/Init/FileCreators.hs | 851 ++++-------- .../Client/Init/FlagExtractors.hs | 267 ++++ .../src/Distribution/Client/Init/Format.hs | 338 +++++ .../Distribution/Client/Init/Heuristics.hs | 396 ------ .../Client/Init/Interactive/Command.hs | 459 +++++++ .../Client/Init/NonInteractive/Command.hs | 437 +++++++ .../Client/Init/NonInteractive/Heuristics.hs | 179 +++ .../src/Distribution/Client/Init/Prompt.hs | 243 ++-- .../src/Distribution/Client/Init/Simple.hs | 138 ++ .../src/Distribution/Client/Init/Types.hs | 505 +++++-- .../src/Distribution/Client/Init/Utils.hs | 293 ++++- .../Distribution/Client/ProjectPlanning.hs | 4 +- .../src/Distribution/Client/Setup.hs | 37 +- .../src/Distribution/Client/Utils.hs | 139 +- cabal-install/tests/UnitTests.hs | 5 +- .../UnitTests/Distribution/Client/Init.hs | 241 +--- .../Distribution/Client/Init/Golden.hs | 367 ++++++ .../Distribution/Client/Init/Interactive.hs | 832 ++++++++++++ .../Client/Init/NonInteractive.hs | 1158 +++++++++++++++++ .../Distribution/Client/Init/Simple.hs | 151 +++ .../Distribution/Client/Init/Utils.hs | 82 ++ .../tests/fixtures/init/exe-only-golden.cabal | 20 - .../cabal-lib-and-exe-no-comments.golden | 61 + .../cabal-lib-and-exe-with-comments.golden} | 69 +- .../golden/cabal/cabal-lib-no-comments.golden | 46 + .../cabal/cabal-lib-with-comments.golden | 90 ++ .../exe/exe-build-tools-with-comments.golden | 21 + .../golden/exe/exe-minimal-no-comments.golden | 5 + .../exe/exe-simple-with-comments.golden | 12 + .../init/golden/exe/exe-simple.golden | 13 + .../init/golden/exe/exe-with-comments.golden | 18 + .../tests/fixtures/init/golden/exe/exe.golden | 11 + .../lib/lib-build-tools-with-comments.golden | 21 + .../golden/lib/lib-minimal-no-comments.golden | 5 + .../lib/lib-simple-with-comments.golden | 12 + .../init/golden/lib/lib-simple.golden | 11 + .../init/golden/lib/lib-with-comments.golden | 18 + .../tests/fixtures/init/golden/lib/lib.golden | 11 + .../pkg-desc/pkg-old-cabal-with-flags.golden | 45 + .../init/golden/pkg-desc/pkg-simple.golden | 21 + .../golden/pkg-desc/pkg-with-comments.golden | 46 + .../golden/pkg-desc/pkg-with-flags.golden | 46 + .../fixtures/init/golden/pkg-desc/pkg.golden | 46 + .../test-build-tools-with-comments.golden | 24 + .../test/test-minimal-no-comments.golden | 6 + .../test/test-simple-with-comments.golden | 15 + .../init/golden/test/test-simple.golden | 14 + .../golden/test/test-with-comments.golden | 21 + .../fixtures/init/golden/test/test.golden | 12 + .../fixtures/init/lib-and-exe-golden.cabal | 31 - .../init/lib-exe-and-test-golden.cabal | 43 - cabal.project | 3 +- .../cabal-lib-and-exe-no-comments.golden | 61 + .../cabal-lib-and-exe-with-comments.golden | 111 ++ .../golden/cabal/cabal-lib-no-comments.golden | 46 + .../cabal/cabal-lib-with-comments.golden | 90 ++ .../exe/exe-build-tools-with-comments.golden | 21 + .../golden/exe/exe-minimal-no-comments.golden | 5 + .../exe/exe-simple-with-comments.golden | 12 + .../init/golden/exe/exe-with-comments.golden | 18 + tests/fixtures/init/golden/exe/exe.golden | 11 + .../lib/lib-build-tools-with-comments.golden | 21 + .../golden/lib/lib-minimal-no-comments.golden | 5 + .../lib/lib-simple-with-comments.golden | 12 + .../init/golden/lib/lib-simple.golden | 11 + .../init/golden/lib/lib-with-comments.golden | 18 + tests/fixtures/init/golden/lib/lib.golden | 11 + .../pkg-desc/pkg-old-cabal-with-flags.golden | 45 + .../golden/pkg-desc/pkg-with-comments.golden | 46 + .../golden/pkg-desc/pkg-with-flags.golden | 46 + .../fixtures/init/golden/pkg-desc/pkg.golden | 46 + .../test-build-tools-with-comments.golden | 24 + .../test/test-minimal-no-comments.golden | 6 + .../test/test-simple-with-comments.golden | 15 + .../golden/test/test-with-comments.golden | 21 + tests/fixtures/init/golden/test/test.golden | 12 + 86 files changed, 7286 insertions(+), 2448 deletions(-) delete mode 100644 cabal-install/src/Distribution/Client/Init/Command.hs create mode 100644 cabal-install/src/Distribution/Client/Init/FlagExtractors.hs create mode 100644 cabal-install/src/Distribution/Client/Init/Format.hs delete mode 100644 cabal-install/src/Distribution/Client/Init/Heuristics.hs create mode 100644 cabal-install/src/Distribution/Client/Init/Interactive/Command.hs create mode 100644 cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs create mode 100644 cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs create mode 100644 cabal-install/src/Distribution/Client/Init/Simple.hs create mode 100644 cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs create mode 100644 cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs create mode 100644 cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs create mode 100644 cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs create mode 100644 cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs delete mode 100644 cabal-install/tests/fixtures/init/exe-only-golden.cabal create mode 100644 cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden rename cabal-install/tests/fixtures/init/{lib-exe-and-test-with-comments-golden.cabal => golden/cabal/cabal-lib-and-exe-with-comments.golden} (65%) create mode 100644 cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden create mode 100644 cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden create mode 100644 cabal-install/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden create mode 100644 cabal-install/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden create mode 100644 cabal-install/tests/fixtures/init/golden/exe/exe-simple-with-comments.golden create mode 100644 cabal-install/tests/fixtures/init/golden/exe/exe-simple.golden create mode 100644 cabal-install/tests/fixtures/init/golden/exe/exe-with-comments.golden create mode 100644 cabal-install/tests/fixtures/init/golden/exe/exe.golden create mode 100644 cabal-install/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden create mode 100644 cabal-install/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden create mode 100644 cabal-install/tests/fixtures/init/golden/lib/lib-simple-with-comments.golden create mode 100644 cabal-install/tests/fixtures/init/golden/lib/lib-simple.golden create mode 100644 cabal-install/tests/fixtures/init/golden/lib/lib-with-comments.golden create mode 100644 cabal-install/tests/fixtures/init/golden/lib/lib.golden create mode 100644 cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden create mode 100644 cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-simple.golden create mode 100644 cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden create mode 100644 cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden create mode 100644 cabal-install/tests/fixtures/init/golden/pkg-desc/pkg.golden create mode 100644 cabal-install/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden create mode 100644 cabal-install/tests/fixtures/init/golden/test/test-minimal-no-comments.golden create mode 100644 cabal-install/tests/fixtures/init/golden/test/test-simple-with-comments.golden create mode 100644 cabal-install/tests/fixtures/init/golden/test/test-simple.golden create mode 100644 cabal-install/tests/fixtures/init/golden/test/test-with-comments.golden create mode 100644 cabal-install/tests/fixtures/init/golden/test/test.golden delete mode 100644 cabal-install/tests/fixtures/init/lib-and-exe-golden.cabal delete mode 100644 cabal-install/tests/fixtures/init/lib-exe-and-test-golden.cabal create mode 100644 tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden create mode 100644 tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden create mode 100644 tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden create mode 100644 tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden create mode 100644 tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden create mode 100644 tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden create mode 100644 tests/fixtures/init/golden/exe/exe-simple-with-comments.golden create mode 100644 tests/fixtures/init/golden/exe/exe-with-comments.golden create mode 100644 tests/fixtures/init/golden/exe/exe.golden create mode 100644 tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden create mode 100644 tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden create mode 100644 tests/fixtures/init/golden/lib/lib-simple-with-comments.golden create mode 100644 tests/fixtures/init/golden/lib/lib-simple.golden create mode 100644 tests/fixtures/init/golden/lib/lib-with-comments.golden create mode 100644 tests/fixtures/init/golden/lib/lib.golden create mode 100644 tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden create mode 100644 tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden create mode 100644 tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden create mode 100644 tests/fixtures/init/golden/pkg-desc/pkg.golden create mode 100644 tests/fixtures/init/golden/test/test-build-tools-with-comments.golden create mode 100644 tests/fixtures/init/golden/test/test-minimal-no-comments.golden create mode 100644 tests/fixtures/init/golden/test/test-simple-with-comments.golden create mode 100644 tests/fixtures/init/golden/test/test-with-comments.golden create mode 100644 tests/fixtures/init/golden/test/test.golden diff --git a/Cabal/src/Distribution/Fields/Pretty.hs b/Cabal/src/Distribution/Fields/Pretty.hs index 7af4728cee2..dfca73a19d4 100644 --- a/Cabal/src/Distribution/Fields/Pretty.hs +++ b/Cabal/src/Distribution/Fields/Pretty.hs @@ -2,6 +2,7 @@ {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveFoldable #-} {-# LANGUAGE DeriveTraversable #-} +{-# LANGUAGE LambdaCase #-} -- | Cabal-like file AST types: 'Field', 'Section' etc, -- -- This (intermediate) data type is used for pretty-printing. @@ -35,6 +36,7 @@ import qualified Text.PrettyPrint as PP data PrettyField ann = PrettyField ann FieldName PP.Doc | PrettySection ann FieldName [PP.Doc] [PrettyField ann] + | PrettyEmpty deriving (Functor, Foldable, Traversable) -- | Prettyprint a list of fields. @@ -74,8 +76,8 @@ showFields' rann post n = unlines . renderFields (Opts rann indent post) indent2 xs = ' ' : ' ' : xs data Opts ann = Opts - { _optAnnotation ::(ann -> [String]) - , _optIndent ::(String -> String) + { _optAnnotation :: ann -> [String] + , _optIndent :: String -> String , _optPostprocess :: ann -> [String] -> [String] } @@ -87,6 +89,7 @@ renderFields opts fields = flattenBlocks $ map (renderField opts len) fields maxNameLength !acc [] = acc maxNameLength !acc (PrettyField _ name _ : rest) = maxNameLength (max acc (BS.length name)) rest maxNameLength !acc (PrettySection {} : rest) = maxNameLength acc rest + maxNameLength !acc (PrettyEmpty : rest) = maxNameLength acc rest -- | Block of lines, -- Boolean parameter tells whether block should be surrounded by empty lines @@ -134,7 +137,9 @@ renderField opts@(Opts rann indent post) _ (PrettySection ann name args fields) ++ post ann [ PP.render $ PP.hsep $ PP.text (fromUTF8BS name) : args ] ++ - (map indent $ renderFields opts fields) + map indent (renderFields opts fields) + +renderField _ _ PrettyEmpty = Block NoMargin NoMargin mempty ------------------------------------------------------------------------------- -- Transform from Parsec.Field @@ -161,7 +166,7 @@ prettyFieldLines _ fls = PP.vcat -- | Used in 'fromParsecFields'. prettySectionArgs :: FieldName -> [P.SectionArg ann] -> [PP.Doc] -prettySectionArgs _ = map $ \sa -> case sa of +prettySectionArgs _ = map $ \case P.SecArgName _ bs -> showToken $ fromUTF8BS bs P.SecArgStr _ bs -> showToken $ fromUTF8BS bs P.SecArgOther _ bs -> PP.text $ fromUTF8BS bs diff --git a/Cabal/src/Distribution/Simple/Test/ExeV10.hs b/Cabal/src/Distribution/Simple/Test/ExeV10.hs index 3a80f94027a..345ee0807fb 100644 --- a/Cabal/src/Distribution/Simple/Test/ExeV10.hs +++ b/Cabal/src/Distribution/Simple/Test/ExeV10.hs @@ -118,7 +118,7 @@ runTest pkg_descr lbi clbi flags suite = do let suiteLog = buildLog exit -- Write summary notice to log file indicating start of test suite - appendFile (logFile suiteLog) $ summarizeSuiteStart $ testName' + appendFile (logFile suiteLog) $ summarizeSuiteStart testName' -- Append contents of temporary log file to the final human- -- readable log file @@ -144,7 +144,7 @@ runTest pkg_descr lbi clbi flags suite = do when isCoverageEnabled $ case PD.library pkg_descr of Nothing -> - die' verbosity $ "Error: test coverage is only supported for packages with a library component" + die' verbosity "Error: test coverage is only supported for packages with a library component" Just library -> markupTest verbosity lbi distPref (prettyShow $ PD.package pkg_descr) suite library diff --git a/Cabal/src/Distribution/Simple/Test/LibV09.hs b/Cabal/src/Distribution/Simple/Test/LibV09.hs index d667d7e0d48..2302e7773e8 100644 --- a/Cabal/src/Distribution/Simple/Test/LibV09.hs +++ b/Cabal/src/Distribution/Simple/Test/LibV09.hs @@ -158,12 +158,11 @@ runTest pkg_descr lbi clbi flags suite = do notice verbosity $ summarizeSuiteFinish suiteLog when isCoverageEnabled $ - case PD.library pkg_descr of - Nothing -> - die' verbosity $ "Error: test coverage is only supported for packages with a library component" - - Just library -> - markupTest verbosity lbi distPref (prettyShow $ PD.package pkg_descr) suite library + case PD.library pkg_descr of + Nothing -> + die' verbosity "Error: test coverage is only supported for packages with a library component" + Just library -> + markupTest verbosity lbi distPref (prettyShow $ PD.package pkg_descr) suite library return suiteLog where diff --git a/cabal-install/cabal-install.cabal b/cabal-install/cabal-install.cabal index 8e42a9bc7dd..25c73f285ea 100644 --- a/cabal-install/cabal-install.cabal +++ b/cabal-install/cabal-install.cabal @@ -119,12 +119,16 @@ library Distribution.Client.IndexUtils.IndexState Distribution.Client.IndexUtils.Timestamp Distribution.Client.Init - Distribution.Client.Init.Command Distribution.Client.Init.Defaults Distribution.Client.Init.FileCreators - Distribution.Client.Init.Heuristics + Distribution.Client.Init.FlagExtractors + Distribution.Client.Init.Format + Distribution.Client.Init.Interactive.Command + Distribution.Client.Init.NonInteractive.Command + Distribution.Client.Init.NonInteractive.Heuristics Distribution.Client.Init.Licenses Distribution.Client.Init.Prompt + Distribution.Client.Init.Simple Distribution.Client.Init.Types Distribution.Client.Init.Utils Distribution.Client.Install @@ -203,6 +207,7 @@ library directory >= 1.2.2.0 && < 1.4, echo >= 0.1.3 && < 0.2, edit-distance >= 0.2.2 && < 0.3, + exceptions, filepath >= 1.4.0.0 && < 1.5, hashable >= 1.0 && < 1.4, HTTP >= 4000.1.5 && < 4000.4, @@ -273,6 +278,11 @@ Test-Suite unit-tests UnitTests.Distribution.Client.Glob UnitTests.Distribution.Client.GZipUtils UnitTests.Distribution.Client.Init + UnitTests.Distribution.Client.Init.Golden + UnitTests.Distribution.Client.Init.Interactive + UnitTests.Distribution.Client.Init.NonInteractive + UnitTests.Distribution.Client.Init.Simple + UnitTests.Distribution.Client.Init.Utils UnitTests.Distribution.Client.Store UnitTests.Distribution.Client.Tar UnitTests.Distribution.Client.TreeDiffInstances diff --git a/cabal-install/main/Main.hs b/cabal-install/main/Main.hs index fcbed901807..6bb112a26a5 100644 --- a/cabal-install/main/Main.hs +++ b/cabal-install/main/Main.hs @@ -13,6 +13,7 @@ -- Entry point to the default cabal-install front-end. ----------------------------------------------------------------------------- +{-# OPTIONS_GHC -Wno-deferred-type-errors #-} module Main (main) where import Distribution.Client.Setup @@ -109,11 +110,12 @@ import Distribution.Client.Sandbox (loadConfigOrSandboxConfig ,updateInstallDirs) import Distribution.Client.Tar (createTarGzFile) import Distribution.Client.Types.Credentials (Password (..)) -import Distribution.Client.Init (initCabal) +import Distribution.Client.Init (initCmd) import Distribution.Client.Manpage (manpageCmd) import Distribution.Client.ManpageFlags (ManpageFlags (..)) import Distribution.Client.Utils (determineNumJobs ,relaxEncodingErrors + ,cabalInstallVersion ) import Distribution.Package (packageId) @@ -219,9 +221,9 @@ mainWorker args = do ++ "defaults if you run 'cabal update'." printOptionsList = putStr . unlines printErrors errs = dieNoVerbosity $ intercalate "\n" errs - printNumericVersion = putStrLn $ display cabalVersion + printNumericVersion = putStrLn $ display cabalInstallVersion printVersion = putStrLn $ "cabal-install version " - ++ display cabalVersion + ++ display cabalInstallVersion ++ "\ncompiled using version " ++ display cabalVersion ++ " of the Cabal library " @@ -918,24 +920,24 @@ unpackAction getFlags extraArgs globalFlags = do getAction getFlags extraArgs globalFlags initAction :: InitFlags -> [String] -> Action -initAction initFlags extraArgs globalFlags = do - let verbosity = fromFlag (initVerbosity initFlags) - when (extraArgs /= []) $ - die' verbosity $ "'init' doesn't take any extra arguments: " ++ unwords extraArgs - config <- loadConfigOrSandboxConfig verbosity globalFlags - let configFlags = savedConfigureFlags config `mappend` - -- override with `--with-compiler` from CLI if available - mempty { configHcPath = initHcPath initFlags } - let initFlags' = savedInitFlags config `mappend` initFlags - let globalFlags' = savedGlobalFlags config `mappend` globalFlags - (comp, _, progdb) <- configCompilerAux' configFlags - withRepoContext verbosity globalFlags' $ \repoContext -> - initCabal verbosity - (configPackageDB' configFlags) - repoContext - comp - progdb - initFlags' +initAction initFlags extraArgs globalFlags + | not (null extraArgs) = + die' verbosity $ "'init' doesn't take any extra arguments: " ++ unwords extraArgs + | otherwise = do + confFlags <- loadConfigOrSandboxConfig verbosity globalFlags + -- override with `--with-compiler` from CLI if available + let confFlags' = savedConfigureFlags confFlags `mappend` compFlags + initFlags' = savedInitFlags confFlags `mappend` initFlags + globalFlags' = savedGlobalFlags confFlags `mappend` globalFlags + + (comp, _, progdb) <- configCompilerAux' confFlags' + + withRepoContext verbosity globalFlags' $ \repoContext -> + initCmd verbosity (configPackageDB' confFlags') + repoContext comp progdb initFlags' + where + verbosity = fromFlag (initVerbosity initFlags) + compFlags = mempty { configHcPath = initHcPath initFlags } userConfigAction :: UserConfigFlags -> [String] -> Action userConfigAction ucflags extraArgs globalFlags = do diff --git a/cabal-install/src/Distribution/Client/Config.hs b/cabal-install/src/Distribution/Client/Config.hs index e7277535587..26ae5a87e3e 100644 --- a/cabal-install/src/Distribution/Client/Config.hs +++ b/cabal-install/src/Distribution/Client/Config.hs @@ -841,8 +841,8 @@ commentSavedConfig = do IT.cabalVersion = toFlag IT.defaultCabalVersion, IT.language = toFlag Haskell2010, IT.license = NoFlag, - IT.sourceDirs = Just [IT.defaultSourceDir], - IT.applicationDirs = Just [IT.defaultApplicationDir] + IT.sourceDirs = Flag [IT.defaultSourceDir], + IT.applicationDirs = Flag [IT.defaultApplicationDir] }, savedInstallFlags = defaultInstallFlags, savedClientInstallFlags= defaultClientInstallFlags, diff --git a/cabal-install/src/Distribution/Client/GenBounds.hs b/cabal-install/src/Distribution/Client/GenBounds.hs index 5fe5ffd8ba6..3636f4ad663 100644 --- a/cabal-install/src/Distribution/Client/GenBounds.hs +++ b/cabal-install/src/Distribution/Client/GenBounds.hs @@ -18,7 +18,7 @@ module Distribution.Client.GenBounds ( import Prelude () import Distribution.Client.Compat.Prelude -import Distribution.Client.Init +import Distribution.Client.Utils ( incVersion ) import Distribution.Client.Freeze ( getFreezePkgs ) @@ -93,7 +93,7 @@ genBounds -> GlobalFlags -> FreezeFlags -> IO () -genBounds verbosity packageDBs repoCtxt comp platform progdb globalFlags freezeFlags = do +genBounds verbosity packageDBs repoCtxt comp platform progdb globalFlags freezeFlags = do let cinfo = compilerInfo comp cwd <- getCurrentDirectory diff --git a/cabal-install/src/Distribution/Client/Init.hs b/cabal-install/src/Distribution/Client/Init.hs index b7b37d23980..c463907581c 100644 --- a/cabal-install/src/Distribution/Client/Init.hs +++ b/cabal-install/src/Distribution/Client/Init.hs @@ -13,13 +13,53 @@ -- ----------------------------------------------------------------------------- -module Distribution.Client.Init ( +module Distribution.Client.Init +( -- * Commands + initCmd +) where - -- * Commands - initCabal - , incVersion +import qualified Distribution.Client.Init.Interactive.Command as Interactive +import qualified Distribution.Client.Init.NonInteractive.Command as NonInteractive +import qualified Distribution.Client.Init.Simple as Simple +import Distribution.Verbosity +import Distribution.Client.Setup (RepoContext) +import Distribution.Simple.Compiler +import Distribution.Simple.Program (ProgramDb) +import Distribution.Client.Init.Types +import Distribution.Simple.Setup +import Distribution.Client.IndexUtils +import System.IO (hSetBuffering, stdout, BufferMode (NoBuffering)) +import Distribution.Client.Init.FileCreators - ) where - -import Distribution.Client.Init.Command - ( initCabal, incVersion ) +-- | This is the main driver for the init script. +-- +initCmd + :: Verbosity + -> PackageDBStack + -> RepoContext + -> Compiler + -> ProgramDb + -> InitFlags + -> IO () +initCmd v packageDBs repoCtxt comp progdb initFlags = do + installedPkgIndex <- getInstalledPackages v comp packageDBs progdb + sourcePkgDb <- getSourcePackages v repoCtxt + hSetBuffering stdout NoBuffering + settings <- createProject v installedPkgIndex sourcePkgDb initFlags + writeProject settings + where + -- When no flag is set, default to interactive. + -- + -- When `--interactive` is set, if we also set `--simple`, + -- then we interactive generate a simple project with sensible defaults. + -- + -- If `--simple` is not set, default to interactive. When the flag + -- is explicitly set to `--non-interactive`, then we choose non-interactive. + -- + createProject = case interactive initFlags of + NoFlag -> Interactive.createProject + Flag True + | fromFlagOrDefault False (simpleProject initFlags) -> + Simple.createProject + | otherwise -> Interactive.createProject + Flag False -> NonInteractive.createProject diff --git a/cabal-install/src/Distribution/Client/Init/Command.hs b/cabal-install/src/Distribution/Client/Init/Command.hs deleted file mode 100644 index 0842250cd1b..00000000000 --- a/cabal-install/src/Distribution/Client/Init/Command.hs +++ /dev/null @@ -1,749 +0,0 @@ ------------------------------------------------------------------------------ --- | --- Module : Distribution.Client.Init.Command --- Copyright : (c) Brent Yorgey 2009 --- License : BSD-like --- --- Maintainer : cabal-devel@haskell.org --- Stability : provisional --- Portability : portable --- --- Implementation of the 'cabal init' command, which creates an initial .cabal --- file for a project. --- ------------------------------------------------------------------------------ - -module Distribution.Client.Init.Command - ( -- * Commands - initCabal - , incVersion - - -- * Helpers - , getSimpleProject - , getLibOrExec - , getCabalVersion - , getPackageName - , getVersion - , getLicense - , getAuthorInfo - , getHomepage - , getSynopsis - , getCategory - , getExtraSourceFiles - , getAppDir - , getSrcDir - , getGenTests - , getTestDir - , getLanguage - , getGenComments - , getModulesBuildToolsAndDeps - ) where - -import Prelude () -import Distribution.Client.Compat.Prelude hiding (empty) - -import System.IO - ( hSetBuffering, stdout, BufferMode(..) ) -import System.Directory - ( getCurrentDirectory, doesDirectoryExist, getDirectoryContents ) -import System.FilePath - ( (), takeBaseName, equalFilePath ) - -import qualified Data.List.NonEmpty as NE -import qualified Data.Map as M -import Control.Monad - ( (>=>) ) -import Control.Arrow - ( (&&&), (***) ) - -import Distribution.CabalSpecVersion - ( CabalSpecVersion (..), showCabalSpecVersion ) -import Distribution.Version - ( Version, mkVersion, alterVersion, majorBoundVersion - , orLaterVersion, earlierVersion, intersectVersionRanges, VersionRange ) -import Distribution.ModuleName - ( ModuleName ) -- And for the Text instance -import Distribution.InstalledPackageInfo - ( InstalledPackageInfo, exposed ) -import qualified Distribution.Package as P -import qualified Distribution.SPDX as SPDX -import Language.Haskell.Extension ( Language(..) ) - -import Distribution.Client.Init.Defaults - ( defaultApplicationDir, defaultCabalVersion, myLibModule, defaultSourceDir ) -import Distribution.Client.Init.FileCreators - ( writeLicense, writeChangeLog, createDirectories, createLibHs, createMainHs - , createTestSuiteIfEligible, writeCabalFile ) -import Distribution.Client.Init.Prompt - ( prompt, promptYesNo, promptStr, promptList, maybePrompt - , promptListOptional ) -import Distribution.Client.Init.Utils - ( eligibleForTestSuite, message ) -import Distribution.Client.Init.Types - ( InitFlags(..), PackageType(..), Category(..) - , displayPackageType ) -import Distribution.Client.Init.Heuristics - ( guessPackageName, guessAuthorNameMail, guessMainFileCandidates, - SourceFileEntry(..), - scanForModules, neededBuildPrograms ) - -import Distribution.Simple.Flag - ( maybeToFlag ) -import Distribution.Simple.Setup - ( Flag(..), flagToMaybe ) -import Distribution.Simple.Configure - ( getInstalledPackages ) -import Distribution.Simple.Compiler - ( PackageDBStack, Compiler ) -import Distribution.Simple.Program - ( ProgramDb ) -import Distribution.Simple.PackageIndex - ( InstalledPackageIndex, moduleNameIndex ) -import Distribution.Simple.Utils - ( die' ) - -import Distribution.Solver.Types.PackageIndex - ( elemByPackageName ) - -import Distribution.Client.IndexUtils - ( getSourcePackages ) -import Distribution.Client.Types - ( SourcePackageDb(..) ) -import Distribution.Client.Setup - ( RepoContext(..) ) - -initCabal :: Verbosity - -> PackageDBStack - -> RepoContext - -> Compiler - -> ProgramDb - -> InitFlags - -> IO () -initCabal verbosity packageDBs repoCtxt comp progdb initFlags = do - - installedPkgIndex <- getInstalledPackages verbosity comp packageDBs progdb - sourcePkgDb <- getSourcePackages verbosity repoCtxt - - hSetBuffering stdout NoBuffering - - initFlags' <- extendFlags verbosity installedPkgIndex sourcePkgDb initFlags - - case license initFlags' of - Flag SPDX.NONE -> return () - _ -> writeLicense initFlags' - writeChangeLog initFlags' - createDirectories (sourceDirs initFlags') - createLibHs initFlags' - createDirectories (applicationDirs initFlags') - createMainHs initFlags' - createTestSuiteIfEligible initFlags' - success <- writeCabalFile initFlags' - - when success $ generateWarnings initFlags' - ---------------------------------------------------------------------------- --- Flag acquisition ----------------------------------------------------- ---------------------------------------------------------------------------- - --- | Fill in more details in InitFlags by guessing, discovering, or prompting --- the user. -extendFlags :: Verbosity -> InstalledPackageIndex -> SourcePackageDb -> InitFlags -> IO InitFlags -extendFlags verbosity pkgIx sourcePkgDb = - getSimpleProject - >=> getLibOrExec - >=> getCabalVersion - >=> getPackageName verbosity sourcePkgDb False - >=> getVersion - >=> getLicense - >=> getAuthorInfo - >=> getHomepage - >=> getSynopsis - >=> getCategory - >=> getExtraSourceFiles - >=> getAppDir - >=> getSrcDir - >=> getGenTests - >=> getTestDir - >=> getLanguage - >=> getGenComments - >=> getModulesBuildToolsAndDeps pkgIx - --- | Combine two actions which may return a value, preferring the first. That --- is, run the second action only if the first doesn't return a value. -infixr 1 ?>> -(?>>) :: IO (Maybe a) -> IO (Maybe a) -> IO (Maybe a) -f ?>> g = do - ma <- f - if isJust ma - then return ma - else g - --- | Ask if a simple project with sensible defaults should be created. -getSimpleProject :: InitFlags -> IO InitFlags -getSimpleProject flags = do - simpleProj <- return (flagToMaybe $ simpleProject flags) - ?>> maybePrompt flags - (promptYesNo - "Should I generate a simple project with sensible defaults" - (Just True)) - return $ case maybeToFlag simpleProj of - Flag True -> - flags { interactive = Flag False - , simpleProject = Flag True - , packageType = Flag LibraryAndExecutable - , cabalVersion = Flag defaultCabalVersion - } - simpleProjFlag@_ -> - flags { simpleProject = simpleProjFlag } - - --- | Get the version of the cabal spec to use. --- --- The spec version can be specified by the InitFlags cabalVersion field. If --- none is specified then the user is prompted to pick from a list of --- supported versions (see code below). -getCabalVersion :: InitFlags -> IO InitFlags -getCabalVersion flags = do - cabVer <- return (flagToMaybe $ cabalVersion flags) - ?>> maybePrompt flags (either (const defaultCabalVersion) id `fmap` - promptList "Please choose version of the Cabal specification to use" - [CabalSpecV1_10, CabalSpecV2_0, CabalSpecV2_2, CabalSpecV2_4, CabalSpecV3_0] - (Just defaultCabalVersion) displayCabalVersion False) - ?>> return (Just defaultCabalVersion) - - return $ flags { cabalVersion = maybeToFlag cabVer } - - where - displayCabalVersion :: CabalSpecVersion -> String - displayCabalVersion v = case v of - CabalSpecV1_10 -> "1.10 (legacy)" - CabalSpecV2_0 -> "2.0 (+ support for Backpack, internal sub-libs, '^>=' operator)" - CabalSpecV2_2 -> "2.2 (+ support for 'common', 'elif', redundant commas, SPDX)" - CabalSpecV2_4 -> "2.4 (+ support for '**' globbing)" - CabalSpecV3_0 -> "3.0 (+ set notation for ==, common stanzas in ifs, more redundant commas, better pkgconfig-depends)" - _ -> showCabalSpecVersion v - - - --- | Get the package name: use the package directory (supplied, or the current --- directory by default) as a guess. It looks at the SourcePackageDb to avoid --- using an existing package name. -getPackageName :: Verbosity -> SourcePackageDb -> Bool -> InitFlags -> IO InitFlags -getPackageName verbosity sourcePkgDb forceAsk flags = do - guess <- maybe (getCurrentDirectory >>= guessPackageName) pure - =<< traverse guessPackageName (flagToMaybe $ packageDir flags) - - pkgName' <- case (flagToMaybe $ packageName flags) >>= maybeForceAsk of - Just pkgName -> return $ Just $ pkgName - _ -> maybePrompt flags (prompt "Package name" (Just guess)) - let pkgName = fromMaybe guess pkgName' - - chooseAgain <- if isPkgRegistered pkgName - then do - answer' <- maybePrompt flags (promptYesNo (promptOtherNameMsg pkgName) (Just True)) - case answer' of - Just answer -> return answer - _ -> die' verbosity $ inUseMsg pkgName - else - return False - - if chooseAgain - then getPackageName verbosity sourcePkgDb True flags - else return $ flags { packageName = Flag pkgName } - - where - maybeForceAsk x = if forceAsk then Nothing else Just x - - isPkgRegistered pkg = elemByPackageName (packageIndex sourcePkgDb) pkg - - inUseMsg pkgName = "The name " ++ (P.unPackageName pkgName) ++ - " is already in use by another package on Hackage." - - promptOtherNameMsg pkgName = (inUseMsg pkgName) ++ - " Do you want to choose a different name" - --- | Package version: use 0.1.0.0 as a last resort, but try prompting the user --- if possible. -getVersion :: InitFlags -> IO InitFlags -getVersion flags = do - let v = Just $ mkVersion [0,1,0,0] - v' <- return (flagToMaybe $ version flags) - ?>> maybePrompt flags (prompt "Package version" v) - ?>> return v - return $ flags { version = maybeToFlag v' } - --- | Choose a license for the package. --- --- The license can come from Initflags (license field), if it is not present --- then prompt the user from a predefined list of licenses. -getLicense :: InitFlags -> IO InitFlags -getLicense flags = do - elic <- return (fmap Right $ flagToMaybe $ license flags) - ?>> maybePrompt flags (promptList "Please choose a license" listedLicenses (Just SPDX.NONE) prettyShow True) - - case elic of - Nothing -> return flags { license = NoFlag } - Just (Right lic) -> return flags { license = Flag lic } - Just (Left str) -> case eitherParsec str of - Right lic -> return flags { license = Flag lic } - -- on error, loop - Left err -> do - putStrLn "The license must be a valid SPDX expression." - putStrLn err - getLicense flags - where - -- perfectly we'll have this and writeLicense (in FileCreators) - -- in a single file - listedLicenses = - SPDX.NONE : - map (\lid -> SPDX.License (SPDX.ELicense (SPDX.ELicenseId lid) Nothing)) - [ SPDX.BSD_2_Clause - , SPDX.BSD_3_Clause - , SPDX.Apache_2_0 - , SPDX.MIT - , SPDX.MPL_2_0 - , SPDX.ISC - - , SPDX.GPL_2_0_only - , SPDX.GPL_3_0_only - , SPDX.LGPL_2_1_only - , SPDX.LGPL_3_0_only - , SPDX.AGPL_3_0_only - - , SPDX.GPL_2_0_or_later - , SPDX.GPL_3_0_or_later - , SPDX.LGPL_2_1_or_later - , SPDX.LGPL_3_0_or_later - , SPDX.AGPL_3_0_or_later - ] - --- | The author's name and email. Prompt, or try to guess from an existing --- darcs repo. -getAuthorInfo :: InitFlags -> IO InitFlags -getAuthorInfo flags = do - (authorName, authorEmail) <- - (flagToMaybe *** flagToMaybe) `fmap` guessAuthorNameMail - authorName' <- return (flagToMaybe $ author flags) - ?>> maybePrompt flags (promptStr "Author name" authorName) - ?>> return authorName - - authorEmail' <- return (flagToMaybe $ email flags) - ?>> maybePrompt flags (promptStr "Maintainer email" authorEmail) - ?>> return authorEmail - - return $ flags { author = maybeToFlag authorName' - , email = maybeToFlag authorEmail' - } - --- | Prompt for a homepage URL for the package. -getHomepage :: InitFlags -> IO InitFlags -getHomepage flags = do - hp <- queryHomepage - hp' <- return (flagToMaybe $ homepage flags) - ?>> maybePrompt flags (promptStr "Project homepage URL" hp) - ?>> return hp - - return $ flags { homepage = maybeToFlag hp' } - --- | Right now this does nothing, but it could be changed to do some --- intelligent guessing. -queryHomepage :: IO (Maybe String) -queryHomepage = return Nothing -- get default remote darcs repo? - --- | Prompt for a project synopsis. -getSynopsis :: InitFlags -> IO InitFlags -getSynopsis flags = do - syn <- return (flagToMaybe $ synopsis flags) - ?>> maybePrompt flags (promptStr "Project synopsis" Nothing) - - return $ flags { synopsis = maybeToFlag syn } - --- | Prompt for a package category. --- Note that it should be possible to do some smarter guessing here too, i.e. --- look at the name of the top level source directory. -getCategory :: InitFlags -> IO InitFlags -getCategory flags = do - cat <- return (flagToMaybe $ category flags) - ?>> fmap join (maybePrompt flags - (promptListOptional "Project category" [Codec ..])) - return $ flags { category = maybeToFlag cat } - --- | Try to guess extra source files (don't prompt the user). -getExtraSourceFiles :: InitFlags -> IO InitFlags -getExtraSourceFiles flags = do - extraSrcFiles <- return (extraSrc flags) - ?>> Just `fmap` guessExtraSourceFiles flags - - return $ flags { extraSrc = extraSrcFiles } - -defaultChangeLog :: FilePath -defaultChangeLog = "CHANGELOG.md" - --- | Try to guess things to include in the extra-source-files field. --- For now, we just look for things in the root directory named --- 'readme', 'changes', or 'changelog', with any sort of --- capitalization and any extension. -guessExtraSourceFiles :: InitFlags -> IO [FilePath] -guessExtraSourceFiles flags = do - dir <- - maybe getCurrentDirectory return . flagToMaybe $ packageDir flags - files <- getDirectoryContents dir - let extraFiles = filter isExtra files - if any isLikeChangeLog extraFiles - then return extraFiles - else return (defaultChangeLog : extraFiles) - - where - isExtra = likeFileNameBase ("README" : changeLogLikeBases) - isLikeChangeLog = likeFileNameBase changeLogLikeBases - likeFileNameBase candidates = (`elem` candidates) . map toUpper . takeBaseName - changeLogLikeBases = ["CHANGES", "CHANGELOG"] - --- | Ask whether the project builds a library or executable. -getLibOrExec :: InitFlags -> IO InitFlags -getLibOrExec flags = do - pkgType <- return (flagToMaybe $ packageType flags) - ?>> maybePrompt flags (either (const Executable) id `fmap` - promptList "What does the package build" - [Executable, Library, LibraryAndExecutable] - Nothing displayPackageType False) - ?>> return (Just Executable) - - -- If this package contains an executable, get the main file name. - mainFile <- if pkgType == Just Library then return Nothing else - getMainFile flags - - return $ flags { packageType = maybeToFlag pkgType - , mainIs = maybeToFlag mainFile - } - - --- | Try to guess the main file of the executable, and prompt the user to choose --- one of them. Top-level modules including the word 'Main' in the file name --- will be candidates, and shorter filenames will be preferred. -getMainFile :: InitFlags -> IO (Maybe FilePath) -getMainFile flags = - return (flagToMaybe $ mainIs flags) - ?>> do - candidates <- guessMainFileCandidates flags - let showCandidate = either (++" (does not yet exist, but will be created)") id - defaultFile = listToMaybe candidates - maybePrompt flags (either id (either id id) `fmap` - promptList "What is the main module of the executable" - candidates - defaultFile showCandidate True) - ?>> return (fmap (either id id) defaultFile) - --- | Ask if a test suite should be generated for the library. -getGenTests :: InitFlags -> IO InitFlags -getGenTests flags = do - genTests <- return (flagToMaybe $ initializeTestSuite flags) - -- Only generate a test suite if the package contains a library. - ?>> if (packageType flags) == Flag Executable then return (Just False) else return Nothing - ?>> maybePrompt flags - (promptYesNo - "Should I generate a test suite for the library" - (Just True)) - return $ flags { initializeTestSuite = maybeToFlag genTests } - --- | Ask for the test suite root directory. -getTestDir :: InitFlags -> IO InitFlags -getTestDir flags = do - dirs <- return (testDirs flags) - -- Only need testDirs when test suite generation is enabled. - ?>> if not (eligibleForTestSuite flags) then return (Just []) else return Nothing - ?>> fmap (fmap ((:[]) . either id id)) (maybePrompt - flags - (promptList "Test directory" ["test"] (Just "test") id True)) - - return $ flags { testDirs = dirs } - --- | Ask for the Haskell base language of the package. -getLanguage :: InitFlags -> IO InitFlags -getLanguage flags = do - lang <- return (flagToMaybe $ language flags) - ?>> maybePrompt flags - (either UnknownLanguage id `fmap` - promptList "What base language is the package written in" - [Haskell2010, Haskell98] - (Just Haskell2010) prettyShow True) - ?>> return (Just Haskell2010) - - if invalidLanguage lang - then putStrLn invalidOtherLanguageMsg >> getLanguage flags - else return $ flags { language = maybeToFlag lang } - - where - invalidLanguage (Just (UnknownLanguage t)) = any (not . isAlphaNum) t - invalidLanguage _ = False - - invalidOtherLanguageMsg = "\nThe language must be alphanumeric. " ++ - "Please enter a different language." - --- | Ask whether to generate explanatory comments. -getGenComments :: InitFlags -> IO InitFlags -getGenComments flags = do - genComments <- return (not <$> flagToMaybe (noComments flags)) - ?>> maybePrompt flags (promptYesNo promptMsg (Just False)) - ?>> return (Just False) - return $ flags { noComments = maybeToFlag (fmap not genComments) } - where - promptMsg = "Add informative comments to each field in the cabal file (y/n)" - --- | Ask for the application root directory. -getAppDir :: InitFlags -> IO InitFlags -getAppDir flags = do - appDirs <- noAppDirIfLibraryOnly - ?>> guessAppDir flags - ?>> promptUserForApplicationDir - ?>> setDefault - return $ flags { applicationDirs = appDirs } - where - -- If the packageType==Library, ignore defined appdir. - noAppDirIfLibraryOnly :: IO (Maybe [String]) - noAppDirIfLibraryOnly - | packageType flags == Flag Library = return $ Just [] - | otherwise = return $ applicationDirs flags - - -- Set the default application directory. - setDefault :: IO (Maybe [String]) - setDefault = pure (Just [defaultApplicationDir]) - - -- Prompt the user for the application directory (defaulting to "app"). - -- Returns 'Nothing' if in non-interactive mode, otherwise will always - -- return a 'Just' value ('Just []' if no separate application directory). - promptUserForApplicationDir :: IO (Maybe [String]) - promptUserForApplicationDir = fmap (either (:[]) id) <$> maybePrompt - flags - (promptList - ("Application " ++ mainFile ++ "directory") - [[defaultApplicationDir], ["src-exe"], []] - (Just [defaultApplicationDir]) - showOption True) - - showOption :: [String] -> String - showOption [] = "(none)" - showOption (x:_) = x - - -- The name - mainFile :: String - mainFile = case mainIs flags of - Flag mainPath -> "(" ++ mainPath ++ ") " - _ -> "" - --- | Try to guess app directory. Could try harder; for the --- moment just looks to see whether there is a directory called 'app'. -guessAppDir :: InitFlags -> IO (Maybe [String]) -guessAppDir flags = do - dir <- maybe getCurrentDirectory return . flagToMaybe $ packageDir flags - appIsDir <- doesDirectoryExist (dir "app") - return $ if appIsDir - then Just ["app"] - else Nothing - --- | Ask for the source (library) root directory. -getSrcDir :: InitFlags -> IO InitFlags -getSrcDir flags = do - srcDirs <- noSourceDirIfExecutableOnly - ?>> guessSourceDir flags - ?>> promptUserForSourceDir - ?>> setDefault - - return $ flags { sourceDirs = srcDirs } - - where - -- If the packageType==Executable, then ignore source dir - noSourceDirIfExecutableOnly :: IO (Maybe [String]) - noSourceDirIfExecutableOnly - | packageType flags == Flag Executable = return $ Just [] - | otherwise = return $ sourceDirs flags - - -- Set the default source directory. - setDefault :: IO (Maybe [String]) - setDefault = pure (Just [defaultSourceDir]) - - -- Prompt the user for the source directory (defaulting to "app"). - -- Returns 'Nothing' if in non-interactive mode, otherwise will always - -- return a 'Just' value ('Just []' if no separate application directory). - promptUserForSourceDir :: IO (Maybe [String]) - promptUserForSourceDir = fmap (either (:[]) id) <$> maybePrompt - flags - (promptList - ("Library source directory") - [[defaultSourceDir], ["lib"], ["src-lib"], []] - (Just [defaultSourceDir]) - showOption True) - - showOption :: [String] -> String - showOption [] = "(none)" - showOption (x:_) = x - - --- | Try to guess source directory. Could try harder; for the --- moment just looks to see whether there is a directory called 'src'. -guessSourceDir :: InitFlags -> IO (Maybe [String]) -guessSourceDir flags = do - dir <- - maybe getCurrentDirectory return . flagToMaybe $ packageDir flags - srcIsDir <- doesDirectoryExist (dir "src") - return $ if srcIsDir - then Just ["src"] - else Nothing - --- | Check whether a potential source file is located in one of the --- source directories. -isSourceFile :: Maybe [FilePath] -> SourceFileEntry -> Bool -isSourceFile Nothing sf = isSourceFile (Just ["."]) sf -isSourceFile (Just srcDirs) sf = any (equalFilePath (relativeSourcePath sf)) srcDirs - --- | Get the list of exposed modules and extra tools needed to build them. -getModulesBuildToolsAndDeps :: InstalledPackageIndex -> InitFlags -> IO InitFlags -getModulesBuildToolsAndDeps pkgIx flags = do - dir <- maybe getCurrentDirectory return . flagToMaybe $ packageDir flags - - sourceFiles0 <- scanForModules dir - - let sourceFiles = filter (isSourceFile (sourceDirs flags)) sourceFiles0 - - Just mods <- return (exposedModules flags) - ?>> (return . Just . map moduleName $ sourceFiles) - - tools <- return (buildTools flags) - ?>> (return . Just . neededBuildPrograms $ sourceFiles) - - deps <- return (dependencies flags) - ?>> Just <$> importsToDeps flags - (fromString "Prelude" : -- to ensure we get base as a dep - ( nub -- only need to consider each imported package once - . filter (`notElem` mods) -- don't consider modules from - -- this package itself - . concatMap imports - $ sourceFiles - ) - ) - pkgIx - - exts <- return (otherExts flags) - ?>> (return . Just . nub . concatMap extensions $ sourceFiles) - - -- If we're initializing a library and there were no modules discovered - -- then create an empty 'MyLib' module. - -- This gets a little tricky when 'sourceDirs' == 'applicationDirs' because - -- then the executable needs to set 'other-modules: MyLib' or else the build - -- fails. - let (finalModsList, otherMods) = case (packageType flags, mods) of - - -- For an executable leave things as they are. - (Flag Executable, _) -> (mods, otherModules flags) - - -- If a non-empty module list exists don't change anything. - (_, (_:_)) -> (mods, otherModules flags) - - -- Library only: 'MyLib' in 'other-modules' only. - (Flag Library, _) -> ([myLibModule], Nothing) - - -- For a 'LibraryAndExecutable' we need to have special handling. - -- If we don't have a module list (Nothing or empty), then create a Lib. - (_, []) -> - if sourceDirs flags == applicationDirs flags - then ([myLibModule], Just [myLibModule]) - else ([myLibModule], Nothing) - - return $ flags { exposedModules = Just finalModsList - , otherModules = otherMods - , buildTools = tools - , dependencies = deps - , otherExts = exts - } - --- | Given a list of imported modules, retrieve the list of dependencies that --- provide those modules. -importsToDeps :: InitFlags -> [ModuleName] -> InstalledPackageIndex -> IO [P.Dependency] -importsToDeps flags mods pkgIx = do - - let modMap :: M.Map ModuleName [InstalledPackageInfo] - modMap = M.map (filter exposed) $ moduleNameIndex pkgIx - - modDeps :: [(ModuleName, Maybe [InstalledPackageInfo])] - modDeps = map (id &&& flip M.lookup modMap) mods - - message flags "\nGuessing dependencies..." - nub . catMaybes <$> traverse (chooseDep flags) modDeps - --- Given a module and a list of installed packages providing it, --- choose a dependency (i.e. package + version range) to use for that --- module. -chooseDep :: InitFlags -> (ModuleName, Maybe [InstalledPackageInfo]) - -> IO (Maybe P.Dependency) - -chooseDep flags (m, Nothing) - = message flags ("\nWarning: no package found providing " ++ prettyShow m ++ ".") - >> return Nothing - -chooseDep flags (m, Just []) - = message flags ("\nWarning: no package found providing " ++ prettyShow m ++ ".") - >> return Nothing - - -- We found some packages: group them by name. -chooseDep flags (m, Just ps) - = case pkgGroups of - -- if there's only one group, i.e. multiple versions of a single package, - -- we make it into a dependency, choosing the latest-ish version (see toDep). - [grp] -> Just <$> toDep grp - -- otherwise, we refuse to choose between different packages and make the user - -- do it. - grps -> do message flags ("\nWarning: multiple packages found providing " - ++ prettyShow m - ++ ": " ++ intercalate ", " (fmap (prettyShow . P.pkgName . NE.head) grps)) - message flags "You will need to pick one and manually add it to the Build-depends: field." - return Nothing - where - pkgGroups = NE.groupBy ((==) `on` P.pkgName) (map P.packageId ps) - - desugar = maybe True (< CabalSpecV2_0) $ flagToMaybe (cabalVersion flags) - - -- Given a list of available versions of the same package, pick a dependency. - toDep :: NonEmpty P.PackageIdentifier -> IO P.Dependency - - -- If only one version, easy. We change e.g. 0.4.2 into 0.4.* - toDep (pid:|[]) = return $ P.Dependency (P.pkgName pid) (pvpize desugar . P.pkgVersion $ pid) P.mainLibSet --TODO sublibraries - - -- Otherwise, choose the latest version and issue a warning. - toDep pids = do - message flags ("\nWarning: multiple versions of " ++ prettyShow (P.pkgName . NE.head $ pids) ++ " provide " ++ prettyShow m ++ ", choosing the latest.") - return $ P.Dependency (P.pkgName . NE.head $ pids) - (pvpize desugar . maximum . fmap P.pkgVersion $ pids) - P.mainLibSet --TODO take into account sublibraries - --- | Given a version, return an API-compatible (according to PVP) version range. --- --- If the boolean argument denotes whether to use a desugared --- representation (if 'True') or the new-style @^>=@-form (if --- 'False'). --- --- Example: @pvpize True (mkVersion [0,4,1])@ produces the version range @>= 0.4 && < 0.5@ (which is the --- same as @0.4.*@). -pvpize :: Bool -> Version -> VersionRange -pvpize False v = majorBoundVersion v -pvpize True v = orLaterVersion v' - `intersectVersionRanges` - earlierVersion (incVersion 1 v') - where v' = alterVersion (take 2) v - --- | Increment the nth version component (counting from 0). -incVersion :: Int -> Version -> Version -incVersion n = alterVersion (incVersion' n) - where - incVersion' 0 [] = [1] - incVersion' 0 (v:_) = [v+1] - incVersion' m [] = replicate m 0 ++ [1] - incVersion' m (v:vs) = v : incVersion' (m-1) vs - --- | Generate warnings for missing fields etc. -generateWarnings :: InitFlags -> IO () -generateWarnings flags = do - message flags "" - when (synopsis flags `elem` [NoFlag, Flag ""]) - (message flags "Warning: no synopsis given. You should edit the .cabal file and add one.") - - message flags "You may want to edit the .cabal file and add a Description field." diff --git a/cabal-install/src/Distribution/Client/Init/Defaults.hs b/cabal-install/src/Distribution/Client/Init/Defaults.hs index 7f87a28f1f1..7a629dc4bbc 100644 --- a/cabal-install/src/Distribution/Client/Init/Defaults.hs +++ b/cabal-install/src/Distribution/Client/Init/Defaults.hs @@ -12,21 +12,52 @@ -- ----------------------------------------------------------------------------- -module Distribution.Client.Init.Defaults ( - defaultApplicationDir - , defaultSourceDir - , defaultCabalVersion - , myLibModule - ) where - -import Prelude (String) - -import Distribution.ModuleName - ( ModuleName ) -- And for the Text instance -import qualified Distribution.ModuleName as ModuleName - ( fromString ) -import Distribution.CabalSpecVersion - ( CabalSpecVersion (..)) +{-# OPTIONS_GHC -Wno-deferred-type-errors #-} +module Distribution.Client.Init.Defaults + +( -- * default init values + defaultApplicationDir +, defaultSourceDir +, defaultCabalVersion +, defaultCabalVersions +, defaultPackageType +, defaultLicense +, defaultLicenseIds +, defaultMainIs +, defaultChangelog +, defaultCategories +, defaultInitFlags +, defaultLanguage +, defaultVersion +, defaultTestDir + -- * MyLib defaults +, myLibModule +, myLibTestFile +, myLibFile +, myLibHs +, myExeHs +, myLibExeHs +, myTestHs +) where + + +import Distribution.ModuleName (ModuleName) +import qualified Distribution.ModuleName as ModuleName(fromString) +import Distribution.CabalSpecVersion (CabalSpecVersion (..)) +import Distribution.Client.Init.Types (PackageType(..), InitFlags(..), HsFilePath, toHsFilePath) +import qualified Distribution.SPDX.License as SPDX +import qualified Distribution.SPDX.LicenseId as SPDX +import Distribution.Simple.Flag (toFlag) +import Distribution.Verbosity (normal) +import Distribution.Types.Version +import Distribution.Simple + + +-- -------------------------------------------------------------------- -- +-- Default flag and init values + +defaultVersion :: Version +defaultVersion = mkVersion [0,1,0,0] defaultApplicationDir :: String defaultApplicationDir = "app" @@ -34,8 +65,127 @@ defaultApplicationDir = "app" defaultSourceDir :: String defaultSourceDir = "src" +defaultTestDir :: String +defaultTestDir = "test" + defaultCabalVersion :: CabalSpecVersion -defaultCabalVersion = CabalSpecV2_4 +defaultCabalVersion = CabalSpecV3_0 + +defaultPackageType :: PackageType +defaultPackageType = Executable + +defaultChangelog :: FilePath +defaultChangelog = "CHANGELOG.md" + +defaultLicense :: SPDX.License +defaultLicense = SPDX.NONE + +defaultMainIs :: HsFilePath +defaultMainIs = toHsFilePath "Main.hs" + +defaultLanguage :: Language +defaultLanguage = Haskell2010 + +defaultLicenseIds :: [SPDX.LicenseId] +defaultLicenseIds = + [ SPDX.BSD_2_Clause + , SPDX.BSD_3_Clause + , SPDX.Apache_2_0 + , SPDX.MIT + , SPDX.MPL_2_0 + , SPDX.ISC + , SPDX.GPL_2_0_only + , SPDX.GPL_3_0_only + , SPDX.LGPL_2_1_only + , SPDX.LGPL_3_0_only + , SPDX.AGPL_3_0_only + , SPDX.GPL_2_0_or_later + , SPDX.GPL_3_0_or_later + , SPDX.LGPL_2_1_or_later + , SPDX.LGPL_3_0_or_later + , SPDX.AGPL_3_0_or_later + ] + +defaultCategories :: [String] +defaultCategories = + [ "Codec" + , "Concurrency" + , "Control" + , "Data" + , "Database" + , "Development" + , "Distribution" + , "Game" + , "Graphics" + , "Language" + , "Math" + , "Network" + , "Sound" + , "System" + , "Testing" + , "Text" + , "Web" + ] + +defaultCabalVersions :: [CabalSpecVersion] +defaultCabalVersions = + [ CabalSpecV1_10 + , CabalSpecV2_0 + , CabalSpecV2_2 + , CabalSpecV2_4 + , CabalSpecV3_0 + , CabalSpecV3_4 + ] + +defaultInitFlags :: InitFlags +defaultInitFlags = mempty { initVerbosity = toFlag normal } + +-- -------------------------------------------------------------------- -- +-- MyLib defaults myLibModule :: ModuleName myLibModule = ModuleName.fromString "MyLib" + +myLibTestFile :: HsFilePath +myLibTestFile = toHsFilePath "MyLibTest.hs" + +myLibFile :: HsFilePath +myLibFile = toHsFilePath "MyLib.hs" + +-- | Default MyLib.hs file. Used when no Lib.hs exists. +myLibHs :: String +myLibHs = unlines + [ "module MyLib (someFunc) where" + , "" + , "someFunc :: IO ()" + , "someFunc = putStrLn \"someFunc\"" + ] + +myExeHs :: [String] +myExeHs = + [ "module Main where" + , "" + , "main :: IO ()" + , "main = putStrLn \"Hello, Haskell!\"" + ] + +myLibExeHs :: [String] +myLibExeHs = + [ "module Main where" + , "" + , "import qualified MyLib (someFunc)" + , "" + , "main :: IO ()" + , "main = do" + , " putStrLn \"Hello, Haskell!\"" + , " MyLib.someFunc" + ] + +-- | Default MyLibTest.hs file. +myTestHs :: String +myTestHs = unlines + [ "module Main (main) where" + , "" + , "main :: IO ()" + , "main = putStrLn \"Test suite not yet implemented.\"" + ] diff --git a/cabal-install/src/Distribution/Client/Init/FileCreators.hs b/cabal-install/src/Distribution/Client/Init/FileCreators.hs index 5e4cc6ab95d..7ce2c26be9c 100644 --- a/cabal-install/src/Distribution/Client/Init/FileCreators.hs +++ b/cabal-install/src/Distribution/Client/Init/FileCreators.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} ----------------------------------------------------------------------------- -- | @@ -12,640 +13,280 @@ -- Functions to create files during 'cabal init'. -- ----------------------------------------------------------------------------- +module Distribution.Client.Init.FileCreators +( -- * Commands + writeProject +, writeLicense +, writeChangeLog +, prepareLibTarget +, prepareExeTarget +, prepareTestTarget +) where + +import Prelude hiding (writeFile) +import Distribution.Client.Compat.Prelude hiding (head, empty, writeFile) + +import Distribution.Client.Utils (getCurrentYear) +import Distribution.Client.Init.Defaults +import Distribution.Client.Init.Licenses + ( bsd2, bsd3, gplv2, gplv3, lgpl21, lgpl3, agplv3, apache20, mit, mpl20, isc ) +import Distribution.Client.Init.Types hiding (putStrLn, putStr, message) +import qualified Distribution.Client.Init.Types as T +import Distribution.Fields.Pretty (PrettyField(..), showFields') +import qualified Distribution.SPDX as SPDX +import Distribution.Types.PackageName -module Distribution.Client.Init.FileCreators ( +import System.Directory hiding (doesDirectoryExist, doesFileExist, createDirectory, renameDirectory, copyFile) +import System.FilePath ((), (<.>)) - -- * Commands - writeLicense - , writeChangeLog - , createDirectories - , createLibHs - , createMainHs - , createTestSuiteIfEligible - , writeCabalFile +import Distribution.Client.Init.Format - -- * For testing - , generateCabalFile - ) where -import Prelude () -import Distribution.Client.Compat.Prelude hiding (empty) +-- -------------------------------------------------------------------- -- +-- File generation -import System.FilePath - ( (), (<.>), takeExtension ) +writeProject :: ProjectSettings -> IO () +writeProject (ProjectSettings opts pkgDesc libTarget exeTarget testTarget) + | null pkgName = do + message opts "\nError: no package name given, so no .cabal file can be generated\n" + | otherwise = do -import Distribution.Types.Dependency -import Distribution.Types.VersionRange + -- clear prompt history a bit" + message opts "" -import Data.Time - ( getCurrentTime, utcToLocalTime, toGregorian, localDay, getCurrentTimeZone ) -import System.Directory - ( getCurrentDirectory, doesFileExist, copyFile - , createDirectoryIfMissing ) + writeLicense opts pkgDesc + writeChangeLog opts pkgDesc -import Text.PrettyPrint hiding ((<>), mode, cat) + let pkgFields = mkPkgDescription opts pkgDesc -import Distribution.Client.Init.Defaults - ( defaultCabalVersion, myLibModule ) -import Distribution.Client.Init.Licenses - ( bsd2, bsd3, gplv2, gplv3, lgpl21, lgpl3, agplv3, apache20, mit, mpl20, isc ) -import Distribution.Client.Init.Utils - ( eligibleForTestSuite, message ) -import Distribution.Client.Init.Types - ( InitFlags(..), BuildType(..), PackageType(..) ) - -import Distribution.CabalSpecVersion -import Distribution.Compat.Newtype - ( Newtype ) -import Distribution.Fields.Field - ( FieldName ) -import Distribution.License - ( licenseFromSPDX ) -import qualified Distribution.ModuleName as ModuleName - ( toFilePath ) -import Distribution.FieldGrammar.Newtypes - ( SpecVersion(..) ) -import Distribution.PackageDescription.FieldGrammar - ( formatDependencyList, formatExposedModules, formatHsSourceDirs, - formatOtherExtensions, formatOtherModules, formatExtraSourceFiles ) -import Distribution.Simple.Flag - ( maybeToFlag ) -import Distribution.Simple.Setup - ( Flag(..), flagToMaybe ) -import Distribution.Simple.Utils - ( toUTF8BS ) -import Distribution.Fields.Pretty - ( PrettyField(..), showFields' ) + libStanza <- prepareLibTarget opts libTarget + exeStanza <- prepareExeTarget opts exeTarget + testStanza <- prepareTestTarget opts testTarget -import qualified Distribution.SPDX as SPDX + writeCabalFile opts $ pkgFields ++ [libStanza, exeStanza, testStanza] + + when (null $ _pkgSynopsis pkgDesc) $ + message opts "\nWarning: no synopsis given. You should edit the .cabal file and add one." -import Distribution.Utils.Path -- TODO + message opts "You may want to edit the .cabal file and add a Description field." + where + pkgName = unPackageName $ _optPkgName opts + + +prepareLibTarget + :: WriteOpts + -> Maybe LibTarget + -> IO (PrettyField FieldAnnotation) +prepareLibTarget _ Nothing = return PrettyEmpty +prepareLibTarget opts (Just libTarget) = do + void $ writeDirectoriesSafe opts srcDirs + -- avoid writing when conflicting exposed paths may + -- exist. + when (expMods == (myLibModule :| [])) $ do + writeFileSafe opts libPath myLibHs + + return $ mkLibStanza opts libTarget + where + expMods = _libExposedModules libTarget + srcDirs = _libSourceDirs libTarget + libPath = case srcDirs of + path:_ -> path _hsFilePath myLibFile + _ -> _hsFilePath myLibFile + +prepareExeTarget + :: WriteOpts + -> Maybe ExeTarget + -> IO (PrettyField FieldAnnotation) +prepareExeTarget _ Nothing = return PrettyEmpty +prepareExeTarget opts (Just exeTarget) = do + void $ writeDirectoriesSafe opts appDirs + void $ writeFileSafe opts mainPath mainHs + return $ mkExeStanza opts exeTarget + where + exeMainIs = _exeMainIs exeTarget + pkgType = _optPkgType opts + appDirs = _exeApplicationDirs exeTarget + mainFile = _hsFilePath exeMainIs + mainPath = case appDirs of + appPath:_ -> appPath mainFile + _ -> mainFile + + mainHs = unlines . mkLiterate exeMainIs $ + if pkgType == LibraryAndExecutable + then myLibExeHs + else myExeHs + +prepareTestTarget + :: WriteOpts + -> Maybe TestTarget + -> IO (PrettyField FieldAnnotation) +prepareTestTarget _ Nothing = return PrettyEmpty +prepareTestTarget opts (Just testTarget) = do + void $ writeDirectoriesSafe opts testDirs' + void $ writeFileSafe opts testPath myTestHs + return $ mkTestStanza opts testTarget + where + testDirs' = _testDirs testTarget + testMainIs = _hsFilePath $ _testMainIs testTarget + testPath = case testDirs' of + p:_ -> p testMainIs + _ -> testMainIs + +writeCabalFile + :: WriteOpts + -> [PrettyField FieldAnnotation] + -- ^ .cabal fields + -> IO () +writeCabalFile opts fields = do + message opts $ "\nGenerating " ++ cabalFileName ++ "..." + exists <- doesFileExist cabalFileName + + if exists && doOverwrite then do + removeFile cabalFileName + writeFileSafe opts cabalFileName cabalContents + else writeFileSafe opts cabalFileName cabalContents + where + doOverwrite = _optOverwrite opts ---------------------------------------------------------------------------- --- File generation ------------------------------------------------------ ---------------------------------------------------------------------------- + cabalContents = showFields' + annCommentLines + postProcessFieldLines + 4 fields --- | Write the LICENSE file, as specified in the InitFlags license field. + cabalFileName = pkgName ++ ".cabal" + pkgName = unPackageName $ _optPkgName opts + +-- | Write the LICENSE file. -- --- For licences that contain the author's name(s), the values are taken +-- For licenses that contain the author's name(s), the values are taken -- from the 'authors' field of 'InitFlags', and if not specified will -- be the string "???". -- --- If the license type is unknown no license file will be created and +-- If the license type is unknown no license file will be prepared and -- a warning will be raised. -writeLicense :: InitFlags -> IO () -writeLicense flags = do - message flags "\nGenerating LICENSE..." +-- +writeLicense :: WriteOpts -> PkgDescription -> IO () +writeLicense writeOpts pkgDesc = do year <- show <$> getCurrentYear - let authors = fromMaybe "???" . flagToMaybe . author $ flags - let isSimpleLicense :: SPDX.License -> Maybe SPDX.LicenseId - isSimpleLicense (SPDX.License (SPDX.ELicense (SPDX.ELicenseId lid) Nothing)) = Just lid - isSimpleLicense _ = Nothing - let licenseFile = - case flagToMaybe (license flags) >>= isSimpleLicense of - Just SPDX.BSD_2_Clause -> Just $ bsd2 authors year - Just SPDX.BSD_3_Clause -> Just $ bsd3 authors year - Just SPDX.Apache_2_0 -> Just apache20 - Just SPDX.MIT -> Just $ mit authors year - Just SPDX.MPL_2_0 -> Just mpl20 - Just SPDX.ISC -> Just $ isc authors year - - -- GNU license come in "only" and "or-later" flavours - -- license file used are the same. - Just SPDX.GPL_2_0_only -> Just gplv2 - Just SPDX.GPL_3_0_only -> Just gplv3 - Just SPDX.LGPL_2_1_only -> Just lgpl21 - Just SPDX.LGPL_3_0_only -> Just lgpl3 - Just SPDX.AGPL_3_0_only -> Just agplv3 - - Just SPDX.GPL_2_0_or_later -> Just gplv2 - Just SPDX.GPL_3_0_or_later -> Just gplv3 - Just SPDX.LGPL_2_1_or_later -> Just lgpl21 - Just SPDX.LGPL_3_0_or_later -> Just lgpl3 - Just SPDX.AGPL_3_0_or_later -> Just agplv3 - - _ -> Nothing - - case licenseFile of - Just licenseText -> writeFileSafe flags "LICENSE" licenseText - Nothing -> message flags "Warning: unknown license type, you must put a copy in LICENSE yourself." - --- | Returns the current calendar year. -getCurrentYear :: IO Integer -getCurrentYear = do - u <- getCurrentTime - z <- getCurrentTimeZone - let l = utcToLocalTime z u - (y, _, _) = toGregorian $ localDay l - return y - -defaultChangeLog :: FilePath -defaultChangeLog = "CHANGELOG.md" + case licenseFile year (_pkgAuthor pkgDesc) of + Just licenseText -> do + message writeOpts "\nCreating LICENSE..." + writeFileSafe writeOpts "LICENSE" licenseText + Nothing -> message writeOpts "Warning: unknown license type, you must put a copy in LICENSE yourself." + where + getLid (SPDX.License (SPDX.ELicense (SPDX.ELicenseId lid) Nothing)) = + Just lid + getLid _ = Nothing + + licenseFile year auth = case getLid $ _pkgLicense pkgDesc of + Just SPDX.BSD_2_Clause -> Just $ bsd2 auth year + Just SPDX.BSD_3_Clause -> Just $ bsd3 auth year + Just SPDX.Apache_2_0 -> Just apache20 + Just SPDX.MIT -> Just $ mit auth year + Just SPDX.MPL_2_0 -> Just mpl20 + Just SPDX.ISC -> Just $ isc auth year + Just SPDX.GPL_2_0_only -> Just gplv2 + Just SPDX.GPL_3_0_only -> Just gplv3 + Just SPDX.LGPL_2_1_only -> Just lgpl21 + Just SPDX.LGPL_3_0_only -> Just lgpl3 + Just SPDX.AGPL_3_0_only -> Just agplv3 + Just SPDX.GPL_2_0_or_later -> Just gplv2 + Just SPDX.GPL_3_0_or_later -> Just gplv3 + Just SPDX.LGPL_2_1_or_later -> Just lgpl21 + Just SPDX.LGPL_3_0_or_later -> Just lgpl3 + Just SPDX.AGPL_3_0_or_later -> Just agplv3 + _ -> Nothing -- | Writes the changelog to the current directory. -writeChangeLog :: InitFlags -> IO () -writeChangeLog flags = when ((defaultChangeLog `elem`) $ fromMaybe [] (extraSrc flags)) $ do - message flags ("Generating "++ defaultChangeLog ++"...") - writeFileSafe flags defaultChangeLog changeLog +-- +writeChangeLog :: WriteOpts -> PkgDescription -> IO () +writeChangeLog opts pkgDesc + | defaultChangelog `elem` _pkgExtraSrcFiles pkgDesc = do + message opts ("Creating " ++ defaultChangelog ++"...") + writeFileSafe opts defaultChangelog changeLog + | otherwise = return () where changeLog = unlines - [ "# Revision history for " ++ pname + [ "# Revision history for " ++ prettyShow (_pkgName pkgDesc) , "" - , "## " ++ pver ++ " -- YYYY-mm-dd" + , "## " ++ prettyShow (_pkgVersion pkgDesc) ++ " -- YYYY-mm-dd" , "" , "* First version. Released on an unsuspecting world." ] - pname = maybe "" prettyShow $ flagToMaybe $ packageName flags - pver = maybe "" prettyShow $ flagToMaybe $ version flags --- | Creates and writes the initialized .cabal file. --- --- Returns @False@ if no package name is specified, @True@ otherwise. -writeCabalFile :: InitFlags -> IO Bool -writeCabalFile flags@(InitFlags{packageName = NoFlag}) = do - message flags "Error: no package name provided." - return False -writeCabalFile flags@(InitFlags{packageName = Flag p}) = do - let cabalFileName = prettyShow p ++ ".cabal" - message flags $ "Generating " ++ cabalFileName ++ "..." - writeFileSafe flags cabalFileName (generateCabalFile cabalFileName flags) - return True - --- | Write a file \"safely\", backing up any existing version (unless --- the overwrite flag is set). -writeFileSafe :: InitFlags -> FilePath -> String -> IO () -writeFileSafe flags fileName content = do - moveExistingFile flags fileName - writeFile fileName content - --- | Create directories, if they were given, and don't already exist. -createDirectories :: Maybe [String] -> IO () -createDirectories mdirs = case mdirs of - Just dirs -> for_ dirs (createDirectoryIfMissing True) - Nothing -> return () - --- | Create MyLib.hs file, if its the only module in the liste. -createLibHs :: InitFlags -> IO () -createLibHs flags = when ((exposedModules flags) == Just [myLibModule]) $ do - let modFilePath = ModuleName.toFilePath myLibModule ++ ".hs" - case sourceDirs flags of - Just (srcPath:_) -> writeLibHs flags (srcPath modFilePath) - _ -> writeLibHs flags modFilePath - --- | Write a MyLib.hs file if it doesn't already exist. -writeLibHs :: InitFlags -> FilePath -> IO () -writeLibHs flags libPath = do - dir <- maybe getCurrentDirectory return (flagToMaybe $ packageDir flags) - let libFullPath = dir libPath - exists <- doesFileExist libFullPath - unless exists $ do - message flags $ "Generating " ++ libPath ++ "..." - writeFileSafe flags libFullPath myLibHs - --- | Default MyLib.hs file. Used when no Lib.hs exists. -myLibHs :: String -myLibHs = unlines - [ "module MyLib (someFunc) where" - , "" - , "someFunc :: IO ()" - , "someFunc = putStrLn \"someFunc\"" - ] - --- | Create Main.hs, but only if we are init'ing an executable and --- the mainIs flag has been provided. -createMainHs :: InitFlags -> IO () -createMainHs flags = - if hasMainHs flags then - case applicationDirs flags of - Just (appPath:_) -> writeMainHs flags (appPath mainFile) - _ -> writeMainHs flags mainFile - else return () - where - mainFile = case mainIs flags of - Flag x -> x - NoFlag -> error "createMainHs: no mainIs" - --- | Write a main file if it doesn't already exist. -writeMainHs :: InitFlags -> FilePath -> IO () -writeMainHs flags mainPath = do - dir <- maybe getCurrentDirectory return (flagToMaybe $ packageDir flags) - let mainFullPath = dir mainPath - exists <- doesFileExist mainFullPath - unless exists $ do - message flags $ "Generating " ++ mainPath ++ "..." - writeFileSafe flags mainFullPath (mainHs flags) - --- | Returns true if a main file exists. -hasMainHs :: InitFlags -> Bool -hasMainHs flags = case mainIs flags of - Flag _ -> (packageType flags == Flag Executable - || packageType flags == Flag LibraryAndExecutable) - _ -> False - --- | Default Main.(l)hs file. Used when no Main.(l)hs exists. --- --- If we are initializing a new 'LibraryAndExecutable' then import 'MyLib'. -mainHs :: InitFlags -> String -mainHs flags = (unlines . map prependPrefix) $ case packageType flags of - Flag LibraryAndExecutable -> - [ "module Main where" - , "" - , "import qualified MyLib (someFunc)" - , "" - , "main :: IO ()" - , "main = do" - , " putStrLn \"Hello, Haskell!\"" - , " MyLib.someFunc" - ] - _ -> - [ "module Main where" - , "" - , "main :: IO ()" - , "main = putStrLn \"Hello, Haskell!\"" - ] - where - prependPrefix :: String -> String - prependPrefix "" = "" - prependPrefix line - | isLiterate = "> " ++ line - | otherwise = line - isLiterate = case mainIs flags of - Flag mainPath -> takeExtension mainPath == ".lhs" - _ -> False - --- | Create a test suite for the package if eligible. -createTestSuiteIfEligible :: InitFlags -> IO () -createTestSuiteIfEligible flags = - when (eligibleForTestSuite flags) $ do - createDirectories (testDirs flags) - createTestHs flags - --- | The name of the test file to generate (if --tests is specified). -testFile :: String -testFile = "MyLibTest.hs" - --- | Create MyLibTest.hs, but only if we are init'ing a library and --- the initializeTestSuite flag has been set. --- --- It is up to the caller to verify that the package is eligible --- for test suite initialization (see eligibleForTestSuite). -createTestHs :: InitFlags -> IO () -createTestHs flags = - case testDirs flags of - Just (testPath:_) -> writeTestHs flags (testPath testFile) - _ -> writeMainHs flags testFile - --- | Write a test file. -writeTestHs :: InitFlags -> FilePath -> IO () -writeTestHs flags testPath = do - dir <- maybe getCurrentDirectory return (flagToMaybe $ packageDir flags) - let testFullPath = dir testPath - exists <- doesFileExist testFullPath - unless exists $ do - message flags $ "Generating " ++ testPath ++ "..." - writeFileSafe flags testFullPath testHs - --- | Default MyLibTest.hs file. -testHs :: String -testHs = unlines - [ "module Main (main) where" - , "" - , "main :: IO ()" - , "main = putStrLn \"Test suite not yet implemented.\"" - ] - - --- | Move an existing file, if there is one, and the overwrite flag is --- not set. -moveExistingFile :: InitFlags -> FilePath -> IO () -moveExistingFile flags fileName = - unless (overwrite flags == Flag True) $ do - e <- doesFileExist fileName - when e $ do - newName <- findNewName fileName - message flags $ "Warning: " ++ fileName ++ " already exists, backing up old version in " ++ newName - copyFile fileName newName - - --- | Given a file path find a new name for the file that does not --- already exist. -findNewName :: FilePath -> IO FilePath -findNewName oldName = findNewName' 0 +-- -------------------------------------------------------------------- -- +-- Utilities + +-- | Possibly generate a message to stdout, taking into account the +-- --quiet flag. +message :: Interactive m => WriteOpts -> String -> m () +message opts = T.message (_optVerbosity opts) + +-- | Write a file \"safely\" if it doesn't exist, backing up any existing version when +-- the overwrite flag is set. +writeFileSafe :: WriteOpts -> FilePath -> String -> IO () +writeFileSafe opts fileName content = do + litExists <- doesFileExist fileName + moveExistingFile litExists + + when (doOverwrite || not litExists) $ + writeFile fileName content where - findNewName' :: Integer -> IO FilePath - findNewName' n = do + doOverwrite = _optOverwrite opts + + moveExistingFile exists + | exists && doOverwrite = do + newName <- findNewName fileName (0 :: Int) + message opts $ concat + [ "Warning: " + , fileName + , " already exists. Backing up old version in " + , newName + ] + + copyFile fileName newName + | exists && not doOverwrite = message opts $ concat + [ "Warning: " + , fileName + , " already exists. Skipping..." + ] + | otherwise = return () + + findNewName oldName n = do let newName = oldName <.> ("save" ++ show n) e <- doesFileExist newName - if e then findNewName' (n+1) else return newName - - --- | Generate a .cabal file from an InitFlags structure. -generateCabalFile :: String -> InitFlags -> String -generateCabalFile fileName c = - showFields' annCommentLines postProcessFieldLines 4 $ catMaybes - [ fieldP "cabal-version" (Flag . SpecVersion $ specVer) - [] - False - - , field "name" (packageName c) - ["Initial package description '" ++ fileName ++ "' generated by", - "'cabal init'. For further documentation, see:", - " http://haskell.org/cabal/users-guide/", - "", - "The name of the package."] - True - - , field "version" (version c) - ["The package version.", - "See the Haskell package versioning policy (PVP) for standards", - "guiding when and how versions should be incremented.", - "https://pvp.haskell.org", - "PVP summary: +-+------- breaking API changes", - " | | +----- non-breaking API additions", - " | | | +--- code changes with no API change"] - True - - , fieldS "synopsis" (synopsis c) - ["A short (one-line) description of the package."] - True - - , fieldS "description" NoFlag - ["A longer description of the package."] - True - - , fieldS "homepage" (homepage c) - ["URL for the project homepage or repository."] - False - - , fieldS "bug-reports" NoFlag - ["A URL where users can report bugs."] - True - - , fieldS "license" licenseStr - ["The license under which the package is released."] - True - - , case license c of - NoFlag -> Nothing - Flag SPDX.NONE -> Nothing - _ -> fieldS "license-file" (Flag "LICENSE") - ["The file containing the license text."] - True - - , fieldS "author" (author c) - ["The package author(s)."] - True - - , fieldS "maintainer" (email c) - ["An email address to which users can send suggestions, bug reports, and patches."] - True - - , fieldS "copyright" NoFlag - ["A copyright notice."] - True - - , fieldS "category" (either id prettyShow `fmap` category c) - [] - True - - , fieldS "build-type" (if specVer >= CabalSpecV2_2 then NoFlag else Flag "Simple") - [] - False - - , fieldPAla "extra-source-files" formatExtraSourceFiles (maybeToFlag (extraSrc c)) - ["Extra files to be distributed with the package, such as examples or a README."] - True - ] - ++ - (case packageType c of - Flag Executable -> [executableStanza] - Flag Library -> [libraryStanza] - Flag LibraryAndExecutable -> [libraryStanza, executableStanza] - _ -> []) - ++ - if eligibleForTestSuite c then [testSuiteStanza] else [] + if e then findNewName oldName (n+1) else return newName - where - specVer :: CabalSpecVersion - specVer = fromMaybe defaultCabalVersion $ flagToMaybe (cabalVersion c) - - licenseStr | specVer < CabalSpecV2_2 = prettyShow . licenseFromSPDX <$> license c - | otherwise = prettyShow <$> license c - - generateBuildInfo :: BuildType -> InitFlags -> [PrettyField FieldAnnotation] - generateBuildInfo buildType c' = catMaybes - [ fieldPAla "other-modules" formatOtherModules (maybeToFlag otherMods) - [ case buildType of - LibBuild -> "Modules included in this library but not exported." - ExecBuild -> "Modules included in this executable, other than Main."] - True - - , fieldPAla "other-extensions" formatOtherExtensions (maybeToFlag (otherExts c)) - ["LANGUAGE extensions used by modules in this package."] - True - - , fieldPAla "build-depends" formatDependencyList (maybeToFlag buildDependencies) - ["Other library packages from which modules are imported."] - True - - , fieldPAla "hs-source-dirs" formatHsSourceDirs - (maybeToFlag $ fmap (fmap unsafeMakeSymbolicPath) $ case buildType of - LibBuild -> sourceDirs c - ExecBuild -> applicationDirs c) - ["Directories containing source files."] - True - - , fieldS "build-tools" (listFieldS $ buildTools c) - ["Extra tools (e.g. alex, hsc2hs, ...) needed to build the source."] - False - - , field "default-language" (language c) - ["Base language which the package is written in."] - True - ] - -- Hack: Can't construct a 'Dependency' which is just 'packageName'(?). - where - buildDependencies :: Maybe [Dependency] - buildDependencies = (++ myLibDep) <$> dependencies c' - - myLibDep :: [Dependency] - myLibDep = if exposedModules c' == Just [myLibModule] && buildType == ExecBuild - then case packageName c' of - Flag pkgName -> - [mkDependency pkgName anyVersion mainLibSet] - _ -> [] - else [] - - -- Only include 'MyLib' in 'other-modules' of the executable. - otherModsFromFlag = otherModules c' - otherMods = if buildType == LibBuild && otherModsFromFlag == Just [myLibModule] - then Nothing - else otherModsFromFlag - - listFieldS :: Maybe [String] -> Flag String - listFieldS Nothing = NoFlag - listFieldS (Just []) = NoFlag - listFieldS (Just xs) = Flag . intercalate ", " $ xs - - -- | Construct a 'PrettyField' from a field that can be automatically - -- converted to a 'Doc' via 'display'. - field :: Pretty t - => FieldName - -> Flag t - -> [String] - -> Bool - -> Maybe (PrettyField FieldAnnotation) - field fieldName fieldContentsFlag = fieldS fieldName (prettyShow <$> fieldContentsFlag) - - -- | Construct a 'PrettyField' from a 'String' field. - fieldS :: FieldName -- ^ Name of the field - -> Flag String -- ^ Field contents - -> [String] -- ^ Comment to explain the field - -> Bool -- ^ Should the field be included (commented out) even if blank? - -> Maybe (PrettyField FieldAnnotation) - fieldS fieldName fieldContentsFlag = fieldD fieldName (text <$> fieldContentsFlag) - - -- | Construct a 'PrettyField' from a Flag which can be 'pretty'-ied. - fieldP :: Pretty a - => FieldName - -> Flag a - -> [String] - -> Bool - -> Maybe (PrettyField FieldAnnotation) - fieldP fieldName fieldContentsFlag fieldComments includeField = - fieldPAla fieldName Identity fieldContentsFlag fieldComments includeField - - -- | Construct a 'PrettyField' from a flag which can be 'pretty'-ied, wrapped in newtypeWrapper. - fieldPAla - :: (Pretty b, Newtype a b) - => FieldName - -> (a -> b) - -> Flag a - -> [String] - -> Bool - -> Maybe (PrettyField FieldAnnotation) - fieldPAla fieldName newtypeWrapper fieldContentsFlag fieldComments includeField = - fieldD fieldName (pretty . newtypeWrapper <$> fieldContentsFlag) fieldComments includeField - - -- | Construct a 'PrettyField' from a 'Doc' Flag. - fieldD :: FieldName -- ^ Name of the field - -> Flag Doc -- ^ Field contents - -> [String] -- ^ Comment to explain the field - -> Bool -- ^ Should the field be included (commented out) even if blank? - -> Maybe (PrettyField FieldAnnotation) - fieldD fieldName fieldContentsFlag fieldComments includeField = - case fieldContentsFlag of - NoFlag -> - -- If there is no content, optionally produce a commented out field. - fieldSEmptyContents fieldName fieldComments includeField - - Flag fieldContents -> - if isEmpty fieldContents - then - -- If the doc is empty, optionally produce a commented out field. - fieldSEmptyContents fieldName fieldComments includeField - else - -- If the doc is not empty, produce a field. - Just $ case (noComments c, minimal c) of - -- If the "--no-comments" flag is set, strip comments. - (Flag True, _) -> - fieldSWithContents fieldName fieldContents [] - -- If the "--minimal" flag is set, strip comments. - (_, Flag True) -> - fieldSWithContents fieldName fieldContents [] - -- Otherwise, include comments. - (_, _) -> - fieldSWithContents fieldName fieldContents fieldComments - - -- | Optionally produce a field with no content (depending on flags). - fieldSEmptyContents :: FieldName - -> [String] - -> Bool - -> Maybe (PrettyField FieldAnnotation) - fieldSEmptyContents fieldName fieldComments includeField - | not includeField || (minimal c == Flag True) = - Nothing - | otherwise = - Just (PrettyField (commentedOutWithComments fieldComments) fieldName empty) - - -- | Produce a field with content. - fieldSWithContents :: FieldName - -> Doc - -> [String] - -> PrettyField FieldAnnotation - fieldSWithContents fieldName fieldContents fieldComments = - PrettyField (withComments (map ("-- " ++) fieldComments)) fieldName fieldContents - - executableStanza :: PrettyField FieldAnnotation - executableStanza = PrettySection annNoComments (toUTF8BS "executable") [exeName] $ catMaybes - [ fieldS "main-is" (mainIs c) - [".hs or .lhs file containing the Main module."] - True - ] - ++ - generateBuildInfo ExecBuild c - where - exeName = text (maybe "" prettyShow . flagToMaybe $ packageName c) - - libraryStanza :: PrettyField FieldAnnotation - libraryStanza = PrettySection annNoComments (toUTF8BS "library") [] $ catMaybes - [ fieldPAla "exposed-modules" formatExposedModules (maybeToFlag (exposedModules c)) - ["Modules exported by the library."] - True - ] - ++ - generateBuildInfo LibBuild c - - - testSuiteStanza :: PrettyField FieldAnnotation - testSuiteStanza = PrettySection annNoComments (toUTF8BS "test-suite") [testSuiteName] $ catMaybes - [ field "default-language" (language c) - ["Base language which the package is written in."] - True - - , fieldS "type" (Flag "exitcode-stdio-1.0") - ["The interface type and version of the test suite."] - True - - , fieldPAla "hs-source-dirs" formatHsSourceDirs - (maybeToFlag $ fmap (fmap unsafeMakeSymbolicPath) $ testDirs c) -- TODO - ["Directories containing source files."] - True - - , fieldS "main-is" (Flag testFile) - ["The entrypoint to the test suite."] - True - - , fieldPAla "build-depends" formatDependencyList (maybeToFlag (dependencies c)) - ["Test dependencies."] - True - ] - where - testSuiteName = - text (maybe "" ((++"-test") . prettyShow) . flagToMaybe $ packageName c) - --- | Annotations for cabal file PrettyField. -data FieldAnnotation = FieldAnnotation - { annCommentedOut :: Bool - -- ^ True iif the field and its contents should be commented out. - , annCommentLines :: [String] - -- ^ Comment lines to place before the field or section. - } - --- | A field annotation instructing the pretty printer to comment out the field --- and any contents, with no comments. -commentedOutWithComments :: [String] -> FieldAnnotation -commentedOutWithComments = FieldAnnotation True . map ("-- " ++) - --- | A field annotation with the specified comment lines. -withComments :: [String] -> FieldAnnotation -withComments = FieldAnnotation False - --- | A field annotation with no comments. -annNoComments :: FieldAnnotation -annNoComments = FieldAnnotation False [] - -postProcessFieldLines :: FieldAnnotation -> [String] -> [String] -postProcessFieldLines ann - | annCommentedOut ann = map ("-- " ++) - | otherwise = id +writeDirectoriesSafe :: WriteOpts -> [String] -> IO () +writeDirectoriesSafe opts dirs = for_ dirs $ \dir -> do + exists <- doesDirectoryExist dir + moveExistingDir dir exists + + let action = if doOverwrite + then "Overwriting" + else "Creating or using already existing" + + message opts $ action ++ " directory ./" ++ dir ++ "..." + unless exists $ + createDirectory dir + where + doOverwrite = _optOverwrite opts + + moveExistingDir oldDir exists + | exists && doOverwrite = do + newDir <- findNewDir oldDir (0 :: Int) + message opts $ concat + [ "Warning: " + , oldDir + , " already exists. Backing up old version in " + , newDir + ] + + renameDirectory oldDir newDir + | exists && doOverwrite = removeDirectoryRecursive oldDir + | otherwise = return () + + findNewDir oldDir n = do + let newDir = oldDir <.> ("save" ++ show n) + e <- doesDirectoryExist newDir + if e then findNewDir oldDir (n+1) else return newDir diff --git a/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs b/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs new file mode 100644 index 00000000000..bf67c323c3a --- /dev/null +++ b/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs @@ -0,0 +1,267 @@ +{-# LANGUAGE LambdaCase #-} +module Distribution.Client.Init.FlagExtractors +( -- * Flag extractors + getPackageDir +, getSimpleProject +, getMinimal +, getCabalVersion +, getPackageName +, getVersion +, getLicense +, getAuthor +, getEmail +, getHomepage +, getSynopsis +, getCategory +, getExtraSrcFiles +, getPackageType +, getMainFile +, getInitializeTestSuite +, getTestDirs +, getLanguage +, getNoComments +, getAppDirs +, getSrcDirs +, getExposedModules +, getBuildTools +, getDependencies +, getOtherExts +, getOverwrite +, getOtherModules + -- * Shared prompts +, simpleProjectPrompt +, initializeTestSuitePrompt +, packageTypePrompt +, testMainPrompt +) where + + +import Prelude () +import Distribution.Client.Compat.Prelude hiding (putStr, putStrLn, getLine, last) + +import qualified Data.List.NonEmpty as NEL + +import Distribution.CabalSpecVersion (CabalSpecVersion(..)) +import Distribution.Version (Version) +import Distribution.ModuleName (ModuleName) +import Distribution.Types.Dependency (Dependency(..)) +import Distribution.Types.PackageName (PackageName) +import qualified Distribution.SPDX as SPDX +import Distribution.Client.Init.Defaults +import Distribution.Client.Init.Types +import Distribution.Simple.Setup (Flag(..), fromFlagOrDefault, flagToMaybe) +import Distribution.Simple.Flag (flagElim) + +import Language.Haskell.Extension (Language(..), Extension(..)) +import Distribution.Client.Init.Prompt + + + +-- -------------------------------------------------------------------- -- +-- Flag extraction + +getPackageDir :: Interactive m => InitFlags -> m FilePath +getPackageDir = flagElim getCurrentDirectory return . packageDir + +-- | Ask if a simple project with sensible defaults should be created. +getSimpleProject :: Interactive m => InitFlags -> m Bool -> m Bool +getSimpleProject flags = fromFlagOrPrompt (simpleProject flags) + +-- | Extract minimal cabal file flag (implies nocomments) +getMinimal :: Interactive m => InitFlags -> m Bool +getMinimal = return . fromFlagOrDefault False . minimal + +-- | Get the version of the cabal spec to use. +-- +-- The spec version can be specified by the InitFlags cabalVersion field. If +-- none is specified then the user is prompted to pick from a list of +-- supported versions (see code below). +getCabalVersion :: Interactive m => InitFlags -> m CabalSpecVersion -> m CabalSpecVersion +getCabalVersion flags = fromFlagOrPrompt (cabalVersion flags) + +-- | Get the package name: use the package directory (supplied, or the current +-- directory by default) as a guess. It looks at the SourcePackageDb to avoid +-- using an existing package name. +getPackageName :: Interactive m => InitFlags -> m PackageName -> m PackageName +getPackageName flags = fromFlagOrPrompt (packageName flags) + +-- | Package version: use 0.1.0.0 as a last resort, but try prompting the user +-- if possible. +getVersion :: Interactive m => InitFlags -> m Version -> m Version +getVersion flags = fromFlagOrPrompt (version flags) + +-- | Choose a license for the package. +-- The license can come from Initflags (license field), if it is not present +-- then prompt the user from a predefined list of licenses. +getLicense :: Interactive m => InitFlags -> m SPDX.License -> m SPDX.License +getLicense flags = fromFlagOrPrompt (license flags) + +-- | The author's name. Prompt, or try to guess from an existing +-- darcs repo. +getAuthor :: Interactive m => InitFlags -> m String -> m String +getAuthor flags = fromFlagOrPrompt (author flags) + +-- | The author's email. Prompt, or try to guess from an existing +-- darcs repo. +getEmail :: Interactive m => InitFlags -> m String -> m String +getEmail flags = fromFlagOrPrompt (email flags) + +-- | Prompt for a homepage URL for the package. +getHomepage :: Interactive m => InitFlags -> m String -> m String +getHomepage flags = fromFlagOrPrompt (homepage flags) + +-- | Prompt for a project synopsis. +getSynopsis :: Interactive m => InitFlags -> m String -> m String +getSynopsis flags = fromFlagOrPrompt (synopsis flags) + +-- | Prompt for a package category. +-- Note that it should be possible to do some smarter guessing here too, i.e. +-- look at the name of the top level source directory. +getCategory :: Interactive m => InitFlags -> m String -> m String +getCategory flags = fromFlagOrPrompt (category flags) + +-- | Try to guess extra source files (don't prompt the user). +getExtraSrcFiles :: Interactive m => InitFlags -> m (NonEmpty String) +getExtraSrcFiles = pure + . flagElim (defaultChangelog NEL.:| []) NEL.fromList + . extraSrc + +-- | Ask whether the project builds a library or executable. +getPackageType :: Interactive m => InitFlags -> m PackageType -> m PackageType +getPackageType flags = fromFlagOrPrompt (packageType flags) + +getMainFile :: Interactive m => InitFlags -> m HsFilePath -> m HsFilePath +getMainFile flags act = case mainIs flags of + Flag a + | isHsFilePath a -> return $ toHsFilePath a + | otherwise -> act + NoFlag -> act + +getInitializeTestSuite :: Interactive m => InitFlags -> m Bool -> m Bool +getInitializeTestSuite flags = fromFlagOrPrompt (initializeTestSuite flags) + +getTestDirs :: Interactive m => InitFlags -> m [String] -> m [String] +getTestDirs flags = fromFlagOrPrompt (testDirs flags) + +-- | Ask for the Haskell base language of the package. +getLanguage :: Interactive m => InitFlags -> m Language -> m Language +getLanguage flags = fromFlagOrPrompt (language flags) + +-- | Ask whether to generate explanatory comments. +getNoComments :: Interactive m => InitFlags -> m Bool -> m Bool +getNoComments flags = fromFlagOrPrompt (noComments flags) + +-- | Ask for the application root directory. +getAppDirs :: Interactive m => InitFlags -> m [String] -> m [String] +getAppDirs flags = fromFlagOrPrompt (applicationDirs flags) + +-- | Ask for the source (library) root directory. +getSrcDirs :: Interactive m => InitFlags -> m [String] -> m [String] +getSrcDirs flags = fromFlagOrPrompt (sourceDirs flags) + +-- | Retrieve the list of exposed modules +getExposedModules :: Interactive m => InitFlags -> m (NonEmpty ModuleName) +getExposedModules = return + . fromMaybe (myLibModule NEL.:| []) + . join + . flagToMaybe + . fmap NEL.nonEmpty + . exposedModules + +-- | Retrieve the list of other modules +getOtherModules :: Interactive m => InitFlags -> m [ModuleName] +getOtherModules = return . fromFlagOrDefault [] . otherModules + +-- | Retrieve the list of build tools +getBuildTools :: Interactive m => InitFlags -> m [String] +getBuildTools = return . fromFlagOrDefault [] . buildTools + +-- | Retrieve the list of dependencies +getDependencies + :: Interactive m + => InitFlags + -> m [Dependency] + -> m [Dependency] +getDependencies flags = fromFlagOrPrompt (dependencies flags) + + +-- | Retrieve the list of extensions +getOtherExts :: Interactive m => InitFlags -> m [Extension] +getOtherExts = return . fromFlagOrDefault [] . otherExts + +-- | Tell whether to overwrite files on write +-- +getOverwrite :: Interactive m => InitFlags -> m Bool +getOverwrite = return . fromFlagOrDefault False . overwrite + +-- -------------------------------------------------------------------- -- +-- Shared prompts + +simpleProjectPrompt :: Interactive m => InitFlags -> m Bool +simpleProjectPrompt flags = getSimpleProject flags $ + promptYesNo + "Should I generate a simple project with sensible defaults" + (Just True) + +initializeTestSuitePrompt :: Interactive m => InitFlags -> m Bool +initializeTestSuitePrompt flags = getInitializeTestSuite flags $ + promptYesNo + "Should I generate a test suite for the library" + (Just True) + +packageTypePrompt :: Interactive m => InitFlags -> m PackageType +packageTypePrompt flags = getPackageType flags $ do + pt <- promptList "What does the package build" + packageTypes + (Just "Executable") + Nothing + False + + return $ fromMaybe Executable (parsePackageType pt) + where + packageTypes = + [ "Library" + , "Executable" + , "Library and Executable" + ] + + parsePackageType = \case + "Library" -> Just Library + "Executable" -> Just Executable + "Library and Executable" -> Just LibraryAndExecutable + _ -> Nothing + +testMainPrompt :: Interactive m => m HsFilePath +testMainPrompt = do + fp <- promptList "What is the main module of the test suite?" + [defaultMainIs', "Main.lhs"] + (Just defaultMainIs') + Nothing + True + + let hs = toHsFilePath fp + + case _hsFileType hs of + InvalidHsPath -> do + putStrLn $ concat + [ "Main file " + , show hs + , " is not a valid haskell file. Source files must end in .hs or .lhs." + ] + testMainPrompt + _ -> return hs + where + defaultMainIs' = show defaultMainIs + +-- -------------------------------------------------------------------- -- +-- utilities + +-- | If a flag is defined, return its value or else execute +-- an interactive action. +-- +fromFlagOrPrompt + :: Interactive m + => Flag a + -> m a + -> m a +fromFlagOrPrompt flag action = flagElim action return flag diff --git a/cabal-install/src/Distribution/Client/Init/Format.hs b/cabal-install/src/Distribution/Client/Init/Format.hs new file mode 100644 index 00000000000..cc5906fb66c --- /dev/null +++ b/cabal-install/src/Distribution/Client/Init/Format.hs @@ -0,0 +1,338 @@ +{-# LANGUAGE OverloadedStrings #-} +-- | +-- Module : Distribution.Client.Init.Format +-- Copyright : (c) Brent Yorgey 2009 +-- License : BSD-like +-- +-- Maintainer : cabal-devel@haskell.org +-- Stability : provisional +-- Portability : portable +-- +-- Pretty printing and field formatting utilities used for file creation. +-- +module Distribution.Client.Init.Format +( -- * cabal file formatters + listFieldS +, field +, fieldD +, commentedOutWithComments +, withComments +, annNoComments +, postProcessFieldLines + -- * stanza generation +, mkLibStanza +, mkExeStanza +, mkTestStanza +, mkPkgDescription +) where + + +import Distribution.Pretty +import Distribution.Fields +import Distribution.Client.Init.Types +import Text.PrettyPrint +import Distribution.Solver.Compat.Prelude hiding (empty) +import Distribution.PackageDescription.FieldGrammar +import Distribution.Simple.Utils +import Distribution.Utils.Path +import Distribution.Package (unPackageName) +import qualified Distribution.SPDX.License as SPDX +import Distribution.CabalSpecVersion + + +-- | Construct a 'PrettyField' from a field that can be automatically +-- converted to a 'Doc' via 'display'. +field + :: Pretty b + => FieldName + -> (a -> b) + -> a + -> [String] + -> Bool + -> WriteOpts + -> PrettyField FieldAnnotation +field fieldName modifier fieldContents = + fieldD fieldName (pretty $ modifier fieldContents) + +-- | Construct a 'PrettyField' from a 'Doc' Flag. +fieldD + :: FieldName -- ^ Name of the field + -> Doc -- ^ Field contents + -> [String] -- ^ Comment to explain the field + -> Bool -- ^ Should the field be included (commented out) even if blank? + -> WriteOpts + -> PrettyField FieldAnnotation +fieldD fieldName fieldContents fieldComments includeField opts + | fieldContents == empty = + -- If there is no content, optionally produce a commented out field. + fieldSEmptyContents fieldComments + | otherwise = + -- If the "--no-comments" flag is set, strip comments. + let comments = if hasNoComments + then [] + else fieldComments + + -- If the "--minimal" flag is set, strip comments. + in fieldSWithContents comments + where + isMinimal = _optMinimal opts + hasNoComments = _optNoComments opts + + fieldSEmptyContents cs + | not includeField || isMinimal = PrettyEmpty + | otherwise = PrettyField + (commentedOutWithComments cs) + fieldName + empty + + fieldSWithContents cs = + PrettyField (withComments (map ("-- " ++) cs)) fieldName fieldContents + + +-- | A field annotation instructing the pretty printer to comment out the field +-- and any contents, with no comments. +commentedOutWithComments :: [String] -> FieldAnnotation +commentedOutWithComments = FieldAnnotation True . map ("-- " ++) + +-- | A field annotation with the specified comment lines. +withComments :: [String] -> FieldAnnotation +withComments = FieldAnnotation False + +-- | A field annotation with no comments. +annNoComments :: FieldAnnotation +annNoComments = FieldAnnotation False [] + +postProcessFieldLines :: FieldAnnotation -> [String] -> [String] +postProcessFieldLines ann + | annCommentedOut ann = fmap ("-- " ++) + | otherwise = id + +-- -------------------------------------------------------------------- -- +-- Stanzas + +mkLibStanza :: WriteOpts -> LibTarget -> PrettyField FieldAnnotation +mkLibStanza opts (LibTarget srcDirs lang expMods otherMods exts deps tools) = + PrettySection annNoComments (toUTF8BS "library") [] + [ field "exposed-modules" formatExposedModules (toList expMods) + ["Modules exported by the library."] + True + opts + + , field "other-modules" formatOtherModules otherMods + ["Modules included in this library but not exported."] + True + opts + + , field "other-extensions" formatOtherExtensions exts + ["LANGUAGE extensions used by modules in this package."] + True + opts + + , field "build-depends" formatDependencyList deps + ["Other library packages from which modules are imported."] + True + opts + + , field "hs-source-dirs" formatHsSourceDirs (unsafeMakeSymbolicPath <$> srcDirs) + ["Directories containing source files."] + True + opts + + , field "build-tools" listFieldS tools + ["Extra tools (e.g. alex, hsc2hs, ...) needed to build the source."] + False + opts + + , field "default-language" id lang + ["Base language which the package is written in."] + True + opts + ] + +mkExeStanza :: WriteOpts -> ExeTarget -> PrettyField FieldAnnotation +mkExeStanza opts (ExeTarget exeMain appDirs lang otherMods exts deps tools) = + PrettySection annNoComments (toUTF8BS "executable") [exeName] + [ field "main-is" unsafeFromHs exeMain + [".hs or .lhs file containing the Main module."] + True + opts + + , field "other-modules" formatOtherModules otherMods + [ "Modules included in this executable, other than Main." ] + True + opts + + , field "other-extensions" formatOtherExtensions exts + ["LANGUAGE extensions used by modules in this package."] + True + opts + , field "build-depends" formatDependencyList deps + ["Other library packages from which modules are imported."] + True + opts + + , field "hs-source-dirs" formatHsSourceDirs + (unsafeMakeSymbolicPath <$> appDirs) + ["Directories containing source files."] + True + opts + + , field "build-tools" listFieldS tools + ["Extra tools (e.g. alex, hsc2hs, ...) needed to build the source."] + False + opts + + , field "default-language" id lang + ["Base language which the package is written in."] + True + opts + ] + where + exeName = pretty $ _optPkgName opts + + +mkTestStanza :: WriteOpts -> TestTarget -> PrettyField FieldAnnotation +mkTestStanza opts (TestTarget testMain dirs lang otherMods exts deps tools) = + PrettySection annNoComments (toUTF8BS "test-suite") [suiteName] + [ field "default-language" id lang + ["Base language which the package is written in."] + True + opts + , field "other-modules" formatOtherModules otherMods + [ "Modules included in this executable, other than Main." ] + True + opts + + , field "other-extensions" formatOtherExtensions exts + ["LANGUAGE extensions used by modules in this package."] + True + opts + + , field "type" text "exitcode-stdio-1.0" + ["The interface type and version of the test suite."] + True + opts + + , field "hs-source-dirs" formatHsSourceDirs + (unsafeMakeSymbolicPath <$> dirs) + ["Directories containing source files."] + True + opts + + , field "main-is" unsafeFromHs testMain + ["The entrypoint to the test suite."] + True + opts + + , field "build-depends" formatDependencyList deps + ["Test dependencies."] + True + opts + + , field "build-tools" listFieldS tools + ["Extra tools (e.g. alex, hsc2hs, ...) needed to build the source."] + False + opts + ] + where + suiteName = text $ unPackageName (_optPkgName opts) ++ "-test" + +mkPkgDescription :: WriteOpts -> PkgDescription -> [PrettyField FieldAnnotation] +mkPkgDescription opts pkgDesc = + [ field "cabal-version" text (showCabalSpecVersion cabalSpec) [] False opts + , field "name" pretty (_pkgName pkgDesc) + ["Initial package description '" ++ prettyShow (_optPkgName opts) ++ "' generated by" + , "'cabal init'. For further documentation, see:" + , " http://haskell.org/cabal/users-guide/" + , "" + , "The name of the package." + ] + True + opts + + , field "version" pretty (_pkgVersion pkgDesc) + ["The package version.", + "See the Haskell package versioning policy (PVP) for standards", + "guiding when and how versions should be incremented.", + "https://pvp.haskell.org", + "PVP summary: +-+------- breaking API changes", + " | | +----- non-breaking API additions", + " | | | +--- code changes with no API change"] + True + opts + + , field "synopsis" text (_pkgSynopsis pkgDesc) + ["A short (one-line) description of the package."] + True + opts + + , field "description" text "" + ["A longer description of the package."] + True + opts + + , field "homepage" text (_pkgHomePage pkgDesc) + ["URL for the project homepage or repository."] + False + opts + + , field "bug-reports" text "" + ["A URL where users can report bugs."] + False + opts + + , field "license" pretty (_pkgLicense pkgDesc) + ["The license under which the package is released."] + True + opts + + , case _pkgLicense pkgDesc of + SPDX.NONE -> PrettyEmpty + _ -> field "license-file" text "LICENSE" + ["The file containing the license text."] + False + opts + + , field "author" text (_pkgAuthor pkgDesc) + ["The package author(s)."] + True + opts + + , field "maintainer" text (_pkgEmail pkgDesc) + ["An email address to which users can send suggestions, bug reports, and patches."] + True + opts + + , field "copyright" text "" + ["A copyright notice."] + True + opts + + , field "category" text (_pkgCategory pkgDesc) + [] + False + opts + , if cabalSpec < CabalSpecV2_2 + then PrettyEmpty + else field "build-type" text "Simple" + [] + False + opts + + , field "extra-source-files" formatExtraSourceFiles (toList $ _pkgExtraSrcFiles pkgDesc) + ["Extra files to be distributed with the package, such as examples or a README."] + True + opts + ] + where + cabalSpec = _pkgCabalVersion pkgDesc + +-- -------------------------------------------------------------------- -- +-- Utils + +listFieldS :: [String] -> Doc +listFieldS = text . intercalate ", " + + +unsafeFromHs :: HsFilePath -> Doc +unsafeFromHs = text . _hsFilePath diff --git a/cabal-install/src/Distribution/Client/Init/Heuristics.hs b/cabal-install/src/Distribution/Client/Init/Heuristics.hs deleted file mode 100644 index f561af091fa..00000000000 --- a/cabal-install/src/Distribution/Client/Init/Heuristics.hs +++ /dev/null @@ -1,396 +0,0 @@ ------------------------------------------------------------------------------ --- | --- Module : Distribution.Client.Init.Heuristics --- Copyright : (c) Benedikt Huber 2009 --- License : BSD-like --- --- Maintainer : cabal-devel@haskell.org --- Stability : provisional --- Portability : portable --- --- Heuristics for creating initial cabal files. --- ------------------------------------------------------------------------------ -module Distribution.Client.Init.Heuristics ( - guessPackageName, - scanForModules, SourceFileEntry(..), - neededBuildPrograms, - guessMainFileCandidates, - guessAuthorNameMail, - knownCategories, -) where - -import Prelude () -import qualified Data.ByteString as BS -import Distribution.Client.Compat.Prelude -import Distribution.Utils.Generic (safeHead, safeTail, safeLast) - -import Distribution.Simple.Setup (Flag(..), flagToMaybe) -import Distribution.Simple.Utils (fromUTF8BS) -import Distribution.ModuleName - ( ModuleName, toFilePath ) -import qualified Distribution.Package as P -import qualified Distribution.PackageDescription as PD - ( category, packageDescription ) -import Distribution.Client.Utils - ( tryCanonicalizePath ) -import Language.Haskell.Extension ( Extension ) - -import Distribution.Solver.Types.PackageIndex - ( allPackagesByName ) -import Distribution.Solver.Types.SourcePackage - ( srcpkgDescription ) - -import Distribution.Client.Types ( SourcePackageDb(..) ) -import Data.Char ( isLower ) -import Data.List ( isInfixOf ) -import qualified Data.Set as Set ( fromList, toList ) -import System.Directory ( getCurrentDirectory, getDirectoryContents, - doesDirectoryExist, doesFileExist, getHomeDirectory, ) -import Distribution.Compat.Environment ( getEnvironment ) -import System.FilePath ( takeExtension, takeBaseName, dropExtension, - (), (<.>), splitDirectories, makeRelative ) - -import Distribution.Client.Init.Types ( InitFlags(..) ) -import Distribution.Client.Compat.Process ( readProcessWithExitCode ) - -import qualified Distribution.Utils.ShortText as ShortText - --- | Return a list of candidate main files for this executable: top-level --- modules including the word 'Main' in the file name. The list is sorted in --- order of preference, shorter file names are preferred. 'Right's are existing --- candidates and 'Left's are those that do not yet exist. -guessMainFileCandidates :: InitFlags -> IO [Either FilePath FilePath] -guessMainFileCandidates flags = do - dir <- - maybe getCurrentDirectory return (flagToMaybe $ packageDir flags) - files <- getDirectoryContents dir - let existingCandidates = filter isMain files - -- We always want to give the user at least one default choice. If either - -- Main.hs or Main.lhs has already been created, then we don't want to - -- suggest the other; however, if neither has been created, then we - -- suggest both. - newCandidates = - if any (`elem` existingCandidates) ["Main.hs", "Main.lhs"] - then [] - else ["Main.hs", "Main.lhs"] - candidates = - sortBy (\x y -> comparing (length . either id id) x y - `mappend` compare x y) - (map Left newCandidates ++ map Right existingCandidates) - return candidates - - where - isMain f = (isInfixOf "Main" f || isInfixOf "main" f) - && (isSuffixOf ".hs" f || isSuffixOf ".lhs" f) - --- | Guess the package name based on the given root directory. -guessPackageName :: FilePath -> IO P.PackageName -guessPackageName = liftM (P.mkPackageName . repair . fromMaybe "" . safeLast . splitDirectories) - . tryCanonicalizePath - where - -- Treat each span of non-alphanumeric characters as a hyphen. Each - -- hyphenated component of a package name must contain at least one - -- alphabetic character. An arbitrary character ('x') will be prepended if - -- this is not the case for the first component, and subsequent components - -- will simply be run together. For example, "1+2_foo-3" will become - -- "x12-foo3". - repair = repair' ('x' :) id - repair' invalid valid x = case dropWhile (not . isAlphaNum) x of - "" -> repairComponent "" - x' -> let (c, r) = first repairComponent $ break (not . isAlphaNum) x' - in c ++ repairRest r - where - repairComponent c | all isDigit c = invalid c - | otherwise = valid c - repairRest = repair' id ('-' :) - --- |Data type of source files found in the working directory -data SourceFileEntry = SourceFileEntry - { relativeSourcePath :: FilePath - , moduleName :: ModuleName - , fileExtension :: String - , imports :: [ModuleName] - , extensions :: [Extension] - } deriving Show - -sfToFileName :: FilePath -> SourceFileEntry -> FilePath -sfToFileName projectRoot (SourceFileEntry relPath m ext _ _) - = projectRoot relPath toFilePath m <.> ext - --- |Search for source files in the given directory --- and return pairs of guessed Haskell source path and --- module names. -scanForModules :: FilePath -> IO [SourceFileEntry] -scanForModules rootDir = scanForModulesIn rootDir rootDir - -scanForModulesIn :: FilePath -> FilePath -> IO [SourceFileEntry] -scanForModulesIn projectRoot srcRoot = scan srcRoot [] - where - scan dir hierarchy = do - entries <- getDirectoryContents (projectRoot dir) - (files, dirs) <- liftM partitionEithers (traverse (tagIsDir dir) entries) - let modules = catMaybes [ guessModuleName hierarchy file - | file <- files - , maybe False isUpper (safeHead file) ] - modules' <- traverse (findImportsAndExts projectRoot) modules - recMods <- traverse (scanRecursive dir hierarchy) dirs - return $ concat (modules' : recMods) - tagIsDir parent entry = do - isDir <- doesDirectoryExist (parent entry) - return $ (if isDir then Right else Left) entry - guessModuleName hierarchy entry - | takeBaseName entry == "Setup" = Nothing - | ext `elem` sourceExtensions = - SourceFileEntry <$> pure relRoot <*> modName <*> pure ext <*> pure [] <*> pure [] - | otherwise = Nothing - where - relRoot = makeRelative projectRoot srcRoot - unqualModName = dropExtension entry - modName = simpleParsec - $ intercalate "." . reverse $ (unqualModName : hierarchy) - ext = case takeExtension entry of '.':e -> e; e -> e - scanRecursive parent hierarchy entry - | maybe False isUpper (safeHead entry) = scan (parent entry) (entry : hierarchy) - | maybe False isLower (safeHead entry) && not (ignoreDir entry) = - scanForModulesIn projectRoot $ foldl () srcRoot (reverse (entry : hierarchy)) - | otherwise = return [] - ignoreDir ('.':_) = True - ignoreDir dir = dir `elem` ["dist", "_darcs"] - --- | Read the contents of the handle and parse for Language pragmas --- and other module names that might be part of this project. -findImportsAndExts :: FilePath -> SourceFileEntry -> IO SourceFileEntry -findImportsAndExts projectRoot sf = do - s <- fromUTF8BS <$> BS.readFile (sfToFileName projectRoot sf) - - let modules = mapMaybe - ( getModName - . drop 1 - . filter (not . null) - . dropWhile (/= "import") - . words - ) - . filter (not . ("--" `isPrefixOf`)) -- poor man's comment filtering - . lines - $ s - - -- TODO: We should probably make a better attempt at parsing - -- comments above. Unfortunately we can't use a full-fledged - -- Haskell parser since cabal's dependencies must be kept at a - -- minimum. - - -- A poor man's LANGUAGE pragma parser. - exts = mapMaybe simpleParsec - . concatMap getPragmas - . filter isLANGUAGEPragma - . map fst - . drop 1 - . takeWhile (not . null . snd) - . iterate (takeBraces . snd) - $ ("",s) - - takeBraces = break (== '}') . dropWhile (/= '{') - - isLANGUAGEPragma = ("{-# LANGUAGE " `isPrefixOf`) - - getPragmas = map trim . splitCommas . takeWhile (/= '#') . drop 13 - - splitCommas "" = [] - splitCommas xs = x : splitCommas (drop 1 y) - where (x,y) = break (==',') xs - - return sf { imports = modules - , extensions = exts - } - - where getModName :: [String] -> Maybe ModuleName - getModName [] = Nothing - getModName ("qualified":ws) = getModName ws - getModName (ms:_) = simpleParsec ms - - - --- Unfortunately we cannot use the version exported by Distribution.Simple.Program -knownSuffixHandlers :: [(String,String)] -knownSuffixHandlers = - [ ("gc", "greencard") - , ("chs", "chs") - , ("hsc", "hsc2hs") - , ("x", "alex") - , ("y", "happy") - , ("ly", "happy") - , ("cpphs", "cpp") - ] - -sourceExtensions :: [String] -sourceExtensions = "hs" : "lhs" : map fst knownSuffixHandlers - -neededBuildPrograms :: [SourceFileEntry] -> [String] -neededBuildPrograms entries = - [ handler - | ext <- nubSet (map fileExtension entries) - , handler <- maybeToList (lookup ext knownSuffixHandlers) - ] - --- | Guess author and email using darcs and git configuration options. Use --- the following in decreasing order of preference: --- --- 1. vcs env vars ($DARCS_EMAIL, $GIT_AUTHOR_*) --- 2. Local repo configs --- 3. Global vcs configs --- 4. The generic $EMAIL --- --- Name and email are processed separately, so the guess might end up being --- a name from DARCS_EMAIL and an email from git config. --- --- Darcs has preference, for tradition's sake. -guessAuthorNameMail :: IO (Flag String, Flag String) -guessAuthorNameMail = fmap authorGuessPure authorGuessIO - --- Ordered in increasing preference, since Flag-as-monoid is identical to --- Last. -authorGuessPure :: AuthorGuessIO -> AuthorGuess -authorGuessPure (AuthorGuessIO { authorGuessEnv = env - , authorGuessLocalDarcs = darcsLocalF - , authorGuessGlobalDarcs = darcsGlobalF - , authorGuessLocalGit = gitLocal - , authorGuessGlobalGit = gitGlobal }) - = mconcat - [ emailEnv env - , gitGlobal - , darcsCfg darcsGlobalF - , gitLocal - , darcsCfg darcsLocalF - , gitEnv env - , darcsEnv env - ] - -authorGuessIO :: IO AuthorGuessIO -authorGuessIO = AuthorGuessIO - <$> getEnvironment - <*> (maybeReadFile $ "_darcs" "prefs" "author") - <*> (maybeReadFile =<< liftM ( (".darcs" "author")) getHomeDirectory) - <*> gitCfg Local - <*> gitCfg Global - --- Types and functions used for guessing the author are now defined: - -type AuthorGuess = (Flag String, Flag String) -type Enviro = [(String, String)] -data GitLoc = Local | Global -data AuthorGuessIO = AuthorGuessIO { - authorGuessEnv :: Enviro, -- ^ Environment lookup table - authorGuessLocalDarcs :: (Maybe String), -- ^ Contents of local darcs author info - authorGuessGlobalDarcs :: (Maybe String), -- ^ Contents of global darcs author info - authorGuessLocalGit :: AuthorGuess, -- ^ Git config --local - authorGuessGlobalGit :: AuthorGuess -- ^ Git config --global - } - -darcsEnv :: Enviro -> AuthorGuess -darcsEnv = maybe mempty nameAndMail . lookup "DARCS_EMAIL" - -gitEnv :: Enviro -> AuthorGuess -gitEnv env = (name, mail) - where - name = maybeFlag "GIT_AUTHOR_NAME" env - mail = maybeFlag "GIT_AUTHOR_EMAIL" env - -darcsCfg :: Maybe String -> AuthorGuess -darcsCfg = maybe mempty nameAndMail - -emailEnv :: Enviro -> AuthorGuess -emailEnv env = (mempty, mail) - where - mail = maybeFlag "EMAIL" env - -gitCfg :: GitLoc -> IO AuthorGuess -gitCfg which = do - name <- gitVar which "user.name" - mail <- gitVar which "user.email" - return (name, mail) - -gitVar :: GitLoc -> String -> IO (Flag String) -gitVar which = fmap happyOutput . gitConfigQuery which - -happyOutput :: (ExitCode, a, t) -> Flag a -happyOutput v = case v of - (ExitSuccess, s, _) -> Flag s - _ -> mempty - -gitConfigQuery :: GitLoc -> String -> IO (ExitCode, String, String) -gitConfigQuery which key = - fmap trim' $ readProcessWithExitCode "git" ["config", w, key] "" - where - w = case which of - Local -> "--local" - Global -> "--global" - trim' (a, b, c) = (a, trim b, c) - -maybeFlag :: String -> Enviro -> Flag String -maybeFlag k = maybe mempty Flag . lookup k - --- | Read the first non-comment, non-trivial line of a file, if it exists -maybeReadFile :: String -> IO (Maybe String) -maybeReadFile f = do - exists <- doesFileExist f - if exists - then fmap getFirstLine $ readFile f - else return Nothing - where - getFirstLine content = - let nontrivialLines = dropWhile (\l -> (null l) || ("#" `isPrefixOf` l)) . lines $ content - in case nontrivialLines of - [] -> Nothing - (l:_) -> Just l - --- |Get list of categories used in Hackage. NOTE: Very slow, needs to be cached -knownCategories :: SourcePackageDb -> [String] -knownCategories (SourcePackageDb sourcePkgIndex _) = nubSet - [ cat | pkg <- maybeToList . safeHead =<< (allPackagesByName sourcePkgIndex) - , let catList = (PD.category . PD.packageDescription . srcpkgDescription) pkg - , cat <- splitString ',' $ ShortText.fromShortText catList - ] - --- Parse name and email, from darcs pref files or environment variable -nameAndMail :: String -> (Flag String, Flag String) -nameAndMail str - | all isSpace nameOrEmail = mempty - | null erest = (mempty, Flag $ trim nameOrEmail) - | otherwise = (Flag $ trim nameOrEmail, Flag mail) - where - (nameOrEmail,erest) = break (== '<') str - (mail,_) = break (== '>') (safeTail erest) - -trim :: String -> String -trim = removeLeadingSpace . reverse . removeLeadingSpace . reverse - where - removeLeadingSpace = dropWhile isSpace - --- split string at given character, and remove whitespace -splitString :: Char -> String -> [String] -splitString sep str = go str where - go s = if null s' then [] else tok : go rest where - s' = dropWhile (\c -> c == sep || isSpace c) s - (tok,rest) = break (==sep) s' - -nubSet :: (Ord a) => [a] -> [a] -nubSet = Set.toList . Set.fromList - -{- -test db testProjectRoot = do - putStrLn "Guessed package name" - (guessPackageName >=> print) testProjectRoot - putStrLn "Guessed name and email" - guessAuthorNameMail >>= print - - mods <- scanForModules testProjectRoot - - putStrLn "Guessed modules" - mapM_ print mods - putStrLn "Needed build programs" - print (neededBuildPrograms mods) - - putStrLn "List of known categories" - print $ knownCategories db --} diff --git a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs new file mode 100644 index 00000000000..2aef676763a --- /dev/null +++ b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs @@ -0,0 +1,459 @@ +{-# LANGUAGE LambdaCase #-} +----------------------------------------------------------------------------- +-- | +-- Module : Distribution.Client.Init.Command +-- Copyright : (c) Brent Yorgey 2009 +-- License : BSD-like +-- +-- Maintainer : cabal-devel@haskell.org +-- Stability : provisional +-- Portability : portable +-- +-- Implementation of the 'cabal init' command, which creates an initial .cabal +-- file for a project. +-- +----------------------------------------------------------------------------- +module Distribution.Client.Init.Interactive.Command +( -- * Commands + createProject + -- ** Target generation +, genPkgDescription +, genLibTarget +, genExeTarget +, genTestTarget + -- ** Prompts +, cabalVersionPrompt +, packageNamePrompt +, versionPrompt +, licensePrompt +, authorPrompt +, emailPrompt +, homepagePrompt +, synopsisPrompt +, categoryPrompt +, mainFilePrompt +, testDirsPrompt +, languagePrompt +, noCommentsPrompt +, appDirsPrompt +, dependenciesPrompt +, srcDirsPrompt +) where + + +import Prelude () +import Distribution.Client.Compat.Prelude hiding (putStr, putStrLn, getLine, last) + + +import Distribution.CabalSpecVersion (CabalSpecVersion(..), showCabalSpecVersion) +import Distribution.Version (Version) +import Distribution.Types.Dependency (Dependency(..)) +import Distribution.Types.PackageName (PackageName, unPackageName) +import qualified Distribution.SPDX as SPDX +import Distribution.Client.Init.Defaults +import Distribution.Client.Init.FlagExtractors +import Distribution.Client.Init.Prompt +import Distribution.Client.Init.Types +import Distribution.Client.Init.Utils +import Distribution.Simple.Setup (Flag(..)) +import Distribution.Simple.PackageIndex (InstalledPackageIndex) +import Distribution.Client.Types (SourcePackageDb(..)) +import Distribution.Solver.Types.PackageIndex (elemByPackageName) + +import Language.Haskell.Extension (Language(..)) + + + +-- | Main driver for interactive prompt code. +-- +createProject + :: Interactive m + => Verbosity + -> InstalledPackageIndex + -> SourcePackageDb + -> InitFlags + -> m ProjectSettings +createProject v pkgIx srcDb initFlags = do + + -- The workflow is as follows: + -- + -- 1. Get the package type, supplied as either a program input or + -- via user prompt. This determines what targets will be built + -- in later steps. + -- + -- 2. Generate package description and the targets specified by + -- the package type. Once this is done, a prompt for building + -- test suites is initiated, and this determines if we build + -- test targets as well. Then we ask if the user wants to + -- comment their .cabal file with pretty comments. + -- + -- 3. The targets are passed to the file creator script, and associated + -- directories/files/modules are created, with the a .cabal file + -- being generated as a final result. + -- + + pkgType <- packageTypePrompt initFlags + isMinimal <- getMinimal initFlags + doOverwrite <- getOverwrite initFlags + pkgDir <- getPackageDir initFlags + pkgDesc <- genPkgDescription initFlags srcDb + + let pkgName = _pkgName pkgDesc + mkOpts cs = WriteOpts + doOverwrite isMinimal cs + v pkgDir pkgType pkgName + + case pkgType of + Library -> do + libTarget <- genLibTarget initFlags pkgIx + testTarget <- addLibDepToTest pkgName <$> + genTestTarget initFlags pkgIx + + comments <- noCommentsPrompt initFlags + + return $ ProjectSettings + (mkOpts comments) pkgDesc + (Just libTarget) Nothing testTarget + + Executable -> do + exeTarget <- genExeTarget initFlags pkgIx + comments <- noCommentsPrompt initFlags + + return $ ProjectSettings + (mkOpts comments) pkgDesc Nothing + (Just exeTarget) Nothing + + LibraryAndExecutable -> do + libTarget <- genLibTarget initFlags pkgIx + + exeTarget <- addLibDepToExe pkgName <$> + genExeTarget initFlags pkgIx + + testTarget <- addLibDepToTest pkgName <$> + genTestTarget initFlags pkgIx + + comments <- noCommentsPrompt initFlags + + return $ ProjectSettings + (mkOpts comments) pkgDesc (Just libTarget) + (Just exeTarget) testTarget + where + -- Add package name as dependency of test suite + -- + addLibDepToTest _ Nothing = Nothing + addLibDepToTest n (Just t) = Just $ t + { _testDependencies = _testDependencies t ++ [mkPackageNameDep n] + } + + -- Add package name as dependency of executable + -- + addLibDepToExe n exe = exe + { _exeDependencies = _exeDependencies exe ++ [mkPackageNameDep n] + } + +-- -------------------------------------------------------------------- -- +-- Target and pkg description generation + +-- | Extract flags relevant to a package description and interactively +-- generate a 'PkgDescription' object for creation. If the user specifies +-- the generation of a simple package, then a simple target with defaults +-- is generated. +-- +genPkgDescription + :: Interactive m + => InitFlags + -> SourcePackageDb + -> m PkgDescription +genPkgDescription flags srcDb = PkgDescription + <$> cabalVersionPrompt flags + <*> packageNamePrompt srcDb flags + <*> versionPrompt flags + <*> licensePrompt flags + <*> authorPrompt flags + <*> emailPrompt flags + <*> homepagePrompt flags + <*> synopsisPrompt flags + <*> categoryPrompt flags + <*> getExtraSrcFiles flags + + +-- | Extract flags relevant to a library target and interactively +-- generate a 'LibTarget' object for creation. If the user specifies +-- the generation of a simple package, then a simple target with defaults +-- is generated. +-- +genLibTarget + :: Interactive m + => InitFlags + -> InstalledPackageIndex + -> m LibTarget +genLibTarget flags pkgs = LibTarget + <$> srcDirsPrompt flags + <*> languagePrompt flags "library" + <*> getExposedModules flags + <*> getOtherModules flags + <*> getOtherExts flags + <*> dependenciesPrompt pkgs flags + <*> getBuildTools flags + +-- | Extract flags relevant to a executable target and interactively +-- generate a 'ExeTarget' object for creation. If the user specifies +-- the generation of a simple package, then a simple target with defaults +-- is generated. +-- +genExeTarget + :: Interactive m + => InitFlags + -> InstalledPackageIndex + -> m ExeTarget +genExeTarget flags pkgs = ExeTarget + <$> mainFilePrompt flags + <*> appDirsPrompt flags + <*> languagePrompt flags "executable" + <*> getOtherModules flags + <*> getOtherExts flags + <*> dependenciesPrompt pkgs flags + <*> getBuildTools flags + +-- | Extract flags relevant to a test target and interactively +-- generate a 'TestTarget' object for creation. If the user specifies +-- the generation of a simple package, then a simple target with defaults +-- is generated. +-- +-- Note: this workflow is only enabled if the user answers affirmatively +-- when prompted, or if the user passes in the flag to enable +-- test suites at command line. +-- +genTestTarget + :: Interactive m + => InitFlags + -> InstalledPackageIndex + -> m (Maybe TestTarget) +genTestTarget flags pkgs = initializeTestSuitePrompt flags >>= go + where + go initialized + | not initialized = return Nothing + | otherwise = fmap Just $ TestTarget + <$> testMainPrompt + <*> testDirsPrompt flags + <*> languagePrompt flags "test suite" + <*> getOtherModules flags + <*> getOtherExts flags + <*> dependenciesPrompt pkgs flags + <*> getBuildTools flags + + +-- -------------------------------------------------------------------- -- +-- Prompts + +cabalVersionPrompt :: Interactive m => InitFlags -> m CabalSpecVersion +cabalVersionPrompt flags = getCabalVersion flags $ do + v <- promptList "Please choose version of the Cabal specification to use" + ppVersions + (Just ppDefault) + (Just takeVersion) + False + -- take just the version numbers for convenience + return $ parseCabalVersion (takeVersion v) + where + -- only used when presenting the default in prompt + takeVersion = takeWhile (/= ' ') + + ppDefault = displayCabalVersion defaultCabalVersion + ppVersions = displayCabalVersion <$> defaultCabalVersions + + parseCabalVersion :: String -> CabalSpecVersion + parseCabalVersion "1.10" = CabalSpecV1_10 + parseCabalVersion "2.0" = CabalSpecV2_0 + parseCabalVersion "2.2" = CabalSpecV2_2 + parseCabalVersion "2.4" = CabalSpecV2_4 + parseCabalVersion "3.0" = CabalSpecV3_0 + parseCabalVersion "3.4" = CabalSpecV3_4 + parseCabalVersion _ = defaultCabalVersion -- 2.4 + + displayCabalVersion :: CabalSpecVersion -> String + displayCabalVersion v = case v of + CabalSpecV1_10 -> "1.10 (legacy)" + CabalSpecV2_0 -> "2.0 (+ support for Backpack, internal sub-libs, '^>=' operator)" + CabalSpecV2_2 -> "2.2 (+ support for 'common', 'elif', redundant commas, SPDX)" + CabalSpecV2_4 -> "2.4 (+ support for '**' globbing)" + CabalSpecV3_0 -> "3.0 (+ set notation for ==, common stanzas in ifs, more redundant commas, better pkgconfig-depends)" + CabalSpecV3_4 -> "3.4 (+ support for 'pkg:sublib' syntax, active repo configuration, rich index-state syntax)" + _ -> showCabalSpecVersion v + +packageNamePrompt :: Interactive m => SourcePackageDb -> InitFlags -> m PackageName +packageNamePrompt srcDb flags = getPackageName flags $ do + defName <- case packageDir flags of + Flag b -> return $ filePathToPkgName b + NoFlag -> currentDirPkgName + + go $ Just defName + where + go defName = prompt "Package name" defName >>= \n -> + if isPkgRegistered n + then do + don'tUseName <- promptYesNo (promptOtherNameMsg n) (Just True) + if don'tUseName + then do + putStrLn (inUseMsg n) + go defName + else return n + else return n + + isPkgRegistered = elemByPackageName (packageIndex srcDb) + + inUseMsg pn = "The name " + ++ unPackageName pn + ++ " is already in use by another package on Hackage." + + promptOtherNameMsg pn = inUseMsg pn ++ " Do you want to choose a different name" + +versionPrompt :: Interactive m => InitFlags -> m Version +versionPrompt flags = getVersion flags go + where + go = do + vv <- promptStr "Package version" (Just $ prettyShow defaultVersion) + case simpleParsec vv of + Nothing -> do + putStrLn + $ "Version must be a valid PVP format (e.g. 0.1.0.0): " + ++ vv + go + Just v -> return v + +licensePrompt :: Interactive m => InitFlags -> m SPDX.License +licensePrompt flags = getLicense flags $ do + l <- promptList "Please choose a license" + licenses + Nothing + Nothing + True + + case simpleParsec l of + Nothing -> do + putStrLn "The license must be a valid SPDX expression." + licensePrompt flags + Just l' -> return l' + where + licenses = SPDX.licenseId <$> defaultLicenseIds + +authorPrompt :: Interactive m => InitFlags -> m String +authorPrompt flags = getAuthor flags $ + promptStr "Author name" Nothing + +emailPrompt :: Interactive m => InitFlags -> m String +emailPrompt flags = getEmail flags $ + promptStr "Maintainer email" Nothing + +homepagePrompt :: Interactive m => InitFlags -> m String +homepagePrompt flags = getHomepage flags $ + promptStr "Project homepage URL" Nothing + +synopsisPrompt :: Interactive m => InitFlags -> m String +synopsisPrompt flags = getSynopsis flags $ + promptStr "Project synopsis" Nothing + +categoryPrompt :: Interactive m => InitFlags -> m String +categoryPrompt flags = getCategory flags $ promptList + "Project category" defaultCategories + (Just "") (Just matchNone) True + where + matchNone s + | null s = "(none)" + | otherwise = s + +mainFilePrompt :: Interactive m => InitFlags -> m HsFilePath +mainFilePrompt flags = getMainFile flags go + where + defaultMainIs' = show defaultMainIs + go = do + fp <- promptList "What is the main module of the executable" + [defaultMainIs', "Main.lhs"] + (Just defaultMainIs') + Nothing + True + + let hs = toHsFilePath fp + + case _hsFileType hs of + InvalidHsPath -> do + putStrLn $ concat + [ "Main file " + , show hs + , " is not a valid haskell file. Source files must end in .hs or .lhs." + ] + go + + _ -> return hs + +testDirsPrompt :: Interactive m => InitFlags -> m [String] +testDirsPrompt flags = getTestDirs flags $ do + dir <- promptStr "Test directory" (Just defaultTestDir) + return [dir] + +languagePrompt :: Interactive m => InitFlags -> String -> m Language +languagePrompt flags pkgType = getLanguage flags $ do + lang <- promptList ("Choose a language for your " ++ pkgType) + ["Haskell2010", "Haskell98"] + (Just "Haskell2010") + Nothing + True + + case lang of + "Haskell2010" -> return Haskell2010 + "Haskell98" -> return Haskell98 + l | all isAlphaNum l -> return $ UnknownLanguage l + _ -> do + putStrLn + $ "\nThe language must be alphanumeric. " + ++ "Please enter a different language." + + languagePrompt flags pkgType + +noCommentsPrompt :: Interactive m => InitFlags -> m Bool +noCommentsPrompt flags = getNoComments flags $ do + doComments <- promptYesNo + "Add informative comments to each field in the cabal file. (y/n)" + (Just True) + + -- + -- if --no-comments is flagged, then we choose not to generate comments + -- for fields in the cabal file, but it's a nicer UX to present the + -- affirmative question which must be negated. + -- + + return (not doComments) + +-- | Ask for the application root directory. +appDirsPrompt :: Interactive m => InitFlags -> m [String] +appDirsPrompt flags = getAppDirs flags $ do + dir <- promptList promptMsg + [defaultApplicationDir, "exe", "src-exe"] + (Just defaultApplicationDir) + Nothing + True + + return [dir] + where + promptMsg = case mainIs flags of + Flag p -> "Application (" ++ p ++ ") directory" + NoFlag -> "Application directory" + +-- | Ask for the source (library) root directory. +srcDirsPrompt :: Interactive m => InitFlags -> m [String] +srcDirsPrompt flags = getSrcDirs flags $ do + dir <- promptList "Library source directory" + [defaultSourceDir, "lib", "src-lib"] + (Just defaultSourceDir) + Nothing + True + + return [dir] + +dependenciesPrompt + :: Interactive m + => InstalledPackageIndex + -> InitFlags + -> m [Dependency] +dependenciesPrompt pkgIx flags = getDependencies flags $ + retrieveDependencies flags [fromString "Prelude"] pkgIx diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs new file mode 100644 index 00000000000..939f0e134b2 --- /dev/null +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs @@ -0,0 +1,437 @@ +{-# LANGUAGE LambdaCase #-} +module Distribution.Client.Init.NonInteractive.Command +( genPkgDescription +, genLibTarget +, genExeTarget +, genTestTarget +, createProject +, packageTypeHeuristics +, authorHeuristics +, emailHeuristics +, cabalVersionHeuristics +, packageNameHeuristics +, versionHeuristics +, mainFileHeuristics +, testDirsHeuristics +, initializeTestSuiteHeuristics +, exposedModulesHeuristics +, libOtherModulesHeuristics +, exeOtherModulesHeuristics +, testOtherModulesHeuristics +, buildToolsHeuristics +, dependenciesHeuristics +, otherExtsHeuristics +, licenseHeuristics +, homepageHeuristics +, synopsisHeuristics +, categoryHeuristics +, extraSourceFilesHeuristics +, appDirsHeuristics +, srcDirsHeuristics +, languageHeuristics +, noCommentsHeuristics +, minimalHeuristics +, overwriteHeuristics +) where +import Distribution.Client.Init.Types + +import Prelude () +import Distribution.Client.Compat.Prelude hiding (putStr, putStrLn, getLine, last, head) + +import Data.List (last, head) +import qualified Data.List.NonEmpty as NEL + +import Distribution.CabalSpecVersion (CabalSpecVersion(..)) +import Distribution.Version (Version) +import Distribution.ModuleName (ModuleName, components) +import Distribution.Types.Dependency (Dependency(..)) +import Distribution.Types.PackageName (PackageName, unPackageName) +import qualified Distribution.SPDX as SPDX +import Distribution.Client.Init.Defaults +import Distribution.Client.Init.NonInteractive.Heuristics +import Distribution.Client.Init.Utils +import Distribution.Client.Init.FlagExtractors +import Distribution.Simple.Setup (Flag(..)) +import Distribution.Simple.PackageIndex (InstalledPackageIndex) +import Distribution.Client.Types (SourcePackageDb(..)) +import Distribution.Solver.Types.PackageIndex (elemByPackageName) +import Distribution.Utils.Generic (safeHead) + +import Language.Haskell.Extension (Language(..), Extension(..)) + +import System.FilePath (splitDirectories, ()) + + +-- | Main driver for interactive prompt code. +-- +createProject + :: Interactive m + => Verbosity + -> InstalledPackageIndex + -> SourcePackageDb + -> InitFlags + -> m ProjectSettings +createProject v pkgIx srcDb initFlags = do + + -- The workflow is as follows: + -- + -- 1. Get the package type, supplied as either a program input or + -- via user prompt. This determines what targets will be built + -- in later steps. + -- + -- 2. Determine whether we generate simple targets or prompt the + -- user for inputs when not supplied as a flag. In general, + -- flag inputs are preferred, and "simple" here means + -- reasonable defaults defined in @Defaults.hs@. + -- + -- 3. Generate package description and the targets specified by + -- the package type. Once this is done, a prompt for building + -- test suites is initiated, and this determines if we build + -- test targets as well. Then we ask if the user wants to + -- comment their .cabal file with pretty comments. + -- + -- 4. The targets are passed to the file creator script, and associated + -- directories/files/modules are created, with the a .cabal file + -- being generated as a final result. + -- + + pkgType <- packageTypeHeuristics initFlags + isMinimal <- getMinimal initFlags + doOverwrite <- getOverwrite initFlags + pkgDir <- packageDirHeuristics initFlags + pkgDesc <- genPkgDescription initFlags srcDb + comments <- noCommentsHeuristics initFlags + + let pkgName = _pkgName pkgDesc + mkOpts cs = WriteOpts + doOverwrite isMinimal cs + v pkgDir pkgType pkgName + + case pkgType of + Library -> do + libTarget <- genLibTarget initFlags pkgIx + testTarget <- genTestTarget initFlags pkgIx + + return $ ProjectSettings + (mkOpts comments) pkgDesc + (Just libTarget) Nothing testTarget + + Executable -> do + exeTarget <- genExeTarget initFlags pkgIx + + return $ ProjectSettings + (mkOpts comments) pkgDesc Nothing + (Just exeTarget) Nothing + + LibraryAndExecutable -> do + libTarget <- genLibTarget initFlags pkgIx + exeTarget <- genExeTarget initFlags pkgIx + testTarget <- genTestTarget initFlags pkgIx + + return $ ProjectSettings + (mkOpts comments) pkgDesc (Just libTarget) + (Just exeTarget) testTarget + +genPkgDescription + :: Interactive m + => InitFlags + -> SourcePackageDb + -> m PkgDescription +genPkgDescription flags srcDb = PkgDescription + <$> cabalVersionHeuristics flags + <*> packageNameHeuristics srcDb flags + <*> versionHeuristics flags + <*> licenseHeuristics flags + <*> authorHeuristics flags + <*> emailHeuristics flags + <*> homepageHeuristics flags + <*> synopsisHeuristics flags + <*> categoryHeuristics flags + <*> extraSourceFilesHeuristics flags + +genLibTarget + :: Interactive m + => InitFlags + -> InstalledPackageIndex + -> m LibTarget +genLibTarget flags pkgs = do + srcDirs <- srcDirsHeuristics flags + let srcDir = fromMaybe defaultSourceDir $ safeHead srcDirs + LibTarget srcDirs + <$> languageHeuristics flags + <*> exposedModulesHeuristics flags + <*> libOtherModulesHeuristics flags + <*> otherExtsHeuristics flags srcDir + <*> dependenciesHeuristics flags srcDir pkgs + <*> buildToolsHeuristics flags srcDir + +genExeTarget + :: Interactive m + => InitFlags + -> InstalledPackageIndex + -> m ExeTarget +genExeTarget flags pkgs = do + appDirs <- appDirsHeuristics flags + let appDir = fromMaybe defaultApplicationDir $ safeHead appDirs + ExeTarget + <$> mainFileHeuristics flags + <*> pure appDirs + <*> languageHeuristics flags + <*> exeOtherModulesHeuristics flags + <*> otherExtsHeuristics flags appDir + <*> dependenciesHeuristics flags appDir pkgs + <*> buildToolsHeuristics flags appDir + +genTestTarget + :: Interactive m + => InitFlags + -> InstalledPackageIndex + -> m (Maybe TestTarget) +genTestTarget flags pkgs = do + initialized <- initializeTestSuiteHeuristics flags + testDirs' <- testDirsHeuristics flags + let testDir = fromMaybe defaultTestDir $ safeHead testDirs' + if not initialized + then return Nothing + else fmap Just $ TestTarget + <$> testMainHeuristics flags + <*> pure testDirs' + <*> languageHeuristics flags + <*> testOtherModulesHeuristics flags + <*> otherExtsHeuristics flags testDir + <*> dependenciesHeuristics flags testDir pkgs + <*> buildToolsHeuristics flags testDir + +-- -------------------------------------------------------------------- -- +-- Get flags from init config + +minimalHeuristics :: Interactive m => InitFlags -> m Bool +minimalHeuristics = getMinimal + +overwriteHeuristics :: Interactive m => InitFlags -> m Bool +overwriteHeuristics = getOverwrite + +packageDirHeuristics :: Interactive m => InitFlags -> m FilePath +packageDirHeuristics = getPackageDir + +-- | Get the version of the cabal spec to use. +-- The spec version can be specified by the InitFlags cabalVersion field. If +-- none is specified then the default version is used. +cabalVersionHeuristics :: Interactive m => InitFlags -> m CabalSpecVersion +cabalVersionHeuristics flags = getCabalVersion flags guessCabalSpecVersion + +-- | Get the package name: use the package directory (supplied, or the current +-- directory by default) as a guess. It looks at the SourcePackageDb to avoid +-- using an existing package name. +packageNameHeuristics :: Interactive m => SourcePackageDb -> InitFlags -> m PackageName +packageNameHeuristics sourcePkgDb flags = getPackageName flags $ do + defName <- guessPackageName =<< case packageDir flags of + Flag a -> return a + NoFlag -> last . splitDirectories <$> getCurrentDirectory + + when (isPkgRegistered defName) + $ putStrLn (inUseMsg defName) + + return defName + + where + isPkgRegistered = elemByPackageName (packageIndex sourcePkgDb) + + inUseMsg pn = "The name " + ++ unPackageName pn + ++ " is already in use by another package on Hackage." + +-- | Package version: use 0.1.0.0 as a last resort +versionHeuristics :: Interactive m => InitFlags -> m Version +versionHeuristics flags = getVersion flags $ return defaultVersion + +-- | Choose a license for the package. +-- The license can come from Initflags (license field), if it is not present +-- then prompt the user from a predefined list of licenses. +licenseHeuristics :: Interactive m => InitFlags -> m SPDX.License +licenseHeuristics flags = getLicense flags $ guessLicense flags + +-- | The author's name. Prompt, or try to guess from an existing +-- darcs repo. +authorHeuristics :: Interactive m => InitFlags -> m String +authorHeuristics flags = getAuthor flags guessAuthorEmail + +-- | The author's email. Prompt, or try to guess from an existing +-- darcs repo. +emailHeuristics :: Interactive m => InitFlags -> m String +emailHeuristics flags = getEmail flags guessAuthorName + +-- | Prompt for a homepage URL for the package. +homepageHeuristics :: Interactive m => InitFlags -> m String +homepageHeuristics flags = getHomepage flags $ return "" + +-- | Prompt for a project synopsis. +synopsisHeuristics :: Interactive m => InitFlags -> m String +synopsisHeuristics flags = getSynopsis flags $ return "" + +-- | Prompt for a package category. +-- Note that it should be possible to do some smarter guessing here too, i.e. +-- look at the name of the top level source directory. +categoryHeuristics :: Interactive m => InitFlags -> m String +categoryHeuristics flags = getCategory flags $ return "(none)" + +-- | Try to guess extra source files. +extraSourceFilesHeuristics :: Interactive m => InitFlags -> m (NonEmpty FilePath) +extraSourceFilesHeuristics flags = case extraSrc flags of + Flag x | not (null x) -> return $ NEL.fromList x + _ -> guessExtraSourceFiles flags + +-- | Try to guess if the project builds a library, an executable, or both. +packageTypeHeuristics :: Interactive m => InitFlags -> m PackageType +packageTypeHeuristics flags = getPackageType flags $ guessPackageType flags + +-- | Try to guess the main file, if nothing is found, fallback +-- to a default value. +mainFileHeuristics :: Interactive m => InitFlags -> m HsFilePath +mainFileHeuristics flags = do + appDir <- head <$> appDirsHeuristics flags + getMainFile flags . guessMainFile $ appDir + +testMainHeuristics :: Interactive m => InitFlags -> m HsFilePath +testMainHeuristics flags = do + testDir <- head <$> testDirsHeuristics flags + guessMainFile testDir + +initializeTestSuiteHeuristics :: Interactive m => InitFlags -> m Bool +initializeTestSuiteHeuristics flags = getInitializeTestSuite flags $ return False + +testDirsHeuristics :: Interactive m => InitFlags -> m [String] +testDirsHeuristics flags = getTestDirs flags $ return [defaultTestDir] + +-- | Ask for the Haskell base language of the package. +languageHeuristics :: Interactive m => InitFlags -> m Language +languageHeuristics flags = getLanguage flags guessLanguage + +-- | Ask whether to generate explanatory comments. +noCommentsHeuristics :: Interactive m => InitFlags -> m Bool +noCommentsHeuristics flags = getNoComments flags $ return False + +-- | Ask for the application root directory. +appDirsHeuristics :: Interactive m => InitFlags -> m [String] +appDirsHeuristics flags = getAppDirs flags $ guessApplicationDirectories flags + +-- | Ask for the source (library) root directory. +srcDirsHeuristics :: Interactive m => InitFlags -> m [String] +srcDirsHeuristics flags = getSrcDirs flags $ guessSourceDirectories flags + +-- | Retrieve the list of exposed modules +exposedModulesHeuristics :: Interactive m => InitFlags -> m (NonEmpty ModuleName) +exposedModulesHeuristics flags = do + mods <- case exposedModules flags of + Flag x -> return x + NoFlag -> do + srcDir <- fromMaybe defaultSourceDir . safeHead <$> srcDirsHeuristics flags + + modules <- filter isHaskell <$> listFilesRecursive srcDir + modulesNames <- traverse retrieveModuleName modules + + otherModules' <- libOtherModulesHeuristics flags + return $ filter (`notElem` otherModules') modulesNames + + return $ if null mods + then myLibModule NEL.:| [] + else NEL.fromList mods + +-- | Retrieve the list of other modules for Libraries, filtering them +-- based on the last component of the module name +libOtherModulesHeuristics :: Interactive m => InitFlags -> m [ModuleName] +libOtherModulesHeuristics flags = case otherModules flags of + Flag x -> return x + NoFlag -> do + let otherCandidates = ["Internal", "Utils"] + srcDir = case sourceDirs flags of + Flag x -> fromMaybe defaultSourceDir $ safeHead x + NoFlag -> defaultSourceDir + + libDir <- ( srcDir) <$> case packageDir flags of + Flag x -> return x + NoFlag -> getCurrentDirectory + + exists <- doesDirectoryExist libDir + if exists + then do + otherModules' <- filter isHaskell <$> listFilesRecursive libDir + filter ((`elem` otherCandidates) . last . components) + <$> traverse retrieveModuleName otherModules' + else return [] + +-- | Retrieve the list of other modules for Executables, it lists everything +-- that is a Haskell file within the application directory, excluding the main file +exeOtherModulesHeuristics :: Interactive m => InitFlags -> m [ModuleName] +exeOtherModulesHeuristics flags = case otherModules flags of + Flag x -> return x + NoFlag -> do + let appDir = case applicationDirs flags of + Flag x -> fromMaybe defaultApplicationDir $ safeHead x + NoFlag -> defaultApplicationDir + + exeDir <- ( appDir) <$> case packageDir flags of + Flag x -> return x + NoFlag -> getCurrentDirectory + + exists <- doesDirectoryExist exeDir + if exists + then do + otherModules' <- filter (\f -> not (isMain f) && isHaskell f) + <$> listFilesRecursive exeDir + traverse retrieveModuleName otherModules' + else return [] + +-- | Retrieve the list of other modules for Tests, it lists everything +-- that is a Haskell file within the tests directory, excluding the main file +testOtherModulesHeuristics :: Interactive m => InitFlags -> m [ModuleName] +testOtherModulesHeuristics flags = case otherModules flags of + Flag x -> return x + NoFlag -> do + let testDir = case testDirs flags of + Flag x -> fromMaybe defaultTestDir $ safeHead x + NoFlag -> defaultTestDir + + testDir' <- ( testDir) <$> case packageDir flags of + Flag x -> return x + NoFlag -> getCurrentDirectory + + exists <- doesDirectoryExist testDir' + if exists + then do + otherModules' <- filter (\f -> not (isMain f) && isHaskell f) + <$> listFilesRecursive testDir' + traverse retrieveModuleName otherModules' + else return [] + +-- | Retrieve the list of build tools +buildToolsHeuristics :: Interactive m => InitFlags -> FilePath -> m [String] +buildToolsHeuristics flags fp = case buildTools flags of + Flag x -> return x + NoFlag -> retrieveBuildTools fp + +-- | Retrieve the list of dependencies +dependenciesHeuristics :: Interactive m => InitFlags -> FilePath -> InstalledPackageIndex -> m [Dependency] +dependenciesHeuristics flags fp pkgIx = getDependencies flags $ do + sources <- retrieveSourceFiles fp + + let mods = case exposedModules flags of + Flag x -> x + NoFlag -> map moduleName sources + + retrieveDependencies flags + ( nub -- skips duplicates + ( fromString "Prelude" -- gets base as dependency + : (filter (`notElem` mods) -- skips modules from this own package + . concatMap imports $ sources))) + pkgIx + +-- | Retrieve the list of extensions +otherExtsHeuristics :: Interactive m => InitFlags -> FilePath -> m [Extension] +otherExtsHeuristics flags fp = case otherExts flags of + Flag x -> return x + NoFlag -> do + sources <- listFilesRecursive fp + extensions' <- traverse retrieveModuleExtensions . filter isHaskell $ sources + + return $ nub . join $ extensions' diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs new file mode 100644 index 00000000000..93348ada043 --- /dev/null +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs @@ -0,0 +1,179 @@ +{-# LANGUAGE LambdaCase #-} +----------------------------------------------------------------------------- +-- | +-- Module : Distribution.Client.Init.NonInteractive.Heuristics +-- Copyright : (c) Benedikt Huber 2009 +-- License : BSD-like +-- +-- Maintainer : cabal-devel@haskell.org +-- Stability : provisional +-- Portability : portable +-- +-- Heuristics for creating initial cabal files. +-- +----------------------------------------------------------------------------- +module Distribution.Client.Init.NonInteractive.Heuristics + ( guessPackageName + , guessMainFile + , guessLicense + , guessExtraSourceFiles + , guessAuthorName + , guessAuthorEmail + , guessCabalSpecVersion + , guessLanguage + , guessPackageType + , guessSourceDirectories + , guessApplicationDirectories + ) where + +import Prelude (read) +import Distribution.Client.Compat.Prelude hiding (readFile, (<|>), many) +import Distribution.Utils.Generic (safeLast) + +import Distribution.Simple.Setup (fromFlagOrDefault) + +import Text.Parsec +import qualified Data.List as L +import qualified Data.List.NonEmpty as NEL +import Distribution.Client.Init.Defaults +import Distribution.Client.Init.Types hiding (break) +import Distribution.Client.Init.Utils +import qualified Distribution.SPDX as SPDX +import System.FilePath +import Distribution.CabalSpecVersion +import Language.Haskell.Extension +import Distribution.Version +import Distribution.Types.PackageName (PackageName, mkPackageName) + + + +-- | Guess the main file, returns a default value if none is found. +guessMainFile :: Interactive m => FilePath -> m HsFilePath +guessMainFile pkgDir = do + files <- filter isMain <$> listFilesRecursive pkgDir + + return $ if null files + then defaultMainIs + else toHsFilePath $ L.head files + +-- | Juggling characters around to guess the desired cabal version based on +-- the system's cabal version. +guessCabalSpecVersion :: Interactive m => m CabalSpecVersion +guessCabalSpecVersion = do + (_, verString, _) <- readProcessWithExitCode "cabal" ["--version"] "" + case runParser versionParser () "" verString of + Right ver@(_:_) -> return $ + read $ "CabalSpecV" ++ format' ver + _ -> return defaultCabalVersion + + where + format' [] = [] + format' ('.':xs) = '_' : takeWhile (/= '.') xs + format' (x:xs) = x : format' xs + +-- | Guess the language specification based on the GHC version +guessLanguage :: Interactive m => m Language +guessLanguage = do + (_, verString, _) <- readProcessWithExitCode "ghc" ["--version"] "" + case simpleParsec <$> runParser versionParser () "" verString of + Right (Just ver) -> return $ + if ver < mkVersion [7,0,1] + then Haskell98 + else Haskell2010 + _ -> return defaultLanguage + +-- | Guess the package name based on the given root directory. +guessPackageName :: Interactive m => FilePath -> m PackageName +guessPackageName = fmap (mkPackageName . repair . fromMaybe "" . safeLast . splitDirectories) + . tryCanonicalizePath + where + -- Treat each span of non-alphanumeric characters as a hyphen. Each + -- hyphenated component of a package name must contain at least one + -- alphabetic character. An arbitrary character ('x') will be prepended if + -- this is not the case for the first component, and subsequent components + -- will simply be run together. For example, "1+2_foo-3" will become + -- "x12-foo3". + repair = repair' ('x' :) id + repair' invalid valid x = case dropWhile (not . isAlphaNum) x of + "" -> repairComponent "" + x' -> let (c, r) = first repairComponent $ break (not . isAlphaNum) x' + in c ++ repairRest r + where + repairComponent c | all isDigit c = invalid c + | otherwise = valid c + repairRest = repair' id ('-' :) + +-- | Try to guess the license from an already existing @LICENSE@ file in +-- the package directory, comparing the file contents with the ones +-- listed in @Licenses.hs@, for now it only returns a default value. +guessLicense :: Interactive m => InitFlags -> m SPDX.License +guessLicense _ = return SPDX.NONE + +guessExtraSourceFiles :: Interactive m => InitFlags -> m (NonEmpty FilePath) +guessExtraSourceFiles flags = do + pkgDir <- fromFlagOrDefault getCurrentDirectory $ fmap return $ packageDir flags + files <- getDirectoryContents pkgDir + + let extSrcCandidates = ["CHANGES", "CHANGELOG", "README"] + extraSrc' = [y | x <- extSrcCandidates, y <- files, x == map toUpper (takeBaseName y)] + + return $ if null extraSrc' + then defaultChangelog NEL.:| [] + else NEL.fromList extraSrc' + +-- | Try to guess the package type from the files in the package directory, +-- looking for unique characteristics from each type, defaults to Executable. +guessPackageType :: Interactive m => InitFlags -> m PackageType +guessPackageType flags = do + let lastDir dirs = L.last . splitDirectories $ dirs + srcCandidates = [defaultSourceDir, "src", "source"] + testCandidates = [defaultTestDir, "test", "tests"] + + pkgDir <- fromFlagOrDefault getCurrentDirectory $ fmap return $ packageDir flags + files <- listFilesInside (\x -> return $ lastDir x `notElem` testCandidates) pkgDir + + let hasExe = not $ null [f | f <- files, isMain $ takeFileName f] + hasLib = not $ null [f | f <- files, lastDir f `elem` srcCandidates] + + return $ case (hasLib, hasExe) of + (True, True) -> LibraryAndExecutable + (True, False) -> Library + _ -> Executable + +-- | Try to guess the application directories from the package directory, +-- using a default value as fallback. +guessApplicationDirectories :: Interactive m => InitFlags -> m [FilePath] +guessApplicationDirectories flags = do + pkgDirs <- listDirectory =<< fromFlagOrDefault getCurrentDirectory + (fmap return $ packageDir flags) + + let candidates = [defaultApplicationDir, "app", "src-exe"] in + return $ case [y | x <- candidates, y <- pkgDirs, x == y] of + [] -> [defaultApplicationDir] + x -> nub x + +-- | Try to guess the source directories, using a default value as fallback. +guessSourceDirectories :: Interactive m => InitFlags -> m [FilePath] +guessSourceDirectories flags = do + pkgDir <- fromFlagOrDefault getCurrentDirectory $ fmap return $ packageDir flags + + doesDirectoryExist (pkgDir "src") >>= return . \case + False -> [defaultSourceDir] + True -> ["src"] + +-- | Guess author and email using git configuration options. +guessAuthorName :: Interactive m => m String +guessAuthorName = guessGitInfo "user.name" + +guessAuthorEmail :: Interactive m => m String +guessAuthorEmail = guessGitInfo "user.email" + +guessGitInfo :: Interactive m => String -> m String +guessGitInfo target = do + info <- readProcessWithExitCode "git" ["config", "--local", target] "" + if null $ snd' info + then trim . snd' <$> readProcessWithExitCode "git" ["config", "--global", target] "" + else return . trim $ snd' info + + where + snd' (_, x, _) = x diff --git a/cabal-install/src/Distribution/Client/Init/Prompt.hs b/cabal-install/src/Distribution/Client/Init/Prompt.hs index 00332782705..ebc995f2ef5 100644 --- a/cabal-install/src/Distribution/Client/Init/Prompt.hs +++ b/cabal-install/src/Distribution/Client/Init/Prompt.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE NoImplicitPrelude #-} ----------------------------------------------------------------------------- -- | -- Module : Distribution.Client.Init.Prompt @@ -12,134 +14,153 @@ -- ----------------------------------------------------------------------------- -module Distribution.Client.Init.Prompt ( +module Distribution.Client.Init.Prompt +( prompt +, promptYesNo +, promptStr +, promptList +) where - -- * Commands - prompt - , promptYesNo - , promptStr - , promptList - , promptListOptional - , maybePrompt - ) where - -import Prelude () -import Distribution.Client.Compat.Prelude hiding (empty) +import Prelude hiding (break, putStrLn, getLine, putStr) +import Distribution.Client.Compat.Prelude hiding (break, empty, getLine, putStr, putStrLn) import Distribution.Client.Init.Types - ( InitFlags(..) ) -import Distribution.Simple.Setup - ( Flag(..) ) - --- | Run a prompt or not based on the interactive flag of the --- InitFlags structure. -maybePrompt :: InitFlags -> IO t -> IO (Maybe t) -maybePrompt flags p = - case interactive flags of - Flag True -> Just `fmap` p - _ -> return Nothing -- | Create a prompt with optional default value that returns a --- String. -promptStr :: String -> Maybe String -> IO String -promptStr = promptDefault' Just id +-- String. +promptStr :: Interactive m => String -> Maybe String -> m String +promptStr = promptDefault Right id -- | Create a yes/no prompt with optional default value. -promptYesNo :: String -- ^ prompt message - -> Maybe Bool -- ^ optional default value - -> IO Bool +promptYesNo + :: Interactive m + => String + -- ^ prompt message + -> Maybe Bool + -- ^ optional default value + -> m Bool promptYesNo = - promptDefault' recogniseYesNo showYesNo + promptDefault recogniseYesNo showYesNo where - recogniseYesNo s | s == "y" || s == "Y" = Just True - | s == "n" || s == "N" = Just False - | otherwise = Nothing + recogniseYesNo s + | (toLower <$> s) == "y" = Right True + | (toLower <$> s) == "n" || s == "N" = Right False + | otherwise = Left $ "Cannot parse input: " ++ s + showYesNo True = "y" showYesNo False = "n" -- | Create a prompt with optional default value that returns a value -- of some Text instance. -prompt :: (Parsec t, Pretty t) => String -> Maybe t -> IO t -prompt = promptDefault' simpleParsec prettyShow - --- | Create a prompt with an optional default value. -promptDefault' :: (String -> Maybe t) -- ^ parser - -> (t -> String) -- ^ pretty-printer - -> String -- ^ prompt message - -> Maybe t -- ^ optional default value - -> IO t -promptDefault' parser ppr pr def = do - putStr $ mkDefPrompt pr (ppr `fmap` def) - inp <- getLine - case (inp, def) of - ("", Just d) -> return d - _ -> case parser inp of - Just t -> return t - Nothing -> do putStrLn $ "Couldn't parse " ++ inp ++ ", please try again!" - promptDefault' parser ppr pr def +prompt :: (Interactive m, Parsec t, Pretty t) => String -> Maybe t -> m t +prompt = promptDefault eitherParsec prettyShow -- | Create a prompt from a prompt string and a String representation -- of an optional default value. mkDefPrompt :: String -> Maybe String -> String -mkDefPrompt pr def = pr ++ "?" ++ defStr def - where defStr Nothing = " " - defStr (Just s) = " [default: " ++ s ++ "] " - --- | Create a prompt from a list of items, where no selected items is --- valid and will be represented as a return value of 'Nothing'. -promptListOptional :: (Pretty t, Eq t) - => String -- ^ prompt - -> [t] -- ^ choices - -> IO (Maybe (Either String t)) -promptListOptional pr choices = promptListOptional' pr choices prettyShow - -promptListOptional' :: Eq t - => String -- ^ prompt - -> [t] -- ^ choices - -> (t -> String) -- ^ show an item - -> IO (Maybe (Either String t)) -promptListOptional' pr choices displayItem = - fmap rearrange - $ promptList pr (Nothing : map Just choices) (Just Nothing) - (maybe "(none)" displayItem) True +mkDefPrompt msg def = msg ++ "?" ++ format def where - rearrange = either (Just . Left) (fmap Right) - --- | Create a prompt from a list of items. -promptList :: Eq t - => String -- ^ prompt - -> [t] -- ^ choices - -> Maybe t -- ^ optional default value - -> (t -> String) -- ^ show an item - -> Bool -- ^ whether to allow an 'other' option - -> IO (Either String t) -promptList pr choices def displayItem other = do - putStrLn $ pr ++ ":" - let options1 = map (\c -> (Just c == def, displayItem c)) choices - options2 = zip ([1..]::[Int]) - (options1 ++ [(False, "Other (specify)") | other]) - traverse_ (putStrLn . \(n,(i,s)) -> showOption n i ++ s) options2 - promptList' displayItem (length options2) choices def other - where showOption n i | n < 10 = " " ++ star i ++ " " ++ rest - | otherwise = " " ++ star i ++ rest - where rest = show n ++ ") " - star True = "*" - star False = " " - -promptList' :: (t -> String) -> Int -> [t] -> Maybe t -> Bool -> IO (Either String t) -promptList' displayItem numChoices choices def other = do - putStr $ mkDefPrompt "Your choice" (displayItem `fmap` def) - inp <- getLine - case (inp, def) of - ("", Just d) -> return $ Right d - _ -> case readMaybe inp of - Nothing -> invalidChoice inp - Just n -> getChoice n - where invalidChoice inp = do putStrLn $ inp ++ " is not a valid choice." - promptList' displayItem numChoices choices def other - getChoice n | n < 1 || n > numChoices = invalidChoice (show n) - | n < numChoices || - (n == numChoices && not other) - = return . Right $ choices !! (n-1) - | otherwise = Left `fmap` promptStr "Please specify" Nothing + format Nothing = " " + format (Just s) = " [default: " ++ s ++ "] " + +-- | Create a prompt from a list of strings +promptList + :: Interactive m + => String + -- ^ prompt + -> [String] + -- ^ choices + -> Maybe String + -- ^ optional default value + -> Maybe (String -> String) + -- ^ modify the default value to present in-prompt + -> Bool + -- ^ whether to allow an 'other' option + -> m String +promptList msg choices def modDef hasOther = do + putStrLn $ msg ++ ":" + + -- Output nicely formatted list of options + for_ prettyChoices $ \(i,c) -> do + let star = if Just c == def + then "*" + else " " + + let output = concat $ if i < 10 + then [" ", star, " ", show i, ") ", c] + else [" ", star, show i, ") ", c] + + putStrLn output + + go + where + prettyChoices = + let cs = if hasOther + then choices ++ ["Other (specify)"] + else choices + in zip [1::Int .. numChoices + 1] cs + + numChoices = length choices + + invalidChoice input = do + let msg' = if null input + then "Empty input is not a valid choice." + else concat + [ input + , " is not a valid choice. Please choose a number from 1 to " + , show (numChoices +1) + , "." + ] + + putStrLn msg' + breakOrContinue ("promptList: " ++ input) go + + go = do + putStr + $ mkDefPrompt "Your choice" + $ maybe def (<$> def) modDef + + input <- getLine + case def of + Just d | null input -> return d + _ -> case readMaybe input of + Nothing -> invalidChoice input + Just n + | n > 0, n <= numChoices -> return $ choices !! (n-1) + | n == numChoices + 1, hasOther -> + promptStr "Please specify" Nothing + | otherwise -> invalidChoice (show n) + +-- | Create a prompt with an optional default value. +promptDefault + :: Interactive m + => (String -> Either String t) + -- ^ parser + -> (t -> String) + -- ^ pretty-printer + -> String + -- ^ prompt message + -> Maybe t + -- ^ optional default value + -> m t +promptDefault parse pprint msg def = do + putStr $ mkDefPrompt msg (pprint <$> def) + input <- getLine + case def of + Just d | null input -> return d + _ -> case parse input of + Right t -> return t + Left err -> do + putStrLn $ "Couldn't parse " ++ input ++ ", please try again!" + breakOrContinue + ("promptDefault: " ++ err ++ " on input: " ++ input) + (promptDefault parse pprint msg def) + +-- | Prompt utility for breaking out of an interactive loop +-- in the pure case +-- +breakOrContinue :: Interactive m => String -> m a -> m a +breakOrContinue msg act = break >>= \case + True -> throwPrompt $ BreakException msg + False -> act diff --git a/cabal-install/src/Distribution/Client/Init/Simple.hs b/cabal-install/src/Distribution/Client/Init/Simple.hs new file mode 100644 index 00000000000..d93134e56e1 --- /dev/null +++ b/cabal-install/src/Distribution/Client/Init/Simple.hs @@ -0,0 +1,138 @@ +module Distribution.Client.Init.Simple +( -- * Project creation + createProject + -- * Gen targets +, genSimplePkgDesc +, genSimpleLibTarget +, genSimpleExeTarget +, genSimpleTestTarget +) where + + +import Distribution.Client.Init.Types +import Distribution.Verbosity +import Distribution.Simple.PackageIndex +import Distribution.Client.Types.SourcePackageDb (SourcePackageDb(..)) +import qualified Data.List.NonEmpty as NEL +import Distribution.Client.Init.Utils (currentDirPkgName, mkPackageNameDep) +import Distribution.Client.Init.Defaults +import Distribution.Simple.Flag (fromFlagOrDefault, flagElim) +import Distribution.Client.Init.FlagExtractors + + +createProject + :: Interactive m + => Verbosity + -> InstalledPackageIndex + -> SourcePackageDb + -> InitFlags + -> m ProjectSettings +createProject v _pkgIx _srcDb initFlags = do + pkgType <- packageTypePrompt initFlags + isMinimal <- getMinimal initFlags + doOverwrite <- getOverwrite initFlags + pkgDir <- getPackageDir initFlags + pkgDesc <- genSimplePkgDesc initFlags + + let pkgName = _pkgName pkgDesc + mkOpts cs = WriteOpts + doOverwrite isMinimal cs + v pkgDir pkgType pkgName + + case pkgType of + Library -> do + libTarget <- genSimpleLibTarget initFlags + testTarget <- addLibDepToTest pkgName <$> genSimpleTestTarget initFlags + return $ ProjectSettings + (mkOpts False) pkgDesc + (Just libTarget) Nothing testTarget + + Executable -> do + exeTarget <- genSimpleExeTarget initFlags + return $ ProjectSettings + (mkOpts False) pkgDesc + Nothing (Just exeTarget) Nothing + + LibraryAndExecutable -> do + libTarget <- genSimpleLibTarget initFlags + testTarget <- addLibDepToTest pkgName <$> genSimpleTestTarget initFlags + exeTarget <- addLibDepToExe pkgName <$> genSimpleExeTarget initFlags + return $ ProjectSettings + (mkOpts False) pkgDesc + (Just libTarget) (Just exeTarget) testTarget + where + -- Add package name as dependency of test suite + -- + addLibDepToTest _ Nothing = Nothing + addLibDepToTest n (Just t) = Just $ t + { _testDependencies = _testDependencies t ++ [mkPackageNameDep n] + } + + -- Add package name as dependency of executable + -- + addLibDepToExe n exe = exe + { _exeDependencies = _exeDependencies exe ++ [mkPackageNameDep n] + } + +genSimplePkgDesc :: Interactive m => InitFlags -> m PkgDescription +genSimplePkgDesc flags = mkPkgDesc <$> currentDirPkgName + where + defaultExtraSrc = defaultChangelog NEL.:| [] + + extractExtraSrc [] = defaultExtraSrc + extractExtraSrc as = NEL.fromList as + + mkPkgDesc pkgName = PkgDescription + (fromFlagOrDefault defaultCabalVersion (cabalVersion flags)) + pkgName + (fromFlagOrDefault defaultVersion (version flags)) + (fromFlagOrDefault defaultLicense (license flags)) + (fromFlagOrDefault "" (author flags)) + (fromFlagOrDefault "" (email flags)) + (fromFlagOrDefault "" (homepage flags)) + (fromFlagOrDefault "" (synopsis flags)) + (fromFlagOrDefault "" (category flags)) + (flagElim defaultExtraSrc extractExtraSrc (extraSrc flags)) + +genSimpleLibTarget :: Interactive m => InitFlags -> m LibTarget +genSimpleLibTarget flags = return $ LibTarget + { _libSourceDirs = fromFlagOrDefault [defaultSourceDir] $ sourceDirs flags + , _libLanguage = fromFlagOrDefault defaultLanguage $ language flags + , _libExposedModules = flagElim (myLibModule NEL.:| []) extractMods $ + exposedModules flags + , _libOtherModules = fromFlagOrDefault [] $ otherModules flags + , _libOtherExts = fromFlagOrDefault [] $ otherExts flags + , _libDependencies = fromFlagOrDefault [] $ dependencies flags + , _libBuildTools= fromFlagOrDefault [] $ buildTools flags + } + + where + extractMods [] = myLibModule NEL.:| [] + extractMods as = NEL.fromList as + +genSimpleExeTarget :: Interactive m => InitFlags -> m ExeTarget +genSimpleExeTarget flags = return $ ExeTarget + { _exeMainIs = flagElim defaultMainIs toHsFilePath $ mainIs flags + , _exeApplicationDirs = fromFlagOrDefault [defaultApplicationDir] $ + applicationDirs flags + , _exeLanguage = fromFlagOrDefault defaultLanguage $ language flags + , _exeOtherModules = fromFlagOrDefault [] $ otherModules flags + , _exeOtherExts = fromFlagOrDefault [] $ otherExts flags + , _exeDependencies = fromFlagOrDefault [] $ dependencies flags + , _exeBuildTools = fromFlagOrDefault [] $ buildTools flags + } + +genSimpleTestTarget :: Interactive m => InitFlags -> m (Maybe TestTarget) +genSimpleTestTarget flags = go <$> initializeTestSuitePrompt flags + where + go initialized + | not initialized = Nothing + | otherwise = Just $ TestTarget + { _testMainIs = flagElim defaultMainIs toHsFilePath $ mainIs flags + , _testDirs = fromFlagOrDefault [defaultTestDir] $ testDirs flags + , _testLanguage = fromFlagOrDefault defaultLanguage $ language flags + , _testOtherModules = fromFlagOrDefault [] $ otherModules flags + , _testOtherExts = fromFlagOrDefault [] $ otherExts flags + , _testDependencies = fromFlagOrDefault [] $ dependencies flags + , _testBuildTools = fromFlagOrDefault [] $ buildTools flags + } diff --git a/cabal-install/src/Distribution/Client/Init/Types.hs b/cabal-install/src/Distribution/Client/Init/Types.hs index e705b7fb359..c80a0f80683 100644 --- a/cabal-install/src/Distribution/Client/Init/Types.hs +++ b/cabal-install/src/Distribution/Client/Init/Types.hs @@ -1,6 +1,7 @@ +{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-} - ------------------------------------------------------------------------------ +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE BangPatterns #-} -- | -- Module : Distribution.Client.Init.Types -- Copyright : (c) Brent Yorgey, Benedikt Huber 2009 @@ -12,89 +13,107 @@ -- -- Some types used by the 'cabal init' command. -- ------------------------------------------------------------------------------ -module Distribution.Client.Init.Types where +module Distribution.Client.Init.Types +( -- * Data + InitFlags(..) + -- ** Targets and descriptions +, PkgDescription(..) +, LibTarget(..) +, ExeTarget(..) +, TestTarget(..) + -- ** package types +, PackageType(..) + -- ** Main file +, HsFilePath(..) +, HsFileType(..) +, fromHsFilePath +, toHsFilePath +, toLiterateHs +, toStandardHs +, mkLiterate +, isHsFilePath + -- * Typeclasses +, Interactive(..) +, BreakException(..) +, PurePrompt(..) +, evalPrompt + -- * Aliases +, IsLiterate +, IsSimple + -- * File creator opts +, WriteOpts(..) +, ProjectSettings(..) + -- * Formatters +, FieldAnnotation(..) +) where + -import Distribution.Client.Compat.Prelude -import Prelude () +import qualified Distribution.Client.Compat.Prelude as P +import Distribution.Client.Compat.Prelude as P hiding (getLine, putStr, putStrLn) +import Prelude (read) -import Distribution.Simple.Setup (Flag(..), toFlag ) +import Control.Monad.Catch +import Data.List.NonEmpty (fromList) + +import Distribution.Simple.Setup (Flag(..)) import Distribution.Types.Dependency as P +import Distribution.Verbosity (silent) import Distribution.Version -import Distribution.Verbosity import qualified Distribution.Package as P import Distribution.SPDX.License (License) import Distribution.ModuleName import Distribution.CabalSpecVersion +import Distribution.Client.Utils as P import Language.Haskell.Extension ( Language(..), Extension ) -import qualified Text.PrettyPrint as Disp -import qualified Distribution.Compat.CharParsing as P -import qualified Data.Map as Map +import qualified System.Directory as P +import qualified System.Process as P +import qualified Distribution.Compat.Environment as P +import System.FilePath --- | InitFlags is really just a simple type to represent certain --- portions of a .cabal file. Rather than have a flag for EVERY --- possible field, we just have one for each field that the user is --- likely to want and/or that we are likely to be able to --- intelligently guess. -data InitFlags = - InitFlags { interactive :: Flag Bool - , quiet :: Flag Bool - , packageDir :: Flag FilePath - , noComments :: Flag Bool - , minimal :: Flag Bool - , simpleProject :: Flag Bool - - , packageName :: Flag P.PackageName - , version :: Flag Version - , cabalVersion :: Flag CabalSpecVersion - , license :: Flag License - , author :: Flag String - , email :: Flag String - , homepage :: Flag String - - , synopsis :: Flag String - , category :: Flag (Either String Category) - , extraSrc :: Maybe [String] - - , packageType :: Flag PackageType - , mainIs :: Flag FilePath - , language :: Flag Language - - , exposedModules :: Maybe [ModuleName] - , otherModules :: Maybe [ModuleName] - , otherExts :: Maybe [Extension] - - , dependencies :: Maybe [P.Dependency] - , applicationDirs :: Maybe [String] - , sourceDirs :: Maybe [String] - , buildTools :: Maybe [String] - - , initializeTestSuite :: Flag Bool - , testDirs :: Maybe [String] - - , initHcPath :: Flag FilePath - - , initVerbosity :: Flag Verbosity - , overwrite :: Flag Bool - } - deriving (Eq, Show, Generic) - - -- the Monoid instance for Flag has later values override earlier - -- ones, which is why we want Maybe [foo] for collecting foo values, - -- not Flag [foo]. - -data BuildType = LibBuild | ExecBuild - deriving Eq - --- The type of package to initialize. -data PackageType = Library | Executable | LibraryAndExecutable - deriving (Show, Read, Eq) -displayPackageType :: PackageType -> String -displayPackageType LibraryAndExecutable = "Library and Executable" -displayPackageType pkgtype = show pkgtype +-- -------------------------------------------------------------------- -- +-- Flags + +-- | InitFlags is a subset of flags available in the +-- @.cabal@ file that represent options that are relevant to the +-- init command process. +-- +data InitFlags = + InitFlags + { interactive :: Flag Bool + , quiet :: Flag Bool + , packageDir :: Flag FilePath + , noComments :: Flag Bool + , minimal :: Flag Bool + , simpleProject :: Flag Bool + , packageName :: Flag P.PackageName + , version :: Flag Version + , cabalVersion :: Flag CabalSpecVersion + , license :: Flag License + , author :: Flag String + , email :: Flag String + , homepage :: Flag String + , synopsis :: Flag String + , category :: Flag String + , extraSrc :: Flag [String] + , packageType :: Flag PackageType + , mainIs :: Flag FilePath + , language :: Flag Language + , exposedModules :: Flag [ModuleName] + , otherModules :: Flag [ModuleName] + , otherExts :: Flag [Extension] + , dependencies :: Flag [P.Dependency] + , applicationDirs :: Flag [String] + , sourceDirs :: Flag [String] + , buildTools :: Flag [String] + , initializeTestSuite :: Flag Bool + , testDirs :: Flag [String] + , initHcPath :: Flag FilePath + , initVerbosity :: Flag Verbosity + , overwrite :: Flag Bool + } deriving (Eq, Show, Generic) instance Monoid InitFlags where mempty = gmempty @@ -103,40 +122,310 @@ instance Monoid InitFlags where instance Semigroup InitFlags where (<>) = gmappend -defaultInitFlags :: InitFlags -defaultInitFlags = mempty - { initVerbosity = toFlag normal - } - --- | Some common package categories (non-exhaustive list). -data Category - = Codec - | Concurrency - | Control - | Data - | Database - | Development - | Distribution - | Game - | Graphics - | Language - | Math - | Network - | Sound - | System - | Testing - | Text - | Web - deriving (Read, Show, Eq, Ord, Bounded, Enum) - -instance Pretty Category where - pretty = Disp.text . show - -instance Parsec Category where - parsec = do - name <- P.munch1 isAlpha - case Map.lookup name names of - Just cat -> pure cat - _ -> P.unexpected $ "Category: " ++ name +-- -------------------------------------------------------------------- -- +-- Targets + +-- | 'PkgDescription' represents the relevant options set by the +-- user when building a package description during the init command +-- process. +-- +data PkgDescription = PkgDescription + { _pkgCabalVersion :: CabalSpecVersion + , _pkgName :: P.PackageName + , _pkgVersion :: Version + , _pkgLicense :: License + , _pkgAuthor :: String + , _pkgEmail :: String + , _pkgHomePage :: String + , _pkgSynopsis :: String + , _pkgCategory :: String + , _pkgExtraSrcFiles :: NonEmpty String + } deriving (Show, Eq) + +-- | 'LibTarget' represents the relevant options set by the +-- user when building a library package during the init command +-- process. +-- +data LibTarget = LibTarget + { _libSourceDirs :: [String] + , _libLanguage :: Language + , _libExposedModules :: NonEmpty ModuleName + , _libOtherModules :: [ModuleName] + , _libOtherExts :: [Extension] + , _libDependencies :: [P.Dependency] + , _libBuildTools :: [String] + } deriving (Show, Eq) + +-- | 'ExeTarget' represents the relevant options set by the +-- user when building an executable package. +-- +data ExeTarget = ExeTarget + { _exeMainIs :: HsFilePath + , _exeApplicationDirs :: [String] + , _exeLanguage :: Language + , _exeOtherModules :: [ModuleName] + , _exeOtherExts :: [Extension] + , _exeDependencies :: [P.Dependency] + , _exeBuildTools :: [String] + } deriving (Show, Eq) + +-- | 'TestTarget' represents the relevant options set by the +-- user when building a library package. +-- +data TestTarget = TestTarget + { _testMainIs :: HsFilePath + , _testDirs :: [String] + , _testLanguage :: Language + , _testOtherModules :: [ModuleName] + , _testOtherExts :: [Extension] + , _testDependencies :: [P.Dependency] + , _testBuildTools :: [String] + } deriving (Show, Eq) + +-- -------------------------------------------------------------------- -- +-- File creator options + +data WriteOpts = WriteOpts + { _optOverwrite :: Bool + , _optMinimal :: Bool + , _optNoComments :: Bool + , _optVerbosity :: Verbosity + , _optPkgDir :: FilePath + , _optPkgType :: PackageType + , _optPkgName :: P.PackageName + } deriving (Eq, Show) + +data ProjectSettings = ProjectSettings + { _pkgOpts :: WriteOpts + , _pkgDesc :: PkgDescription + , _pkgLibTarget :: Maybe LibTarget + , _pkgExeTarget :: Maybe ExeTarget + , _pkgTestTarget :: Maybe TestTarget + } deriving (Eq, Show) + +-- -------------------------------------------------------------------- -- +-- Other types + +-- | Enum to denote whether the user wants to build a library target, +-- executable target, or library and executable targets. +-- +data PackageType = Library | Executable | LibraryAndExecutable + deriving (Eq, Show, Generic) + +data HsFileType + = Literate + | Standard + | InvalidHsPath + deriving (Eq, Show) + +data HsFilePath = HsFilePath + { _hsFilePath :: FilePath + , _hsFileType :: HsFileType + } deriving Eq + +instance Show HsFilePath where + show (HsFilePath fp ty) = case ty of + Literate -> fp + Standard -> fp + InvalidHsPath -> "Invalid haskell source file: " ++ fp + +fromHsFilePath :: HsFilePath -> Maybe FilePath +fromHsFilePath (HsFilePath fp ty) = case ty of + Literate -> Just fp + Standard -> Just fp + InvalidHsPath -> Nothing + +isHsFilePath :: FilePath -> Bool +isHsFilePath fp = case _hsFileType $ toHsFilePath fp of + InvalidHsPath -> False + _ -> True + +toHsFilePath :: FilePath -> HsFilePath +toHsFilePath fp + | takeExtension fp == ".lhs" = HsFilePath fp Literate + | takeExtension fp == ".hs" = HsFilePath fp Standard + | otherwise = HsFilePath fp InvalidHsPath + +toLiterateHs :: HsFilePath -> HsFilePath +toLiterateHs (HsFilePath fp Standard) = HsFilePath + (dropExtension fp ++ ".lhs") + Literate +toLiterateHs a = a + +toStandardHs :: HsFilePath -> HsFilePath +toStandardHs (HsFilePath fp Literate) = HsFilePath + (dropExtension fp ++ ".hs") + Standard +toStandardHs a = a + +mkLiterate :: HsFilePath -> [String] -> [String] +mkLiterate (HsFilePath _ Literate) hs = + (\line -> if null line then line else "> " ++ line) <$> hs +mkLiterate _ hs = hs + +-- -------------------------------------------------------------------- -- +-- Interactive prompt monad + +newtype PurePrompt a = PurePrompt + { _runPrompt + :: NonEmpty String + -> Either BreakException (a, NonEmpty String) + } deriving (Functor) + +evalPrompt :: PurePrompt a -> NonEmpty String -> a +evalPrompt act s = case _runPrompt act s of + Left e -> error $ show e + Right (a,_) -> a + +instance Applicative PurePrompt where + pure a = PurePrompt $ \s -> Right (a, s) + PurePrompt ff <*> PurePrompt aa = PurePrompt $ \s -> case ff s of + Left e -> Left e + Right (f, s') -> case aa s' of + Left e -> Left e + Right (a, s'') -> Right (f a, s'') + +instance Monad PurePrompt where + return = pure + PurePrompt a >>= k = PurePrompt $ \s -> case a s of + Left e -> Left e + Right (a', s') -> _runPrompt (k a') s' + +class Monad m => Interactive m where + -- input functions + getLine :: m String + readFile :: FilePath -> m String + getCurrentDirectory :: m FilePath + getHomeDirectory :: m FilePath + getDirectoryContents :: FilePath -> m [FilePath] + listDirectory :: FilePath -> m [FilePath] + doesDirectoryExist :: FilePath -> m Bool + doesFileExist :: FilePath -> m Bool + tryCanonicalizePath :: FilePath -> m FilePath + readProcessWithExitCode :: FilePath -> [String] -> String -> m (ExitCode, String, String) + getEnvironment :: m [(String, String)] + listFilesInside :: (FilePath -> m Bool) -> FilePath -> m [FilePath] + listFilesRecursive :: FilePath -> m [FilePath] + + -- output functions + putStr :: String -> m () + putStrLn :: String -> m () + createDirectory :: FilePath -> m () + writeFile :: FilePath -> String -> m () + copyFile :: FilePath -> FilePath -> m () + renameDirectory :: FilePath -> FilePath -> m () + message :: Verbosity -> String -> m () + + -- misc functions + break :: m Bool + throwPrompt :: BreakException -> m a + +instance Interactive IO where + getLine = P.getLine + readFile = P.readFile + getCurrentDirectory = P.getCurrentDirectory + getHomeDirectory = P.getHomeDirectory + getDirectoryContents = P.getDirectoryContents + listDirectory = P.listDirectory + doesDirectoryExist = P.doesDirectoryExist + doesFileExist = P.doesFileExist + tryCanonicalizePath = P.tryCanonicalizePath + readProcessWithExitCode = P.readProcessWithExitCode + getEnvironment = P.getEnvironment + listFilesInside = P.listFilesInside + listFilesRecursive = P.listFilesRecursive + + putStr = P.putStr + putStrLn = P.putStrLn + createDirectory = P.createDirectory + writeFile = P.writeFile + copyFile = P.copyFile + renameDirectory = P.renameDirectory + message q = unless (q == silent) . putStrLn + + break = return False + throwPrompt = throwM + +instance Interactive PurePrompt where + getLine = pop + readFile !_ = pop + getCurrentDirectory = popAbsolute + getHomeDirectory = popAbsolute + -- expects stack input of form "[\"foo\", \"bar\", \"baz\"]" + getDirectoryContents !_ = popList + listDirectory !_ = popList + doesDirectoryExist !_ = popBool + doesFileExist !_ = popBool + tryCanonicalizePath !_ = popAbsolute + readProcessWithExitCode !_ !_ !_ = do + input <- pop + return (ExitSuccess, input, "") + getEnvironment = fmap (map read) popList + listFilesInside pred' !_ = do + input <- map splitDirectories <$> popList + map joinPath <$> filterM (fmap and . traverse pred') input + listFilesRecursive !_ = popList + + putStr !_ = return () + putStrLn !_ = return () + createDirectory !_ = return () + writeFile !_ !_ = return () + copyFile !_ !_ = return () + renameDirectory !_ !_ = return () + message !_ !_ = return () + + break = return True + throwPrompt (BreakException e) = PurePrompt $ \s -> Left $ BreakException + ("Error: " ++ e ++ "\nStacktrace: " ++ show s) + +pop :: PurePrompt String +pop = PurePrompt $ \ (p:|ps) -> Right (p,fromList ps) + +popAbsolute :: PurePrompt String +popAbsolute = do + input <- pop + return $ "/home/test/" ++ input + +popBool :: PurePrompt Bool +popBool = pop >>= \case + "True" -> pure True + "False" -> pure False + s -> throwPrompt $ BreakException $ "popBool: " ++ s + +popList :: PurePrompt [String] +popList = pop >>= \a -> case safeRead a of + Nothing -> throwPrompt $ BreakException ("popList: " ++ show a) + Just as -> return as where - names = Map.fromList [ (show cat, cat) | cat <- [ minBound .. maxBound ] ] + safeRead s + | [(x, "")] <- reads s = Just x + | otherwise = Nothing + +-- | A pure exception thrown exclusively by the pure prompter +-- to cancel infinite loops in the prompting process. +-- +-- For example, in order to break on parse errors, or user-driven +-- continuations that do not make sense to test. +-- +newtype BreakException = BreakException String deriving (Eq, Show) + +instance Exception BreakException + +-- | Convenience alias for the literate haskell flag +-- +type IsLiterate = Bool + +-- | Convenience alias for generating simple projects +-- +type IsSimple = Bool + +-- -------------------------------------------------------------------- -- +-- Field annotation for pretty formatters + +-- | Annotations for cabal file PrettyField. +data FieldAnnotation = FieldAnnotation + { annCommentedOut :: Bool + -- ^ True iif the field and its contents should be commented out. + , annCommentLines :: [String] + -- ^ Comment lines to place before the field or section. + } diff --git a/cabal-install/src/Distribution/Client/Init/Utils.hs b/cabal-install/src/Distribution/Client/Init/Utils.hs index a3cfe06fe4e..0ac8f2f8cf8 100644 --- a/cabal-install/src/Distribution/Client/Init/Utils.hs +++ b/cabal-install/src/Distribution/Client/Init/Utils.hs @@ -1,38 +1,265 @@ ------------------------------------------------------------------------------ --- | --- Module : Distribution.Client.Init.Utils --- Copyright : (c) Brent Yorgey 2009 --- License : BSD-like --- --- Maintainer : cabal-devel@haskell.org --- Stability : provisional --- Portability : portable +{-# LANGUAGE RecordWildCards #-} + +module Distribution.Client.Init.Utils +( SourceFileEntry(..) +, retrieveSourceFiles +, retrieveModuleName +, retrieveModuleImports +, retrieveModuleExtensions +, retrieveBuildTools +, retrieveDependencies +, isMain +, isHaskell +, isSourceFile +, versionParser +, trim +, currentDirPkgName +, filePathToPkgName +, mkPackageNameDep +) where + + +import qualified Prelude +import Distribution.Client.Compat.Prelude hiding (empty, readFile, Parsec, many) +import Distribution.Utils.Generic (isInfixOf) + +import Control.Monad (forM) + +import qualified Data.List.NonEmpty as NE +import qualified Data.Map as M +import Language.Haskell.Extension (Extension(..)) +import System.FilePath + +import Distribution.CabalSpecVersion (CabalSpecVersion(..)) +import Distribution.ModuleName (ModuleName) +import Distribution.InstalledPackageInfo (InstalledPackageInfo, exposed) +import qualified Distribution.Package as P +import qualified Distribution.Types.PackageName as PN +import Distribution.Simple.PackageIndex (InstalledPackageIndex, moduleNameIndex) +import Distribution.Simple.Setup (Flag(..), fromFlagOrDefault) +import Distribution.Verbosity +import Distribution.Version +import Distribution.Client.Init.Defaults +import Distribution.Client.Init.Types +import Text.Parsec +import Distribution.Types.PackageName +import Distribution.Types.Dependency (Dependency, mkDependency) +import qualified Distribution.Compat.NonEmptySet as NES +import Distribution.Types.LibraryName + + +-- |Data type of source files found in the working directory +data SourceFileEntry = SourceFileEntry + { relativeSourcePath :: FilePath + , moduleName :: ModuleName + , fileExtension :: String + , imports :: [ModuleName] + , extensions :: [Extension] + } deriving Show + +-- Unfortunately we cannot use the version exported by Distribution.Simple.Program +knownSuffixHandlers :: String -> String +knownSuffixHandlers ".gc" = "greencard" +knownSuffixHandlers ".chs" = "chs" +knownSuffixHandlers ".hsc" = "hsc2hs" +knownSuffixHandlers ".x" = "alex" +knownSuffixHandlers ".y" = "happy" +knownSuffixHandlers ".ly" = "happy" +knownSuffixHandlers ".cpphs" = "cpp" +knownSuffixHandlers _ = "" + + +-- | Check if a given file has main file characteristics +isMain :: String -> Bool +isMain f = (isInfixOf "Main" f || isInfixOf "main" f) + && isSuffixOf ".hs" f || isSuffixOf ".lhs" f + +-- | Check if a given file has a Haskell extension +isHaskell :: String -> Bool +isHaskell f = isSuffixOf ".hs" f || isSuffixOf ".lhs" f + +isBuildTool :: String -> Bool +isBuildTool f = not . null . knownSuffixHandlers $ takeExtension f + +retrieveBuildTools :: Interactive m => FilePath -> m [String] +retrieveBuildTools fp = do + files <- map takeExtension <$> listFilesRecursive fp + + return [knownSuffixHandlers f | f <- files, isBuildTool f] + +retrieveSourceFiles :: Interactive m => FilePath -> m [SourceFileEntry] +retrieveSourceFiles fp = do + files <- filter isHaskell <$> listFilesRecursive fp + + forM files $ \f -> do + let fileExtension = takeExtension f + relativeSourcePath <- makeRelative f <$> getCurrentDirectory + moduleName <- retrieveModuleName f + imports <- retrieveModuleImports f + extensions <- retrieveModuleExtensions f + + return $ SourceFileEntry {..} + +-- | Given a module, retrieve its name +retrieveModuleName :: Interactive m => FilePath -> m ModuleName +retrieveModuleName m = do + fromString . trim . grabModuleName <$> readFile m + + where + stop c = (c /= '\\') && (c /= ' ') + + grabModuleName [] = [] + grabModuleName ('m':'o':'d':'u':'l':'e':' ':xs) = takeWhile' stop xs + grabModuleName (_:xs) = grabModuleName xs + +-- | Given a module, retrieve all of its imports +retrieveModuleImports :: Interactive m => FilePath -> m [ModuleName] +retrieveModuleImports m = do + map (fromString . trim) . grabModuleImports <$> readFile m + + where + stop c = (c /= '\\') && (c /= ' ') && (c /= '(') + + grabModuleImports [] = [] + grabModuleImports ('i':'m':'p':'o':'r':'t':' ':xs) = case trim xs of -- in case someone uses a weird formatting + ('q':'u':'a':'l':'i':'f':'i':'e':'d':' ':ys) -> takeWhile' stop ys : grabModuleImports (dropWhile' stop ys) + _ -> takeWhile' stop xs : grabModuleImports (dropWhile' stop xs) + grabModuleImports (_:xs) = grabModuleImports xs + +-- | Given a module, retrieve all of its language pragmas +retrieveModuleExtensions :: Interactive m => FilePath -> m [Extension] +retrieveModuleExtensions m = do + catMaybes <$> map (simpleParsec . trim) . grabModuleExtensions <$> readFile m + + where + stop c = (c /= '\\') && (c /= ' ') && (c /= ',') + + grabModuleExtensions [] = [] + grabModuleExtensions ('L':'A':'N':'G':'U':'A':'G':'E':' ':xs) = takeWhile' stop xs : grabModuleExtensions (dropWhile' stop xs) + grabModuleExtensions (',':xs) = takeWhile' stop xs : grabModuleExtensions (dropWhile' stop xs) + grabModuleExtensions (_:xs) = grabModuleExtensions xs + +takeWhile' :: (Char -> Bool) -> String -> String +takeWhile' p = takeWhile p . trim + +dropWhile' :: (Char -> Bool) -> String -> String +dropWhile' p = dropWhile p . trim + +trim :: String -> String +trim = removeLeadingSpace . reverse . removeLeadingSpace . reverse + where + removeLeadingSpace = dropWhile isSpace + +-- | Check whether a potential source file is located in one of the +-- source directories. +isSourceFile :: Maybe [FilePath] -> SourceFileEntry -> Bool +isSourceFile Nothing sf = isSourceFile (Just ["."]) sf +isSourceFile (Just srcDirs) sf = any (equalFilePath (relativeSourcePath sf)) srcDirs + +retrieveDependencies :: Interactive m => InitFlags -> [ModuleName] -> InstalledPackageIndex -> m [P.Dependency] +retrieveDependencies flags mods' pkgIx = do + let mods = mods' + + modMap :: M.Map ModuleName [InstalledPackageInfo] + modMap = M.map (filter exposed) $ moduleNameIndex pkgIx + + modDeps :: [(ModuleName, Maybe [InstalledPackageInfo])] + modDeps = map (\mn -> (mn, M.lookup mn modMap)) mods + -- modDeps = map (id &&& flip M.lookup modMap) mods + + message (fromFlagOrDefault silent $ initVerbosity flags) "\nGuessing dependencies..." + nub . catMaybes <$> traverse (chooseDep flags) modDeps + +-- Given a module and a list of installed packages providing it, +-- choose a dependency (i.e. package + version range) to use for that +-- module. +chooseDep + :: Interactive m + => InitFlags + -> (ModuleName, Maybe [InstalledPackageInfo]) + -> m (Maybe P.Dependency) +chooseDep flags (m, mipi) = case mipi of + -- We found some packages: group them by name. + Just ps@(_:_) -> + case NE.groupBy (\x y -> P.pkgName x == P.pkgName y) $ map P.packageId ps of + -- if there's only one group, i.e. multiple versions of a single package, + -- we make it into a dependency, choosing the latest-ish version. + + -- Given a list of available versions of the same package, pick a dependency. + [grp] -> fmap Just $ case grp of + + -- If only one version, easy. We change e.g. 0.4.2 into 0.4.* + (pid:|[]) -> + return $ P.Dependency + (P.pkgName pid) + (pvpize desugar . P.pkgVersion $ pid) + P.mainLibSet --TODO sublibraries + + -- Otherwise, choose the latest version and issue a warning. + pids -> do + message v ("\nWarning: multiple versions of " ++ prettyShow (P.pkgName . NE.head $ pids) ++ " provide " ++ prettyShow m ++ ", choosing the latest.") + return $ P.Dependency + (P.pkgName . NE.head $ pids) + (pvpize desugar . maximum . fmap P.pkgVersion $ pids) + P.mainLibSet --TODO take into account sublibraries + + -- if multiple packages are found, we refuse to choose between + -- different packages and make the user do it + grps -> do + message v ("\nWarning: multiple packages found providing " ++ prettyShow m ++ ": " ++ intercalate ", " (fmap (prettyShow . P.pkgName . NE.head) grps)) + message v "You will need to pick one and manually add it to the build-depends field." + return Nothing + + _ -> do + message v ("\nWarning: no package found providing " ++ prettyShow m ++ ".") + return Nothing + + where + v = fromFlagOrDefault normal (initVerbosity flags) + + -- desugar if cabal version lower than 2.0 + desugar = case cabalVersion flags of + Flag x -> x < CabalSpecV2_0 + NoFlag -> defaultCabalVersion < CabalSpecV2_0 + +-- | Given a version, return an API-compatible (according to PVP) version range. -- --- Shared utilities used by multiple cabal init modules. +-- If the boolean argument denotes whether to use a desugared +-- representation (if 'True') or the new-style @^>=@-form (if +-- 'False'). -- ------------------------------------------------------------------------------ +-- Example: @pvpize True (mkVersion [0,4,1])@ produces the version range @>= 0.4 && < 0.5@ (which is the +-- same as @0.4.*@). +pvpize :: Bool -> Version -> VersionRange +pvpize False v = majorBoundVersion v +pvpize True v = orLaterVersion v' + `intersectVersionRanges` + earlierVersion (incVersion 1 v') + where + v' = alterVersion (take 2) v -module Distribution.Client.Init.Utils ( - eligibleForTestSuite - , message - ) where + -- Increment the nth version component (counting from 0). + incVersion :: Int -> Version -> Version + incVersion n = alterVersion (incVersion' n) + where + incVersion' 0 [] = [1] + incVersion' 0 (v'':_) = [v'' + 1] + incVersion' m [] = replicate m 0 ++ [1] + incVersion' m (v'':vs) = v'' : incVersion' (m-1) vs -import Distribution.Solver.Compat.Prelude -import Prelude () +versionParser :: Parsec String () String +versionParser = do + skipMany (noneOf "1234567890") + many $ choice + [ oneOf "1234567890" + , oneOf "." + ] -import Distribution.Simple.Setup - ( Flag(..) ) -import Distribution.Client.Init.Types - ( InitFlags(..), PackageType(..) ) - --- | Returns true if this package is eligible for test suite initialization. -eligibleForTestSuite :: InitFlags -> Bool -eligibleForTestSuite flags = - Flag True == initializeTestSuite flags - && Flag Executable /= packageType flags - --- | Possibly generate a message to stdout, taking into account the --- --quiet flag. -message :: InitFlags -> String -> IO () -message (InitFlags{quiet = Flag True}) _ = return () -message _ s = putStrLn s +filePathToPkgName :: FilePath -> P.PackageName +filePathToPkgName = PN.mkPackageName . Prelude.last . splitDirectories + +currentDirPkgName :: Interactive m => m P.PackageName +currentDirPkgName = filePathToPkgName <$> getCurrentDirectory + +mkPackageNameDep :: PackageName -> Dependency +mkPackageNameDep pkg = mkDependency pkg anyVersion (NES.singleton LMainLibName) diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 445bf48e42d..b7cd6793880 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -84,7 +84,7 @@ import qualified Distribution.Client.SolverInstallPlan as SolverInstallPlan import Distribution.Client.Dependency import Distribution.Client.Dependency.Types import qualified Distribution.Client.IndexUtils as IndexUtils -import Distribution.Client.Init (incVersion) +import Distribution.Client.Utils (incVersion) import Distribution.Client.Targets (userToPackageConstraint) import Distribution.Client.DistDirLayout import Distribution.Client.SetupWrapper @@ -1758,7 +1758,7 @@ elaborateInstallPlan verbosity platform compiler compilerprogdb pkgConfigDB -- package needs to be rebuilt. (It needs to be done here, -- because the ElaboratedConfiguredPackage is where we test -- whether or not there have been changes.) - TestStanzas -> listToMaybe [ v | v <- maybeToList tests, _ <- PD.testSuites elabPkgDescription ] + TestStanzas -> listToMaybe [ v | v <- maybeToList tests, _ <- PD.testSuites elabPkgDescription ] BenchStanzas -> listToMaybe [ v | v <- maybeToList benchmarks, _ <- PD.benchmarks elabPkgDescription ] where tests, benchmarks :: Maybe Bool diff --git a/cabal-install/src/Distribution/Client/Setup.hs b/cabal-install/src/Distribution/Client/Setup.hs index 59a04be4738..32c875c09a2 100644 --- a/cabal-install/src/Distribution/Client/Setup.hs +++ b/cabal-install/src/Distribution/Client/Setup.hs @@ -71,7 +71,7 @@ import Distribution.Client.IndexUtils.ActiveRepos import Distribution.Client.IndexUtils.IndexState ( TotalIndexState, headTotalIndexState ) import qualified Distribution.Client.Init.Types as IT - ( InitFlags(..), PackageType(..), defaultInitFlags ) +import qualified Distribution.Client.Init.Defaults as IT import Distribution.Client.Targets ( UserConstraint, readUserConstraint ) import Distribution.Utils.NubList @@ -2215,14 +2215,13 @@ initOptions _ = , option ['c'] ["category"] "Project category." IT.category (\v flags -> flags { IT.category = v }) - (reqArg' "CATEGORY" (\s -> toFlag $ maybe (Left s) Right (readMaybe s)) - (flagToList . fmap (either id show))) + (reqArgFlag "CATEGORY") , option ['x'] ["extra-source-file"] "Extra source file to be distributed with tarball." IT.extraSrc (\v flags -> flags { IT.extraSrc = v }) - (reqArg' "FILE" (Just . (:[])) - (fromMaybe [])) + (reqArg' "FILE" (Flag . (:[])) + (fromFlagOrDefault [])) , option [] ["lib", "is-library"] "Build a library." @@ -2250,8 +2249,8 @@ initOptions _ = , option [] ["test-dir"] "Directory containing tests." IT.testDirs (\v flags -> flags { IT.testDirs = v }) - (reqArg' "DIR" (Just . (:[])) - (fromMaybe [])) + (reqArg' "DIR" (Flag . (:[])) + (fromFlagOrDefault [])) , option [] ["simple"] "Create a simple project with sensible defaults." @@ -2278,41 +2277,41 @@ initOptions _ = IT.exposedModules (\v flags -> flags { IT.exposedModules = v }) (reqArg "MODULE" (parsecToReadE ("Cannot parse module name: "++) - ((Just . (:[])) `fmap` parsec)) - (maybe [] (fmap prettyShow))) + (Flag . (:[]) <$> parsec)) + (flagElim [] (fmap prettyShow))) , option [] ["extension"] "Use a LANGUAGE extension (in the other-extensions field)." IT.otherExts (\v flags -> flags { IT.otherExts = v }) (reqArg "EXTENSION" (parsecToReadE ("Cannot parse extension: "++) - ((Just . (:[])) `fmap` parsec)) - (maybe [] (fmap prettyShow))) + (Flag . (:[]) <$> parsec)) + (flagElim [] (fmap prettyShow))) , option ['d'] ["dependency"] "Package dependency." IT.dependencies (\v flags -> flags { IT.dependencies = v }) (reqArg "PACKAGE" (parsecToReadE ("Cannot parse dependency: "++) - ((Just . (:[])) `fmap` parsec)) - (maybe [] (fmap prettyShow))) + (Flag . (:[]) <$> parsec)) + (flagElim [] (fmap prettyShow))) , option [] ["application-dir"] "Directory containing package application executable." IT.applicationDirs (\v flags -> flags { IT.applicationDirs = v}) - (reqArg' "DIR" (Just . (:[])) - (fromMaybe [])) + (reqArg' "DIR" (Flag . (:[])) + (fromFlagOrDefault [])) , option [] ["source-dir", "sourcedir"] "Directory containing package library source." IT.sourceDirs (\v flags -> flags { IT.sourceDirs = v }) - (reqArg' "DIR" (Just . (:[])) - (fromMaybe [])) + (reqArg' "DIR" (Flag. (:[])) + (fromFlagOrDefault [])) , option [] ["build-tool"] "Required external build tool." IT.buildTools (\v flags -> flags { IT.buildTools = v }) - (reqArg' "TOOL" (Just . (:[])) - (fromMaybe [])) + (reqArg' "TOOL" (Flag . (:[])) + (fromFlagOrDefault [])) -- NB: this is a bit of a transitional hack and will likely be -- removed again if `cabal init` is migrated to the v2-* command diff --git a/cabal-install/src/Distribution/Client/Utils.hs b/cabal-install/src/Distribution/Client/Utils.hs index c52eee302ed..9803a55d46c 100644 --- a/cabal-install/src/Distribution/Client/Utils.hs +++ b/cabal-install/src/Distribution/Client/Utils.hs @@ -1,27 +1,33 @@ {-# LANGUAGE ForeignFunctionInterface, CPP #-} -module Distribution.Client.Utils ( MergeResult(..) - , mergeBy, duplicates, duplicatesBy - , readMaybe - , inDir, withEnv, withEnvOverrides - , logDirChange, withExtraPathEnv - , determineNumJobs, numberOfProcessors - , removeExistingFile - , withTempFileName - , makeAbsoluteToCwd - , makeRelativeToCwd, makeRelativeToDir - , makeRelativeCanonical - , filePathToByteString - , byteStringToFilePath, tryCanonicalizePath - , canonicalizePathNoThrow - , moreRecentFile, existsAndIsMoreRecentThan - , tryFindAddSourcePackageDesc - , tryFindPackageDesc - , relaxEncodingErrors - , ProgressPhase (..) - , progressMessage - , cabalInstallVersion) - where +module Distribution.Client.Utils + ( MergeResult(..) + , mergeBy, duplicates, duplicatesBy + , readMaybe + , inDir, withEnv, withEnvOverrides + , logDirChange, withExtraPathEnv + , determineNumJobs, numberOfProcessors + , removeExistingFile + , withTempFileName + , makeAbsoluteToCwd + , makeRelativeToCwd, makeRelativeToDir + , makeRelativeCanonical + , filePathToByteString + , byteStringToFilePath, tryCanonicalizePath + , canonicalizePathNoThrow + , moreRecentFile, existsAndIsMoreRecentThan + , tryFindAddSourcePackageDesc + , tryFindPackageDesc + , relaxEncodingErrors + , ProgressPhase (..) + , progressMessage + , cabalInstallVersion + , pvpize + , incVersion + , getCurrentYear + , listFilesRecursive + , listFilesInside + ) where import Prelude () import Distribution.Client.Compat.Prelude @@ -44,7 +50,7 @@ import qualified Control.Exception as Exception ( finally, bracket ) import System.Directory ( canonicalizePath, doesFileExist, getCurrentDirectory - , removeFile, setCurrentDirectory ) + , removeFile, setCurrentDirectory, getDirectoryContents, doesDirectoryExist ) import System.IO ( Handle, hClose, openTempFile , hGetEncoding, hSetEncoding @@ -55,14 +61,16 @@ import GHC.IO.Encoding ( recover, TextEncoding(TextEncoding) ) import GHC.IO.Encoding.Failure ( recoverEncode, CodingFailureMode(TransliterateCodingFailure) ) - +import Data.Time.Clock.POSIX (getCurrentTime) +import Data.Time.LocalTime (getCurrentTimeZone, localDay) +import Data.Time (utcToLocalTime) +import Data.Time.Calendar (toGregorian) #if defined(mingw32_HOST_OS) || MIN_VERSION_directory(1,2,3) import qualified System.Directory as Dir import qualified System.IO.Error as IOError #endif - -- | Generic merging utility. For sorted input lists this is a full outer join. -- mergeBy :: (a -> b -> Ordering) -> [a] -> [b] -> [MergeResult a b] @@ -359,5 +367,86 @@ progressMessage verbosity phase subject = do ProgressInstalling -> "Installing " ProgressCompleted -> "Completed " +-- TODO: write a test around this. Don't abuse Paths_cabal_install. +-- cabalInstallVersion :: Version cabalInstallVersion = mkVersion [3,5] + +-- | Given a version, return an API-compatible (according to PVP) version range. +-- +-- If the boolean argument denotes whether to use a desugared +-- representation (if 'True') or the new-style @^>=@-form (if +-- 'False'). +-- +-- Example: @pvpize True (mkVersion [0,4,1])@ produces the version range @>= 0.4 && < 0.5@ (which is the +-- same as @0.4.*@). +pvpize :: Bool -> Version -> VersionRange +pvpize False v = majorBoundVersion v +pvpize True v = orLaterVersion v' + `intersectVersionRanges` + earlierVersion (incVersion 1 v') + where v' = alterVersion (take 2) v + +-- | Increment the nth version component (counting from 0). +incVersion :: Int -> Version -> Version +incVersion n = alterVersion (incVersion' n) + where + incVersion' 0 [] = [1] + incVersion' 0 (v:_) = [v+1] + incVersion' m [] = replicate m 0 ++ [1] + incVersion' m (v:vs) = v : incVersion' (m-1) vs + +-- | Returns the current calendar year. +getCurrentYear :: IO Integer +getCurrentYear = do + u <- getCurrentTime + z <- getCurrentTimeZone + let l = utcToLocalTime z u + (y, _, _) = toGregorian $ localDay l + return y + +-- | From System.Directory.Extra +-- https://hackage.haskell.org/package/extra-1.7.9 +listFilesInside :: (FilePath -> IO Bool) -> FilePath -> IO [FilePath] +listFilesInside test dir = ifM (notM $ test $ dropTrailingPathSeparator dir) (pure []) $ do + (dirs,files) <- partitionM doesDirectoryExist =<< listContents dir + rest <- concatMapM (listFilesInside test) dirs + pure $ files ++ rest + +-- | From System.Directory.Extra +-- https://hackage.haskell.org/package/extra-1.7.9 +listFilesRecursive :: FilePath -> IO [FilePath] +listFilesRecursive = listFilesInside (const $ pure True) + +-- | From System.Directory.Extra +-- https://hackage.haskell.org/package/extra-1.7.9 +listContents :: FilePath -> IO [FilePath] +listContents dir = do + xs <- getDirectoryContents dir + pure $ sort [dir x | x <- xs, not $ all (== '.') x] + +-- | From Control.Monad.Extra +-- https://hackage.haskell.org/package/extra-1.7.9 +ifM :: Monad m => m Bool -> m a -> m a -> m a +ifM b t f = do b' <- b; if b' then t else f + +-- | From Control.Monad.Extra +-- https://hackage.haskell.org/package/extra-1.7.9 +concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b] +{-# INLINE concatMapM #-} +concatMapM op = foldr f (pure []) + where f x xs = do x' <- op x; if null x' then xs else do xs' <- xs; pure $ x' ++ xs' + +-- | From Control.Monad.Extra +-- https://hackage.haskell.org/package/extra-1.7.9 +partitionM :: Monad m => (a -> m Bool) -> [a] -> m ([a], [a]) +partitionM _ [] = pure ([], []) +partitionM f (x:xs) = do + res <- f x + (as,bs) <- partitionM f xs + pure ([x | res]++as, [x | not res]++bs) + +-- | From Control.Monad.Extra +-- https://hackage.haskell.org/package/extra-1.7.9 +notM :: Functor m => m Bool -> m Bool +notM = fmap not diff --git a/cabal-install/tests/UnitTests.hs b/cabal-install/tests/UnitTests.hs index 5783d9fce54..1c08f86adda 100644 --- a/cabal-install/tests/UnitTests.hs +++ b/cabal-install/tests/UnitTests.hs @@ -24,7 +24,8 @@ import qualified UnitTests.Distribution.Client.Get main :: IO () -main = +main = do + initTests <- UnitTests.Distribution.Client.Init.tests defaultMain $ testGroup "Unit Tests" [ testGroup "UnitTests.Distribution.Solver.Modular.Builder" UnitTests.Distribution.Solver.Modular.Builder.tests @@ -40,7 +41,7 @@ main = , testGroup "Distribution.Client.GZipUtils" UnitTests.Distribution.Client.GZipUtils.tests , testGroup "Distribution.Client.Init" - UnitTests.Distribution.Client.Init.tests + initTests , testGroup "Distribution.Client.Store" UnitTests.Distribution.Client.Store.tests , testGroup "Distribution.Client.Tar" diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init.hs index 9a2f042482b..30e08474c47 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init.hs @@ -1,220 +1,49 @@ module UnitTests.Distribution.Client.Init - ( tests - ) where - -import Distribution.Client.Init.FileCreators - ( generateCabalFile ) +( tests +) where import Test.Tasty -import Test.Tasty.HUnit -import Test.Tasty.Golden (goldenVsString) - -import System.FilePath - ( () ) -import qualified Data.ByteString.Lazy as BS -import qualified Data.ByteString.Lazy.Char8 as BS8 - -import Distribution.Client.Init.Command - ( getLibOrExec, getAppDir, getSrcDir ) -import Distribution.Client.Init.Types - ( InitFlags(..), PackageType(..), defaultInitFlags ) -import Distribution.Simple.Setup - ( Flag(..) ) - -import Distribution.CabalSpecVersion - ( CabalSpecVersion(CabalSpecV2_4) ) -import Distribution.Types.Dependency - ( Dependency, mkDependency, mainLibSet ) -import Distribution.Types.PackageName - ( mkPackageName ) -import Distribution.Types.VersionRange - ( majorBoundVersion ) -import Distribution.Types.Version - ( mkVersion ) -import qualified Distribution.ModuleName as ModuleName - ( fromString ) -import qualified Distribution.SPDX as SPDX -import Language.Haskell.Extension ( Language(..) ) - -tests :: [TestTree] -tests = [ testGroup "cabal init goldens" - [ checkCabalFileGolden exeFlags "exe-only-golden.cabal" - , checkCabalFileGolden libAndExeFlags "lib-and-exe-golden.cabal" - , checkCabalFileGolden libExeAndTestFlags "lib-exe-and-test-golden.cabal" - , checkCabalFileGolden libExeAndTestWithCommentsFlags "lib-exe-and-test-with-comments-golden.cabal" - ] - , testGroup "Check init flag outputs against init script builds" - [ checkInitFlags "Check library-only build flags" libFlags Library - , checkInitFlags "Check lib+exe build flags" libAndExeFlags LibraryAndExecutable - , checkInitFlags "Check exe-only build flags" exeFlags Executable - ] - ] - -checkCabalFileGolden :: InitFlags -> FilePath -> TestTree -checkCabalFileGolden flags goldenFileName = - goldenVsString goldenFileName goldenFilePath generatedCabalFile - where - goldenFilePath :: FilePath - goldenFilePath = "tests" "fixtures" "init" goldenFileName - - generatedCabalFile :: IO BS.ByteString - generatedCabalFile = pure . BS8.pack $ generateCabalFile goldenFileName flags - -checkInitFlags :: String -> InitFlags -> PackageType -> TestTree -checkInitFlags label flags pkgType = testCase label $ do - flags' <- getLibOrExec rawFlags - >>= getAppDir - >>= getSrcDir - - flags @=? flags' - where - rawFlags - | pkgType == Executable = baseFlags - { packageType = Flag pkgType - , exposedModules = Nothing - } - | otherwise = baseFlags { packageType = Flag pkgType } - - --- ================================================== --- Base flags to set common InitFlags values. - -baseFlags :: InitFlags -baseFlags = defaultInitFlags { - -- Values common to all (or most) test flags. - packageName = Flag (mkPackageName "foo") - , noComments = Flag False - , minimal = Flag True - , version = Flag (mkVersion [3,2,1]) - , synopsis = Flag "The foo package" - , homepage = Flag "https://github.com/foo/foo" - , license = Flag SPDX.NONE - , author = Flag "me" - , email = Flag "me@me.me" - , category = Flag (Left "SomeCat") - , cabalVersion = Flag CabalSpecV2_4 - , extraSrc = Just ["CHANGELOG.md"] - , interactive = Flag False - , otherModules = Nothing - , otherExts = Nothing - , language = Flag Haskell2010 - , buildTools = Nothing - , dependencies = Just testDependencies - , quiet = Flag True - , packageDir = NoFlag - , simpleProject = Flag False - , initHcPath = NoFlag - , overwrite = NoFlag - -- Commonly overridden values in test InitFlags. - -- It is fine to provide the same value in an overridden InitFlags - -- to make it clear what that particular test case is differentiating - -- from others. - , packageType = Flag Executable - , mainIs = Flag "Main.hs" - , applicationDirs = Just ["app"] - , sourceDirs = Nothing - , exposedModules = Just [ModuleName.fromString "MyLib"] - , initializeTestSuite = Flag False - , testDirs = Nothing - } +import qualified UnitTests.Distribution.Client.Init.Interactive as Interactive +import qualified UnitTests.Distribution.Client.Init.NonInteractive as NonInteractive +import qualified UnitTests.Distribution.Client.Init.Golden as Golden +import qualified UnitTests.Distribution.Client.Init.Simple as Simple +import UnitTests.Distribution.Client.Init.Utils --- ================================================== --- Simple library flags - -libFlags :: InitFlags -libFlags = baseFlags - { packageType = Flag Library - , mainIs = NoFlag - , sourceDirs = Just ["src"] - , applicationDirs = Just [] - } - --- ================================================== --- Simple exe. - -exeFlags :: InitFlags -exeFlags = baseFlags { - -- Create an executable only, with main living in app/Main.hs. - packageType = Flag Executable - , mainIs = Flag "Main.hs" - , sourceDirs = Just [] - , applicationDirs = Just ["app"] - , exposedModules = Nothing - } - - --- ================================================== --- Simple lib and exe (as created by `cabal init --libandexe`). --- --- Specifically, having 'exposedModules = Just ["MyLib"]' is a special --- case which results in the executable depending on the library from --- the same package, i.e. 'build-depends = foo' with no version --- constraints. - -libAndExeFlags :: InitFlags -libAndExeFlags = baseFlags { - -- Create a library and executable - packageType = Flag LibraryAndExecutable - - -- Main living in app/Main.hs. - , mainIs = Flag "Main.hs" - , applicationDirs = Just ["app"] - - -- Library sources live in src/ and expose the module MyLib. - , sourceDirs = Just ["src"] - } - - --- ================================================== --- Lib, exe, and test suite - -libExeAndTestFlags :: InitFlags -libExeAndTestFlags = baseFlags { - -- Create a library and executable - packageType = Flag LibraryAndExecutable - - -- Main living in app/Main.hs. - , mainIs = Flag "Main.hs" - , applicationDirs = Just ["app"] +import Distribution.Client.Config +import Distribution.Client.IndexUtils +import Distribution.Client.Init.Types +import Distribution.Client.Sandbox +import Distribution.Client.Setup +import Distribution.Verbosity - -- Library sources live in src/ and expose the modules A and B. - , sourceDirs = Just ["src"] - , exposedModules = Just (map ModuleName.fromString ["A", "B"]) - -- Create a test suite living in tests/ - , initializeTestSuite = Flag True - , testDirs = Just ["tests"] - } +tests :: IO [TestTree] +tests = do + confFlags <- loadConfigOrSandboxConfig v defaultGlobalFlags --- ================================================== --- Lib, exe, and test suite with comments. + let confFlags' = savedConfigureFlags confFlags `mappend` compFlags + initFlags' = savedInitFlags confFlags `mappend` emptyFlags + globalFlags' = savedGlobalFlags confFlags `mappend` defaultGlobalFlags -libExeAndTestWithCommentsFlags :: InitFlags -libExeAndTestWithCommentsFlags = libExeAndTestFlags { - minimal = Flag False - , noComments = Flag False - , quiet = Flag False - } + (comp, _, progdb) <- configCompilerAux' confFlags' + withRepoContext v globalFlags' $ \repoCtx -> do + let pkgDb = configPackageDB' confFlags' + pkgIx <- getInstalledPackages v comp pkgDb progdb + srcDb <- getSourcePackages v repoCtx --- ================================================== --- Test dependency. + return + [ Interactive.tests v initFlags' comp pkgIx srcDb + , NonInteractive.tests v initFlags' comp pkgIx srcDb + , Golden.tests v initFlags' comp pkgIx srcDb + , Simple.tests v initFlags' comp pkgIx srcDb + ] + where + v :: Verbosity + v = normal -testDependencies :: [Dependency] -testDependencies = - [ mkDependency - (mkPackageName "base") - (majorBoundVersion (mkVersion [4,13,0,0])) - mainLibSet - , mkDependency - (mkPackageName "containers") - (majorBoundVersion (mkVersion [5,7,0,0])) - mainLibSet - , mkDependency - (mkPackageName "unordered-containers") - (majorBoundVersion (mkVersion [2,7,0,0])) - mainLibSet - ] + compFlags :: ConfigFlags + compFlags = mempty { configHcPath = initHcPath emptyFlags } diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs new file mode 100644 index 00000000000..34052296ef7 --- /dev/null +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs @@ -0,0 +1,367 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE LambdaCase #-} +module UnitTests.Distribution.Client.Init.Golden +( tests +) where + + +import Test.Tasty +import Test.Tasty.Golden +import Test.Tasty.HUnit + +import qualified Data.ByteString.Lazy.Char8 as BS8 +import Data.List.NonEmpty (fromList) +import Data.List.NonEmpty as NEL (NonEmpty) +#if __GLASGOW_HASKELL__ < 804 +import Data.Semigroup ((<>)) +#endif + +import Distribution.Client.Init.Types +import Distribution.Simple.PackageIndex hiding (fromList) +import Distribution.Verbosity +import Distribution.Simple.Compiler +import Distribution.Client.Types.SourcePackageDb +import Distribution.Client.Init.Interactive.Command +import Distribution.Client.Init.Format +import Distribution.Fields.Pretty +import Distribution.Types.PackageName (PackageName) +import Distribution.Client.Init.FlagExtractors +import Distribution.Simple.Flag +import Distribution.CabalSpecVersion + +import System.FilePath + +import UnitTests.Distribution.Client.Init.Utils + +-- -------------------------------------------------------------------- -- +-- golden test suite + +-- | Golden executable tests. +-- +-- We test target generation against a golden file in @tests/fixtures/init/@ for +-- executables, libraries, and test targets with the following: +-- +-- * Empty flags, non-simple target gen, no special options +-- * Empty flags, simple target gen, no special options +-- * Empty flags, non-simple target gen, with generated comments (no minimal setting) +-- * Empty flags, non-simple target gen, with minimal setting (no generated comments) +-- * Empty flags, non-simple target gen, minimal and generated comments set. +-- +-- Additionally, we test whole @.cabal@ file generation for every combination +-- of library, lib + tests, exe, exe + tests, exe + lib, exe + lib + tests +-- and so on against the same options. +-- +tests + :: Verbosity + -> InitFlags + -> Compiler + -> InstalledPackageIndex + -> SourcePackageDb + -> TestTree +tests v initFlags _comp pkgIx srcDb = testGroup "golden" + [ goldenLibTests v pkgIx pkgDir pkgName + , goldenExeTests v pkgIx pkgDir pkgName + , goldenTestTests v pkgIx pkgDir pkgName + , goldenPkgDescTests v srcDb pkgDir pkgName + , goldenCabalTests v pkgIx srcDb + ] + where + pkgDir = evalPrompt (getPackageDir initFlags) + $ fromList ["."] + pkgName = evalPrompt (packageNamePrompt srcDb initFlags) + $ fromList ["test-package", "y"] + +-- goldenCabalTests +-- :: Verbosity +-- -> InstalledPackageIndex +-- -> FilePath +-- -> PackageName +-- -> SourcePackageDb +-- -> TestTree +-- goldenCabalTests v pkgIx pkgDir pkgName srcDb = testGroup ".cabal golden tests" +-- [ goldenVsString "Create lib .cabal project" (goldenCabal "lib-cabal.golden") $ +-- runGoldenCabal emptyFlags { packageType = Flag Library } +-- , goldenVsString "Create lib+test .cabal project" (goldenCabal "lib-test-cabal.golden") $ +-- runGoldenCabal emptyFlags +-- { packageType = Flag Library +-- , initializeTestSuite = Flag True +-- } +-- , goldenVsString "Create lib .cabal project" (goldenCabal "exe-cabal.golden") $ +-- runGoldenCabal emptyFlags { packageType = Flag Executable } +-- ] +-- where +-- runGoldenCabal flags = +-- case _runPrompt (createProject v pkgIx srcDb flags) of +-- Right (t, _) -> return . BS8.pack $ showFields' +-- annCommentLines postProcessFieldLines +-- 4 [mkCabalStanza opts t] +-- Left e -> assertFailure $ show e + +goldenPkgDescTests + :: Verbosity + -> SourcePackageDb + -> FilePath + -> PackageName + -> TestTree +goldenPkgDescTests v srcDb pkgDir pkgName = testGroup "package description golden tests" + [ goldenVsString "Empty flags, non-simple, no comments" + (goldenPkgDesc "pkg.golden") $ + let opts = WriteOpts False False False v pkgDir Library pkgName + in runPkgDesc opts emptyFlags pkgArgs + + , goldenVsString "Empty flags, non-simple, with comments" + (goldenPkgDesc "pkg-with-comments.golden") $ + let opts = WriteOpts False False False v pkgDir Library pkgName + in runPkgDesc opts emptyFlags pkgArgs + + , goldenVsString "Dummy flags, with comments" + (goldenPkgDesc "pkg-with-flags.golden") $ + let opts = WriteOpts False False False v pkgDir Library pkgName + in runPkgDesc opts dummyFlags pkgArgs + + , goldenVsString "Dummy flags, old cabal version, with comments" + (goldenPkgDesc "pkg-old-cabal-with-flags.golden") $ + let opts = WriteOpts False False False v pkgDir Library pkgName + in runPkgDesc opts (dummyFlags {cabalVersion = Flag CabalSpecV2_0}) pkgArgs + ] + where + runPkgDesc opts flags args = do + case _runPrompt (genPkgDescription flags srcDb) args of + Left e -> assertFailure $ show e + Right (pkg, _) -> mkStanza $ mkPkgDescription opts pkg + +goldenExeTests + :: Verbosity + -> InstalledPackageIndex + -> FilePath + -> PackageName + -> TestTree +goldenExeTests v pkgIx pkgDir pkgName = testGroup "exe golden tests" + [ goldenVsString "Empty flags, not simple, no options" + (goldenExe "exe.golden") $ + let opts = WriteOpts False False True v pkgDir Executable pkgName + in runGoldenExe opts exeArgs emptyFlags + + , goldenVsString "Empty flags, not simple, with comments + no minimal" + (goldenExe "exe-with-comments.golden") $ + let opts = WriteOpts False False False v pkgDir Executable pkgName + in runGoldenExe opts exeArgs emptyFlags + + , goldenVsString "Empty flags, not simple, with minimal + no comments" + (goldenExe "exe-minimal-no-comments.golden") $ + let opts = WriteOpts False True True v pkgDir Executable pkgName + in runGoldenExe opts exeArgs emptyFlags + + , goldenVsString "Empty flags, not simple, with minimal + comments" + (goldenExe "exe-simple-with-comments.golden") $ + let opts = WriteOpts False True False v pkgDir Executable pkgName + in runGoldenExe opts exeArgs emptyFlags + + , goldenVsString "Build tools flag, not simple, with comments + no minimal" + (goldenExe "exe-build-tools-with-comments.golden") $ + let opts = WriteOpts False False False v pkgDir Executable pkgName + in runGoldenExe opts exeArgs (emptyFlags {buildTools = Flag ["happy"]}) + ] + where + runGoldenExe opts args flags = + case _runPrompt (genExeTarget flags pkgIx) args of + Right (t, _) -> mkStanza [mkExeStanza opts $ t {_exeDependencies = mangleBaseDep t _exeDependencies}] + Left e -> assertFailure $ show e + +goldenLibTests + :: Verbosity + -> InstalledPackageIndex + -> FilePath + -> PackageName + -> TestTree +goldenLibTests v pkgIx pkgDir pkgName = testGroup "lib golden tests" + [ goldenVsString "Empty flags, not simple, no options" + (goldenLib "lib.golden") $ + let opts = WriteOpts False False True v pkgDir Library pkgName + in runGoldenLib opts libArgs emptyFlags + + , goldenVsString "Empty flags, simple, no options" (goldenLib "lib-simple.golden") $ + let opts = WriteOpts False False True v pkgDir Library pkgName + in runGoldenLib opts libArgs emptyFlags + + , goldenVsString "Empty flags, not simple, with comments + no minimal" + (goldenLib "lib-with-comments.golden") $ + let opts = WriteOpts False False False v pkgDir Library pkgName + in runGoldenLib opts libArgs emptyFlags + + , goldenVsString "Empty flags, not simple, with minimal + no comments" + (goldenLib "lib-minimal-no-comments.golden") $ + let opts = WriteOpts False True True v pkgDir Library pkgName + in runGoldenLib opts libArgs emptyFlags + + , goldenVsString "Empty flags, not simple, with minimal + comments" + (goldenLib "lib-simple-with-comments.golden") $ + let opts = WriteOpts False True False v pkgDir Library pkgName + in runGoldenLib opts libArgs emptyFlags + + , goldenVsString "Build tools flag, not simple, with comments + no minimal" + (goldenLib "lib-build-tools-with-comments.golden") $ + let opts = WriteOpts False False False v pkgDir Library pkgName + in runGoldenLib opts libArgs (emptyFlags {buildTools = Flag ["happy"]}) + ] + where + runGoldenLib opts args flags = + case _runPrompt (genLibTarget flags pkgIx) args of + Right (t, _) -> mkStanza [mkLibStanza opts $ t {_libDependencies = mangleBaseDep t _libDependencies}] + Left e -> assertFailure $ show e + +goldenTestTests + :: Verbosity + -> InstalledPackageIndex + -> FilePath + -> PackageName + -> TestTree +goldenTestTests v pkgIx pkgDir pkgName = testGroup "test golden tests" + [ goldenVsString "Empty flags, not simple, no options" + (goldenTest "test.golden") $ + let opts = WriteOpts False False True v pkgDir Library pkgName + in runGoldenTest opts testArgs emptyFlags + + , goldenVsString "Empty flags, not simple, with comments + no minimal" + (goldenTest "test-with-comments.golden") $ + let opts = WriteOpts False False False v pkgDir Library pkgName + in runGoldenTest opts testArgs emptyFlags + + , goldenVsString "Empty flags, not simple, with minimal + no comments" + (goldenTest "test-minimal-no-comments.golden") $ + let opts = WriteOpts False True True v pkgDir Library pkgName + in runGoldenTest opts testArgs emptyFlags + + , goldenVsString "Empty flags, not simple, with minimal + comments" + (goldenTest "test-simple-with-comments.golden") $ + let opts = WriteOpts False True False v pkgDir Library pkgName + in runGoldenTest opts testArgs emptyFlags + + , goldenVsString "Empty flags, not simple, with minimal + comments" + (goldenTest "test-simple-with-comments.golden") $ + let opts = WriteOpts False True False v pkgDir Library pkgName + in runGoldenTest opts testArgs emptyFlags + + , goldenVsString "Build tools flag, not simple, with comments + no minimal" + (goldenTest "test-build-tools-with-comments.golden") $ + let opts = WriteOpts False False False v pkgDir Library pkgName + in runGoldenTest opts testArgs (emptyFlags {buildTools = Flag ["happy"]}) + ] + where + runGoldenTest opts args flags = + case _runPrompt (genTestTarget flags pkgIx) args of + Left e -> assertFailure $ show e + Right (Nothing, _) -> assertFailure + "goldenTestTests: Tests not enabled." + Right (Just t, _) -> mkStanza [mkTestStanza opts $ t {_testDependencies = mangleBaseDep t _testDependencies}] + +-- | Full cabal file golden tests +goldenCabalTests + :: Verbosity + -> InstalledPackageIndex + -> SourcePackageDb + -> TestTree +goldenCabalTests v pkgIx srcDb = testGroup ".cabal file golden tests" + [ goldenVsString "Library and executable, empty flags, not simple, with comments + no minimal" + (goldenCabal "cabal-lib-and-exe-with-comments.golden") $ + runGoldenTest (fullProjArgs "Y") emptyFlags + + , goldenVsString "Library and executable, empty flags, not simple, no comments + no minimal" + (goldenCabal "cabal-lib-and-exe-no-comments.golden") $ + runGoldenTest (fullProjArgs "N") emptyFlags + + , goldenVsString "Library, empty flags, not simple, with comments + no minimal" + (goldenCabal "cabal-lib-with-comments.golden") $ + runGoldenTest (libProjArgs "Y") emptyFlags + + , goldenVsString "Library, empty flags, not simple, no comments + no minimal" + (goldenCabal "cabal-lib-no-comments.golden") $ + runGoldenTest (libProjArgs "N") emptyFlags + ] + where + runGoldenTest args flags = + case _runPrompt (createProject v pkgIx srcDb flags) args of + Left e -> assertFailure $ show e + + (Right (ProjectSettings opts pkgDesc (Just libTarget) (Just exeTarget) (Just testTarget), _)) -> do + let pkgFields = mkPkgDescription opts pkgDesc + libStanza = mkLibStanza opts $ libTarget {_libDependencies = mangleBaseDep libTarget _libDependencies} + exeStanza = mkExeStanza opts $ exeTarget {_exeDependencies = mangleBaseDep exeTarget _exeDependencies} + testStanza = mkTestStanza opts $ testTarget {_testDependencies = mangleBaseDep testTarget _testDependencies} + + mkStanza $ pkgFields ++ [libStanza, exeStanza, testStanza] + + (Right (ProjectSettings opts pkgDesc (Just libTarget) Nothing (Just testTarget), _)) -> do + let pkgFields = mkPkgDescription opts pkgDesc + libStanza = mkLibStanza opts $ libTarget {_libDependencies = mangleBaseDep libTarget _libDependencies} + testStanza = mkTestStanza opts $ testTarget {_testDependencies = mangleBaseDep testTarget _testDependencies} + + mkStanza $ pkgFields ++ [libStanza, testStanza] + + (Right (ProjectSettings _ _ l e t, _)) -> assertFailure $ + show l ++ "\n" ++ show e ++ "\n" ++ show t + + +-- -------------------------------------------------------------------- -- +-- utils + +mkStanza :: [PrettyField FieldAnnotation] -> IO BS8.ByteString +mkStanza fields = return . BS8.pack $ showFields' + annCommentLines postProcessFieldLines + 4 fields + +golden :: FilePath +golden = "tests" "fixtures" "init" "golden" + +goldenExe :: FilePath -> FilePath +goldenExe file = golden "exe" file + +goldenTest :: FilePath -> FilePath +goldenTest file = golden "test" file + +goldenLib :: FilePath -> FilePath +goldenLib file = golden "lib" file + +goldenCabal :: FilePath -> FilePath +goldenCabal file = golden "cabal" file + +goldenPkgDesc :: FilePath -> FilePath +goldenPkgDesc file = golden "pkg-desc" file + +libArgs :: NonEmpty String +libArgs = fromList ["1", "2"] + +exeArgs :: NonEmpty String +exeArgs = fromList ["1", "2", "1"] + +testArgs :: NonEmpty String +testArgs = fromList ["y", "1", "test", "1"] + +pkgArgs :: NonEmpty String +pkgArgs = fromList + [ "4" + , "foo-package" + , "y" + , "0.1.0.0" + , "2" + , "foo-kmett" + , "foo-kmett@kmett.kmett" + , "home" + , "synopsis" + , "4" + ] + +libProjArgs :: String -> NonEmpty String +libProjArgs comments = fromList ["1", "foo-package"] + <> pkgArgs + <> libArgs + <> testArgs + <> fromList [comments] + +fullProjArgs :: String -> NonEmpty String +fullProjArgs comments = fromList ["3", "foo-package"] + <> pkgArgs + <> libArgs + <> exeArgs + <> testArgs + <> fromList [comments] diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs new file mode 100644 index 00000000000..4b85e741f07 --- /dev/null +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs @@ -0,0 +1,832 @@ +module UnitTests.Distribution.Client.Init.Interactive +( tests +) where + + +import Prelude as P +import Test.Tasty +import Test.Tasty.HUnit + +import Distribution.Client.Init.Defaults +import Distribution.Client.Init.Interactive.Command +import Distribution.Client.Init.Types + +import qualified Distribution.SPDX as SPDX + +import Data.List.NonEmpty hiding (zip) +import Distribution.Client.Types +import Distribution.Simple.Compiler +import Distribution.Simple.PackageIndex hiding (fromList) +import Distribution.Types.PackageName +import Distribution.Types.Version +import Distribution.Verbosity + +import Language.Haskell.Extension + +import UnitTests.Distribution.Client.Init.Utils +import Distribution.Client.Init.FlagExtractors +import Distribution.Simple.Setup +import Distribution.CabalSpecVersion + + +-- -------------------------------------------------------------------- -- +-- Init Test main + +tests + :: Verbosity + -> InitFlags + -> Compiler + -> InstalledPackageIndex + -> SourcePackageDb + -> TestTree +tests _v initFlags _comp pkgIx srcDb = + testGroup "Distribution.Client.Init.Interactive.Command.hs" + [ createProjectTest pkgIx srcDb + , fileCreatorTests pkgIx srcDb pkgName + , interactiveTests srcDb + ] + where + pkgName = evalPrompt (packageNamePrompt srcDb initFlags) $ + fromList ["test-package", "y"] + + -- pkgNm = evalPrompt (getPackageName srcDb initFlags) $ fromList ["test-package", "y"] + +createProjectTest + :: InstalledPackageIndex + -> SourcePackageDb + -> TestTree +createProjectTest pkgIx srcDb = testGroup "createProject tests" + [ testGroup "with flags" + [ testCase "Check the non-interactive workflow" $ do + let dummyFlags' = dummyFlags + { packageType = Flag LibraryAndExecutable + , minimal = Flag False + , overwrite = Flag False + , packageDir = Flag "/home/test/test-package" + , extraSrc = Flag ["CHANGELOG.md"] + , exposedModules = Flag [] + , otherModules = Flag [] + , otherExts = Flag [] + , buildTools = Flag [] + , mainIs = Flag "quxApp/Main.hs" + , dependencies = Flag [] + } + + case (_runPrompt $ createProject silent pkgIx srcDb dummyFlags') (fromList ["3", "quxTest/Main.hs"]) of + Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do + _optOverwrite opts @?= False + _optMinimal opts @?= False + _optNoComments opts @?= True + _optVerbosity opts @?= silent + _optPkgDir opts @?= "/home/test/test-package" + _optPkgType opts @?= LibraryAndExecutable + _optPkgName opts @?= mkPackageName "QuxPackage" + + _pkgCabalVersion desc @?= CabalSpecV2_2 + _pkgName desc @?= mkPackageName "QuxPackage" + _pkgVersion desc @?= mkVersion [4,2,6] + _pkgLicense desc @?! SPDX.NONE + _pkgAuthor desc @?= "Foobar" + _pkgEmail desc @?= "foobar@qux.com" + _pkgHomePage desc @?= "qux.com" + _pkgSynopsis desc @?= "We are Qux, and this is our package" + _pkgCategory desc @?= "Control" + _pkgExtraSrcFiles desc @?= "CHANGELOG.md" :| [] + + _libSourceDirs lib @?= ["quxSrc"] + _libLanguage lib @?= Haskell98 + _libExposedModules lib @?= myLibModule :| [] + _libOtherModules lib @?= [] + _libOtherExts lib @?= [] + _libDependencies lib @?= [] + _libBuildTools lib @?= [] + + _exeMainIs exe @?= HsFilePath "quxApp/Main.hs" Standard + _exeApplicationDirs exe @?= ["quxApp"] + _exeLanguage exe @?= Haskell98 + _exeOtherModules exe @?= [] + _exeOtherExts exe @?= [] + _exeDependencies exe @?! [] + _exeBuildTools exe @?= [] + + _testMainIs test @?= HsFilePath "quxTest/Main.hs" Standard + _testDirs test @?= ["quxTest"] + _testLanguage test @?= Haskell98 + _testOtherModules test @?= [] + _testOtherExts test @?= [] + _testDependencies test @?! [] + _testBuildTools test @?= [] + + Right (ProjectSettings _ _ lib exe test, _) -> do + lib @?! Nothing + exe @?! Nothing + test @?! Nothing + Left e -> assertFailure $ show e + ] + + , testGroup "with tests" + [ testCase "Check the interactive library and executable workflow" $ do + let inputs = fromList + -- package type + [ "3" + -- package dir + , "test-package" + -- package description + -- cabal version + , "4" + -- package name + , "test-package" + , "test-package" + -- version + , "3.1.2.3" + -- license + , "3" + -- author + , "Foobar" + -- email + , "foobar@qux.com" + -- homepage + , "qux.com" + -- synopsis + , "Qux's package" + -- category + , "3" + -- library target + -- source dir + , "1" + -- language + , "2" + -- executable target + -- main file + , "1" + -- application dir + , "2" + -- language + , "2" + -- test target + -- main file + , "1" + -- test dir + , "test" + -- language + , "1" + -- comments + , "y" + ] + + case (_runPrompt $ createProject silent pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of + Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do + _optOverwrite opts @?= False + _optMinimal opts @?= False + _optNoComments opts @?= False + _optVerbosity opts @?= silent + _optPkgDir opts @?= "/home/test/test-package" + _optPkgType opts @?= LibraryAndExecutable + _optPkgName opts @?= mkPackageName "test-package" + + _pkgCabalVersion desc @?= CabalSpecV2_4 + _pkgName desc @?= mkPackageName "test-package" + _pkgVersion desc @?= mkVersion [3,1,2,3] + _pkgLicense desc @?! SPDX.NONE + _pkgAuthor desc @?= "Foobar" + _pkgEmail desc @?= "foobar@qux.com" + _pkgHomePage desc @?= "qux.com" + _pkgSynopsis desc @?= "Qux's package" + _pkgCategory desc @?= "Control" + _pkgExtraSrcFiles desc @?= "CHANGELOG.md" :| [] + + _libSourceDirs lib @?= ["src"] + _libLanguage lib @?= Haskell98 + _libExposedModules lib @?= myLibModule :| [] + _libOtherModules lib @?= [] + _libOtherExts lib @?= [] + _libDependencies lib @?! [] + _libBuildTools lib @?= [] + + _exeMainIs exe @?= HsFilePath "Main.hs" Standard + _exeApplicationDirs exe @?= ["exe"] + _exeLanguage exe @?= Haskell98 + _exeOtherModules exe @?= [] + _exeOtherExts exe @?= [] + _exeDependencies exe @?! [] + _exeBuildTools exe @?= [] + + _testMainIs test @?= HsFilePath "Main.hs" Standard + _testDirs test @?= ["test"] + _testLanguage test @?= Haskell2010 + _testOtherModules test @?= [] + _testOtherExts test @?= [] + _testDependencies test @?! [] + _testBuildTools test @?= [] + + Right (ProjectSettings _ _ lib exe test, _) -> do + lib @?! Nothing + exe @?! Nothing + test @?! Nothing + Left e -> assertFailure $ show e + + , testCase "Check the interactive library workflow" $ do + let inputs = fromList + -- package type + [ "1" + -- package dir + , "test-package" + -- package description + -- cabal version + , "4" + -- package name + , "test-package" + , "test-package" + -- version + , "3.1.2.3" + -- license + , "3" + -- author + , "Foobar" + -- email + , "foobar@qux.com" + -- homepage + , "qux.com" + -- synopsis + , "Qux's package" + -- category + , "3" + -- library target + -- source dir + , "1" + -- language + , "2" + -- test target + -- main file + , "1" + -- test dir + , "test" + -- language + , "1" + -- comments + , "y" + ] + + case (_runPrompt $ createProject silent pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of + Right (ProjectSettings opts desc (Just lib) Nothing (Just test), _) -> do + _optOverwrite opts @?= False + _optMinimal opts @?= False + _optNoComments opts @?= False + _optVerbosity opts @?= silent + _optPkgDir opts @?= "/home/test/test-package" + _optPkgType opts @?= Library + _optPkgName opts @?= mkPackageName "test-package" + + _pkgCabalVersion desc @?= CabalSpecV2_4 + _pkgName desc @?= mkPackageName "test-package" + _pkgVersion desc @?= mkVersion [3,1,2,3] + _pkgLicense desc @?! SPDX.NONE + _pkgAuthor desc @?= "Foobar" + _pkgEmail desc @?= "foobar@qux.com" + _pkgHomePage desc @?= "qux.com" + _pkgSynopsis desc @?= "Qux's package" + _pkgCategory desc @?= "Control" + _pkgExtraSrcFiles desc @?= "CHANGELOG.md" :| [] + + _libSourceDirs lib @?= ["src"] + _libLanguage lib @?= Haskell98 + _libExposedModules lib @?= myLibModule :| [] + _libOtherModules lib @?= [] + _libOtherExts lib @?= [] + _libDependencies lib @?! [] + _libBuildTools lib @?= [] + + _testMainIs test @?= HsFilePath "Main.hs" Standard + _testDirs test @?= ["test"] + _testLanguage test @?= Haskell2010 + _testOtherModules test @?= [] + _testOtherExts test @?= [] + _testDependencies test @?! [] + _testBuildTools test @?= [] + + Right (ProjectSettings _ _ lib exe test, _) -> do + lib @?! Nothing + exe @?= Nothing + test @?! Nothing + Left e -> assertFailure $ show e + ] + , testGroup "without tests" + [ testCase "Check the interactive library and executable workflow" $ do + let inputs = fromList + -- package type + [ "3" + -- package dir + , "test-package" + -- package description + -- cabal version + , "4" + -- package name + , "test-package" + , "test-package" + -- version + , "3.1.2.3" + -- license + , "3" + -- author + , "Foobar" + -- email + , "foobar@qux.com" + -- homepage + , "qux.com" + -- synopsis + , "Qux's package" + -- category + , "3" + -- library target + -- source dir + , "1" + -- language + , "2" + -- executable target + -- main file + , "1" + -- application dir + , "2" + -- language + , "2" + -- test suite + , "n" + -- comments + , "y" + ] + + case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + Right (ProjectSettings opts desc (Just lib) (Just exe) Nothing, _) -> do + _optOverwrite opts @?= False + _optMinimal opts @?= False + _optNoComments opts @?= False + _optVerbosity opts @?= silent + _optPkgDir opts @?= "/home/test/test-package" + _optPkgType opts @?= LibraryAndExecutable + _optPkgName opts @?= mkPackageName "test-package" + + _pkgCabalVersion desc @?= CabalSpecV2_4 + _pkgName desc @?= mkPackageName "test-package" + _pkgVersion desc @?= mkVersion [3,1,2,3] + _pkgLicense desc @?! SPDX.NONE + _pkgAuthor desc @?= "Foobar" + _pkgEmail desc @?= "foobar@qux.com" + _pkgHomePage desc @?= "qux.com" + _pkgSynopsis desc @?= "Qux's package" + _pkgCategory desc @?= "Control" + _pkgExtraSrcFiles desc @?= "CHANGELOG.md" :| [] + + _libSourceDirs lib @?= ["src"] + _libLanguage lib @?= Haskell98 + _libExposedModules lib @?= myLibModule :| [] + _libOtherModules lib @?= [] + _libOtherExts lib @?= [] + _libDependencies lib @?! [] + _libBuildTools lib @?= [] + + _exeMainIs exe @?= HsFilePath "Main.hs" Standard + _exeApplicationDirs exe @?= ["exe"] + _exeLanguage exe @?= Haskell98 + _exeOtherModules exe @?= [] + _exeOtherExts exe @?= [] + _exeDependencies exe @?! [] + _exeBuildTools exe @?= [] + + Right (ProjectSettings _ _ lib exe test, _) -> do + lib @?! Nothing + exe @?! Nothing + test @?= Nothing + Left e -> assertFailure $ show e + + , testCase "Check the interactive library workflow" $ do + let inputs = fromList + -- package type + [ "1" + -- package dir + , "test-package" + -- package description + -- cabal version + , "4" + -- package name + , "test-package" + , "test-package" + -- version + , "3.1.2.3" + -- license + , "3" + -- author + , "Foobar" + -- email + , "foobar@qux.com" + -- homepage + , "qux.com" + -- synopsis + , "Qux's package" + -- category + , "3" + -- library target + -- source dir + , "1" + -- language + , "2" + -- test suite + , "n" + -- comments + , "y" + ] + + case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + Right (ProjectSettings opts desc (Just lib) Nothing Nothing, _) -> do + _optOverwrite opts @?= False + _optMinimal opts @?= False + _optNoComments opts @?= False + _optVerbosity opts @?= silent + _optPkgDir opts @?= "/home/test/test-package" + _optPkgType opts @?= Library + _optPkgName opts @?= mkPackageName "test-package" + + _pkgCabalVersion desc @?= CabalSpecV2_4 + _pkgName desc @?= mkPackageName "test-package" + _pkgVersion desc @?= mkVersion [3,1,2,3] + _pkgLicense desc @?! SPDX.NONE + _pkgAuthor desc @?= "Foobar" + _pkgEmail desc @?= "foobar@qux.com" + _pkgHomePage desc @?= "qux.com" + _pkgSynopsis desc @?= "Qux's package" + _pkgCategory desc @?= "Control" + _pkgExtraSrcFiles desc @?= "CHANGELOG.md" :| [] + + _libSourceDirs lib @?= ["src"] + _libLanguage lib @?= Haskell98 + _libExposedModules lib @?= myLibModule :| [] + _libOtherModules lib @?= [] + _libOtherExts lib @?= [] + _libDependencies lib @?! [] + _libBuildTools lib @?= [] + + Right (ProjectSettings _ _ lib exe test, _) -> do + lib @?! Nothing + exe @?= Nothing + test @?= Nothing + Left e -> assertFailure $ show e + + , testCase "Check the interactive executable workflow" $ do + let inputs = fromList + -- package type + [ "2" + -- package dir + , "test-package" + -- package description + -- cabal version + , "4" + -- package name + , "test-package" + , "test-package" + -- version + , "3.1.2.3" + -- license + , "3" + -- author + , "Foobar" + -- email + , "foobar@qux.com" + -- homepage + , "qux.com" + -- synopsis + , "Qux's package" + -- category + , "3" + -- executable target + -- main file + , "1" + -- application dir + , "2" + -- language + , "2" + -- comments + , "y" + ] + + case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + Right (ProjectSettings opts desc Nothing (Just exe) Nothing, _) -> do + _optOverwrite opts @?= False + _optMinimal opts @?= False + _optNoComments opts @?= False + _optVerbosity opts @?= silent + _optPkgDir opts @?= "/home/test/test-package" + _optPkgType opts @?= Executable + _optPkgName opts @?= mkPackageName "test-package" + + _pkgCabalVersion desc @?= CabalSpecV2_4 + _pkgName desc @?= mkPackageName "test-package" + _pkgVersion desc @?= mkVersion [3,1,2,3] + _pkgLicense desc @?! SPDX.NONE + _pkgAuthor desc @?= "Foobar" + _pkgEmail desc @?= "foobar@qux.com" + _pkgHomePage desc @?= "qux.com" + _pkgSynopsis desc @?= "Qux's package" + _pkgCategory desc @?= "Control" + _pkgExtraSrcFiles desc @?= "CHANGELOG.md" :| [] + + _exeMainIs exe @?= HsFilePath "Main.hs" Standard + _exeApplicationDirs exe @?= ["exe"] + _exeLanguage exe @?= Haskell98 + _exeOtherModules exe @?= [] + _exeOtherExts exe @?= [] + _exeDependencies exe @?! [] + _exeBuildTools exe @?= [] + + Right (ProjectSettings _ _ lib exe test, _) -> do + lib @?= Nothing + exe @?! Nothing + test @?= Nothing + Left e -> assertFailure $ show e + ] + ] + +fileCreatorTests :: InstalledPackageIndex -> SourcePackageDb -> PackageName -> TestTree +fileCreatorTests pkgIx srcDb _pkgName = testGroup "generators" + [ testGroup "genPkgDescription" + [ testCase "Check common package flags workflow" $ do + let inputs = fromList + [ "1" -- pick the first cabal version in the list + , "my-test-package" -- package name + , "y" -- "yes to prompt internal to package name" + , "0.2.0.1" -- package version + , "2" -- pick the second license in the list + , "Foobar" -- author name + , "foobar@qux.com" -- maintainer email + , "qux.com" -- package homepage + , "Qux's package" -- package synopsis + , "3" -- pick the third category in the list + ] + runGenTest inputs $ genPkgDescription emptyFlags srcDb + ] + , testGroup "genLibTarget" + [ testCase "Check library package flags workflow" $ do + let inputs = fromList + [ "1" -- pick the first source directory in the list + , "2" -- pick the second language in the list + ] + + runGenTest inputs $ genLibTarget emptyFlags pkgIx + ] + , testGroup "genExeTarget" + [ testCase "Check executable package flags workflow" $ do + let inputs = fromList + [ "1" -- pick the first main file option in the list + , "2" -- pick the second application directory in the list + , "1" -- pick the first language in the list + ] + + runGenTest inputs $ genExeTarget emptyFlags pkgIx + ] + , testGroup "genTestTarget" + [ testCase "Check test package flags workflow" $ do + let inputs = fromList + [ "1" -- pick the first main file option in the list + , "test" -- package test dir + , "1" -- pick the first language in the list + ] + + runGenTest inputs $ genTestTarget + (emptyFlags {initializeTestSuite = Flag True}) pkgIx + ] + ] + where + runGenTest inputs go = case _runPrompt go inputs of + Left e -> assertFailure $ show e + Right{} -> return () + +interactiveTests :: SourcePackageDb -> TestTree +interactiveTests srcDb = testGroup "Check top level getter functions" + [ testGroup "Simple prompt tests" + [ testGroup "Check packageNamePrompt output" + [ testSimplePrompt "New package name 1" + (packageNamePrompt srcDb) (mkPackageName "test-package") + [ "test-package" + , "test-package" + ] + , testSimplePrompt "New package name 2" + (packageNamePrompt srcDb) (mkPackageName "test-package") + [ "test-package" + , "" + ] + , testSimplePrompt "Existing package name 1" + (packageNamePrompt srcDb) (mkPackageName "test-package") + [ "test-package" + , "cabal-install" + , "y" + , "test-package" + ] + , testSimplePrompt "Existing package name 2" + (packageNamePrompt srcDb) (mkPackageName "cabal-install") + [ "test-package" + , "cabal-install" + , "n" + ] + ] + , testGroup "Check mainFilePrompt output" + [ testSimplePrompt "New valid main file" + mainFilePrompt defaultMainIs + [ "1" + ] + , testSimplePrompt "New valid other main file" + mainFilePrompt (HsFilePath "Main.hs" Standard) + [ "3" + , "Main.hs" + ] + , testSimplePrompt "Invalid other main file" + mainFilePrompt (HsFilePath "Main.lhs" Literate) + [ "3" + , "Yoink.jl" + , "2" + ] + ] + , testGroup "Check versionPrompt output" + [ testSimplePrompt "Proper PVP" + versionPrompt (mkVersion [0,3,1,0]) + [ "0.3.1.0" + ] + , testSimplePrompt "No PVP" + versionPrompt (mkVersion [0,3,1,0]) + [ "yee-haw" + , "0.3.1.0" + ] + ] + , testGroup "Check synopsisPrompt output" + [ testSimplePrompt "1" synopsisPrompt + "We are Qux, and this is our package" ["We are Qux, and this is our package"] + , testSimplePrompt "2" synopsisPrompt + "Resistance is futile, you will be assimilated" ["Resistance is futile, you will be assimilated"] + ] + , testSimplePrompt "Check authorPrompt output" authorPrompt + "Foobar" ["Foobar"] + , testSimplePrompt "Check emailPrompt output" emailPrompt + "foobar@qux.com" ["foobar@qux.com"] + , testSimplePrompt "Check homepagePrompt output" homepagePrompt + "qux.com" ["qux.com"] + , testSimplePrompt "Check testDirsPrompt output" testDirsPrompt + ["quxTest"] ["quxTest"] + -- this tests 4) other, and can be used to model more inputs in case of failure + , testSimplePrompt "Check srcDirsPrompt output" srcDirsPrompt + ["app"] ["4", "app"] + ] + , testGroup "Numbered prompt tests" + [ testGroup "Check categoryPrompt output" + [ testNumberedPrompt "Category indices" categoryPrompt + defaultCategories + , testSimplePrompt "Other category" + categoryPrompt "Unlisted" + [ show $ P.length defaultCategories + 1 + , "Unlisted" + ] + , testSimplePrompt "No category" + categoryPrompt "" + [ "" + ] + ] + , testGroup "Check licensePrompt output" $ let other = show (1 + P.length defaultLicenseIds) in + [ testNumberedPrompt "License indices" licensePrompt $ + fmap (\l -> SPDX.License $ SPDX.ELicense (SPDX.ELicenseId l) Nothing) defaultLicenseIds + , testSimplePrompt "Other license 1" + licensePrompt (mkLicense SPDX.CC_BY_NC_ND_4_0) + [ other + , "CC-BY-NC-ND-4.0" + ] + , testSimplePrompt "Other license 2" + licensePrompt (mkLicense SPDX.D_FSL_1_0) + [ other + , "D-FSL-1.0" + ] + , testSimplePrompt "Other license 3" + licensePrompt (mkLicense SPDX.NPOSL_3_0) + [ other + , "NPOSL-3.0" + ] + , testSimplePrompt "Invalid license" + licensePrompt SPDX.NONE + [ other + , "yay" + , other + , "NONE" + ] + , testPromptBreak "Invalid index" + licensePrompt + [ "42" + ] + ] + , testGroup "Check languagePrompt output" + [ testNumberedPrompt "Language indices" (`languagePrompt` "test") + [Haskell2010, Haskell98] + , testSimplePrompt "Other language" + (`languagePrompt` "test") (UnknownLanguage "Haskell2022") + [ "3" + , "Haskell2022" + ] + , testSimplePrompt "Invalid language" + (`languagePrompt` "test") Haskell2010 + [ "3" + , "Lang_TS!" + , "1" + ] + ] + , testGroup "Check srcDirsPrompt output" + [ testNumberedPrompt "Soruce dirs indices" srcDirsPrompt + [[defaultSourceDir], ["lib"], ["src-lib"]] + , testSimplePrompt "Other source dir" + srcDirsPrompt ["src"] + [ "4" + , "src" + ] + ] + , testGroup "Check appDirsPrompt output" + [ testNumberedPrompt "App dirs indices" appDirsPrompt + [[defaultApplicationDir], ["exe"], ["src-exe"]] + , testSimplePrompt "Other app dir" + appDirsPrompt ["app"] + [ "4" + , "app" + ] + ] + , testNumberedPrompt "Check packageTypePrompt output" packageTypePrompt + [Library, Executable, LibraryAndExecutable] + , testNumberedPrompt "Check cabalVersionPrompt output" cabalVersionPrompt + defaultCabalVersions + ] + , testGroup "Bool prompt tests" + [ testBoolPrompt "Check noCommentsPrompt output - y" noCommentsPrompt False "y" + , testBoolPrompt "Check noCommentsPrompt output - Y" noCommentsPrompt False "Y" + , testBoolPrompt "Check noCommentsPrompt output - n" noCommentsPrompt True "n" + , testBoolPrompt "Check noCommentsPrompt output - N" noCommentsPrompt True "N" + ] + ] + + + +-- -------------------------------------------------------------------- -- +-- Prompt test utils + + +testSimplePrompt + :: Eq a + => Show a + => String + -> (InitFlags -> PurePrompt a) + -> a + -> [String] + -> TestTree +testSimplePrompt label f target = + testPrompt label f (assertFailure . show) (\(a,_) -> target @=? a) + +testPromptBreak + :: Eq a + => Show a + => String + -> (InitFlags -> PurePrompt a) + -> [String] + -> TestTree +testPromptBreak label f = + testPrompt label f go (assertFailure . show) + where + go BreakException{} = + return () + +testPrompt + :: Eq a + => Show a + => String + -> (InitFlags -> PurePrompt a) + -> (BreakException -> Assertion) + -> ((a, NonEmpty String) -> Assertion) + -> [String] + -> TestTree +testPrompt label f g h input = testCase label $ + case (_runPrompt $ f emptyFlags) (fromList input) of + Left x -> g x -- :: BreakException + Right x -> h x -- :: (a, other inputs) + +testNumberedPrompt :: (Eq a, Show a) => String -> (InitFlags -> PurePrompt a) -> [a] -> TestTree +testNumberedPrompt label act = testGroup label . (++ goBreak) . fmap go . indexed1 + where + indexed1 = zip [1 :: Int ..] + mkLabel a n = "testing index " + ++ show n + ++ ") with: " + ++ show a + + go (n, a) = + testSimplePrompt (mkLabel a n) act a [show n] + goBreak = + [ testPromptBreak "testing index -1" act ["-1"] + , testPromptBreak "testing index 1000" act ["1000"] + ] + +testBoolPrompt + :: String + -> (InitFlags -> PurePrompt Bool) + -> Bool + -> String + -> TestTree +testBoolPrompt label act target b = + testSimplePrompt label act target [b] diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs new file mode 100644 index 00000000000..69e38d31609 --- /dev/null +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs @@ -0,0 +1,1158 @@ +module UnitTests.Distribution.Client.Init.NonInteractive + ( tests + ) where + +import Test.Tasty +import Test.Tasty.HUnit + +import UnitTests.Distribution.Client.Init.Utils + +import qualified Data.List.NonEmpty as NEL +import qualified Distribution.SPDX as SPDX + +import Distribution.Client.Init.Defaults +import Distribution.Client.Init.NonInteractive.Command +import Distribution.Client.Init.Types +import Distribution.Client.Types +import Distribution.Simple +import Distribution.Simple.PackageIndex +import Distribution.Verbosity +import Distribution.CabalSpecVersion +import Distribution.ModuleName (fromString) +import Distribution.Simple.Flag + +tests + :: Verbosity + -> InitFlags + -> Compiler + -> InstalledPackageIndex + -> SourcePackageDb + -> TestTree +tests _v _initFlags _comp pkgIx srcDb = + testGroup "cabal init non-interactive" + [ testGroup "driver function test" + [ driverFunctionTest pkgIx srcDb + ] + , testGroup "target creator tests" + [ fileCreatorTests pkgIx srcDb + ] + , testGroup "non-interactive tests" + [ nonInteractiveTests pkgIx srcDb + ] + ] + +driverFunctionTest + :: InstalledPackageIndex + -> SourcePackageDb + -> TestTree +driverFunctionTest pkgIx srcDb = testGroup "createProject" + [ testGroup "with flags" + [ testCase "Check the non-interactive workflow 1" $ do + let dummyFlags' = dummyFlags + { packageType = Flag LibraryAndExecutable + , minimal = Flag False + , overwrite = Flag False + , packageDir = Flag "/home/test/test-package" + , extraSrc = Flag ["CHANGELOG.md"] + , exposedModules = Flag [] + , otherModules = Flag [] + , otherExts = Flag [] + , buildTools = Flag [] + , mainIs = Flag "quxApp/Main.hs" + , dependencies = Flag [] + } + inputs = NEL.fromList + [ "[\"quxTest/Main.hs\"]" + ] + + case (_runPrompt $ createProject silent pkgIx srcDb dummyFlags') inputs of + Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do + _optOverwrite opts @?= False + _optMinimal opts @?= False + _optNoComments opts @?= True + _optVerbosity opts @?= silent + _optPkgDir opts @?= "/home/test/test-package" + _optPkgType opts @?= LibraryAndExecutable + _optPkgName opts @?= mkPackageName "QuxPackage" + + _pkgCabalVersion desc @?= CabalSpecV2_2 + _pkgName desc @?= mkPackageName "QuxPackage" + _pkgVersion desc @?= mkVersion [4,2,6] + _pkgLicense desc @?! SPDX.NONE + _pkgAuthor desc @?= "Foobar" + _pkgEmail desc @?= "foobar@qux.com" + _pkgHomePage desc @?= "qux.com" + _pkgSynopsis desc @?= "We are Qux, and this is our package" + _pkgCategory desc @?= "Control" + _pkgExtraSrcFiles desc @?= "CHANGELOG.md" NEL.:| [] + + _libSourceDirs lib @?= ["quxSrc"] + _libLanguage lib @?= Haskell98 + _libExposedModules lib @?= myLibModule NEL.:| [] + _libOtherModules lib @?= [] + _libOtherExts lib @?= [] + _libDependencies lib @?= [] + _libBuildTools lib @?= [] + + _exeMainIs exe @?= HsFilePath "quxApp/Main.hs" Standard + _exeApplicationDirs exe @?= ["quxApp"] + _exeLanguage exe @?= Haskell98 + _exeOtherModules exe @?= [] + _exeOtherExts exe @?= [] + _exeDependencies exe @?= [] + _exeBuildTools exe @?= [] + + _testMainIs test @?= HsFilePath "quxTest/Main.hs" Standard + _testDirs test @?= ["quxTest"] + _testLanguage test @?= Haskell98 + _testOtherModules test @?= [] + _testOtherExts test @?= [] + _testDependencies test @?= [] + _testBuildTools test @?= [] + + Right (ProjectSettings _ _ lib exe test, _) -> do + lib @?! Nothing + exe @?! Nothing + test @?! Nothing + Left e -> assertFailure $ show e + + , testCase "Check the non-interactive workflow 2" $ do + let dummyFlags' = dummyFlags + { packageType = Flag LibraryAndExecutable + , minimal = Flag False + , overwrite = Flag False + , packageDir = Flag "/home/test/test-package" + , extraSrc = Flag [] + , exposedModules = Flag [] + , otherModules = NoFlag + , otherExts = Flag [] + , buildTools = Flag [] + , mainIs = Flag "quxApp/Main.hs" + , dependencies = Flag [] + } + inputs = NEL.fromList + -- extra sources + [ "[\"CHANGELOG.md\"]" + -- lib other modules + , "False" + -- exe other modules + , "False" + -- test main file + , "[\"quxTest/Main.hs\"]" + -- test other modules + , "False" + ] + + case (_runPrompt $ createProject silent pkgIx srcDb dummyFlags') inputs of + Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do + _optOverwrite opts @?= False + _optMinimal opts @?= False + _optNoComments opts @?= True + _optVerbosity opts @?= silent + _optPkgDir opts @?= "/home/test/test-package" + _optPkgType opts @?= LibraryAndExecutable + _optPkgName opts @?= mkPackageName "QuxPackage" + + _pkgCabalVersion desc @?= CabalSpecV2_2 + _pkgName desc @?= mkPackageName "QuxPackage" + _pkgVersion desc @?= mkVersion [4,2,6] + _pkgLicense desc @?! SPDX.NONE + _pkgAuthor desc @?= "Foobar" + _pkgEmail desc @?= "foobar@qux.com" + _pkgHomePage desc @?= "qux.com" + _pkgSynopsis desc @?= "We are Qux, and this is our package" + _pkgCategory desc @?= "Control" + _pkgExtraSrcFiles desc @?= "CHANGELOG.md" NEL.:| [] + + _libSourceDirs lib @?= ["quxSrc"] + _libLanguage lib @?= Haskell98 + _libExposedModules lib @?= myLibModule NEL.:| [] + _libOtherModules lib @?= [] + _libOtherExts lib @?= [] + _libDependencies lib @?= [] + _libBuildTools lib @?= [] + + _exeMainIs exe @?= HsFilePath "quxApp/Main.hs" Standard + _exeApplicationDirs exe @?= ["quxApp"] + _exeLanguage exe @?= Haskell98 + _exeOtherModules exe @?= [] + _exeOtherExts exe @?= [] + _exeDependencies exe @?= [] + _exeBuildTools exe @?= [] + + _testMainIs test @?= HsFilePath "quxTest/Main.hs" Standard + _testDirs test @?= ["quxTest"] + _testLanguage test @?= Haskell98 + _testOtherModules test @?= [] + _testOtherExts test @?= [] + _testDependencies test @?= [] + _testBuildTools test @?= [] + + Right (ProjectSettings _ _ lib exe test, _) -> do + lib @?! Nothing + exe @?! Nothing + test @?! Nothing + Left e -> assertFailure $ show e + ] + , testGroup "with tests" + [ testCase "Check the non-interactive library and executable workflow" $ do + let inputs = NEL.fromList + -- package type + [ "test-package" + , "[\".\", \"..\", \"src/\", \"app/Main.hs\"]" + -- package dir + , "test-package" + -- package description + -- cabal version + , "cabal-install version 3.4.0.0\ncompiled using version 3.4.0.0 of the Cabal library \n" + -- package name + , "test-package" + , "test-package" + -- author name + , "" + , "Foobar" + -- author email + , "" + , "foobar@qux.com" + -- extra source files + , "test-package" + , "[]" + -- library target + -- source dirs + , "src" + , "True" + -- language + , "The Glorious Glasgow Haskell Compilation System, version 8.8.4" + -- exposed modules + , "src" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + , "test-package" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + -- other modules + , "test-package" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\", \"src/Baz/Internal.hs\"]" + , "module Foo where" + , "module Bar where" + , "module Baz.Internal where" + -- other extensions + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" + , "\"{-# LANGUAGE RecordWildCards #-}\"" + -- dependencies + , "[\"src/Foo.hs\"]" + , "test-package" + , "module Main where" + , "import Control.Monad.Extra" + , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" + -- build tools + , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" + -- executable target + -- application dirs + , "app" + , "[]" + -- main file + , "test-package" + , "[\"test-package/app/\"]" + , "[]" + -- language + , "The Glorious Glasgow Haskell Compilation System, version 7.10.3" + -- other modules + , "test-package" + , "True" + , "[\"app/Main.hs\", \"app/Foo.hs\", \"app/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + -- other extensions + , "[\"app/Foo.hs\", \"app/Bar.hs\"]" + , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" + , "\"{-# LANGUAGE RecordWildCards #-}\"" + -- dependencies + , "[\"app/Main.hs\"]" + , "test-package" + , "module Main where" + , "import Control.Monad.Extra" + , "{-# LANGUAGE OverloadedStrings, DataKinds #-}" + -- build tools + , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" + -- test target + -- main file + , "[\"test-package/test/\"]" + -- language + , "The Glorious Glasgow Haskell Compilation System, version 7.10.3" + -- other modules + , "test-package" + , "True" + , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + -- other extensions + , "[\"test/Foo.hs\", \"test/Bar.hs\"]" + , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" + , "\"{-# LANGUAGE RecordWildCards #-}\"" + -- dependencies + , "[\"test/Main.hs\"]" + , "test-package" + , "module Main where" + , "import Test.Tasty\nimport Test.Tasty.HUnit" + , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" + -- build tools + , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/bar.y\"]" + ] + + case (_runPrompt $ createProject silent pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of + Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do + _optOverwrite opts @?= False + _optMinimal opts @?= False + _optNoComments opts @?= False + _optVerbosity opts @?= silent + _optPkgDir opts @?= "/home/test/test-package" + _optPkgType opts @?= LibraryAndExecutable + _optPkgName opts @?= mkPackageName "test-package" + + _pkgCabalVersion desc @?= CabalSpecV3_4 + _pkgName desc @?= mkPackageName "test-package" + _pkgVersion desc @?= mkVersion [0,1,0,0] + _pkgLicense desc @?= SPDX.NONE + _pkgAuthor desc @?= "Foobar" + _pkgEmail desc @?= "foobar@qux.com" + _pkgHomePage desc @?= "" + _pkgSynopsis desc @?= "" + _pkgCategory desc @?= "(none)" + _pkgExtraSrcFiles desc @?= "CHANGELOG.md" NEL.:| [] + + _libSourceDirs lib @?= ["src"] + _libLanguage lib @?= Haskell2010 + _libExposedModules lib @?= NEL.fromList (map fromString ["Foo", "Bar"]) + _libOtherModules lib @?= map fromString ["Baz.Internal"] + _libOtherExts lib @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] + _libDependencies lib @?! [] + _libBuildTools lib @?= ["happy"] + + _exeMainIs exe @?= HsFilePath "Main.hs" Standard + _exeApplicationDirs exe @?= ["app"] + _exeLanguage exe @?= Haskell2010 + _exeOtherModules exe @?= map fromString ["Foo", "Bar"] + _exeOtherExts exe @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] + _exeDependencies exe @?! [] + _exeBuildTools exe @?= ["happy"] + + _testMainIs test @?= HsFilePath "Main.hs" Standard + _testDirs test @?= ["test"] + _testLanguage test @?= Haskell2010 + _testOtherModules test @?= map fromString ["Foo", "Bar"] + _testOtherExts test @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] + _testDependencies test @?! [] + _testBuildTools test @?= ["happy"] + + Right (ProjectSettings _ _ lib exe test, _) -> do + lib @?! Nothing + exe @?! Nothing + test @?! Nothing + Left e -> assertFailure $ show e + + , testCase "Check the non-interactive library workflow" $ do + let inputs = NEL.fromList + -- package type + [ "test-package" + , "[\".\", \"..\", \"src/\", \"test/Main.hs\"]" + -- package dir + , "test-package" + -- package description + -- cabal version + , "cabal-install version 3.4.0.0\ncompiled using version 3.4.0.0 of the Cabal library \n" + -- package name + , "test-package" + , "test-package" + -- author name + , "Foobar" + -- author email + , "foobar@qux.com" + -- extra source files + , "test-package" + , "[]" + -- library target + -- source dirs + , "src" + , "True" + -- language + , "The Glorious Glasgow Haskell Compilation System, version 8.8.4" + -- exposed modules + , "src" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + , "test-package" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + -- other modules + , "test-package" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\", \"src/Baz/Internal.hs\"]" + , "module Foo where" + , "module Bar where" + , "module Baz.Internal where" + -- other extensions + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" + , "\"{-# LANGUAGE RecordWildCards #-}\"" + -- dependencies + , "[\"src/Foo.hs\"]" + , "test-package" + , "module Main where" + , "import Control.Monad.Extra" + , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" + -- build tools + , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" + -- test target + -- main file + , "[\"test-package/test/\"]" + -- language + , "The Glorious Glasgow Haskell Compilation System, version 7.10.3" + -- other modules + , "test-package" + , "True" + , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + -- other extensions + , "[\"test/Foo.hs\", \"test/Bar.hs\"]" + , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" + , "\"{-# LANGUAGE RecordWildCards #-}\"" + -- dependencies + , "[\"test/Main.hs\"]" + , "test-package" + , "module Main where" + , "import Test.Tasty\nimport Test.Tasty.HUnit" + , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" + -- build tools + , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/bar.y\"]" + ] + + case (_runPrompt $ createProject silent pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of + Right (ProjectSettings opts desc (Just lib) Nothing (Just test), _) -> do + _optOverwrite opts @?= False + _optMinimal opts @?= False + _optNoComments opts @?= False + _optVerbosity opts @?= silent + _optPkgDir opts @?= "/home/test/test-package" + _optPkgType opts @?= Library + _optPkgName opts @?= mkPackageName "test-package" + + _pkgCabalVersion desc @?= CabalSpecV3_4 + _pkgName desc @?= mkPackageName "test-package" + _pkgVersion desc @?= mkVersion [0,1,0,0] + _pkgLicense desc @?= SPDX.NONE + _pkgAuthor desc @?= "Foobar" + _pkgEmail desc @?= "foobar@qux.com" + _pkgHomePage desc @?= "" + _pkgSynopsis desc @?= "" + _pkgCategory desc @?= "(none)" + _pkgExtraSrcFiles desc @?= "CHANGELOG.md" NEL.:| [] + + _libSourceDirs lib @?= ["src"] + _libLanguage lib @?= Haskell2010 + _libExposedModules lib @?= NEL.fromList (map fromString ["Foo", "Bar"]) + _libOtherModules lib @?= map fromString ["Baz.Internal"] + _libOtherExts lib @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] + _libDependencies lib @?! [] + _libBuildTools lib @?= ["happy"] + + _testMainIs test @?= HsFilePath "Main.hs" Standard + _testDirs test @?= ["test"] + _testLanguage test @?= Haskell2010 + _testOtherModules test @?= map fromString ["Foo", "Bar"] + _testOtherExts test @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] + _testDependencies test @?! [] + _testBuildTools test @?= ["happy"] + + Right (ProjectSettings _ _ lib exe test, _) -> do + lib @?! Nothing + exe @?= Nothing + test @?! Nothing + Left e -> assertFailure $ show e + ] + , testGroup "without tests" + [ testCase "Check the non-interactive library and executable workflow" $ do + let inputs = NEL.fromList + -- package type + [ "test-package" + , "[\".\", \"..\", \"src/\", \"app/Main.hs\"]" + -- package dir + , "test-package" + -- package description + -- cabal version + , "cabal-install version 3.4.0.0\ncompiled using version 3.4.0.0 of the Cabal library \n" + -- package name + , "test-package" + , "test-package" + -- author name + , "" + , "Foobar" + -- author email + , "" + , "foobar@qux.com" + -- extra source files + , "test-package" + , "[]" + -- library target + -- source dirs + , "src" + , "True" + -- language + , "The Glorious Glasgow Haskell Compilation System, version 8.8.4" + -- exposed modules + , "src" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + , "test-package" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + -- other modules + , "test-package" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\", \"src/Baz/Internal.hs\"]" + , "module Foo where" + , "module Bar where" + , "module Baz.Internal where" + -- other extensions + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" + , "\"{-# LANGUAGE RecordWildCards #-}\"" + -- dependencies + , "[\"src/Foo.hs\"]" + , "test-package" + , "module Main where" + , "import Control.Monad.Extra" + , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" + -- build tools + , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" + -- executable target + -- application dirs + , "app" + , "[]" + -- main file + , "test-package" + , "[\"test-package/app/\"]" + , "[]" + -- language + , "The Glorious Glasgow Haskell Compilation System, version 7.10.3" + -- other modules + , "test-package" + , "True" + , "[\"app/Main.hs\", \"app/Foo.hs\", \"app/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + -- other extensions + , "[\"app/Foo.hs\", \"app/Bar.hs\"]" + , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" + , "\"{-# LANGUAGE RecordWildCards #-}\"" + -- dependencies + , "[\"app/Main.hs\"]" + , "test-package" + , "module Main where" + , "import Control.Monad.Extra" + , "{-# LANGUAGE OverloadedStrings, DataKinds #-}" + -- build tools + , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" + ] + + case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + Right (ProjectSettings opts desc (Just lib) (Just exe) Nothing, _) -> do + _optOverwrite opts @?= False + _optMinimal opts @?= False + _optNoComments opts @?= False + _optVerbosity opts @?= silent + _optPkgDir opts @?= "/home/test/test-package" + _optPkgType opts @?= LibraryAndExecutable + _optPkgName opts @?= mkPackageName "test-package" + + _pkgCabalVersion desc @?= CabalSpecV3_4 + _pkgName desc @?= mkPackageName "test-package" + _pkgVersion desc @?= mkVersion [0,1,0,0] + _pkgLicense desc @?= SPDX.NONE + _pkgAuthor desc @?= "Foobar" + _pkgEmail desc @?= "foobar@qux.com" + _pkgHomePage desc @?= "" + _pkgSynopsis desc @?= "" + _pkgCategory desc @?= "(none)" + _pkgExtraSrcFiles desc @?= "CHANGELOG.md" NEL.:| [] + + _libSourceDirs lib @?= ["src"] + _libLanguage lib @?= Haskell2010 + _libExposedModules lib @?= NEL.fromList (map fromString ["Foo", "Bar"]) + _libOtherModules lib @?= map fromString ["Baz.Internal"] + _libOtherExts lib @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] + _libDependencies lib @?! [] + _libBuildTools lib @?= ["happy"] + + _exeMainIs exe @?= HsFilePath "Main.hs" Standard + _exeApplicationDirs exe @?= ["app"] + _exeLanguage exe @?= Haskell2010 + _exeOtherModules exe @?= map fromString ["Foo", "Bar"] + _exeOtherExts exe @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] + _exeDependencies exe @?! [] + _exeBuildTools exe @?= ["happy"] + + Right (ProjectSettings _ _ lib exe test, _) -> do + lib @?! Nothing + exe @?! Nothing + test @?= Nothing + Left e -> assertFailure $ show e + + , testCase "Check the non-interactive library workflow" $ do + let inputs = NEL.fromList + -- package type + [ "test-package" + , "[\".\", \"..\", \"src/\"]" + -- package dir + , "test-package" + -- package description + -- cabal version + , "cabal-install version 3.4.0.0\ncompiled using version 3.4.0.0 of the Cabal library \n" + -- package name + , "test-package" + , "test-package" + -- author name + , "" + , "Foobar" + -- author email + , "" + , "foobar@qux.com" + -- extra source files + , "test-package" + , "[]" + -- library target + -- source dirs + , "src" + , "True" + -- language + , "The Glorious Glasgow Haskell Compilation System, version 8.8.4" + -- exposed modules + , "src" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + , "test-package" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + -- other modules + , "test-package" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\", \"src/Baz/Internal.hs\"]" + , "module Foo where" + , "module Bar where" + , "module Baz.Internal where" + -- other extensions + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" + , "\"{-# LANGUAGE RecordWildCards #-}\"" + -- dependencies + , "[\"src/Foo.hs\"]" + , "test-package" + , "module Main where" + , "import Control.Monad.Extra" + , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" + -- build tools + , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" + ] + + case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + Right (ProjectSettings opts desc (Just lib) Nothing Nothing, _) -> do + _optOverwrite opts @?= False + _optMinimal opts @?= False + _optNoComments opts @?= False + _optVerbosity opts @?= silent + _optPkgDir opts @?= "/home/test/test-package" + _optPkgType opts @?= Library + _optPkgName opts @?= mkPackageName "test-package" + + _pkgCabalVersion desc @?= CabalSpecV3_4 + _pkgName desc @?= mkPackageName "test-package" + _pkgVersion desc @?= mkVersion [0,1,0,0] + _pkgLicense desc @?= SPDX.NONE + _pkgAuthor desc @?= "Foobar" + _pkgEmail desc @?= "foobar@qux.com" + _pkgHomePage desc @?= "" + _pkgSynopsis desc @?= "" + _pkgCategory desc @?= "(none)" + _pkgExtraSrcFiles desc @?= "CHANGELOG.md" NEL.:| [] + + _libSourceDirs lib @?= ["src"] + _libLanguage lib @?= Haskell2010 + _libExposedModules lib @?= NEL.fromList (map fromString ["Foo", "Bar"]) + _libOtherModules lib @?= map fromString ["Baz.Internal"] + _libOtherExts lib @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] + _libDependencies lib @?! [] + _libBuildTools lib @?= ["happy"] + + Right (ProjectSettings _ _ lib exe test, _) -> do + lib @?! Nothing + exe @?= Nothing + test @?= Nothing + Left e -> assertFailure $ show e + + , testCase "Check the non-interactive executable workflow" $ do + let inputs = NEL.fromList + -- package type + [ "test-package" + , "[\".\", \"..\", \"app/Main.hs\"]" + -- package dir + , "test-package" + -- package description + -- cabal version + , "cabal-install version 3.4.0.0\ncompiled using version 3.4.0.0 of the Cabal library \n" + -- package name + , "test-package" + , "test-package" + -- author name + , "" + , "Foobar" + -- author email + , "" + , "foobar@qux.com" + -- extra source files + , "test-package" + , "[]" + -- executable target + -- application dirs + , "app" + , "[]" + -- main file + , "test-package" + , "[\"test-package/app/\"]" + , "[]" + -- language + , "The Glorious Glasgow Haskell Compilation System, version 7.10.3" + -- other modules + , "test-package" + , "True" + , "[\"app/Main.hs\", \"app/Foo.hs\", \"app/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + -- other extensions + , "[\"app/Foo.hs\", \"app/Bar.hs\"]" + , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" + , "\"{-# LANGUAGE RecordWildCards #-}\"" + -- dependencies + , "[\"app/Main.hs\"]" + , "test-package" + , "module Main where" + , "import Control.Monad.Extra" + , "{-# LANGUAGE OverloadedStrings, DataKinds #-}" + -- build tools + , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" + ] + + case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + Right (ProjectSettings opts desc Nothing (Just exe) Nothing, _) -> do + _optOverwrite opts @?= False + _optMinimal opts @?= False + _optNoComments opts @?= False + _optVerbosity opts @?= silent + _optPkgDir opts @?= "/home/test/test-package" + _optPkgType opts @?= Executable + _optPkgName opts @?= mkPackageName "test-package" + + _pkgCabalVersion desc @?= CabalSpecV3_4 + _pkgName desc @?= mkPackageName "test-package" + _pkgVersion desc @?= mkVersion [0,1,0,0] + _pkgLicense desc @?= SPDX.NONE + _pkgAuthor desc @?= "Foobar" + _pkgEmail desc @?= "foobar@qux.com" + _pkgHomePage desc @?= "" + _pkgSynopsis desc @?= "" + _pkgCategory desc @?= "(none)" + _pkgExtraSrcFiles desc @?= "CHANGELOG.md" NEL.:| [] + + _exeMainIs exe @?= HsFilePath "Main.hs" Standard + _exeApplicationDirs exe @?= ["app"] + _exeLanguage exe @?= Haskell2010 + _exeOtherModules exe @?= map fromString ["Foo", "Bar"] + _exeOtherExts exe @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] + _exeDependencies exe @?! [] + _exeBuildTools exe @?= ["happy"] + + Right (ProjectSettings _ _ lib exe test, _) -> do + lib @?= Nothing + exe @?! Nothing + test @?= Nothing + Left e -> assertFailure $ show e + ] + ] + +fileCreatorTests + :: InstalledPackageIndex + -> SourcePackageDb + -> TestTree +fileCreatorTests pkgIx srcDb = testGroup "generators" + [ testGroup "genPkgDescription" + [ testCase "Check common package flags workflow" $ do + let inputs = NEL.fromList + -- cabal version + [ "cabal-install version 2.4.0.0\ncompiled using version 2.4.0.0 of the Cabal library \n" + -- package name + , "test-package" + , "test-package" + -- author name + , "" + , "Foobar" + -- author email + , "" + , "foobar@qux.com" + -- extra source files + , "test-package" + , "[]" + ] + + case (_runPrompt $ genPkgDescription emptyFlags srcDb) inputs of + Left e -> assertFailure $ show e + Right{} -> return () + ] + , testGroup "genLibTarget" + [ testCase "Check library package flags workflow" $ do + let inputs = NEL.fromList + -- source dirs + [ "src" + , "True" + -- language + , "The Glorious Glasgow Haskell Compilation System, version 7.10.3" + -- exposed modules + , "src" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + , "test-package" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + -- other modules + , "test-package" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\", \"src/Baz/Internal.hs\"]" + , "module Foo where" + , "module Bar where" + , "module Baz.Internal where" + -- other extensions + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" + , "\"{-# LANGUAGE RecordWildCards #-}\"" + -- dependencies + , "[\"src/Foo.hs\"]" + , "test-package" + , "module Main where" + , "import Control.Monad.Extra" + , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" + -- build tools + , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" + ] + + case (_runPrompt $ genLibTarget emptyFlags pkgIx) inputs of + Left e -> assertFailure $ show e + Right{} -> return () + ] + , testGroup "genExeTarget" + [ testCase "Check executable package flags workflow" $ do + let inputs = NEL.fromList + -- application dirs + [ "app" + , "[]" + -- main file + , "test-package" + , "[\"test-package/app/\"]" + , "[]" + -- language + , "The Glorious Glasgow Haskell Compilation System, version 7.10.3" + -- other modules + , "test-package" + , "True" + , "[\"app/Main.hs\", \"app/Foo.hs\", \"app/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + -- other extensions + , "[\"app/Foo.hs\", \"app/Bar.hs\"]" + , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" + , "\"{-# LANGUAGE RecordWildCards #-}\"" + -- dependencies + , "[\"app/Main.hs\"]" + , "test-package" + , "module Main where" + , "import Control.Monad.Extra" + , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" + -- build tools + , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" + ] + + case (_runPrompt $ genExeTarget emptyFlags pkgIx) inputs of + Left e -> assertFailure $ show e + Right{} -> return () + ] + , testGroup "genTestTarget" + [ testCase "Check test package flags workflow" $ do + let inputs = NEL.fromList + -- main file + [ "[]" + -- language + , "The Glorious Glasgow Haskell Compilation System, version 7.10.3" + -- other modules + , "test-package" + , "True" + , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + -- other extensions + , "[\"test/Foo.hs\", \"test/Bar.hs\"]" + , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" + , "\"{-# LANGUAGE RecordWildCards #-}\"" + -- dependencies + , "[\"test/Main.hs\"]" + , "test-package" + , "module Main where" + , "import Test.Tasty\nimport Test.Tasty.HUnit" + , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" + -- build tools + , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/bar.y\"]" + ] + + case (_runPrompt $ genTestTarget (emptyFlags {initializeTestSuite = Flag True}) pkgIx) inputs of + Left e -> assertFailure $ show e + Right{} -> return () + ] + ] + +nonInteractiveTests + :: InstalledPackageIndex + -> SourcePackageDb + -> TestTree +nonInteractiveTests _pkgIx srcDb = testGroup "Check top level getter functions" + [ testGroup "Simple heuristics tests" + [ testGroup "Check packageNameHeuristics output" + [ testSimple "New package name" (packageNameHeuristics srcDb) + (mkPackageName "test-package") + [ "test-package" + , "test-package" + ] + , testSimple "Existing package name" (packageNameHeuristics srcDb) + (mkPackageName "cabal-install") + [ "test-package" + , "cabal-install" + ] + ] + , testSimple "Check authorHeuristics output" authorHeuristics "Foobar" + [ "" + , "Foobar" + ] + , testSimple "Check emailHeuristics output" emailHeuristics "foobar@qux.com" + [ "" + , "foobar@qux.com" + ] + , testSimple "Check srcDirsHeuristics output" srcDirsHeuristics ["src"] + [ "src" + , "True" + ] + , testSimple "Check appDirsHeuristics output" appDirsHeuristics ["app"] + [ "test-package" + , "[\"test-package/app/\"]" + ] + , testGroup "Check packageTypeHeuristics output" + [ testSimple "Library" packageTypeHeuristics Library + [ "test-package" + , "[\".\", \"..\", \"test/Main.hs\", \"src/\"]" + ] + , testSimple "Executable" packageTypeHeuristics Executable + [ "test-package" + , "[\".\", \"..\", \"app/Main.hs\"]" + ] + , testSimple "Library and Executable" packageTypeHeuristics LibraryAndExecutable + [ "test-package" + , "[\".\", \"..\", \"src/\", \"app/Main.hs\"]" + ] + ] + , testGroup "Check cabalVersionHeuristics output" + [ testSimple "Broken command" cabalVersionHeuristics defaultCabalVersion + [""] + , testSimple "Proper answer" cabalVersionHeuristics CabalSpecV2_4 + ["cabal-install version 2.4.0.0\ncompiled using version 2.4.0.0 of the Cabal library \n"] + ] + , testGroup "Check languageHeuristics output" + [ testSimple "No compiler at all" languageHeuristics Haskell2010 + [""] + , testSimple "Higher version compiler" languageHeuristics Haskell2010 + ["The Glorious Glasgow Haskell Compilation System, version 7.10.3"] + , testSimple "Lower version compiler" languageHeuristics Haskell98 + ["The Glorious Glasgow Haskell Compilation System, version 6.4.2"] + ] + , testGroup "Check extraSourceFilesHeuristics output" + [ testSimple "No extra sources" extraSourceFilesHeuristics + (defaultChangelog NEL.:| []) + [ "test-package" + , "[]" + ] + , testSimple "Extra source files present" extraSourceFilesHeuristics + ("README.md" NEL.:| []) + [ "test-package" + , "[\"README.md\"]" + ] + ] + , testGroup "Check mainFileHeuristics output" + [ testSimple "No main file defined" mainFileHeuristics + (toHsFilePath "Main.hs") + [ "test-package" + , "[\"test-package/app/\"]" + , "[]" + ] + , testSimple "Main file already defined" mainFileHeuristics + (toHsFilePath "app/Main.hs") + [ "test-package" + , "[\"test-package/app/\"]" + , "[\"app/Main.hs\"]" + ] + , testSimple "Main lhs file already defined" mainFileHeuristics + (toHsFilePath "app/Main.lhs") + [ "test-package" + , "[\"test-package/app/\"]" + , "[\"app/Main.lhs\"]" + ] + ] + , testGroup "Check exposedModulesHeuristics output" + [ testSimple "Default exposed modules" exposedModulesHeuristics + (myLibModule NEL.:| []) + [ "src" + , "True" + , "[]" + , "test-package" + , "True" + , "[]" + ] + , testSimple "Contains exposed modules" exposedModulesHeuristics + (NEL.fromList $ map fromString ["Foo", "Bar"]) + [ "src" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + , "test-package" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + ] + ] + , testGroup "Check libOtherModulesHeuristics output" + [ testSimple "Library directory exists" libOtherModulesHeuristics + (map fromString ["Baz.Internal"]) + [ "test-package" + , "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\", \"src/Baz/Internal.hs\"]" + , "module Foo where" + , "module Bar where" + , "module Baz.Internal where" + ] + , testSimple "Library directory doesn't exist" libOtherModulesHeuristics [] + [ "test-package" + , "False" + ] + ] + , testGroup "Check exeOtherModulesHeuristics output" + [ testSimple "Executable directory exists" exeOtherModulesHeuristics + (map fromString ["Foo", "Bar"]) + [ "test-package" + , "True" + , "[\"app/Main.hs\", \"app/Foo.hs\", \"app/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + ] + , testSimple "Executable directory doesn't exist" exeOtherModulesHeuristics [] + [ "test-package" + , "False" + ] + ] + , testGroup "Check testOtherModulesHeuristics output" + [ testSimple "Test directory exists" testOtherModulesHeuristics + (map fromString ["Foo", "Bar"]) + [ "test-package" + , "True" + , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/Bar.hs\"]" + , "module Foo where" + , "module Bar where" + ] + , testSimple "Test directory doesn't exist" testOtherModulesHeuristics [] + [ "test-package" + , "False" + ] + ] + , testSimple "Check buildToolsHeuristics output" (`buildToolsHeuristics` "") ["happy"] + ["[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]"] + , testSimple "Check otherExtsHeuristics output" (`otherExtsHeuristics` "") + (map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards]) + [ "[\"src/Foo.hs\", \"src/Bar.hs\"]" + , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" + , "\"{-# LANGUAGE RecordWildCards #-}\"" + ] + + , testSimple "Check versionHeuristics output" versionHeuristics (mkVersion [0,1,0,0]) [""] + , testSimple "Check homepageHeuristics output" homepageHeuristics "" [""] + , testSimple "Check synopsisHeuristics output" synopsisHeuristics "" [""] + , testSimple "Check testDirsHeuristics output" testDirsHeuristics ["test"] [""] + , testSimple "Check categoryHeuristics output" categoryHeuristics "(none)" [""] + , testSimple "Check minimalHeuristics output" minimalHeuristics False [""] + , testSimple "Check overwriteHeuristics output" overwriteHeuristics False [""] + , testSimple "Check initializeTestSuiteHeuristics output" initializeTestSuiteHeuristics False [""] + , testSimple "Check licenseHeuristics output" licenseHeuristics SPDX.NONE [""] + ] + , testGroup "Bool heuristics tests" + [ testBool "Check noCommentsHeuristics output" noCommentsHeuristics False "" + ] + ] + +testSimple + :: Eq a + => Show a + => String + -> (InitFlags -> PurePrompt a) + -> a + -> [String] + -> TestTree +testSimple label f target = + testGo label f (assertFailure . show) (\(a, _) -> target @=? a) + +testBool + :: String + -> (InitFlags -> PurePrompt Bool) + -> Bool + -> String + -> TestTree +testBool label f target input = + testSimple label f target [input] + +testGo + :: Eq a + => Show a + => String + -> (InitFlags -> PurePrompt a) + -> (BreakException -> Assertion) + -> ((a, NEL.NonEmpty String) -> Assertion) + -> [String] + -> TestTree +testGo label f g h inputs = testCase label $ + case (_runPrompt $ f emptyFlags) (NEL.fromList inputs) of + Left x -> g x + Right x -> h x diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs new file mode 100644 index 00000000000..059fc334c89 --- /dev/null +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs @@ -0,0 +1,151 @@ +module UnitTests.Distribution.Client.Init.Simple +( tests +) where + + +import Prelude as P +import Test.Tasty +import Test.Tasty.HUnit + +import Distribution.Client.Init.Defaults +import Distribution.Client.Init.Simple +import Distribution.Client.Init.Types + + +import Data.List.NonEmpty hiding (zip) +import Distribution.Client.Types +import Distribution.Simple.Compiler +import Distribution.Simple.PackageIndex hiding (fromList) +import Distribution.Types.PackageName +import Distribution.Verbosity + + +import UnitTests.Distribution.Client.Init.Utils +import Distribution.Simple.Setup +import qualified Data.List.NonEmpty as NEL +import Distribution.Types.Dependency +import Distribution.Client.Init.Utils (mkPackageNameDep) + +tests + :: Verbosity + -> InitFlags + -> Compiler + -> InstalledPackageIndex + -> SourcePackageDb + -> TestTree +tests v _initFlags _comp pkgIx srcDb = testGroup "Distribution.Client.Init.Simple.hs" + [ simpleCreateProjectTests v pkgIx srcDb pkgName + ] + where + pkgName = mkPackageName "simple-test" + +simpleCreateProjectTests + :: Verbosity + -> InstalledPackageIndex + -> SourcePackageDb + -> PackageName + -> TestTree +simpleCreateProjectTests v pkgIx srcDb pkgName = + testGroup "Simple createProject tests" + [ testCase "Simple lib createProject - no tests" $ do + let inputs = fromList + [ "1" -- package type: Library + , "simple-test" -- package dir (ignored, piped to current dir due to prompt monad) + , "n" -- no tests + ] + + flags = emptyFlags { packageType = Flag Library } + settings = ProjectSettings + (WriteOpts False False False v "/home/test/1" Library pkgName) + (simplePkgDesc pkgName) (Just simpleLibTarget) + Nothing Nothing + + case _runPrompt (createProject v pkgIx srcDb flags) inputs of + Left e -> assertFailure $ "Failed to create simple lib project: " ++ show e + Right (settings', _) -> settings @=? settings' + + , testCase "Simple lib createProject - with tests" $ do + let inputs = fromList ["1", "simple-test", "y", "1"] + flags = emptyFlags { packageType = Flag Library } + settings = ProjectSettings + (WriteOpts False False False v "/home/test/1" Library pkgName) + (simplePkgDesc pkgName) (Just simpleLibTarget) + Nothing (Just $ simpleTestTarget (Just pkgName)) + + case _runPrompt (createProject v pkgIx srcDb flags) inputs of + Left e -> assertFailure $ "Failed to create simple lib (with tests)project: " ++ show e + Right (settings', _) -> settings @=? settings' + + , testCase "Simple exe createProject" $ do + let inputs = fromList ["2", "simple-test"] + flags = emptyFlags { packageType = Flag Executable } + settings = ProjectSettings + (WriteOpts False False False v "/home/test/2" Executable pkgName) + (simplePkgDesc pkgName) Nothing + (Just $ simpleExeTarget Nothing) Nothing + + case _runPrompt (createProject v pkgIx srcDb flags) inputs of + Left e -> assertFailure $ "Failed to create simple exe project: " ++ show e + Right (settings', _) -> settings @=? settings' + + , testCase "Simple lib+exe createProject - no tests" $ do + let inputs = fromList ["2", "simple-test", "n"] + flags = emptyFlags { packageType = Flag LibraryAndExecutable } + settings = ProjectSettings + (WriteOpts False False False v "/home/test/2" LibraryAndExecutable pkgName) + (simplePkgDesc pkgName) (Just simpleLibTarget) + (Just $ simpleExeTarget (Just pkgName)) Nothing + + case _runPrompt (createProject v pkgIx srcDb flags) inputs of + Left e -> assertFailure $ "Failed to create simple lib+exe project: " ++ show e + Right (settings', _) -> settings @=? settings' + , testCase "Simple lib+exe createProject - with tests" $ do + let inputs = fromList ["2", "simple-test", "y", "1"] + flags = emptyFlags { packageType = Flag LibraryAndExecutable } + settings = ProjectSettings + (WriteOpts False False False v "/home/test/2" LibraryAndExecutable pkgName) + (simplePkgDesc pkgName) (Just simpleLibTarget) + (Just $ simpleExeTarget (Just pkgName)) + (Just $ simpleTestTarget (Just pkgName)) + + case _runPrompt (createProject v pkgIx srcDb flags) inputs of + Left e -> assertFailure $ "Failed to create simple lib+exe (with tests) project: " ++ show e + Right (settings', _) -> settings @=? settings' + ] + +-- -------------------------------------------------------------------- -- +-- Utils + +mkPkgDep :: Maybe PackageName -> [Dependency] +mkPkgDep Nothing = [] +mkPkgDep (Just pn) = [mkPackageNameDep pn] + +simplePkgDesc :: PackageName -> PkgDescription +simplePkgDesc pkgName = PkgDescription + defaultCabalVersion + pkgName + defaultVersion + defaultLicense + "" "" "" "" "" + (defaultChangelog NEL.:| []) + +simpleLibTarget :: LibTarget +simpleLibTarget = LibTarget + [defaultSourceDir] + defaultLanguage + (myLibModule NEL.:| []) + [] [] [] [] + +simpleExeTarget :: Maybe PackageName -> ExeTarget +simpleExeTarget pn = ExeTarget + defaultMainIs + [defaultApplicationDir] + defaultLanguage + [] [] (mkPkgDep pn) [] + +simpleTestTarget :: Maybe PackageName -> TestTarget +simpleTestTarget pn = TestTarget + defaultMainIs + [defaultTestDir] + defaultLanguage + [] [] (mkPkgDep pn) [] diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs new file mode 100644 index 00000000000..199f6f6eb67 --- /dev/null +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs @@ -0,0 +1,82 @@ +module UnitTests.Distribution.Client.Init.Utils +( dummyFlags +, emptyFlags +, mkLicense +, mangleBaseDep +, (@?!) +, (@!?) +) where + + +import Distribution.Client.Init.Types + +import qualified Distribution.SPDX as SPDX + +import Distribution.CabalSpecVersion +import Distribution.Simple.Setup +import Distribution.Types.PackageName +import Distribution.Types.Version +import Language.Haskell.Extension +import Test.Tasty.HUnit +import Distribution.Types.Dependency +import Distribution.Types.VersionRange + + +-- -------------------------------------------------------------------- -- +-- Test flags + +dummyFlags :: InitFlags +dummyFlags = emptyFlags + { noComments = Flag True + , packageName = Flag (mkPackageName "QuxPackage") + , version = Flag (mkVersion [4,2,6]) + , cabalVersion = Flag CabalSpecV2_2 + , license = Flag $ SPDX.License $ SPDX.ELicense (SPDX.ELicenseId SPDX.MIT) Nothing + , author = Flag "Foobar" + , email = Flag "foobar@qux.com" + , homepage = Flag "qux.com" + , synopsis = Flag "We are Qux, and this is our package" + , category = Flag "Control" + , language = Flag Haskell98 + , initializeTestSuite = Flag True + , sourceDirs = Flag ["quxSrc"] + , testDirs = Flag ["quxTest"] + , applicationDirs = Flag ["quxApp"] + } + +emptyFlags :: InitFlags +emptyFlags = mempty + +-- -------------------------------------------------------------------- -- +-- Test utils + +mkLicense :: SPDX.LicenseId -> SPDX.License +mkLicense lid = SPDX.License (SPDX.ELicense (SPDX.ELicenseId lid) Nothing) + +mangleBaseDep :: a -> (a -> [Dependency]) -> [Dependency] +mangleBaseDep target f = + [ if unPackageName x == "base" + then Dependency x anyVersion z + else dep + | dep@(Dependency x _ z) <- f target + ] + +infix 1 @?!, @!? + +-- | Just like @'@?='@, except it checks for difference rather than equality. +(@?!) + :: (Eq a, Show a, HasCallStack) + => a + -> a + -> Assertion +actual @?! unexpected = assertBool + ("unexpected: " ++ show unexpected) + (actual /= unexpected) + +-- | Just like @'@=?'@, except it checks for difference rather than equality. +(@!?) + :: (Eq a, Show a, HasCallStack) + => a + -> a + -> Assertion +(@!?) = flip (@?!) diff --git a/cabal-install/tests/fixtures/init/exe-only-golden.cabal b/cabal-install/tests/fixtures/init/exe-only-golden.cabal deleted file mode 100644 index 8887173111b..00000000000 --- a/cabal-install/tests/fixtures/init/exe-only-golden.cabal +++ /dev/null @@ -1,20 +0,0 @@ -cabal-version: 2.4 -name: foo -version: 3.2.1 -synopsis: The foo package -homepage: https://github.com/foo/foo -license: NONE -author: me -maintainer: me@me.me -category: SomeCat -extra-source-files: CHANGELOG.md - -executable foo - main-is: Main.hs - build-depends: - base ^>=4.13.0.0, - containers ^>=5.7.0.0, - unordered-containers ^>=2.7.0.0 - - hs-source-dirs: app - default-language: Haskell2010 diff --git a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden new file mode 100644 index 00000000000..8c75394d2c8 --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden @@ -0,0 +1,61 @@ +cabal-version: 2.4 +name: y +version: 0.1.0.0 +synopsis: synopsis + +-- A longer description of the package. +-- description: +homepage: home +license: BSD-3-Clause +license-file: LICENSE +author: foo-kmett +maintainer: foo-kmett@kmett.kmett + +-- A copyright notice. +-- copyright: +category: Data +build-type: Simple +extra-source-files: CHANGELOG.md + +library + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: base + hs-source-dirs: src + default-language: Haskell98 + +executable y + main-is: Main.hs + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: + base, + y + + hs-source-dirs: exe + default-language: Haskell2010 + +test-suite y-test + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: + base, + y + diff --git a/cabal-install/tests/fixtures/init/lib-exe-and-test-with-comments-golden.cabal b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden similarity index 65% rename from cabal-install/tests/fixtures/init/lib-exe-and-test-with-comments-golden.cabal rename to cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden index adfaea7733b..f0b2b216bda 100644 --- a/cabal-install/tests/fixtures/init/lib-exe-and-test-with-comments-golden.cabal +++ b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden @@ -1,54 +1,53 @@ cabal-version: 2.4 --- Initial package description 'lib-exe-and-test-with-comments-golden.cabal' generated by +-- Initial package description 'y' generated by -- 'cabal init'. For further documentation, see: -- http://haskell.org/cabal/users-guide/ -- -- The name of the package. -name: foo +name: y -- The package version. -- See the Haskell package versioning policy (PVP) for standards -- guiding when and how versions should be incremented. -- https://pvp.haskell.org --- PVP summary: +-+------- breaking API changes --- | | +----- non-breaking API additions --- | | | +--- code changes with no API change -version: 3.2.1 +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 0.1.0.0 -- A short (one-line) description of the package. -synopsis: The foo package +synopsis: synopsis -- A longer description of the package. -- description: -- URL for the project homepage or repository. -homepage: https://github.com/foo/foo - --- A URL where users can report bugs. --- bug-reports: +homepage: home -- The license under which the package is released. -license: NONE +license: BSD-3-Clause + +-- The file containing the license text. +license-file: LICENSE -- The package author(s). -author: me +author: foo-kmett -- An email address to which users can send suggestions, bug reports, and patches. -maintainer: me@me.me +maintainer: foo-kmett@kmett.kmett -- A copyright notice. -- copyright: -category: SomeCat +category: Data +build-type: Simple -- Extra files to be distributed with the package, such as examples or a README. extra-source-files: CHANGELOG.md library -- Modules exported by the library. - exposed-modules: - A - B + exposed-modules: MyLib -- Modules included in this library but not exported. -- other-modules: @@ -57,18 +56,15 @@ library -- other-extensions: -- Other library packages from which modules are imported. - build-depends: - base ^>=4.13.0.0, - containers ^>=5.7.0.0, - unordered-containers ^>=2.7.0.0 + build-depends: base -- Directories containing source files. hs-source-dirs: src -- Base language which the package is written in. - default-language: Haskell2010 + default-language: Haskell98 -executable foo +executable y -- .hs or .lhs file containing the Main module. main-is: Main.hs @@ -80,31 +76,36 @@ executable foo -- Other library packages from which modules are imported. build-depends: - base ^>=4.13.0.0, - containers ^>=5.7.0.0, - unordered-containers ^>=2.7.0.0 + base, + y -- Directories containing source files. - hs-source-dirs: app + hs-source-dirs: exe -- Base language which the package is written in. default-language: Haskell2010 -test-suite foo-test +test-suite y-test -- Base language which the package is written in. default-language: Haskell2010 + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + -- The interface type and version of the test suite. type: exitcode-stdio-1.0 -- Directories containing source files. - hs-source-dirs: tests + hs-source-dirs: test -- The entrypoint to the test suite. - main-is: MyLibTest.hs + main-is: Main.hs -- Test dependencies. build-depends: - base ^>=4.13.0.0, - containers ^>=5.7.0.0, - unordered-containers ^>=2.7.0.0 + base, + y + diff --git a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden new file mode 100644 index 00000000000..336bd3fb210 --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden @@ -0,0 +1,46 @@ +cabal-version: 2.4 +name: y +version: 0.1.0.0 +synopsis: synopsis + +-- A longer description of the package. +-- description: +homepage: home +license: BSD-3-Clause +license-file: LICENSE +author: foo-kmett +maintainer: foo-kmett@kmett.kmett + +-- A copyright notice. +-- copyright: +category: Data +build-type: Simple +extra-source-files: CHANGELOG.md + +library + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: base + hs-source-dirs: src + default-language: Haskell98 + +test-suite y-test + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: + base, + y + diff --git a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden new file mode 100644 index 00000000000..14b06a911c5 --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden @@ -0,0 +1,90 @@ +cabal-version: 2.4 + +-- Initial package description 'y' generated by +-- 'cabal init'. For further documentation, see: +-- http://haskell.org/cabal/users-guide/ +-- +-- The name of the package. +name: y + +-- The package version. +-- See the Haskell package versioning policy (PVP) for standards +-- guiding when and how versions should be incremented. +-- https://pvp.haskell.org +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 0.1.0.0 + +-- A short (one-line) description of the package. +synopsis: synopsis + +-- A longer description of the package. +-- description: + +-- URL for the project homepage or repository. +homepage: home + +-- The license under which the package is released. +license: BSD-3-Clause + +-- The file containing the license text. +license-file: LICENSE + +-- The package author(s). +author: foo-kmett + +-- An email address to which users can send suggestions, bug reports, and patches. +maintainer: foo-kmett@kmett.kmett + +-- A copyright notice. +-- copyright: +category: Data +build-type: Simple + +-- Extra files to be distributed with the package, such as examples or a README. +extra-source-files: CHANGELOG.md + +library + -- Modules exported by the library. + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: base + + -- Directories containing source files. + hs-source-dirs: src + + -- Base language which the package is written in. + default-language: Haskell98 + +test-suite y-test + -- Base language which the package is written in. + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- The interface type and version of the test suite. + type: exitcode-stdio-1.0 + + -- Directories containing source files. + hs-source-dirs: test + + -- The entrypoint to the test suite. + main-is: Main.hs + + -- Test dependencies. + build-depends: + base, + y + diff --git a/cabal-install/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden b/cabal-install/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden new file mode 100644 index 00000000000..cbf34dde765 --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden @@ -0,0 +1,21 @@ +executable y + -- .hs or .lhs file containing the Main module. + main-is: Main.hs + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: base + + -- Directories containing source files. + hs-source-dirs: exe + + -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. + build-tools: happy + + -- Base language which the package is written in. + default-language: Haskell2010 diff --git a/cabal-install/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden b/cabal-install/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden new file mode 100644 index 00000000000..88d69ab18db --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden @@ -0,0 +1,5 @@ +executable y + main-is: Main.hs + build-depends: base + hs-source-dirs: exe + default-language: Haskell2010 diff --git a/cabal-install/tests/fixtures/init/golden/exe/exe-simple-with-comments.golden b/cabal-install/tests/fixtures/init/golden/exe/exe-simple-with-comments.golden new file mode 100644 index 00000000000..19fdb84a1a6 --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/exe/exe-simple-with-comments.golden @@ -0,0 +1,12 @@ +executable y + -- .hs or .lhs file containing the Main module. + main-is: Main.hs + + -- Other library packages from which modules are imported. + build-depends: base + + -- Directories containing source files. + hs-source-dirs: exe + + -- Base language which the package is written in. + default-language: Haskell2010 diff --git a/cabal-install/tests/fixtures/init/golden/exe/exe-simple.golden b/cabal-install/tests/fixtures/init/golden/exe/exe-simple.golden new file mode 100644 index 00000000000..e6dfaa77ebe --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/exe/exe-simple.golden @@ -0,0 +1,13 @@ +executable y + main-is: Main.hs + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + -- build-depends: + hs-source-dirs: app + default-language: Haskell2010 diff --git a/cabal-install/tests/fixtures/init/golden/exe/exe-with-comments.golden b/cabal-install/tests/fixtures/init/golden/exe/exe-with-comments.golden new file mode 100644 index 00000000000..deb7bb063da --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/exe/exe-with-comments.golden @@ -0,0 +1,18 @@ +executable y + -- .hs or .lhs file containing the Main module. + main-is: Main.hs + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: base + + -- Directories containing source files. + hs-source-dirs: exe + + -- Base language which the package is written in. + default-language: Haskell2010 diff --git a/cabal-install/tests/fixtures/init/golden/exe/exe.golden b/cabal-install/tests/fixtures/init/golden/exe/exe.golden new file mode 100644 index 00000000000..3f4d9c54fe6 --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/exe/exe.golden @@ -0,0 +1,11 @@ +executable y + main-is: Main.hs + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: base + hs-source-dirs: exe + default-language: Haskell2010 diff --git a/cabal-install/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden b/cabal-install/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden new file mode 100644 index 00000000000..436ed85d096 --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden @@ -0,0 +1,21 @@ +library + -- Modules exported by the library. + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: base + + -- Directories containing source files. + hs-source-dirs: src + + -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. + build-tools: happy + + -- Base language which the package is written in. + default-language: Haskell98 diff --git a/cabal-install/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden b/cabal-install/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden new file mode 100644 index 00000000000..99e5d7fffb8 --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden @@ -0,0 +1,5 @@ +library + exposed-modules: MyLib + build-depends: base + hs-source-dirs: src + default-language: Haskell98 diff --git a/cabal-install/tests/fixtures/init/golden/lib/lib-simple-with-comments.golden b/cabal-install/tests/fixtures/init/golden/lib/lib-simple-with-comments.golden new file mode 100644 index 00000000000..5583deefa19 --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/lib/lib-simple-with-comments.golden @@ -0,0 +1,12 @@ +library + -- Modules exported by the library. + exposed-modules: MyLib + + -- Other library packages from which modules are imported. + build-depends: base + + -- Directories containing source files. + hs-source-dirs: src + + -- Base language which the package is written in. + default-language: Haskell98 diff --git a/cabal-install/tests/fixtures/init/golden/lib/lib-simple.golden b/cabal-install/tests/fixtures/init/golden/lib/lib-simple.golden new file mode 100644 index 00000000000..8dd9dbcecbd --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/lib/lib-simple.golden @@ -0,0 +1,11 @@ +library + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: base + hs-source-dirs: src + default-language: Haskell98 diff --git a/cabal-install/tests/fixtures/init/golden/lib/lib-with-comments.golden b/cabal-install/tests/fixtures/init/golden/lib/lib-with-comments.golden new file mode 100644 index 00000000000..d64fb60b613 --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/lib/lib-with-comments.golden @@ -0,0 +1,18 @@ +library + -- Modules exported by the library. + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: base + + -- Directories containing source files. + hs-source-dirs: src + + -- Base language which the package is written in. + default-language: Haskell98 diff --git a/cabal-install/tests/fixtures/init/golden/lib/lib.golden b/cabal-install/tests/fixtures/init/golden/lib/lib.golden new file mode 100644 index 00000000000..8dd9dbcecbd --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/lib/lib.golden @@ -0,0 +1,11 @@ +library + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: base + hs-source-dirs: src + default-language: Haskell98 diff --git a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden new file mode 100644 index 00000000000..776f6abd320 --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden @@ -0,0 +1,45 @@ +cabal-version: 2.0 + +-- Initial package description 'y' generated by +-- 'cabal init'. For further documentation, see: +-- http://haskell.org/cabal/users-guide/ +-- +-- The name of the package. +name: QuxPackage + +-- The package version. +-- See the Haskell package versioning policy (PVP) for standards +-- guiding when and how versions should be incremented. +-- https://pvp.haskell.org +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 4.2.6 + +-- A short (one-line) description of the package. +synopsis: We are Qux, and this is our package + +-- A longer description of the package. +-- description: + +-- URL for the project homepage or repository. +homepage: qux.com + +-- The license under which the package is released. +license: MIT + +-- The file containing the license text. +license-file: LICENSE + +-- The package author(s). +author: Foobar + +-- An email address to which users can send suggestions, bug reports, and patches. +maintainer: foobar@qux.com + +-- A copyright notice. +-- copyright: +category: Control + +-- Extra files to be distributed with the package, such as examples or a README. +extra-source-files: CHANGELOG.md diff --git a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-simple.golden b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-simple.golden new file mode 100644 index 00000000000..b44bf495121 --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-simple.golden @@ -0,0 +1,21 @@ +cabal-version: 3.0 +name: 4 +version: 0.1.0.0 + +-- A short (one-line) description of the package. +-- synopsis: + +-- A longer description of the package. +-- description: +license: NONE + +-- The package author(s). +-- author: + +-- An email address to which users can send suggestions, bug reports, and patches. +-- maintainer: + +-- A copyright notice. +-- copyright: +build-type: Simple +extra-source-files: CHANGELOG.md diff --git a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden new file mode 100644 index 00000000000..47924235c7f --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden @@ -0,0 +1,46 @@ +cabal-version: 2.4 + +-- Initial package description 'y' generated by +-- 'cabal init'. For further documentation, see: +-- http://haskell.org/cabal/users-guide/ +-- +-- The name of the package. +name: y + +-- The package version. +-- See the Haskell package versioning policy (PVP) for standards +-- guiding when and how versions should be incremented. +-- https://pvp.haskell.org +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 0.1.0.0 + +-- A short (one-line) description of the package. +synopsis: synopsis + +-- A longer description of the package. +-- description: + +-- URL for the project homepage or repository. +homepage: home + +-- The license under which the package is released. +license: BSD-3-Clause + +-- The file containing the license text. +license-file: LICENSE + +-- The package author(s). +author: foo-kmett + +-- An email address to which users can send suggestions, bug reports, and patches. +maintainer: foo-kmett@kmett.kmett + +-- A copyright notice. +-- copyright: +category: Data +build-type: Simple + +-- Extra files to be distributed with the package, such as examples or a README. +extra-source-files: CHANGELOG.md diff --git a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden new file mode 100644 index 00000000000..52613c0f0d7 --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden @@ -0,0 +1,46 @@ +cabal-version: 2.2 + +-- Initial package description 'y' generated by +-- 'cabal init'. For further documentation, see: +-- http://haskell.org/cabal/users-guide/ +-- +-- The name of the package. +name: QuxPackage + +-- The package version. +-- See the Haskell package versioning policy (PVP) for standards +-- guiding when and how versions should be incremented. +-- https://pvp.haskell.org +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 4.2.6 + +-- A short (one-line) description of the package. +synopsis: We are Qux, and this is our package + +-- A longer description of the package. +-- description: + +-- URL for the project homepage or repository. +homepage: qux.com + +-- The license under which the package is released. +license: MIT + +-- The file containing the license text. +license-file: LICENSE + +-- The package author(s). +author: Foobar + +-- An email address to which users can send suggestions, bug reports, and patches. +maintainer: foobar@qux.com + +-- A copyright notice. +-- copyright: +category: Control +build-type: Simple + +-- Extra files to be distributed with the package, such as examples or a README. +extra-source-files: CHANGELOG.md diff --git a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg.golden b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg.golden new file mode 100644 index 00000000000..47924235c7f --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg.golden @@ -0,0 +1,46 @@ +cabal-version: 2.4 + +-- Initial package description 'y' generated by +-- 'cabal init'. For further documentation, see: +-- http://haskell.org/cabal/users-guide/ +-- +-- The name of the package. +name: y + +-- The package version. +-- See the Haskell package versioning policy (PVP) for standards +-- guiding when and how versions should be incremented. +-- https://pvp.haskell.org +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 0.1.0.0 + +-- A short (one-line) description of the package. +synopsis: synopsis + +-- A longer description of the package. +-- description: + +-- URL for the project homepage or repository. +homepage: home + +-- The license under which the package is released. +license: BSD-3-Clause + +-- The file containing the license text. +license-file: LICENSE + +-- The package author(s). +author: foo-kmett + +-- An email address to which users can send suggestions, bug reports, and patches. +maintainer: foo-kmett@kmett.kmett + +-- A copyright notice. +-- copyright: +category: Data +build-type: Simple + +-- Extra files to be distributed with the package, such as examples or a README. +extra-source-files: CHANGELOG.md diff --git a/cabal-install/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden b/cabal-install/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden new file mode 100644 index 00000000000..5171d02708a --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden @@ -0,0 +1,24 @@ +test-suite y-test + -- Base language which the package is written in. + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- The interface type and version of the test suite. + type: exitcode-stdio-1.0 + + -- Directories containing source files. + hs-source-dirs: test + + -- The entrypoint to the test suite. + main-is: Main.hs + + -- Test dependencies. + build-depends: base + + -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. + build-tools: happy diff --git a/cabal-install/tests/fixtures/init/golden/test/test-minimal-no-comments.golden b/cabal-install/tests/fixtures/init/golden/test/test-minimal-no-comments.golden new file mode 100644 index 00000000000..b092956a6d2 --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/test/test-minimal-no-comments.golden @@ -0,0 +1,6 @@ +test-suite y-test + default-language: Haskell2010 + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: base diff --git a/cabal-install/tests/fixtures/init/golden/test/test-simple-with-comments.golden b/cabal-install/tests/fixtures/init/golden/test/test-simple-with-comments.golden new file mode 100644 index 00000000000..6388f8583de --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/test/test-simple-with-comments.golden @@ -0,0 +1,15 @@ +test-suite y-test + -- Base language which the package is written in. + default-language: Haskell2010 + + -- The interface type and version of the test suite. + type: exitcode-stdio-1.0 + + -- Directories containing source files. + hs-source-dirs: test + + -- The entrypoint to the test suite. + main-is: Main.hs + + -- Test dependencies. + build-depends: base diff --git a/cabal-install/tests/fixtures/init/golden/test/test-simple.golden b/cabal-install/tests/fixtures/init/golden/test/test-simple.golden new file mode 100644 index 00000000000..44095ab9a95 --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/test/test-simple.golden @@ -0,0 +1,14 @@ +test-suite y-test + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + + -- Test dependencies. + -- build-depends: diff --git a/cabal-install/tests/fixtures/init/golden/test/test-with-comments.golden b/cabal-install/tests/fixtures/init/golden/test/test-with-comments.golden new file mode 100644 index 00000000000..2381ebd092e --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/test/test-with-comments.golden @@ -0,0 +1,21 @@ +test-suite y-test + -- Base language which the package is written in. + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- The interface type and version of the test suite. + type: exitcode-stdio-1.0 + + -- Directories containing source files. + hs-source-dirs: test + + -- The entrypoint to the test suite. + main-is: Main.hs + + -- Test dependencies. + build-depends: base diff --git a/cabal-install/tests/fixtures/init/golden/test/test.golden b/cabal-install/tests/fixtures/init/golden/test/test.golden new file mode 100644 index 00000000000..7a36e096fb2 --- /dev/null +++ b/cabal-install/tests/fixtures/init/golden/test/test.golden @@ -0,0 +1,12 @@ +test-suite y-test + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: base diff --git a/cabal-install/tests/fixtures/init/lib-and-exe-golden.cabal b/cabal-install/tests/fixtures/init/lib-and-exe-golden.cabal deleted file mode 100644 index d90c89bed19..00000000000 --- a/cabal-install/tests/fixtures/init/lib-and-exe-golden.cabal +++ /dev/null @@ -1,31 +0,0 @@ -cabal-version: 2.4 -name: foo -version: 3.2.1 -synopsis: The foo package -homepage: https://github.com/foo/foo -license: NONE -author: me -maintainer: me@me.me -category: SomeCat -extra-source-files: CHANGELOG.md - -library - exposed-modules: MyLib - build-depends: - base ^>=4.13.0.0, - containers ^>=5.7.0.0, - unordered-containers ^>=2.7.0.0 - - hs-source-dirs: src - default-language: Haskell2010 - -executable foo - main-is: Main.hs - build-depends: - base ^>=4.13.0.0, - containers ^>=5.7.0.0, - unordered-containers ^>=2.7.0.0, - foo - - hs-source-dirs: app - default-language: Haskell2010 diff --git a/cabal-install/tests/fixtures/init/lib-exe-and-test-golden.cabal b/cabal-install/tests/fixtures/init/lib-exe-and-test-golden.cabal deleted file mode 100644 index 924237c2dea..00000000000 --- a/cabal-install/tests/fixtures/init/lib-exe-and-test-golden.cabal +++ /dev/null @@ -1,43 +0,0 @@ -cabal-version: 2.4 -name: foo -version: 3.2.1 -synopsis: The foo package -homepage: https://github.com/foo/foo -license: NONE -author: me -maintainer: me@me.me -category: SomeCat -extra-source-files: CHANGELOG.md - -library - exposed-modules: - A - B - - build-depends: - base ^>=4.13.0.0, - containers ^>=5.7.0.0, - unordered-containers ^>=2.7.0.0 - - hs-source-dirs: src - default-language: Haskell2010 - -executable foo - main-is: Main.hs - build-depends: - base ^>=4.13.0.0, - containers ^>=5.7.0.0, - unordered-containers ^>=2.7.0.0 - - hs-source-dirs: app - default-language: Haskell2010 - -test-suite foo-test - default-language: Haskell2010 - type: exitcode-stdio-1.0 - hs-source-dirs: tests - main-is: MyLibTest.hs - build-depends: - base ^>=4.13.0.0, - containers ^>=5.7.0.0, - unordered-containers ^>=2.7.0.0 diff --git a/cabal.project b/cabal.project index e07642f2a2c..fd4b237b37f 100644 --- a/cabal.project +++ b/cabal.project @@ -1,7 +1,8 @@ packages: Cabal/ cabal-testsuite/ -packages: cabal-install-solver/ packages: cabal-install/ +packages: cabal-install-solver/ packages: solver-benchmarks/ + tests: True packages: Cabal-QuickCheck/ diff --git a/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden b/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden new file mode 100644 index 00000000000..32e4d1ca857 --- /dev/null +++ b/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden @@ -0,0 +1,61 @@ +cabal-version: 2.4 +name: y +version: 0.1.0.0 +synopsis: synopsis + +-- A longer description of the package. +-- description: +homepage: home +license: BSD-3-Clause +license-file: LICENSE +author: foo-kmett +maintainer: foo-kmett@kmett.kmett + +-- A copyright notice. +-- copyright: +category: Data +build-type: Simple +extra-source-files: CHANGELOG.md + +library + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: base ^>=4.14.1.0 + hs-source-dirs: src + default-language: Haskell98 + +executable y + main-is: Main.hs + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: + base ^>=4.14.1.0, + y + + hs-source-dirs: exe + default-language: Haskell2010 + +test-suite y-test + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: + base ^>=4.14.1.0, + y + diff --git a/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden b/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden new file mode 100644 index 00000000000..7dcde8264b2 --- /dev/null +++ b/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden @@ -0,0 +1,111 @@ +cabal-version: 2.4 + +-- Initial package description 'y' generated by +-- 'cabal init'. For further documentation, see: +-- http://haskell.org/cabal/users-guide/ +-- +-- The name of the package. +name: y + +-- The package version. +-- See the Haskell package versioning policy (PVP) for standards +-- guiding when and how versions should be incremented. +-- https://pvp.haskell.org +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 0.1.0.0 + +-- A short (one-line) description of the package. +synopsis: synopsis + +-- A longer description of the package. +-- description: + +-- URL for the project homepage or repository. +homepage: home + +-- The license under which the package is released. +license: BSD-3-Clause + +-- The file containing the license text. +license-file: LICENSE + +-- The package author(s). +author: foo-kmett + +-- An email address to which users can send suggestions, bug reports, and patches. +maintainer: foo-kmett@kmett.kmett + +-- A copyright notice. +-- copyright: +category: Data +build-type: Simple + +-- Extra files to be distributed with the package, such as examples or a README. +extra-source-files: CHANGELOG.md + +library + -- Modules exported by the library. + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: base ^>=4.14.1.0 + + -- Directories containing source files. + hs-source-dirs: src + + -- Base language which the package is written in. + default-language: Haskell98 + +executable y + -- .hs or .lhs file containing the Main module. + main-is: Main.hs + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: + base ^>=4.14.1.0, + y + + -- Directories containing source files. + hs-source-dirs: exe + + -- Base language which the package is written in. + default-language: Haskell2010 + +test-suite y-test + -- Base language which the package is written in. + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- The interface type and version of the test suite. + type: exitcode-stdio-1.0 + + -- Directories containing source files. + hs-source-dirs: test + + -- The entrypoint to the test suite. + main-is: Main.hs + + -- Test dependencies. + build-depends: + base ^>=4.14.1.0, + y + diff --git a/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden b/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden new file mode 100644 index 00000000000..6cceb218542 --- /dev/null +++ b/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden @@ -0,0 +1,46 @@ +cabal-version: 2.4 +name: y +version: 0.1.0.0 +synopsis: synopsis + +-- A longer description of the package. +-- description: +homepage: home +license: BSD-3-Clause +license-file: LICENSE +author: foo-kmett +maintainer: foo-kmett@kmett.kmett + +-- A copyright notice. +-- copyright: +category: Data +build-type: Simple +extra-source-files: CHANGELOG.md + +library + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: base ^>=4.14.1.0 + hs-source-dirs: src + default-language: Haskell98 + +test-suite y-test + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: + base ^>=4.14.1.0, + y + diff --git a/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden b/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden new file mode 100644 index 00000000000..0ec5e6be0eb --- /dev/null +++ b/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden @@ -0,0 +1,90 @@ +cabal-version: 2.4 + +-- Initial package description 'y' generated by +-- 'cabal init'. For further documentation, see: +-- http://haskell.org/cabal/users-guide/ +-- +-- The name of the package. +name: y + +-- The package version. +-- See the Haskell package versioning policy (PVP) for standards +-- guiding when and how versions should be incremented. +-- https://pvp.haskell.org +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 0.1.0.0 + +-- A short (one-line) description of the package. +synopsis: synopsis + +-- A longer description of the package. +-- description: + +-- URL for the project homepage or repository. +homepage: home + +-- The license under which the package is released. +license: BSD-3-Clause + +-- The file containing the license text. +license-file: LICENSE + +-- The package author(s). +author: foo-kmett + +-- An email address to which users can send suggestions, bug reports, and patches. +maintainer: foo-kmett@kmett.kmett + +-- A copyright notice. +-- copyright: +category: Data +build-type: Simple + +-- Extra files to be distributed with the package, such as examples or a README. +extra-source-files: CHANGELOG.md + +library + -- Modules exported by the library. + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: base ^>=4.14.1.0 + + -- Directories containing source files. + hs-source-dirs: src + + -- Base language which the package is written in. + default-language: Haskell98 + +test-suite y-test + -- Base language which the package is written in. + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- The interface type and version of the test suite. + type: exitcode-stdio-1.0 + + -- Directories containing source files. + hs-source-dirs: test + + -- The entrypoint to the test suite. + main-is: Main.hs + + -- Test dependencies. + build-depends: + base ^>=4.14.1.0, + y + diff --git a/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden b/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden new file mode 100644 index 00000000000..b2e99868127 --- /dev/null +++ b/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden @@ -0,0 +1,21 @@ +executable y + -- .hs or .lhs file containing the Main module. + main-is: Main.hs + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: base ^>=4.14.1.0 + + -- Directories containing source files. + hs-source-dirs: exe + + -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. + build-tools: happy + + -- Base language which the package is written in. + default-language: Haskell2010 diff --git a/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden b/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden new file mode 100644 index 00000000000..35810f1662a --- /dev/null +++ b/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden @@ -0,0 +1,5 @@ +executable y + main-is: Main.hs + build-depends: base ^>=4.14.1.0 + hs-source-dirs: exe + default-language: Haskell2010 diff --git a/tests/fixtures/init/golden/exe/exe-simple-with-comments.golden b/tests/fixtures/init/golden/exe/exe-simple-with-comments.golden new file mode 100644 index 00000000000..a791a4a0eed --- /dev/null +++ b/tests/fixtures/init/golden/exe/exe-simple-with-comments.golden @@ -0,0 +1,12 @@ +executable y + -- .hs or .lhs file containing the Main module. + main-is: Main.hs + + -- Other library packages from which modules are imported. + build-depends: base ^>=4.14.1.0 + + -- Directories containing source files. + hs-source-dirs: exe + + -- Base language which the package is written in. + default-language: Haskell2010 diff --git a/tests/fixtures/init/golden/exe/exe-with-comments.golden b/tests/fixtures/init/golden/exe/exe-with-comments.golden new file mode 100644 index 00000000000..d7a0a16e9b8 --- /dev/null +++ b/tests/fixtures/init/golden/exe/exe-with-comments.golden @@ -0,0 +1,18 @@ +executable y + -- .hs or .lhs file containing the Main module. + main-is: Main.hs + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: base ^>=4.14.1.0 + + -- Directories containing source files. + hs-source-dirs: exe + + -- Base language which the package is written in. + default-language: Haskell2010 diff --git a/tests/fixtures/init/golden/exe/exe.golden b/tests/fixtures/init/golden/exe/exe.golden new file mode 100644 index 00000000000..c61210c04ea --- /dev/null +++ b/tests/fixtures/init/golden/exe/exe.golden @@ -0,0 +1,11 @@ +executable y + main-is: Main.hs + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: base ^>=4.14.1.0 + hs-source-dirs: exe + default-language: Haskell2010 diff --git a/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden b/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden new file mode 100644 index 00000000000..8d41c633f60 --- /dev/null +++ b/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden @@ -0,0 +1,21 @@ +library + -- Modules exported by the library. + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: base ^>=4.14.1.0 + + -- Directories containing source files. + hs-source-dirs: src + + -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. + build-tools: happy + + -- Base language which the package is written in. + default-language: Haskell98 diff --git a/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden b/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden new file mode 100644 index 00000000000..64c71f80310 --- /dev/null +++ b/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden @@ -0,0 +1,5 @@ +library + exposed-modules: MyLib + build-depends: base ^>=4.14.1.0 + hs-source-dirs: src + default-language: Haskell98 diff --git a/tests/fixtures/init/golden/lib/lib-simple-with-comments.golden b/tests/fixtures/init/golden/lib/lib-simple-with-comments.golden new file mode 100644 index 00000000000..f6daa328415 --- /dev/null +++ b/tests/fixtures/init/golden/lib/lib-simple-with-comments.golden @@ -0,0 +1,12 @@ +library + -- Modules exported by the library. + exposed-modules: MyLib + + -- Other library packages from which modules are imported. + build-depends: base ^>=4.14.1.0 + + -- Directories containing source files. + hs-source-dirs: src + + -- Base language which the package is written in. + default-language: Haskell98 diff --git a/tests/fixtures/init/golden/lib/lib-simple.golden b/tests/fixtures/init/golden/lib/lib-simple.golden new file mode 100644 index 00000000000..61271518061 --- /dev/null +++ b/tests/fixtures/init/golden/lib/lib-simple.golden @@ -0,0 +1,11 @@ +library + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: base ^>=4.14.1.0 + hs-source-dirs: src + default-language: Haskell98 diff --git a/tests/fixtures/init/golden/lib/lib-with-comments.golden b/tests/fixtures/init/golden/lib/lib-with-comments.golden new file mode 100644 index 00000000000..84ba9445f2a --- /dev/null +++ b/tests/fixtures/init/golden/lib/lib-with-comments.golden @@ -0,0 +1,18 @@ +library + -- Modules exported by the library. + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: base ^>=4.14.1.0 + + -- Directories containing source files. + hs-source-dirs: src + + -- Base language which the package is written in. + default-language: Haskell98 diff --git a/tests/fixtures/init/golden/lib/lib.golden b/tests/fixtures/init/golden/lib/lib.golden new file mode 100644 index 00000000000..61271518061 --- /dev/null +++ b/tests/fixtures/init/golden/lib/lib.golden @@ -0,0 +1,11 @@ +library + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: base ^>=4.14.1.0 + hs-source-dirs: src + default-language: Haskell98 diff --git a/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden b/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden new file mode 100644 index 00000000000..776f6abd320 --- /dev/null +++ b/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden @@ -0,0 +1,45 @@ +cabal-version: 2.0 + +-- Initial package description 'y' generated by +-- 'cabal init'. For further documentation, see: +-- http://haskell.org/cabal/users-guide/ +-- +-- The name of the package. +name: QuxPackage + +-- The package version. +-- See the Haskell package versioning policy (PVP) for standards +-- guiding when and how versions should be incremented. +-- https://pvp.haskell.org +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 4.2.6 + +-- A short (one-line) description of the package. +synopsis: We are Qux, and this is our package + +-- A longer description of the package. +-- description: + +-- URL for the project homepage or repository. +homepage: qux.com + +-- The license under which the package is released. +license: MIT + +-- The file containing the license text. +license-file: LICENSE + +-- The package author(s). +author: Foobar + +-- An email address to which users can send suggestions, bug reports, and patches. +maintainer: foobar@qux.com + +-- A copyright notice. +-- copyright: +category: Control + +-- Extra files to be distributed with the package, such as examples or a README. +extra-source-files: CHANGELOG.md diff --git a/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden b/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden new file mode 100644 index 00000000000..47924235c7f --- /dev/null +++ b/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden @@ -0,0 +1,46 @@ +cabal-version: 2.4 + +-- Initial package description 'y' generated by +-- 'cabal init'. For further documentation, see: +-- http://haskell.org/cabal/users-guide/ +-- +-- The name of the package. +name: y + +-- The package version. +-- See the Haskell package versioning policy (PVP) for standards +-- guiding when and how versions should be incremented. +-- https://pvp.haskell.org +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 0.1.0.0 + +-- A short (one-line) description of the package. +synopsis: synopsis + +-- A longer description of the package. +-- description: + +-- URL for the project homepage or repository. +homepage: home + +-- The license under which the package is released. +license: BSD-3-Clause + +-- The file containing the license text. +license-file: LICENSE + +-- The package author(s). +author: foo-kmett + +-- An email address to which users can send suggestions, bug reports, and patches. +maintainer: foo-kmett@kmett.kmett + +-- A copyright notice. +-- copyright: +category: Data +build-type: Simple + +-- Extra files to be distributed with the package, such as examples or a README. +extra-source-files: CHANGELOG.md diff --git a/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden b/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden new file mode 100644 index 00000000000..52613c0f0d7 --- /dev/null +++ b/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden @@ -0,0 +1,46 @@ +cabal-version: 2.2 + +-- Initial package description 'y' generated by +-- 'cabal init'. For further documentation, see: +-- http://haskell.org/cabal/users-guide/ +-- +-- The name of the package. +name: QuxPackage + +-- The package version. +-- See the Haskell package versioning policy (PVP) for standards +-- guiding when and how versions should be incremented. +-- https://pvp.haskell.org +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 4.2.6 + +-- A short (one-line) description of the package. +synopsis: We are Qux, and this is our package + +-- A longer description of the package. +-- description: + +-- URL for the project homepage or repository. +homepage: qux.com + +-- The license under which the package is released. +license: MIT + +-- The file containing the license text. +license-file: LICENSE + +-- The package author(s). +author: Foobar + +-- An email address to which users can send suggestions, bug reports, and patches. +maintainer: foobar@qux.com + +-- A copyright notice. +-- copyright: +category: Control +build-type: Simple + +-- Extra files to be distributed with the package, such as examples or a README. +extra-source-files: CHANGELOG.md diff --git a/tests/fixtures/init/golden/pkg-desc/pkg.golden b/tests/fixtures/init/golden/pkg-desc/pkg.golden new file mode 100644 index 00000000000..47924235c7f --- /dev/null +++ b/tests/fixtures/init/golden/pkg-desc/pkg.golden @@ -0,0 +1,46 @@ +cabal-version: 2.4 + +-- Initial package description 'y' generated by +-- 'cabal init'. For further documentation, see: +-- http://haskell.org/cabal/users-guide/ +-- +-- The name of the package. +name: y + +-- The package version. +-- See the Haskell package versioning policy (PVP) for standards +-- guiding when and how versions should be incremented. +-- https://pvp.haskell.org +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 0.1.0.0 + +-- A short (one-line) description of the package. +synopsis: synopsis + +-- A longer description of the package. +-- description: + +-- URL for the project homepage or repository. +homepage: home + +-- The license under which the package is released. +license: BSD-3-Clause + +-- The file containing the license text. +license-file: LICENSE + +-- The package author(s). +author: foo-kmett + +-- An email address to which users can send suggestions, bug reports, and patches. +maintainer: foo-kmett@kmett.kmett + +-- A copyright notice. +-- copyright: +category: Data +build-type: Simple + +-- Extra files to be distributed with the package, such as examples or a README. +extra-source-files: CHANGELOG.md diff --git a/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden b/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden new file mode 100644 index 00000000000..1377709f290 --- /dev/null +++ b/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden @@ -0,0 +1,24 @@ +test-suite y-test + -- Base language which the package is written in. + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- The interface type and version of the test suite. + type: exitcode-stdio-1.0 + + -- Directories containing source files. + hs-source-dirs: test + + -- The entrypoint to the test suite. + main-is: Main.hs + + -- Test dependencies. + build-depends: base ^>=4.14.1.0 + + -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. + build-tools: happy diff --git a/tests/fixtures/init/golden/test/test-minimal-no-comments.golden b/tests/fixtures/init/golden/test/test-minimal-no-comments.golden new file mode 100644 index 00000000000..b7560beb966 --- /dev/null +++ b/tests/fixtures/init/golden/test/test-minimal-no-comments.golden @@ -0,0 +1,6 @@ +test-suite y-test + default-language: Haskell2010 + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: base ^>=4.14.1.0 diff --git a/tests/fixtures/init/golden/test/test-simple-with-comments.golden b/tests/fixtures/init/golden/test/test-simple-with-comments.golden new file mode 100644 index 00000000000..0ebefd519b6 --- /dev/null +++ b/tests/fixtures/init/golden/test/test-simple-with-comments.golden @@ -0,0 +1,15 @@ +test-suite y-test + -- Base language which the package is written in. + default-language: Haskell2010 + + -- The interface type and version of the test suite. + type: exitcode-stdio-1.0 + + -- Directories containing source files. + hs-source-dirs: test + + -- The entrypoint to the test suite. + main-is: Main.hs + + -- Test dependencies. + build-depends: base ^>=4.14.1.0 diff --git a/tests/fixtures/init/golden/test/test-with-comments.golden b/tests/fixtures/init/golden/test/test-with-comments.golden new file mode 100644 index 00000000000..df91ae84267 --- /dev/null +++ b/tests/fixtures/init/golden/test/test-with-comments.golden @@ -0,0 +1,21 @@ +test-suite y-test + -- Base language which the package is written in. + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- The interface type and version of the test suite. + type: exitcode-stdio-1.0 + + -- Directories containing source files. + hs-source-dirs: test + + -- The entrypoint to the test suite. + main-is: Main.hs + + -- Test dependencies. + build-depends: base ^>=4.14.1.0 diff --git a/tests/fixtures/init/golden/test/test.golden b/tests/fixtures/init/golden/test/test.golden new file mode 100644 index 00000000000..6bafb438873 --- /dev/null +++ b/tests/fixtures/init/golden/test/test.golden @@ -0,0 +1,12 @@ +test-suite y-test + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: base ^>=4.14.1.0 From 5892f423943322fe66e1a3ae4ca16f7985c8bf66 Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Tue, 4 May 2021 14:13:49 -0400 Subject: [PATCH 02/37] Add changelog.d entry for #7344 --- cabal-install/main/Main.hs | 1 - .../Distribution/Client/Init/Golden.hs | 26 ------------------- changelog.d/pr-7344 | 24 +++++++++++++++++ 3 files changed, 24 insertions(+), 27 deletions(-) create mode 100644 changelog.d/pr-7344 diff --git a/cabal-install/main/Main.hs b/cabal-install/main/Main.hs index 6bb112a26a5..02c1469cadf 100644 --- a/cabal-install/main/Main.hs +++ b/cabal-install/main/Main.hs @@ -13,7 +13,6 @@ -- Entry point to the default cabal-install front-end. ----------------------------------------------------------------------------- -{-# OPTIONS_GHC -Wno-deferred-type-errors #-} module Main (main) where import Distribution.Client.Setup diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs index 34052296ef7..f7e82edded5 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs @@ -71,32 +71,6 @@ tests v initFlags _comp pkgIx srcDb = testGroup "golden" pkgName = evalPrompt (packageNamePrompt srcDb initFlags) $ fromList ["test-package", "y"] --- goldenCabalTests --- :: Verbosity --- -> InstalledPackageIndex --- -> FilePath --- -> PackageName --- -> SourcePackageDb --- -> TestTree --- goldenCabalTests v pkgIx pkgDir pkgName srcDb = testGroup ".cabal golden tests" --- [ goldenVsString "Create lib .cabal project" (goldenCabal "lib-cabal.golden") $ --- runGoldenCabal emptyFlags { packageType = Flag Library } --- , goldenVsString "Create lib+test .cabal project" (goldenCabal "lib-test-cabal.golden") $ --- runGoldenCabal emptyFlags --- { packageType = Flag Library --- , initializeTestSuite = Flag True --- } --- , goldenVsString "Create lib .cabal project" (goldenCabal "exe-cabal.golden") $ --- runGoldenCabal emptyFlags { packageType = Flag Executable } --- ] --- where --- runGoldenCabal flags = --- case _runPrompt (createProject v pkgIx srcDb flags) of --- Right (t, _) -> return . BS8.pack $ showFields' --- annCommentLines postProcessFieldLines --- 4 [mkCabalStanza opts t] --- Left e -> assertFailure $ show e - goldenPkgDescTests :: Verbosity -> SourcePackageDb diff --git a/changelog.d/pr-7344 b/changelog.d/pr-7344 new file mode 100644 index 00000000000..dc5eb40044a --- /dev/null +++ b/changelog.d/pr-7344 @@ -0,0 +1,24 @@ +synopsis: Cabal init rewrite +pr: #7344 +issues: #7273 #7256 #7255 #7251 #6758 #6864 #1074 +significance: significant +description: { + +- Restructures the `cabal init` command to fix historical + issues. All flags are preserved. + - Codebases for interactive and non-interactive flags + are disentangled. + - Data structures now exploit relevant stanza structure + and formatters only care about stanza data + - Heuristics and prompts have a pure and impure implementation. + +- Sets default behavior to be `--interactive` as opposed to + `--non-interactive`. + +- Rewrites tests to achieve 98% coverage + - Golden files now test every stanza individually + - Every flag is covered by a unit test + - Interactive, simple, and non-interactive workflows are + covered. + +} \ No newline at end of file From 186d448f97232629597acb8cd95a6c8ecf430a48 Mon Sep 17 00:00:00 2001 From: Patrick Augusto Date: Tue, 4 May 2021 18:54:05 -0300 Subject: [PATCH 03/37] Changing to canonicalizePathNoThrow to prevent exceptions --- .../Distribution/Client/Init/NonInteractive/Heuristics.hs | 2 +- cabal-install/src/Distribution/Client/Init/Types.hs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs index 93348ada043..c8e9b9dcee1 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs @@ -85,7 +85,7 @@ guessLanguage = do -- | Guess the package name based on the given root directory. guessPackageName :: Interactive m => FilePath -> m PackageName guessPackageName = fmap (mkPackageName . repair . fromMaybe "" . safeLast . splitDirectories) - . tryCanonicalizePath + . canonicalizePathNoThrow where -- Treat each span of non-alphanumeric characters as a hyphen. Each -- hyphenated component of a package name must contain at least one diff --git a/cabal-install/src/Distribution/Client/Init/Types.hs b/cabal-install/src/Distribution/Client/Init/Types.hs index c80a0f80683..3d19b97f5f2 100644 --- a/cabal-install/src/Distribution/Client/Init/Types.hs +++ b/cabal-install/src/Distribution/Client/Init/Types.hs @@ -301,7 +301,7 @@ class Monad m => Interactive m where listDirectory :: FilePath -> m [FilePath] doesDirectoryExist :: FilePath -> m Bool doesFileExist :: FilePath -> m Bool - tryCanonicalizePath :: FilePath -> m FilePath + canonicalizePathNoThrow :: FilePath -> m FilePath readProcessWithExitCode :: FilePath -> [String] -> String -> m (ExitCode, String, String) getEnvironment :: m [(String, String)] listFilesInside :: (FilePath -> m Bool) -> FilePath -> m [FilePath] @@ -329,7 +329,7 @@ instance Interactive IO where listDirectory = P.listDirectory doesDirectoryExist = P.doesDirectoryExist doesFileExist = P.doesFileExist - tryCanonicalizePath = P.tryCanonicalizePath + canonicalizePathNoThrow = P.canonicalizePathNoThrow readProcessWithExitCode = P.readProcessWithExitCode getEnvironment = P.getEnvironment listFilesInside = P.listFilesInside @@ -356,7 +356,7 @@ instance Interactive PurePrompt where listDirectory !_ = popList doesDirectoryExist !_ = popBool doesFileExist !_ = popBool - tryCanonicalizePath !_ = popAbsolute + canonicalizePathNoThrow !_ = popAbsolute readProcessWithExitCode !_ !_ !_ = do input <- pop return (ExitSuccess, input, "") From 6a7621c6530bcb39aee0ab95abaf0eed727bd916 Mon Sep 17 00:00:00 2001 From: Patrick Augusto Date: Tue, 4 May 2021 18:55:50 -0300 Subject: [PATCH 04/37] Preppending the package dir to the app dir --- .../Distribution/Client/Init/NonInteractive/Heuristics.hs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs index c8e9b9dcee1..9f32105d4d9 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs @@ -144,13 +144,14 @@ guessPackageType flags = do -- using a default value as fallback. guessApplicationDirectories :: Interactive m => InitFlags -> m [FilePath] guessApplicationDirectories flags = do - pkgDirs <- listDirectory =<< fromFlagOrDefault getCurrentDirectory + pkgDirs <- fromFlagOrDefault getCurrentDirectory (fmap return $ packageDir flags) + pkgDirsContents <- listDirectory pkgDirs let candidates = [defaultApplicationDir, "app", "src-exe"] in - return $ case [y | x <- candidates, y <- pkgDirs, x == y] of + return $ case [y | x <- candidates, y <- pkgDirsContents, x == y] of [] -> [defaultApplicationDir] - x -> nub x + x -> map ( pkgDirs) . nub $ x -- | Try to guess the source directories, using a default value as fallback. guessSourceDirectories :: Interactive m => InitFlags -> m [FilePath] From 7c82d28914838c5b875eab12cdeceb2017ed4559 Mon Sep 17 00:00:00 2001 From: Patrick Augusto Date: Tue, 4 May 2021 20:07:14 -0300 Subject: [PATCH 05/37] Using the compiler version from Distribution.Simple.Compiler --- cabal-install/src/Distribution/Client/Init.hs | 2 +- .../Client/Init/Interactive/Command.hs | 4 +- .../Client/Init/NonInteractive/Command.hs | 35 +++++---- .../Client/Init/NonInteractive/Heuristics.hs | 16 ++-- .../src/Distribution/Client/Init/Simple.hs | 4 +- .../Distribution/Client/Init/Golden.hs | 9 ++- .../Distribution/Client/Init/Interactive.hs | 21 ++--- .../Client/Init/NonInteractive.hs | 77 ++++++++----------- .../Distribution/Client/Init/Simple.hs | 17 ++-- 9 files changed, 89 insertions(+), 96 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init.hs b/cabal-install/src/Distribution/Client/Init.hs index c463907581c..25109531eff 100644 --- a/cabal-install/src/Distribution/Client/Init.hs +++ b/cabal-install/src/Distribution/Client/Init.hs @@ -45,7 +45,7 @@ initCmd v packageDBs repoCtxt comp progdb initFlags = do installedPkgIndex <- getInstalledPackages v comp packageDBs progdb sourcePkgDb <- getSourcePackages v repoCtxt hSetBuffering stdout NoBuffering - settings <- createProject v installedPkgIndex sourcePkgDb initFlags + settings <- createProject v comp installedPkgIndex sourcePkgDb initFlags writeProject settings where -- When no flag is set, default to interactive. diff --git a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs index 2aef676763a..26720985de6 100644 --- a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs @@ -61,6 +61,7 @@ import Distribution.Client.Types (SourcePackageDb(..)) import Distribution.Solver.Types.PackageIndex (elemByPackageName) import Language.Haskell.Extension (Language(..)) +import Distribution.Simple.Compiler @@ -69,11 +70,12 @@ import Language.Haskell.Extension (Language(..)) createProject :: Interactive m => Verbosity + -> Compiler -> InstalledPackageIndex -> SourcePackageDb -> InitFlags -> m ProjectSettings -createProject v pkgIx srcDb initFlags = do +createProject v _comp pkgIx srcDb initFlags = do -- The workflow is as follows: -- diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs index 939f0e134b2..b73243596dd 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs @@ -60,6 +60,7 @@ import Distribution.Utils.Generic (safeHead) import Language.Haskell.Extension (Language(..), Extension(..)) import System.FilePath (splitDirectories, ()) +import Distribution.Simple.Compiler -- | Main driver for interactive prompt code. @@ -67,11 +68,12 @@ import System.FilePath (splitDirectories, ()) createProject :: Interactive m => Verbosity + -> Compiler -> InstalledPackageIndex -> SourcePackageDb -> InitFlags -> m ProjectSettings -createProject v pkgIx srcDb initFlags = do +createProject v comp pkgIx srcDb initFlags = do -- The workflow is as follows: -- @@ -109,24 +111,24 @@ createProject v pkgIx srcDb initFlags = do case pkgType of Library -> do - libTarget <- genLibTarget initFlags pkgIx - testTarget <- genTestTarget initFlags pkgIx + libTarget <- genLibTarget initFlags comp pkgIx + testTarget <- genTestTarget initFlags comp pkgIx return $ ProjectSettings (mkOpts comments) pkgDesc (Just libTarget) Nothing testTarget Executable -> do - exeTarget <- genExeTarget initFlags pkgIx + exeTarget <- genExeTarget initFlags comp pkgIx return $ ProjectSettings (mkOpts comments) pkgDesc Nothing (Just exeTarget) Nothing LibraryAndExecutable -> do - libTarget <- genLibTarget initFlags pkgIx - exeTarget <- genExeTarget initFlags pkgIx - testTarget <- genTestTarget initFlags pkgIx + libTarget <- genLibTarget initFlags comp pkgIx + exeTarget <- genExeTarget initFlags comp pkgIx + testTarget <- genTestTarget initFlags comp pkgIx return $ ProjectSettings (mkOpts comments) pkgDesc (Just libTarget) @@ -152,13 +154,14 @@ genPkgDescription flags srcDb = PkgDescription genLibTarget :: Interactive m => InitFlags + -> Compiler -> InstalledPackageIndex -> m LibTarget -genLibTarget flags pkgs = do +genLibTarget flags comp pkgs = do srcDirs <- srcDirsHeuristics flags let srcDir = fromMaybe defaultSourceDir $ safeHead srcDirs LibTarget srcDirs - <$> languageHeuristics flags + <$> languageHeuristics flags comp <*> exposedModulesHeuristics flags <*> libOtherModulesHeuristics flags <*> otherExtsHeuristics flags srcDir @@ -168,15 +171,16 @@ genLibTarget flags pkgs = do genExeTarget :: Interactive m => InitFlags + -> Compiler -> InstalledPackageIndex -> m ExeTarget -genExeTarget flags pkgs = do +genExeTarget flags comp pkgs = do appDirs <- appDirsHeuristics flags let appDir = fromMaybe defaultApplicationDir $ safeHead appDirs ExeTarget <$> mainFileHeuristics flags <*> pure appDirs - <*> languageHeuristics flags + <*> languageHeuristics flags comp <*> exeOtherModulesHeuristics flags <*> otherExtsHeuristics flags appDir <*> dependenciesHeuristics flags appDir pkgs @@ -185,9 +189,10 @@ genExeTarget flags pkgs = do genTestTarget :: Interactive m => InitFlags + -> Compiler -> InstalledPackageIndex -> m (Maybe TestTarget) -genTestTarget flags pkgs = do +genTestTarget flags comp pkgs = do initialized <- initializeTestSuiteHeuristics flags testDirs' <- testDirsHeuristics flags let testDir = fromMaybe defaultTestDir $ safeHead testDirs' @@ -196,7 +201,7 @@ genTestTarget flags pkgs = do else fmap Just $ TestTarget <$> testMainHeuristics flags <*> pure testDirs' - <*> languageHeuristics flags + <*> languageHeuristics flags comp <*> testOtherModulesHeuristics flags <*> otherExtsHeuristics flags testDir <*> dependenciesHeuristics flags testDir pkgs @@ -304,8 +309,8 @@ testDirsHeuristics :: Interactive m => InitFlags -> m [String] testDirsHeuristics flags = getTestDirs flags $ return [defaultTestDir] -- | Ask for the Haskell base language of the package. -languageHeuristics :: Interactive m => InitFlags -> m Language -languageHeuristics flags = getLanguage flags guessLanguage +languageHeuristics :: Interactive m => InitFlags -> Compiler -> m Language +languageHeuristics flags comp = getLanguage flags $ guessLanguage comp -- | Ask whether to generate explanatory comments. noCommentsHeuristics :: Interactive m => InitFlags -> m Bool diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs index 9f32105d4d9..9bc3be80b70 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs @@ -44,6 +44,7 @@ import Distribution.CabalSpecVersion import Language.Haskell.Extension import Distribution.Version import Distribution.Types.PackageName (PackageName, mkPackageName) +import Distribution.Simple.Compiler @@ -72,15 +73,12 @@ guessCabalSpecVersion = do format' (x:xs) = x : format' xs -- | Guess the language specification based on the GHC version -guessLanguage :: Interactive m => m Language -guessLanguage = do - (_, verString, _) <- readProcessWithExitCode "ghc" ["--version"] "" - case simpleParsec <$> runParser versionParser () "" verString of - Right (Just ver) -> return $ - if ver < mkVersion [7,0,1] - then Haskell98 - else Haskell2010 - _ -> return defaultLanguage +guessLanguage :: Interactive m => Compiler -> m Language +guessLanguage Compiler {compilerId = CompilerId GHC ver} = + return $ if ver < mkVersion [7,0,1] + then Haskell98 + else Haskell2010 +guessLanguage _ = return defaultLanguage -- | Guess the package name based on the given root directory. guessPackageName :: Interactive m => FilePath -> m PackageName diff --git a/cabal-install/src/Distribution/Client/Init/Simple.hs b/cabal-install/src/Distribution/Client/Init/Simple.hs index d93134e56e1..de8ecaff3ed 100644 --- a/cabal-install/src/Distribution/Client/Init/Simple.hs +++ b/cabal-install/src/Distribution/Client/Init/Simple.hs @@ -18,16 +18,18 @@ import Distribution.Client.Init.Utils (currentDirPkgName, mkPackageNameDep) import Distribution.Client.Init.Defaults import Distribution.Simple.Flag (fromFlagOrDefault, flagElim) import Distribution.Client.Init.FlagExtractors +import Distribution.Simple.Compiler createProject :: Interactive m => Verbosity + -> Compiler -> InstalledPackageIndex -> SourcePackageDb -> InitFlags -> m ProjectSettings -createProject v _pkgIx _srcDb initFlags = do +createProject v _comp _pkgIx _srcDb initFlags = do pkgType <- packageTypePrompt initFlags isMinimal <- getMinimal initFlags doOverwrite <- getOverwrite initFlags diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs index f7e82edded5..20233d37634 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs @@ -58,12 +58,12 @@ tests -> InstalledPackageIndex -> SourcePackageDb -> TestTree -tests v initFlags _comp pkgIx srcDb = testGroup "golden" +tests v initFlags comp pkgIx srcDb = testGroup "golden" [ goldenLibTests v pkgIx pkgDir pkgName , goldenExeTests v pkgIx pkgDir pkgName , goldenTestTests v pkgIx pkgDir pkgName , goldenPkgDescTests v srcDb pkgDir pkgName - , goldenCabalTests v pkgIx srcDb + , goldenCabalTests v comp pkgIx srcDb ] where pkgDir = evalPrompt (getPackageDir initFlags) @@ -232,10 +232,11 @@ goldenTestTests v pkgIx pkgDir pkgName = testGroup "test golden tests" -- | Full cabal file golden tests goldenCabalTests :: Verbosity + -> Compiler -> InstalledPackageIndex -> SourcePackageDb -> TestTree -goldenCabalTests v pkgIx srcDb = testGroup ".cabal file golden tests" +goldenCabalTests v comp pkgIx srcDb = testGroup ".cabal file golden tests" [ goldenVsString "Library and executable, empty flags, not simple, with comments + no minimal" (goldenCabal "cabal-lib-and-exe-with-comments.golden") $ runGoldenTest (fullProjArgs "Y") emptyFlags @@ -254,7 +255,7 @@ goldenCabalTests v pkgIx srcDb = testGroup ".cabal file golden tests" ] where runGoldenTest args flags = - case _runPrompt (createProject v pkgIx srcDb flags) args of + case _runPrompt (createProject v comp pkgIx srcDb flags) args of Left e -> assertFailure $ show e (Right (ProjectSettings opts pkgDesc (Just libTarget) (Just exeTarget) (Just testTarget), _)) -> do diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs index 4b85e741f07..8fc2205fc85 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs @@ -39,9 +39,9 @@ tests -> InstalledPackageIndex -> SourcePackageDb -> TestTree -tests _v initFlags _comp pkgIx srcDb = +tests _v initFlags comp pkgIx srcDb = testGroup "Distribution.Client.Init.Interactive.Command.hs" - [ createProjectTest pkgIx srcDb + [ createProjectTest comp pkgIx srcDb , fileCreatorTests pkgIx srcDb pkgName , interactiveTests srcDb ] @@ -52,10 +52,11 @@ tests _v initFlags _comp pkgIx srcDb = -- pkgNm = evalPrompt (getPackageName srcDb initFlags) $ fromList ["test-package", "y"] createProjectTest - :: InstalledPackageIndex + :: Compiler + -> InstalledPackageIndex -> SourcePackageDb -> TestTree -createProjectTest pkgIx srcDb = testGroup "createProject tests" +createProjectTest comp pkgIx srcDb = testGroup "createProject tests" [ testGroup "with flags" [ testCase "Check the non-interactive workflow" $ do let dummyFlags' = dummyFlags @@ -72,7 +73,7 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" , dependencies = Flag [] } - case (_runPrompt $ createProject silent pkgIx srcDb dummyFlags') (fromList ["3", "quxTest/Main.hs"]) of + case (_runPrompt $ createProject silent comp pkgIx srcDb dummyFlags') (fromList ["3", "quxTest/Main.hs"]) of Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -174,7 +175,7 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" , "y" ] - case (_runPrompt $ createProject silent pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of + case (_runPrompt $ createProject silent comp pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -267,7 +268,7 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" , "y" ] - case (_runPrompt $ createProject silent pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of + case (_runPrompt $ createProject silent comp pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of Right (ProjectSettings opts desc (Just lib) Nothing (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -355,7 +356,7 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" , "y" ] - case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + case (_runPrompt $ createProject silent comp pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc (Just lib) (Just exe) Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -435,7 +436,7 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" , "y" ] - case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + case (_runPrompt $ createProject silent comp pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc (Just lib) Nothing Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -507,7 +508,7 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" , "y" ] - case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + case (_runPrompt $ createProject silent comp pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc Nothing (Just exe) Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs index 69e38d31609..2b57c11073d 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs @@ -20,6 +20,7 @@ import Distribution.Verbosity import Distribution.CabalSpecVersion import Distribution.ModuleName (fromString) import Distribution.Simple.Flag +import Data.List (foldl') tests :: Verbosity @@ -28,24 +29,25 @@ tests -> InstalledPackageIndex -> SourcePackageDb -> TestTree -tests _v _initFlags _comp pkgIx srcDb = +tests _v _initFlags comp pkgIx srcDb = testGroup "cabal init non-interactive" [ testGroup "driver function test" - [ driverFunctionTest pkgIx srcDb + [ driverFunctionTest pkgIx srcDb comp ] , testGroup "target creator tests" - [ fileCreatorTests pkgIx srcDb + [ fileCreatorTests pkgIx srcDb comp ] , testGroup "non-interactive tests" - [ nonInteractiveTests pkgIx srcDb + [ nonInteractiveTests pkgIx srcDb comp ] ] driverFunctionTest :: InstalledPackageIndex -> SourcePackageDb + -> Compiler -> TestTree -driverFunctionTest pkgIx srcDb = testGroup "createProject" +driverFunctionTest pkgIx srcDb comp = testGroup "createProject" [ testGroup "with flags" [ testCase "Check the non-interactive workflow 1" $ do let dummyFlags' = dummyFlags @@ -65,7 +67,7 @@ driverFunctionTest pkgIx srcDb = testGroup "createProject" [ "[\"quxTest/Main.hs\"]" ] - case (_runPrompt $ createProject silent pkgIx srcDb dummyFlags') inputs of + case (_runPrompt $ createProject silent comp pkgIx srcDb dummyFlags') inputs of Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -143,7 +145,7 @@ driverFunctionTest pkgIx srcDb = testGroup "createProject" , "False" ] - case (_runPrompt $ createProject silent pkgIx srcDb dummyFlags') inputs of + case (_runPrompt $ createProject silent comp pkgIx srcDb dummyFlags') inputs of Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -221,8 +223,6 @@ driverFunctionTest pkgIx srcDb = testGroup "createProject" -- source dirs , "src" , "True" - -- language - , "The Glorious Glasgow Haskell Compilation System, version 8.8.4" -- exposed modules , "src" , "True" @@ -261,8 +261,6 @@ driverFunctionTest pkgIx srcDb = testGroup "createProject" , "test-package" , "[\"test-package/app/\"]" , "[]" - -- language - , "The Glorious Glasgow Haskell Compilation System, version 7.10.3" -- other modules , "test-package" , "True" @@ -284,8 +282,6 @@ driverFunctionTest pkgIx srcDb = testGroup "createProject" -- test target -- main file , "[\"test-package/test/\"]" - -- language - , "The Glorious Glasgow Haskell Compilation System, version 7.10.3" -- other modules , "test-package" , "True" @@ -306,7 +302,7 @@ driverFunctionTest pkgIx srcDb = testGroup "createProject" , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/bar.y\"]" ] - case (_runPrompt $ createProject silent pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of + case (_runPrompt $ createProject silent comp pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -381,8 +377,6 @@ driverFunctionTest pkgIx srcDb = testGroup "createProject" -- source dirs , "src" , "True" - -- language - , "The Glorious Glasgow Haskell Compilation System, version 8.8.4" -- exposed modules , "src" , "True" @@ -416,8 +410,6 @@ driverFunctionTest pkgIx srcDb = testGroup "createProject" -- test target -- main file , "[\"test-package/test/\"]" - -- language - , "The Glorious Glasgow Haskell Compilation System, version 7.10.3" -- other modules , "test-package" , "True" @@ -438,7 +430,7 @@ driverFunctionTest pkgIx srcDb = testGroup "createProject" , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/bar.y\"]" ] - case (_runPrompt $ createProject silent pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of + case (_runPrompt $ createProject silent comp pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of Right (ProjectSettings opts desc (Just lib) Nothing (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -508,8 +500,6 @@ driverFunctionTest pkgIx srcDb = testGroup "createProject" -- source dirs , "src" , "True" - -- language - , "The Glorious Glasgow Haskell Compilation System, version 8.8.4" -- exposed modules , "src" , "True" @@ -548,8 +538,6 @@ driverFunctionTest pkgIx srcDb = testGroup "createProject" , "test-package" , "[\"test-package/app/\"]" , "[]" - -- language - , "The Glorious Glasgow Haskell Compilation System, version 7.10.3" -- other modules , "test-package" , "True" @@ -570,7 +558,7 @@ driverFunctionTest pkgIx srcDb = testGroup "createProject" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] - case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + case (_runPrompt $ createProject silent comp pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc (Just lib) (Just exe) Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -639,8 +627,6 @@ driverFunctionTest pkgIx srcDb = testGroup "createProject" -- source dirs , "src" , "True" - -- language - , "The Glorious Glasgow Haskell Compilation System, version 8.8.4" -- exposed modules , "src" , "True" @@ -673,7 +659,7 @@ driverFunctionTest pkgIx srcDb = testGroup "createProject" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] - case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + case (_runPrompt $ createProject silent comp pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc (Just lib) Nothing Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -738,8 +724,6 @@ driverFunctionTest pkgIx srcDb = testGroup "createProject" , "test-package" , "[\"test-package/app/\"]" , "[]" - -- language - , "The Glorious Glasgow Haskell Compilation System, version 7.10.3" -- other modules , "test-package" , "True" @@ -760,7 +744,7 @@ driverFunctionTest pkgIx srcDb = testGroup "createProject" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] - case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of + case (_runPrompt $ createProject silent comp pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc Nothing (Just exe) Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -800,8 +784,9 @@ driverFunctionTest pkgIx srcDb = testGroup "createProject" fileCreatorTests :: InstalledPackageIndex -> SourcePackageDb + -> Compiler -> TestTree -fileCreatorTests pkgIx srcDb = testGroup "generators" +fileCreatorTests pkgIx srcDb comp = testGroup "generators" [ testGroup "genPkgDescription" [ testCase "Check common package flags workflow" $ do let inputs = NEL.fromList @@ -831,8 +816,6 @@ fileCreatorTests pkgIx srcDb = testGroup "generators" -- source dirs [ "src" , "True" - -- language - , "The Glorious Glasgow Haskell Compilation System, version 7.10.3" -- exposed modules , "src" , "True" @@ -865,7 +848,7 @@ fileCreatorTests pkgIx srcDb = testGroup "generators" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] - case (_runPrompt $ genLibTarget emptyFlags pkgIx) inputs of + case (_runPrompt $ genLibTarget emptyFlags comp pkgIx) inputs of Left e -> assertFailure $ show e Right{} -> return () ] @@ -879,8 +862,6 @@ fileCreatorTests pkgIx srcDb = testGroup "generators" , "test-package" , "[\"test-package/app/\"]" , "[]" - -- language - , "The Glorious Glasgow Haskell Compilation System, version 7.10.3" -- other modules , "test-package" , "True" @@ -901,7 +882,7 @@ fileCreatorTests pkgIx srcDb = testGroup "generators" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] - case (_runPrompt $ genExeTarget emptyFlags pkgIx) inputs of + case (_runPrompt $ genExeTarget emptyFlags comp pkgIx) inputs of Left e -> assertFailure $ show e Right{} -> return () ] @@ -910,8 +891,6 @@ fileCreatorTests pkgIx srcDb = testGroup "generators" let inputs = NEL.fromList -- main file [ "[]" - -- language - , "The Glorious Glasgow Haskell Compilation System, version 7.10.3" -- other modules , "test-package" , "True" @@ -932,7 +911,7 @@ fileCreatorTests pkgIx srcDb = testGroup "generators" , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/bar.y\"]" ] - case (_runPrompt $ genTestTarget (emptyFlags {initializeTestSuite = Flag True}) pkgIx) inputs of + case (_runPrompt $ genTestTarget (emptyFlags {initializeTestSuite = Flag True}) comp pkgIx) inputs of Left e -> assertFailure $ show e Right{} -> return () ] @@ -941,8 +920,9 @@ fileCreatorTests pkgIx srcDb = testGroup "generators" nonInteractiveTests :: InstalledPackageIndex -> SourcePackageDb + -> Compiler -> TestTree -nonInteractiveTests _pkgIx srcDb = testGroup "Check top level getter functions" +nonInteractiveTests pkgIx srcDb comp = testGroup "Check top level getter functions" [ testGroup "Simple heuristics tests" [ testGroup "Check packageNameHeuristics output" [ testSimple "New package name" (packageNameHeuristics srcDb) @@ -993,12 +973,15 @@ nonInteractiveTests _pkgIx srcDb = testGroup "Check top level getter functions" ["cabal-install version 2.4.0.0\ncompiled using version 2.4.0.0 of the Cabal library \n"] ] , testGroup "Check languageHeuristics output" - [ testSimple "No compiler at all" languageHeuristics Haskell2010 - [""] - , testSimple "Higher version compiler" languageHeuristics Haskell2010 - ["The Glorious Glasgow Haskell Compilation System, version 7.10.3"] - , testSimple "Lower version compiler" languageHeuristics Haskell98 - ["The Glorious Glasgow Haskell Compilation System, version 6.4.2"] + [ testSimple "Non GHC compiler" + (`languageHeuristics` (comp {compilerId = CompilerId Helium $ mkVersion [1,8,1]})) + Haskell2010 [] + , testSimple "Higher version compiler" + (`languageHeuristics` (comp {compilerId = CompilerId GHC $ mkVersion [8,10,4]})) + Haskell2010 [] + , testSimple "Lower version compiler" + (`languageHeuristics` (comp {compilerId = CompilerId GHC $ mkVersion [6,0,1]})) + Haskell98 [] ] , testGroup "Check extraSourceFilesHeuristics output" [ testSimple "No extra sources" extraSourceFilesHeuristics diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs index 059fc334c89..a7ae4892708 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs @@ -33,19 +33,20 @@ tests -> InstalledPackageIndex -> SourcePackageDb -> TestTree -tests v _initFlags _comp pkgIx srcDb = testGroup "Distribution.Client.Init.Simple.hs" - [ simpleCreateProjectTests v pkgIx srcDb pkgName +tests v _initFlags comp pkgIx srcDb = testGroup "Distribution.Client.Init.Simple.hs" + [ simpleCreateProjectTests v comp pkgIx srcDb pkgName ] where pkgName = mkPackageName "simple-test" simpleCreateProjectTests :: Verbosity + -> Compiler -> InstalledPackageIndex -> SourcePackageDb -> PackageName -> TestTree -simpleCreateProjectTests v pkgIx srcDb pkgName = +simpleCreateProjectTests v comp pkgIx srcDb pkgName = testGroup "Simple createProject tests" [ testCase "Simple lib createProject - no tests" $ do let inputs = fromList @@ -60,7 +61,7 @@ simpleCreateProjectTests v pkgIx srcDb pkgName = (simplePkgDesc pkgName) (Just simpleLibTarget) Nothing Nothing - case _runPrompt (createProject v pkgIx srcDb flags) inputs of + case _runPrompt (createProject v comp pkgIx srcDb flags) inputs of Left e -> assertFailure $ "Failed to create simple lib project: " ++ show e Right (settings', _) -> settings @=? settings' @@ -72,7 +73,7 @@ simpleCreateProjectTests v pkgIx srcDb pkgName = (simplePkgDesc pkgName) (Just simpleLibTarget) Nothing (Just $ simpleTestTarget (Just pkgName)) - case _runPrompt (createProject v pkgIx srcDb flags) inputs of + case _runPrompt (createProject v comp pkgIx srcDb flags) inputs of Left e -> assertFailure $ "Failed to create simple lib (with tests)project: " ++ show e Right (settings', _) -> settings @=? settings' @@ -84,7 +85,7 @@ simpleCreateProjectTests v pkgIx srcDb pkgName = (simplePkgDesc pkgName) Nothing (Just $ simpleExeTarget Nothing) Nothing - case _runPrompt (createProject v pkgIx srcDb flags) inputs of + case _runPrompt (createProject v comp pkgIx srcDb flags) inputs of Left e -> assertFailure $ "Failed to create simple exe project: " ++ show e Right (settings', _) -> settings @=? settings' @@ -96,7 +97,7 @@ simpleCreateProjectTests v pkgIx srcDb pkgName = (simplePkgDesc pkgName) (Just simpleLibTarget) (Just $ simpleExeTarget (Just pkgName)) Nothing - case _runPrompt (createProject v pkgIx srcDb flags) inputs of + case _runPrompt (createProject v comp pkgIx srcDb flags) inputs of Left e -> assertFailure $ "Failed to create simple lib+exe project: " ++ show e Right (settings', _) -> settings @=? settings' , testCase "Simple lib+exe createProject - with tests" $ do @@ -108,7 +109,7 @@ simpleCreateProjectTests v pkgIx srcDb pkgName = (Just $ simpleExeTarget (Just pkgName)) (Just $ simpleTestTarget (Just pkgName)) - case _runPrompt (createProject v pkgIx srcDb flags) inputs of + case _runPrompt (createProject v comp pkgIx srcDb flags) inputs of Left e -> assertFailure $ "Failed to create simple lib+exe (with tests) project: " ++ show e Right (settings', _) -> settings @=? settings' ] From 299db9a7043e8f11d4a5bad38f66f2bc62f237ca Mon Sep 17 00:00:00 2001 From: Patrick Augusto Date: Tue, 4 May 2021 20:35:47 -0300 Subject: [PATCH 06/37] Adding tests for base version bounds --- .../Client/Init/NonInteractive.hs | 10 ++++ .../Distribution/Client/Init/Utils.hs | 55 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs index 2b57c11073d..921b0a6ec04 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs @@ -1082,6 +1082,16 @@ nonInteractiveTests pkgIx srcDb comp = testGroup "Check top level getter functio , "False" ] ] + , testGroup "Check dependenciesHeuristics output" + [ testSimple "base version bounds is correct" + (fmap + (flip foldl' anyVersion $ \a (Dependency n v _) -> + if unPackageName n == "base" then v else a) + . (\x -> dependenciesHeuristics x "" pkgIx)) + (baseVersion comp) + [ "[]" + ] + ] , testSimple "Check buildToolsHeuristics output" (`buildToolsHeuristics` "") ["happy"] ["[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]"] , testSimple "Check otherExtsHeuristics output" (`otherExtsHeuristics` "") diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs index 199f6f6eb67..1c7bfc9e174 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs @@ -2,6 +2,7 @@ module UnitTests.Distribution.Client.Init.Utils ( dummyFlags , emptyFlags , mkLicense +, baseVersion , mangleBaseDep , (@?!) , (@!?) @@ -20,6 +21,8 @@ import Language.Haskell.Extension import Test.Tasty.HUnit import Distribution.Types.Dependency import Distribution.Types.VersionRange +import Distribution.Simple.Compiler +import Distribution.Pretty -- -------------------------------------------------------------------- -- @@ -47,6 +50,58 @@ dummyFlags = emptyFlags emptyFlags :: InitFlags emptyFlags = mempty +-- | Retireves the proper base version based on the GHC version +baseVersion :: Compiler -> VersionRange +baseVersion Compiler {compilerId = CompilerId GHC ver} = + let ghcToBase = baseVersion' . prettyShow $ ver in + if null ghcToBase + then anyVersion + else majorBoundVersion $ mkVersion ghcToBase +baseVersion _ = anyVersion + +baseVersion' :: String -> [Int] +baseVersion' "9.0.1" = [4,15,0,0] +baseVersion' "8.10.4" = [4,14,1,0] +baseVersion' "8.10.3" = [4,14,1,0] +baseVersion' "8.10.2" = [4,14,1,0] +baseVersion' "8.10.1" = [4,14,0,0] +baseVersion' "8.8.4" = [4,13,0,0] +baseVersion' "8.8.3" = [4,13,0,0] +baseVersion' "8.8.2" = [4,13,0,0] +baseVersion' "8.8.1" = [4,13,0,0] +baseVersion' "8.6.5" = [4,12,0,0] +baseVersion' "8.6.4" = [4,12,0,0] +baseVersion' "8.6.3" = [4,12,0,0] +baseVersion' "8.6.2" = [4,12,0,0] +baseVersion' "8.6.1" = [4,12,0,0] +baseVersion' "8.4.4" = [4,11,1,0] +baseVersion' "8.4.3" = [4,11,1,0] +baseVersion' "8.4.2" = [4,11,1,0] +baseVersion' "8.4.1" = [4,11,0,0] +baseVersion' "8.2.2" = [4,10,1,0] +baseVersion' "8.2.1" = [4,10,0,0] +baseVersion' "8.0.2" = [4,10,0,0] +baseVersion' "8.0.1" = [4,9,1,0] +baseVersion' "7.10.3" = [4,9,0,0] +baseVersion' "7.10.2" = [4,8,2,0] +baseVersion' "7.10.1" = [4,8,1,0] +baseVersion' "7.8.4" = [4,8,0,0] +baseVersion' "7.8.3" = [4,7,0,2] +baseVersion' "7.8.2" = [4,7,0,1] +baseVersion' "7.8.1" = [4,7,0,0] +baseVersion' "7.6.3" = [4,7,0,0] +baseVersion' "7.6.2" = [4,6,0,1] +baseVersion' "7.6.1" = [4,6,0,0] +baseVersion' "7.4.2" = [4,5,1,0] +baseVersion' "7.4.1" = [4,5,0,0] +baseVersion' "7.2.2" = [4,4,1,0] +baseVersion' "7.2.1" = [4,4,0,0] +baseVersion' "7.0.4" = [4,3,1,0] +baseVersion' "7.0.3" = [4,3,1,0] +baseVersion' "7.0.2" = [4,3,1,0] +baseVersion' "7.0.1" = [4,3,0,0] +baseVersion' _ = [] + -- -------------------------------------------------------------------- -- -- Test utils From b5b1865568e46a9ffb97ce779f025d4a4ca284e4 Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Wed, 5 May 2021 08:34:44 -0400 Subject: [PATCH 07/37] revert compiler argument in createProject --- cabal-install/src/Distribution/Client/Init.hs | 4 +-- .../Client/Init/Interactive/Command.hs | 5 +--- .../Client/Init/NonInteractive/Command.hs | 6 ++--- .../src/Distribution/Client/Init/Prompt.hs | 2 ++ .../src/Distribution/Client/Init/Simple.hs | 4 +-- .../UnitTests/Distribution/Client/Init.hs | 6 ++--- .../Distribution/Client/Init/Golden.hs | 15 +++++------ .../Distribution/Client/Init/Interactive.hs | 25 ++++++++----------- .../Client/Init/NonInteractive.hs | 20 +++++++-------- .../Distribution/Client/Init/Simple.hs | 19 ++++++-------- 10 files changed, 47 insertions(+), 59 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init.hs b/cabal-install/src/Distribution/Client/Init.hs index 25109531eff..bf8c1f9d397 100644 --- a/cabal-install/src/Distribution/Client/Init.hs +++ b/cabal-install/src/Distribution/Client/Init.hs @@ -45,7 +45,7 @@ initCmd v packageDBs repoCtxt comp progdb initFlags = do installedPkgIndex <- getInstalledPackages v comp packageDBs progdb sourcePkgDb <- getSourcePackages v repoCtxt hSetBuffering stdout NoBuffering - settings <- createProject v comp installedPkgIndex sourcePkgDb initFlags + settings <- createProject v installedPkgIndex sourcePkgDb initFlags writeProject settings where -- When no flag is set, default to interactive. @@ -62,4 +62,4 @@ initCmd v packageDBs repoCtxt comp progdb initFlags = do | fromFlagOrDefault False (simpleProject initFlags) -> Simple.createProject | otherwise -> Interactive.createProject - Flag False -> NonInteractive.createProject + Flag False -> NonInteractive.createProject comp diff --git a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs index 26720985de6..1705dd5aefc 100644 --- a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs @@ -61,8 +61,6 @@ import Distribution.Client.Types (SourcePackageDb(..)) import Distribution.Solver.Types.PackageIndex (elemByPackageName) import Language.Haskell.Extension (Language(..)) -import Distribution.Simple.Compiler - -- | Main driver for interactive prompt code. @@ -70,12 +68,11 @@ import Distribution.Simple.Compiler createProject :: Interactive m => Verbosity - -> Compiler -> InstalledPackageIndex -> SourcePackageDb -> InitFlags -> m ProjectSettings -createProject v _comp pkgIx srcDb initFlags = do +createProject v pkgIx srcDb initFlags = do -- The workflow is as follows: -- diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs index b73243596dd..ba67052ebf8 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs @@ -67,13 +67,13 @@ import Distribution.Simple.Compiler -- createProject :: Interactive m - => Verbosity - -> Compiler + => Compiler + -> Verbosity -> InstalledPackageIndex -> SourcePackageDb -> InitFlags -> m ProjectSettings -createProject v comp pkgIx srcDb initFlags = do +createProject comp v pkgIx srcDb initFlags = do -- The workflow is as follows: -- diff --git a/cabal-install/src/Distribution/Client/Init/Prompt.hs b/cabal-install/src/Distribution/Client/Init/Prompt.hs index ebc995f2ef5..efe539a51a0 100644 --- a/cabal-install/src/Distribution/Client/Init/Prompt.hs +++ b/cabal-install/src/Distribution/Client/Init/Prompt.hs @@ -75,6 +75,8 @@ promptList -- ^ optional default value -> Maybe (String -> String) -- ^ modify the default value to present in-prompt + -- e.g. empty string maps to "(none)", but only in the + -- prompt. -> Bool -- ^ whether to allow an 'other' option -> m String diff --git a/cabal-install/src/Distribution/Client/Init/Simple.hs b/cabal-install/src/Distribution/Client/Init/Simple.hs index de8ecaff3ed..d93134e56e1 100644 --- a/cabal-install/src/Distribution/Client/Init/Simple.hs +++ b/cabal-install/src/Distribution/Client/Init/Simple.hs @@ -18,18 +18,16 @@ import Distribution.Client.Init.Utils (currentDirPkgName, mkPackageNameDep) import Distribution.Client.Init.Defaults import Distribution.Simple.Flag (fromFlagOrDefault, flagElim) import Distribution.Client.Init.FlagExtractors -import Distribution.Simple.Compiler createProject :: Interactive m => Verbosity - -> Compiler -> InstalledPackageIndex -> SourcePackageDb -> InitFlags -> m ProjectSettings -createProject v _comp _pkgIx _srcDb initFlags = do +createProject v _pkgIx _srcDb initFlags = do pkgType <- packageTypePrompt initFlags isMinimal <- getMinimal initFlags doOverwrite <- getOverwrite initFlags diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init.hs index 30e08474c47..ce3b1119f13 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init.hs @@ -36,10 +36,10 @@ tests = do srcDb <- getSourcePackages v repoCtx return - [ Interactive.tests v initFlags' comp pkgIx srcDb + [ Interactive.tests v initFlags' pkgIx srcDb , NonInteractive.tests v initFlags' comp pkgIx srcDb - , Golden.tests v initFlags' comp pkgIx srcDb - , Simple.tests v initFlags' comp pkgIx srcDb + , Golden.tests v initFlags' pkgIx srcDb + , Simple.tests v initFlags' pkgIx srcDb ] where v :: Verbosity diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs index 20233d37634..8db25bdc10a 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs @@ -19,7 +19,6 @@ import Data.Semigroup ((<>)) import Distribution.Client.Init.Types import Distribution.Simple.PackageIndex hiding (fromList) import Distribution.Verbosity -import Distribution.Simple.Compiler import Distribution.Client.Types.SourcePackageDb import Distribution.Client.Init.Interactive.Command import Distribution.Client.Init.Format @@ -54,16 +53,15 @@ import UnitTests.Distribution.Client.Init.Utils tests :: Verbosity -> InitFlags - -> Compiler -> InstalledPackageIndex -> SourcePackageDb -> TestTree -tests v initFlags comp pkgIx srcDb = testGroup "golden" +tests v initFlags pkgIx srcDb = testGroup "golden" [ goldenLibTests v pkgIx pkgDir pkgName , goldenExeTests v pkgIx pkgDir pkgName , goldenTestTests v pkgIx pkgDir pkgName , goldenPkgDescTests v srcDb pkgDir pkgName - , goldenCabalTests v comp pkgIx srcDb + , goldenCabalTests v pkgIx srcDb ] where pkgDir = evalPrompt (getPackageDir initFlags) @@ -232,11 +230,10 @@ goldenTestTests v pkgIx pkgDir pkgName = testGroup "test golden tests" -- | Full cabal file golden tests goldenCabalTests :: Verbosity - -> Compiler -> InstalledPackageIndex -> SourcePackageDb -> TestTree -goldenCabalTests v comp pkgIx srcDb = testGroup ".cabal file golden tests" +goldenCabalTests v pkgIx srcDb = testGroup ".cabal file golden tests" [ goldenVsString "Library and executable, empty flags, not simple, with comments + no minimal" (goldenCabal "cabal-lib-and-exe-with-comments.golden") $ runGoldenTest (fullProjArgs "Y") emptyFlags @@ -255,13 +252,13 @@ goldenCabalTests v comp pkgIx srcDb = testGroup ".cabal file golden tests" ] where runGoldenTest args flags = - case _runPrompt (createProject v comp pkgIx srcDb flags) args of + case _runPrompt (createProject v pkgIx srcDb flags) args of Left e -> assertFailure $ show e (Right (ProjectSettings opts pkgDesc (Just libTarget) (Just exeTarget) (Just testTarget), _)) -> do let pkgFields = mkPkgDescription opts pkgDesc - libStanza = mkLibStanza opts $ libTarget {_libDependencies = mangleBaseDep libTarget _libDependencies} - exeStanza = mkExeStanza opts $ exeTarget {_exeDependencies = mangleBaseDep exeTarget _exeDependencies} + libStanza = mkLibStanza opts $ libTarget {_libDependencies = mangleBaseDep libTarget _libDependencies} + exeStanza = mkExeStanza opts $ exeTarget {_exeDependencies = mangleBaseDep exeTarget _exeDependencies} testStanza = mkTestStanza opts $ testTarget {_testDependencies = mangleBaseDep testTarget _testDependencies} mkStanza $ pkgFields ++ [libStanza, exeStanza, testStanza] diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs index 8fc2205fc85..9becd089492 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs @@ -15,7 +15,6 @@ import qualified Distribution.SPDX as SPDX import Data.List.NonEmpty hiding (zip) import Distribution.Client.Types -import Distribution.Simple.Compiler import Distribution.Simple.PackageIndex hiding (fromList) import Distribution.Types.PackageName import Distribution.Types.Version @@ -35,13 +34,12 @@ import Distribution.CabalSpecVersion tests :: Verbosity -> InitFlags - -> Compiler -> InstalledPackageIndex -> SourcePackageDb -> TestTree -tests _v initFlags comp pkgIx srcDb = +tests _v initFlags pkgIx srcDb = testGroup "Distribution.Client.Init.Interactive.Command.hs" - [ createProjectTest comp pkgIx srcDb + [ createProjectTest pkgIx srcDb , fileCreatorTests pkgIx srcDb pkgName , interactiveTests srcDb ] @@ -52,11 +50,10 @@ tests _v initFlags comp pkgIx srcDb = -- pkgNm = evalPrompt (getPackageName srcDb initFlags) $ fromList ["test-package", "y"] createProjectTest - :: Compiler - -> InstalledPackageIndex + :: InstalledPackageIndex -> SourcePackageDb -> TestTree -createProjectTest comp pkgIx srcDb = testGroup "createProject tests" +createProjectTest pkgIx srcDb = testGroup "createProject tests" [ testGroup "with flags" [ testCase "Check the non-interactive workflow" $ do let dummyFlags' = dummyFlags @@ -73,7 +70,7 @@ createProjectTest comp pkgIx srcDb = testGroup "createProject tests" , dependencies = Flag [] } - case (_runPrompt $ createProject silent comp pkgIx srcDb dummyFlags') (fromList ["3", "quxTest/Main.hs"]) of + case (_runPrompt $ createProject silent pkgIx srcDb dummyFlags') (fromList ["3", "quxTest/Main.hs"]) of Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -175,7 +172,7 @@ createProjectTest comp pkgIx srcDb = testGroup "createProject tests" , "y" ] - case (_runPrompt $ createProject silent comp pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of + case (_runPrompt $ createProject silent pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -268,7 +265,7 @@ createProjectTest comp pkgIx srcDb = testGroup "createProject tests" , "y" ] - case (_runPrompt $ createProject silent comp pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of + case (_runPrompt $ createProject silent pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of Right (ProjectSettings opts desc (Just lib) Nothing (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -356,7 +353,7 @@ createProjectTest comp pkgIx srcDb = testGroup "createProject tests" , "y" ] - case (_runPrompt $ createProject silent comp pkgIx srcDb emptyFlags) inputs of + case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc (Just lib) (Just exe) Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -436,7 +433,7 @@ createProjectTest comp pkgIx srcDb = testGroup "createProject tests" , "y" ] - case (_runPrompt $ createProject silent comp pkgIx srcDb emptyFlags) inputs of + case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc (Just lib) Nothing Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -508,7 +505,7 @@ createProjectTest comp pkgIx srcDb = testGroup "createProject tests" , "y" ] - case (_runPrompt $ createProject silent comp pkgIx srcDb emptyFlags) inputs of + case (_runPrompt $ createProject silent pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc Nothing (Just exe) Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -732,7 +729,7 @@ interactiveTests srcDb = testGroup "Check top level getter functions" , "1" ] ] - , testGroup "Check srcDirsPrompt output" + , testGroup "Check srcDirsPrompt output" [ testNumberedPrompt "Soruce dirs indices" srcDirsPrompt [[defaultSourceDir], ["lib"], ["src-lib"]] , testSimplePrompt "Other source dir" diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs index 921b0a6ec04..c927914cd51 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs @@ -67,7 +67,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" [ "[\"quxTest/Main.hs\"]" ] - case (_runPrompt $ createProject silent comp pkgIx srcDb dummyFlags') inputs of + case (_runPrompt $ createProject comp silent pkgIx srcDb dummyFlags') inputs of Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -145,7 +145,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "False" ] - case (_runPrompt $ createProject silent comp pkgIx srcDb dummyFlags') inputs of + case (_runPrompt $ createProject comp silent pkgIx srcDb dummyFlags') inputs of Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -302,7 +302,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/bar.y\"]" ] - case (_runPrompt $ createProject silent comp pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of + case (_runPrompt $ createProject comp silent pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of Right (ProjectSettings opts desc (Just lib) (Just exe) (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -430,7 +430,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/bar.y\"]" ] - case (_runPrompt $ createProject silent comp pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of + case (_runPrompt $ createProject comp silent pkgIx srcDb (emptyFlags {initializeTestSuite = Flag True})) inputs of Right (ProjectSettings opts desc (Just lib) Nothing (Just test), _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -558,7 +558,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] - case (_runPrompt $ createProject silent comp pkgIx srcDb emptyFlags) inputs of + case (_runPrompt $ createProject comp silent pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc (Just lib) (Just exe) Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -659,7 +659,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] - case (_runPrompt $ createProject silent comp pkgIx srcDb emptyFlags) inputs of + case (_runPrompt $ createProject comp silent pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc (Just lib) Nothing Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -744,7 +744,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] - case (_runPrompt $ createProject silent comp pkgIx srcDb emptyFlags) inputs of + case (_runPrompt $ createProject comp silent pkgIx srcDb emptyFlags) inputs of Right (ProjectSettings opts desc Nothing (Just exe) Nothing, _) -> do _optOverwrite opts @?= False _optMinimal opts @?= False @@ -973,10 +973,10 @@ nonInteractiveTests pkgIx srcDb comp = testGroup "Check top level getter functio ["cabal-install version 2.4.0.0\ncompiled using version 2.4.0.0 of the Cabal library \n"] ] , testGroup "Check languageHeuristics output" - [ testSimple "Non GHC compiler" + [ testSimple "Non GHC compiler" (`languageHeuristics` (comp {compilerId = CompilerId Helium $ mkVersion [1,8,1]})) Haskell2010 [] - , testSimple "Higher version compiler" + , testSimple "Higher version compiler" (`languageHeuristics` (comp {compilerId = CompilerId GHC $ mkVersion [8,10,4]})) Haskell2010 [] , testSimple "Lower version compiler" @@ -1085,7 +1085,7 @@ nonInteractiveTests pkgIx srcDb comp = testGroup "Check top level getter functio , testGroup "Check dependenciesHeuristics output" [ testSimple "base version bounds is correct" (fmap - (flip foldl' anyVersion $ \a (Dependency n v _) -> + (flip foldl' anyVersion $ \a (Dependency n v _) -> if unPackageName n == "base" then v else a) . (\x -> dependenciesHeuristics x "" pkgIx)) (baseVersion comp) diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs index a7ae4892708..88cd44d5404 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs @@ -14,7 +14,6 @@ import Distribution.Client.Init.Types import Data.List.NonEmpty hiding (zip) import Distribution.Client.Types -import Distribution.Simple.Compiler import Distribution.Simple.PackageIndex hiding (fromList) import Distribution.Types.PackageName import Distribution.Verbosity @@ -29,24 +28,22 @@ import Distribution.Client.Init.Utils (mkPackageNameDep) tests :: Verbosity -> InitFlags - -> Compiler -> InstalledPackageIndex -> SourcePackageDb -> TestTree -tests v _initFlags comp pkgIx srcDb = testGroup "Distribution.Client.Init.Simple.hs" - [ simpleCreateProjectTests v comp pkgIx srcDb pkgName +tests v _initFlags pkgIx srcDb = testGroup "Distribution.Client.Init.Simple.hs" + [ simpleCreateProjectTests v pkgIx srcDb pkgName ] where pkgName = mkPackageName "simple-test" simpleCreateProjectTests :: Verbosity - -> Compiler -> InstalledPackageIndex -> SourcePackageDb -> PackageName -> TestTree -simpleCreateProjectTests v comp pkgIx srcDb pkgName = +simpleCreateProjectTests v pkgIx srcDb pkgName = testGroup "Simple createProject tests" [ testCase "Simple lib createProject - no tests" $ do let inputs = fromList @@ -61,7 +58,7 @@ simpleCreateProjectTests v comp pkgIx srcDb pkgName = (simplePkgDesc pkgName) (Just simpleLibTarget) Nothing Nothing - case _runPrompt (createProject v comp pkgIx srcDb flags) inputs of + case _runPrompt (createProject v pkgIx srcDb flags) inputs of Left e -> assertFailure $ "Failed to create simple lib project: " ++ show e Right (settings', _) -> settings @=? settings' @@ -73,7 +70,7 @@ simpleCreateProjectTests v comp pkgIx srcDb pkgName = (simplePkgDesc pkgName) (Just simpleLibTarget) Nothing (Just $ simpleTestTarget (Just pkgName)) - case _runPrompt (createProject v comp pkgIx srcDb flags) inputs of + case _runPrompt (createProject v pkgIx srcDb flags) inputs of Left e -> assertFailure $ "Failed to create simple lib (with tests)project: " ++ show e Right (settings', _) -> settings @=? settings' @@ -85,7 +82,7 @@ simpleCreateProjectTests v comp pkgIx srcDb pkgName = (simplePkgDesc pkgName) Nothing (Just $ simpleExeTarget Nothing) Nothing - case _runPrompt (createProject v comp pkgIx srcDb flags) inputs of + case _runPrompt (createProject v pkgIx srcDb flags) inputs of Left e -> assertFailure $ "Failed to create simple exe project: " ++ show e Right (settings', _) -> settings @=? settings' @@ -97,7 +94,7 @@ simpleCreateProjectTests v comp pkgIx srcDb pkgName = (simplePkgDesc pkgName) (Just simpleLibTarget) (Just $ simpleExeTarget (Just pkgName)) Nothing - case _runPrompt (createProject v comp pkgIx srcDb flags) inputs of + case _runPrompt (createProject v pkgIx srcDb flags) inputs of Left e -> assertFailure $ "Failed to create simple lib+exe project: " ++ show e Right (settings', _) -> settings @=? settings' , testCase "Simple lib+exe createProject - with tests" $ do @@ -109,7 +106,7 @@ simpleCreateProjectTests v comp pkgIx srcDb pkgName = (Just $ simpleExeTarget (Just pkgName)) (Just $ simpleTestTarget (Just pkgName)) - case _runPrompt (createProject v comp pkgIx srcDb flags) inputs of + case _runPrompt (createProject v pkgIx srcDb flags) inputs of Left e -> assertFailure $ "Failed to create simple lib+exe (with tests) project: " ++ show e Right (settings', _) -> settings @=? settings' ] From c92b2ada257eacdf4ad8e1dac142d06e865fcd85 Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Wed, 5 May 2021 09:11:09 -0400 Subject: [PATCH 08/37] explicit fix for 6864 --- .../src/Distribution/Client/Config.hs | 1 + .../Client/Init/FlagExtractors.hs | 19 +++++---- .../src/Distribution/Client/Init/Format.hs | 11 +++-- .../Client/Init/Interactive/Command.hs | 2 +- .../Client/Init/NonInteractive/Command.hs | 13 +++--- .../Client/Init/NonInteractive/Heuristics.hs | 14 +++---- .../src/Distribution/Client/Init/Simple.hs | 3 +- .../src/Distribution/Client/Init/Types.hs | 4 +- .../Distribution/Client/Init/Interactive.hs | 18 +++++--- .../Client/Init/NonInteractive.hs | 41 +++++++++++-------- .../Distribution/Client/Init/Simple.hs | 1 + 11 files changed, 78 insertions(+), 49 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Config.hs b/cabal-install/src/Distribution/Client/Config.hs index 26ae5a87e3e..1ce620d0d36 100644 --- a/cabal-install/src/Distribution/Client/Config.hs +++ b/cabal-install/src/Distribution/Client/Config.hs @@ -264,6 +264,7 @@ instance Semigroup SavedConfig where IT.email = combine IT.email, IT.exposedModules = combineMonoid savedInitFlags IT.exposedModules, IT.extraSrc = combineMonoid savedInitFlags IT.extraSrc, + IT.extraDoc = combineMonoid savedInitFlags IT.extraDoc, IT.homepage = combine IT.homepage, IT.initHcPath = combine IT.initHcPath, IT.initVerbosity = combine IT.initVerbosity, diff --git a/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs b/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs index bf67c323c3a..c98214af4c9 100644 --- a/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs +++ b/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs @@ -14,6 +14,7 @@ module Distribution.Client.Init.FlagExtractors , getSynopsis , getCategory , getExtraSrcFiles +, getExtraDocFiles , getPackageType , getMainFile , getInitializeTestSuite @@ -121,10 +122,14 @@ getCategory :: Interactive m => InitFlags -> m String -> m String getCategory flags = fromFlagOrPrompt (category flags) -- | Try to guess extra source files (don't prompt the user). -getExtraSrcFiles :: Interactive m => InitFlags -> m (NonEmpty String) -getExtraSrcFiles = pure - . flagElim (defaultChangelog NEL.:| []) NEL.fromList - . extraSrc +getExtraSrcFiles :: Interactive m => InitFlags -> m [String] +getExtraSrcFiles = pure . fromFlagOrDefault [] . extraSrc + +-- | Try to guess extra source files (don't prompt the user). +getExtraDocFiles :: Interactive m => InitFlags -> m (NonEmpty String) +getExtraDocFiles = pure + . flagElim (defaultChangelog NEL.:| []) NEL.fromList + . extraDoc -- | Ask whether the project builds a library or executable. getPackageType :: Interactive m => InitFlags -> m PackageType -> m PackageType @@ -163,9 +168,9 @@ getSrcDirs flags = fromFlagOrPrompt (sourceDirs flags) getExposedModules :: Interactive m => InitFlags -> m (NonEmpty ModuleName) getExposedModules = return . fromMaybe (myLibModule NEL.:| []) - . join - . flagToMaybe - . fmap NEL.nonEmpty + . join + . flagToMaybe + . fmap NEL.nonEmpty . exposedModules -- | Retrieve the list of other modules diff --git a/cabal-install/src/Distribution/Client/Init/Format.hs b/cabal-install/src/Distribution/Client/Init/Format.hs index cc5906fb66c..c856e9379e7 100644 --- a/cabal-install/src/Distribution/Client/Init/Format.hs +++ b/cabal-install/src/Distribution/Client/Init/Format.hs @@ -318,11 +318,16 @@ mkPkgDescription opts pkgDesc = [] False opts - - , field "extra-source-files" formatExtraSourceFiles (toList $ _pkgExtraSrcFiles pkgDesc) - ["Extra files to be distributed with the package, such as examples or a README."] + , field "extra-doc-files" formatExtraSourceFiles (toList $ _pkgExtraDocFiles pkgDesc) + ["Extra doc files to be distributed with the package, such as a CHANGELOG or a README."] True opts + , case _pkgExtraSrcFiles pkgDesc of + [] -> PrettyEmpty + lst -> field "extra-source-files" formatExtraSourceFiles lst + ["Extra source files to be distributed with the package, such as examples, or a tutorial module."] + True + opts ] where cabalSpec = _pkgCabalVersion pkgDesc diff --git a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs index 1705dd5aefc..eac769d2b5c 100644 --- a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs @@ -174,7 +174,7 @@ genPkgDescription flags srcDb = PkgDescription <*> synopsisPrompt flags <*> categoryPrompt flags <*> getExtraSrcFiles flags - + <*> getExtraDocFiles flags -- | Extract flags relevant to a library target and interactively -- generate a 'LibTarget' object for creation. If the user specifies diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs index ba67052ebf8..36ce74b847b 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs @@ -25,7 +25,7 @@ module Distribution.Client.Init.NonInteractive.Command , homepageHeuristics , synopsisHeuristics , categoryHeuristics -, extraSourceFilesHeuristics +, extraDocFileHeuristics , appDirsHeuristics , srcDirsHeuristics , languageHeuristics @@ -149,7 +149,8 @@ genPkgDescription flags srcDb = PkgDescription <*> homepageHeuristics flags <*> synopsisHeuristics flags <*> categoryHeuristics flags - <*> extraSourceFilesHeuristics flags + <*> getExtraSrcFiles flags + <*> extraDocFileHeuristics flags genLibTarget :: Interactive m @@ -278,13 +279,13 @@ synopsisHeuristics flags = getSynopsis flags $ return "" -- Note that it should be possible to do some smarter guessing here too, i.e. -- look at the name of the top level source directory. categoryHeuristics :: Interactive m => InitFlags -> m String -categoryHeuristics flags = getCategory flags $ return "(none)" +categoryHeuristics flags = getCategory flags $ return "" -- | Try to guess extra source files. -extraSourceFilesHeuristics :: Interactive m => InitFlags -> m (NonEmpty FilePath) -extraSourceFilesHeuristics flags = case extraSrc flags of +extraDocFileHeuristics :: Interactive m => InitFlags -> m (NonEmpty FilePath) +extraDocFileHeuristics flags = case extraDoc flags of Flag x | not (null x) -> return $ NEL.fromList x - _ -> guessExtraSourceFiles flags + _ -> guessExtraDocFiles flags -- | Try to guess if the project builds a library, an executable, or both. packageTypeHeuristics :: Interactive m => InitFlags -> m PackageType diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs index 9bc3be80b70..855821399ed 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs @@ -16,7 +16,7 @@ module Distribution.Client.Init.NonInteractive.Heuristics ( guessPackageName , guessMainFile , guessLicense - , guessExtraSourceFiles + , guessExtraDocFiles , guessAuthorName , guessAuthorEmail , guessCabalSpecVersion @@ -107,17 +107,17 @@ guessPackageName = fmap (mkPackageName . repair . fromMaybe "" . safeLast . spli guessLicense :: Interactive m => InitFlags -> m SPDX.License guessLicense _ = return SPDX.NONE -guessExtraSourceFiles :: Interactive m => InitFlags -> m (NonEmpty FilePath) -guessExtraSourceFiles flags = do +guessExtraDocFiles :: Interactive m => InitFlags -> m (NonEmpty FilePath) +guessExtraDocFiles flags = do pkgDir <- fromFlagOrDefault getCurrentDirectory $ fmap return $ packageDir flags files <- getDirectoryContents pkgDir - let extSrcCandidates = ["CHANGES", "CHANGELOG", "README"] - extraSrc' = [y | x <- extSrcCandidates, y <- files, x == map toUpper (takeBaseName y)] + let extraDocCandidates = ["CHANGES", "CHANGELOG", "README"] + extraDocs = [y | x <- extraDocCandidates, y <- files, x == map toUpper (takeBaseName y)] - return $ if null extraSrc' + return $ if null extraDocs then defaultChangelog NEL.:| [] - else NEL.fromList extraSrc' + else NEL.fromList extraDocs -- | Try to guess the package type from the files in the package directory, -- looking for unique characteristics from each type, defaults to Executable. diff --git a/cabal-install/src/Distribution/Client/Init/Simple.hs b/cabal-install/src/Distribution/Client/Init/Simple.hs index d93134e56e1..e6febddf1e4 100644 --- a/cabal-install/src/Distribution/Client/Init/Simple.hs +++ b/cabal-install/src/Distribution/Client/Init/Simple.hs @@ -92,7 +92,8 @@ genSimplePkgDesc flags = mkPkgDesc <$> currentDirPkgName (fromFlagOrDefault "" (homepage flags)) (fromFlagOrDefault "" (synopsis flags)) (fromFlagOrDefault "" (category flags)) - (flagElim defaultExtraSrc extractExtraSrc (extraSrc flags)) + (fromFlagOrDefault [] (extraSrc flags)) + (flagElim defaultExtraSrc extractExtraSrc (extraDoc flags)) genSimpleLibTarget :: Interactive m => InitFlags -> m LibTarget genSimpleLibTarget flags = return $ LibTarget diff --git a/cabal-install/src/Distribution/Client/Init/Types.hs b/cabal-install/src/Distribution/Client/Init/Types.hs index 3d19b97f5f2..5d074ef4727 100644 --- a/cabal-install/src/Distribution/Client/Init/Types.hs +++ b/cabal-install/src/Distribution/Client/Init/Types.hs @@ -98,6 +98,7 @@ data InitFlags = , synopsis :: Flag String , category :: Flag String , extraSrc :: Flag [String] + , extraDoc :: Flag [String] , packageType :: Flag PackageType , mainIs :: Flag FilePath , language :: Flag Language @@ -139,7 +140,8 @@ data PkgDescription = PkgDescription , _pkgHomePage :: String , _pkgSynopsis :: String , _pkgCategory :: String - , _pkgExtraSrcFiles :: NonEmpty String + , _pkgExtraSrcFiles :: [String] + , _pkgExtraDocFiles :: NonEmpty String } deriving (Show, Eq) -- | 'LibTarget' represents the relevant options set by the diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs index 9becd089492..bb60282aa99 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs @@ -89,7 +89,8 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" _pkgHomePage desc @?= "qux.com" _pkgSynopsis desc @?= "We are Qux, and this is our package" _pkgCategory desc @?= "Control" - _pkgExtraSrcFiles desc @?= "CHANGELOG.md" :| [] + _pkgExtraSrcFiles desc @?= [] + _pkgExtraDocFiles desc @?= "CHANGELOG.md" :| [] _libSourceDirs lib @?= ["quxSrc"] _libLanguage lib @?= Haskell98 @@ -191,7 +192,8 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" _pkgHomePage desc @?= "qux.com" _pkgSynopsis desc @?= "Qux's package" _pkgCategory desc @?= "Control" - _pkgExtraSrcFiles desc @?= "CHANGELOG.md" :| [] + _pkgExtraSrcFiles desc @?= [] + _pkgExtraDocFiles desc @?= "CHANGELOG.md" :| [] _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell98 @@ -284,7 +286,8 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" _pkgHomePage desc @?= "qux.com" _pkgSynopsis desc @?= "Qux's package" _pkgCategory desc @?= "Control" - _pkgExtraSrcFiles desc @?= "CHANGELOG.md" :| [] + _pkgExtraSrcFiles desc @?= [] + _pkgExtraDocFiles desc @?= "CHANGELOG.md" :| [] _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell98 @@ -372,7 +375,8 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" _pkgHomePage desc @?= "qux.com" _pkgSynopsis desc @?= "Qux's package" _pkgCategory desc @?= "Control" - _pkgExtraSrcFiles desc @?= "CHANGELOG.md" :| [] + _pkgExtraSrcFiles desc @?= [] + _pkgExtraDocFiles desc @?= "CHANGELOG.md" :| [] _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell98 @@ -452,7 +456,8 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" _pkgHomePage desc @?= "qux.com" _pkgSynopsis desc @?= "Qux's package" _pkgCategory desc @?= "Control" - _pkgExtraSrcFiles desc @?= "CHANGELOG.md" :| [] + _pkgExtraSrcFiles desc @?= [] + _pkgExtraDocFiles desc @?= "CHANGELOG.md" :| [] _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell98 @@ -524,7 +529,8 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" _pkgHomePage desc @?= "qux.com" _pkgSynopsis desc @?= "Qux's package" _pkgCategory desc @?= "Control" - _pkgExtraSrcFiles desc @?= "CHANGELOG.md" :| [] + _pkgExtraSrcFiles desc @?= [] + _pkgExtraDocFiles desc @?= "CHANGELOG.md" :| [] _exeMainIs exe @?= HsFilePath "Main.hs" Standard _exeApplicationDirs exe @?= ["exe"] diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs index c927914cd51..ee498828b7b 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs @@ -55,7 +55,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , minimal = Flag False , overwrite = Flag False , packageDir = Flag "/home/test/test-package" - , extraSrc = Flag ["CHANGELOG.md"] + , extraDoc = Flag ["CHANGELOG.md"] , exposedModules = Flag [] , otherModules = Flag [] , otherExts = Flag [] @@ -86,7 +86,8 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _pkgHomePage desc @?= "qux.com" _pkgSynopsis desc @?= "We are Qux, and this is our package" _pkgCategory desc @?= "Control" - _pkgExtraSrcFiles desc @?= "CHANGELOG.md" NEL.:| [] + _pkgExtraSrcFiles desc @?= [] + _pkgExtraDocFiles desc @?= "CHANGELOG.md" NEL.:| [] _libSourceDirs lib @?= ["quxSrc"] _libLanguage lib @?= Haskell98 @@ -164,7 +165,8 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _pkgHomePage desc @?= "qux.com" _pkgSynopsis desc @?= "We are Qux, and this is our package" _pkgCategory desc @?= "Control" - _pkgExtraSrcFiles desc @?= "CHANGELOG.md" NEL.:| [] + _pkgExtraSrcFiles desc @?= [] + _pkgExtraDocFiles desc @?= "CHANGELOG.md" NEL.:| [] _libSourceDirs lib @?= ["quxSrc"] _libLanguage lib @?= Haskell98 @@ -320,8 +322,9 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _pkgEmail desc @?= "foobar@qux.com" _pkgHomePage desc @?= "" _pkgSynopsis desc @?= "" - _pkgCategory desc @?= "(none)" - _pkgExtraSrcFiles desc @?= "CHANGELOG.md" NEL.:| [] + _pkgCategory desc @?= "" + _pkgExtraSrcFiles desc @?= [] + _pkgExtraDocFiles desc @?= "CHANGELOG.md" NEL.:| [] _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell2010 @@ -448,8 +451,9 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _pkgEmail desc @?= "foobar@qux.com" _pkgHomePage desc @?= "" _pkgSynopsis desc @?= "" - _pkgCategory desc @?= "(none)" - _pkgExtraSrcFiles desc @?= "CHANGELOG.md" NEL.:| [] + _pkgCategory desc @?= "" + _pkgExtraSrcFiles desc @?= [] + _pkgExtraDocFiles desc @?= "CHANGELOG.md" NEL.:| [] _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell2010 @@ -576,8 +580,9 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _pkgEmail desc @?= "foobar@qux.com" _pkgHomePage desc @?= "" _pkgSynopsis desc @?= "" - _pkgCategory desc @?= "(none)" - _pkgExtraSrcFiles desc @?= "CHANGELOG.md" NEL.:| [] + _pkgCategory desc @?= "" + _pkgExtraSrcFiles desc @?= [] + _pkgExtraDocFiles desc @?= "CHANGELOG.md" NEL.:| [] _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell2010 @@ -677,8 +682,9 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _pkgEmail desc @?= "foobar@qux.com" _pkgHomePage desc @?= "" _pkgSynopsis desc @?= "" - _pkgCategory desc @?= "(none)" - _pkgExtraSrcFiles desc @?= "CHANGELOG.md" NEL.:| [] + _pkgCategory desc @?= "" + _pkgExtraSrcFiles desc @?= [] + _pkgExtraDocFiles desc @?= "CHANGELOG.md" NEL.:| [] _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell2010 @@ -762,8 +768,9 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _pkgEmail desc @?= "foobar@qux.com" _pkgHomePage desc @?= "" _pkgSynopsis desc @?= "" - _pkgCategory desc @?= "(none)" - _pkgExtraSrcFiles desc @?= "CHANGELOG.md" NEL.:| [] + _pkgCategory desc @?= "" + _pkgExtraSrcFiles desc @?= [] + _pkgExtraDocFiles desc @?= "CHANGELOG.md" NEL.:| [] _exeMainIs exe @?= HsFilePath "Main.hs" Standard _exeApplicationDirs exe @?= ["app"] @@ -983,13 +990,13 @@ nonInteractiveTests pkgIx srcDb comp = testGroup "Check top level getter functio (`languageHeuristics` (comp {compilerId = CompilerId GHC $ mkVersion [6,0,1]})) Haskell98 [] ] - , testGroup "Check extraSourceFilesHeuristics output" - [ testSimple "No extra sources" extraSourceFilesHeuristics + , testGroup "Check extraDocFileHeuristics output" + [ testSimple "No extra sources" extraDocFileHeuristics (defaultChangelog NEL.:| []) [ "test-package" , "[]" ] - , testSimple "Extra source files present" extraSourceFilesHeuristics + , testSimple "Extra doc files present" extraDocFileHeuristics ("README.md" NEL.:| []) [ "test-package" , "[\"README.md\"]" @@ -1105,7 +1112,7 @@ nonInteractiveTests pkgIx srcDb comp = testGroup "Check top level getter functio , testSimple "Check homepageHeuristics output" homepageHeuristics "" [""] , testSimple "Check synopsisHeuristics output" synopsisHeuristics "" [""] , testSimple "Check testDirsHeuristics output" testDirsHeuristics ["test"] [""] - , testSimple "Check categoryHeuristics output" categoryHeuristics "(none)" [""] + , testSimple "Check categoryHeuristics output" categoryHeuristics "" [""] , testSimple "Check minimalHeuristics output" minimalHeuristics False [""] , testSimple "Check overwriteHeuristics output" overwriteHeuristics False [""] , testSimple "Check initializeTestSuiteHeuristics output" initializeTestSuiteHeuristics False [""] diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs index 88cd44d5404..d7c01a2f97b 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs @@ -125,6 +125,7 @@ simplePkgDesc pkgName = PkgDescription defaultVersion defaultLicense "" "" "" "" "" + [] (defaultChangelog NEL.:| []) simpleLibTarget :: LibTarget From d2242f3c93c5ab73263a71cd0480bd8e7dd39b6b Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Wed, 5 May 2021 09:17:45 -0400 Subject: [PATCH 09/37] Add flag for extra doc file --- cabal-install/src/Distribution/Client/Init/Simple.hs | 8 ++++---- cabal-install/src/Distribution/Client/Setup.hs | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/Simple.hs b/cabal-install/src/Distribution/Client/Init/Simple.hs index e6febddf1e4..1b85465afcd 100644 --- a/cabal-install/src/Distribution/Client/Init/Simple.hs +++ b/cabal-install/src/Distribution/Client/Init/Simple.hs @@ -77,10 +77,10 @@ createProject v _pkgIx _srcDb initFlags = do genSimplePkgDesc :: Interactive m => InitFlags -> m PkgDescription genSimplePkgDesc flags = mkPkgDesc <$> currentDirPkgName where - defaultExtraSrc = defaultChangelog NEL.:| [] + defaultExtraDoc = defaultChangelog NEL.:| [] - extractExtraSrc [] = defaultExtraSrc - extractExtraSrc as = NEL.fromList as + extractExtraDoc [] = defaultExtraDoc + extractExtraDoc as = NEL.fromList as mkPkgDesc pkgName = PkgDescription (fromFlagOrDefault defaultCabalVersion (cabalVersion flags)) @@ -93,7 +93,7 @@ genSimplePkgDesc flags = mkPkgDesc <$> currentDirPkgName (fromFlagOrDefault "" (synopsis flags)) (fromFlagOrDefault "" (category flags)) (fromFlagOrDefault [] (extraSrc flags)) - (flagElim defaultExtraSrc extractExtraSrc (extraDoc flags)) + (flagElim defaultExtraDoc extractExtraDoc (extraDoc flags)) genSimpleLibTarget :: Interactive m => InitFlags -> m LibTarget genSimpleLibTarget flags = return $ LibTarget diff --git a/cabal-install/src/Distribution/Client/Setup.hs b/cabal-install/src/Distribution/Client/Setup.hs index 32c875c09a2..63b6f808920 100644 --- a/cabal-install/src/Distribution/Client/Setup.hs +++ b/cabal-install/src/Distribution/Client/Setup.hs @@ -2222,6 +2222,10 @@ initOptions _ = IT.extraSrc (\v flags -> flags { IT.extraSrc = v }) (reqArg' "FILE" (Flag . (:[])) (fromFlagOrDefault [])) + , option [] ["extra-doc-file"] + "Extra doc file to be distributed with tarball." + IT.extraDoc (\v flags -> flags { IT.extraDoc = v }) + (reqArg' "FILE" (Flag . (:[])) (fromFlagOrDefault [])) , option [] ["lib", "is-library"] "Build a library." From e398baa142ca24fd7a11839f18c2826ec327c42d Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Wed, 5 May 2021 10:59:30 -0400 Subject: [PATCH 10/37] add adaptive fix for #6864 --- .../src/Distribution/Client/Init/Defaults.hs | 2 -- .../Client/Init/FlagExtractors.hs | 10 +++--- .../src/Distribution/Client/Init/Format.hs | 26 ++++++++++----- .../Client/Init/Interactive/Command.hs | 7 ++-- .../Client/Init/NonInteractive/Command.hs | 7 ++-- .../Client/Init/NonInteractive/Heuristics.hs | 10 +++--- .../src/Distribution/Client/Init/Simple.hs | 7 ++-- .../src/Distribution/Client/Init/Types.hs | 4 +-- .../src/Distribution/Client/Init/Utils.hs | 14 ++++++++ .../Distribution/Client/Init/Interactive.hs | 25 +++++++------- .../Client/Init/NonInteractive.hs | 33 ++++++++++--------- .../Distribution/Client/Init/Simple.hs | 5 +-- 12 files changed, 88 insertions(+), 62 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/Defaults.hs b/cabal-install/src/Distribution/Client/Init/Defaults.hs index 7a629dc4bbc..f58bdf89a30 100644 --- a/cabal-install/src/Distribution/Client/Init/Defaults.hs +++ b/cabal-install/src/Distribution/Client/Init/Defaults.hs @@ -11,8 +11,6 @@ -- Default values to use in cabal init (if not specified in config/flags). -- ----------------------------------------------------------------------------- - -{-# OPTIONS_GHC -Wno-deferred-type-errors #-} module Distribution.Client.Init.Defaults ( -- * default init values diff --git a/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs b/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs index c98214af4c9..d74eebe3136 100644 --- a/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs +++ b/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs @@ -55,6 +55,7 @@ import Distribution.Simple.Flag (flagElim) import Language.Haskell.Extension (Language(..), Extension(..)) import Distribution.Client.Init.Prompt +import qualified Data.Set as Set @@ -122,13 +123,14 @@ getCategory :: Interactive m => InitFlags -> m String -> m String getCategory flags = fromFlagOrPrompt (category flags) -- | Try to guess extra source files (don't prompt the user). -getExtraSrcFiles :: Interactive m => InitFlags -> m [String] -getExtraSrcFiles = pure . fromFlagOrDefault [] . extraSrc +getExtraSrcFiles :: Interactive m => InitFlags -> m (Set String) +getExtraSrcFiles = pure . flagElim mempty Set.fromList . extraSrc -- | Try to guess extra source files (don't prompt the user). -getExtraDocFiles :: Interactive m => InitFlags -> m (NonEmpty String) +getExtraDocFiles :: Interactive m => InitFlags -> m (Maybe (Set String)) getExtraDocFiles = pure - . flagElim (defaultChangelog NEL.:| []) NEL.fromList + . Just + . flagElim (Set.singleton defaultChangelog) Set.fromList . extraDoc -- | Ask whether the project builds a library or executable. diff --git a/cabal-install/src/Distribution/Client/Init/Format.hs b/cabal-install/src/Distribution/Client/Init/Format.hs index c856e9379e7..8ad1f4908e4 100644 --- a/cabal-install/src/Distribution/Client/Init/Format.hs +++ b/cabal-install/src/Distribution/Client/Init/Format.hs @@ -318,16 +318,24 @@ mkPkgDescription opts pkgDesc = [] False opts - , field "extra-doc-files" formatExtraSourceFiles (toList $ _pkgExtraDocFiles pkgDesc) - ["Extra doc files to be distributed with the package, such as a CHANGELOG or a README."] - True - opts + , case _pkgExtraDocFiles pkgDesc of + Nothing -> PrettyEmpty + Just fs + | null fs -> PrettyEmpty + | otherwise -> + field "extra-doc-files" formatExtraSourceFiles (toList fs) + ["Extra doc files to be distributed with the package, such as a CHANGELOG or a README."] + True + opts + , case _pkgExtraSrcFiles pkgDesc of - [] -> PrettyEmpty - lst -> field "extra-source-files" formatExtraSourceFiles lst - ["Extra source files to be distributed with the package, such as examples, or a tutorial module."] - True - opts + fs + | null fs -> PrettyEmpty + | otherwise -> + field "extra-source-files" formatExtraSourceFiles (toList fs) + ["Extra source files to be distributed with the package, such as examples, or a tutorial module."] + True + opts ] where cabalSpec = _pkgCabalVersion pkgDesc diff --git a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs index eac769d2b5c..f5c1aa0e546 100644 --- a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs @@ -44,7 +44,6 @@ module Distribution.Client.Init.Interactive.Command import Prelude () import Distribution.Client.Compat.Prelude hiding (putStr, putStrLn, getLine, last) - import Distribution.CabalSpecVersion (CabalSpecVersion(..), showCabalSpecVersion) import Distribution.Version (Version) import Distribution.Types.Dependency (Dependency(..)) @@ -95,7 +94,7 @@ createProject v pkgIx srcDb initFlags = do isMinimal <- getMinimal initFlags doOverwrite <- getOverwrite initFlags pkgDir <- getPackageDir initFlags - pkgDesc <- genPkgDescription initFlags srcDb + pkgDesc <- fixupDocFiles <$> genPkgDescription initFlags srcDb let pkgName = _pkgName pkgDesc mkOpts cs = WriteOpts @@ -262,7 +261,7 @@ cabalVersionPrompt flags = getCabalVersion flags $ do ppVersions = displayCabalVersion <$> defaultCabalVersions parseCabalVersion :: String -> CabalSpecVersion - parseCabalVersion "1.10" = CabalSpecV1_10 + parseCabalVersion "1.24" = CabalSpecV1_24 parseCabalVersion "2.0" = CabalSpecV2_0 parseCabalVersion "2.2" = CabalSpecV2_2 parseCabalVersion "2.4" = CabalSpecV2_4 @@ -272,7 +271,7 @@ cabalVersionPrompt flags = getCabalVersion flags $ do displayCabalVersion :: CabalSpecVersion -> String displayCabalVersion v = case v of - CabalSpecV1_10 -> "1.10 (legacy)" + CabalSpecV1_24 -> "1.24 (legacy)" CabalSpecV2_0 -> "2.0 (+ support for Backpack, internal sub-libs, '^>=' operator)" CabalSpecV2_2 -> "2.2 (+ support for 'common', 'elif', redundant commas, SPDX)" CabalSpecV2_4 -> "2.4 (+ support for '**' globbing)" diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs index 36ce74b847b..f83f3aa3cf1 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs @@ -61,6 +61,7 @@ import Language.Haskell.Extension (Language(..), Extension(..)) import System.FilePath (splitDirectories, ()) import Distribution.Simple.Compiler +import qualified Data.Set as Set -- | Main driver for interactive prompt code. @@ -101,7 +102,7 @@ createProject comp v pkgIx srcDb initFlags = do isMinimal <- getMinimal initFlags doOverwrite <- getOverwrite initFlags pkgDir <- packageDirHeuristics initFlags - pkgDesc <- genPkgDescription initFlags srcDb + pkgDesc <- fixupDocFiles <$> genPkgDescription initFlags srcDb comments <- noCommentsHeuristics initFlags let pkgName = _pkgName pkgDesc @@ -282,9 +283,9 @@ categoryHeuristics :: Interactive m => InitFlags -> m String categoryHeuristics flags = getCategory flags $ return "" -- | Try to guess extra source files. -extraDocFileHeuristics :: Interactive m => InitFlags -> m (NonEmpty FilePath) +extraDocFileHeuristics :: Interactive m => InitFlags -> m (Maybe (Set FilePath)) extraDocFileHeuristics flags = case extraDoc flags of - Flag x | not (null x) -> return $ NEL.fromList x + Flag x -> return $ Just $ Set.fromList x _ -> guessExtraDocFiles flags -- | Try to guess if the project builds a library, an executable, or both. diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs index 855821399ed..78f74b11d2d 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs @@ -34,7 +34,6 @@ import Distribution.Simple.Setup (fromFlagOrDefault) import Text.Parsec import qualified Data.List as L -import qualified Data.List.NonEmpty as NEL import Distribution.Client.Init.Defaults import Distribution.Client.Init.Types hiding (break) import Distribution.Client.Init.Utils @@ -45,6 +44,7 @@ import Language.Haskell.Extension import Distribution.Version import Distribution.Types.PackageName (PackageName, mkPackageName) import Distribution.Simple.Compiler +import qualified Data.Set as Set @@ -107,7 +107,7 @@ guessPackageName = fmap (mkPackageName . repair . fromMaybe "" . safeLast . spli guessLicense :: Interactive m => InitFlags -> m SPDX.License guessLicense _ = return SPDX.NONE -guessExtraDocFiles :: Interactive m => InitFlags -> m (NonEmpty FilePath) +guessExtraDocFiles :: Interactive m => InitFlags -> m (Maybe (Set FilePath)) guessExtraDocFiles flags = do pkgDir <- fromFlagOrDefault getCurrentDirectory $ fmap return $ packageDir flags files <- getDirectoryContents pkgDir @@ -115,9 +115,9 @@ guessExtraDocFiles flags = do let extraDocCandidates = ["CHANGES", "CHANGELOG", "README"] extraDocs = [y | x <- extraDocCandidates, y <- files, x == map toUpper (takeBaseName y)] - return $ if null extraDocs - then defaultChangelog NEL.:| [] - else NEL.fromList extraDocs + return $ Just $ if null extraDocs + then Set.singleton defaultChangelog + else Set.fromList extraDocs -- | Try to guess the package type from the files in the package directory, -- looking for unique characteristics from each type, defaults to Executable. diff --git a/cabal-install/src/Distribution/Client/Init/Simple.hs b/cabal-install/src/Distribution/Client/Init/Simple.hs index 1b85465afcd..8a28c8db7e7 100644 --- a/cabal-install/src/Distribution/Client/Init/Simple.hs +++ b/cabal-install/src/Distribution/Client/Init/Simple.hs @@ -18,6 +18,7 @@ import Distribution.Client.Init.Utils (currentDirPkgName, mkPackageNameDep) import Distribution.Client.Init.Defaults import Distribution.Simple.Flag (fromFlagOrDefault, flagElim) import Distribution.Client.Init.FlagExtractors +import qualified Data.Set as Set createProject @@ -77,10 +78,10 @@ createProject v _pkgIx _srcDb initFlags = do genSimplePkgDesc :: Interactive m => InitFlags -> m PkgDescription genSimplePkgDesc flags = mkPkgDesc <$> currentDirPkgName where - defaultExtraDoc = defaultChangelog NEL.:| [] + defaultExtraDoc = Just $ Set.singleton defaultChangelog extractExtraDoc [] = defaultExtraDoc - extractExtraDoc as = NEL.fromList as + extractExtraDoc fs = Just $ Set.fromList fs mkPkgDesc pkgName = PkgDescription (fromFlagOrDefault defaultCabalVersion (cabalVersion flags)) @@ -92,7 +93,7 @@ genSimplePkgDesc flags = mkPkgDesc <$> currentDirPkgName (fromFlagOrDefault "" (homepage flags)) (fromFlagOrDefault "" (synopsis flags)) (fromFlagOrDefault "" (category flags)) - (fromFlagOrDefault [] (extraSrc flags)) + (flagElim mempty Set.fromList (extraSrc flags)) (flagElim defaultExtraDoc extractExtraDoc (extraDoc flags)) genSimpleLibTarget :: Interactive m => InitFlags -> m LibTarget diff --git a/cabal-install/src/Distribution/Client/Init/Types.hs b/cabal-install/src/Distribution/Client/Init/Types.hs index 5d074ef4727..e6c1b696874 100644 --- a/cabal-install/src/Distribution/Client/Init/Types.hs +++ b/cabal-install/src/Distribution/Client/Init/Types.hs @@ -140,8 +140,8 @@ data PkgDescription = PkgDescription , _pkgHomePage :: String , _pkgSynopsis :: String , _pkgCategory :: String - , _pkgExtraSrcFiles :: [String] - , _pkgExtraDocFiles :: NonEmpty String + , _pkgExtraSrcFiles :: Set String + , _pkgExtraDocFiles :: Maybe (Set String) } deriving (Show, Eq) -- | 'LibTarget' represents the relevant options set by the diff --git a/cabal-install/src/Distribution/Client/Init/Utils.hs b/cabal-install/src/Distribution/Client/Init/Utils.hs index 0ac8f2f8cf8..c48b2a89b30 100644 --- a/cabal-install/src/Distribution/Client/Init/Utils.hs +++ b/cabal-install/src/Distribution/Client/Init/Utils.hs @@ -16,6 +16,7 @@ module Distribution.Client.Init.Utils , currentDirPkgName , filePathToPkgName , mkPackageNameDep +, fixupDocFiles ) where @@ -263,3 +264,16 @@ currentDirPkgName = filePathToPkgName <$> getCurrentDirectory mkPackageNameDep :: PackageName -> Dependency mkPackageNameDep pkg = mkDependency pkg anyVersion (NES.singleton LMainLibName) + +-- when cabal-version < 1.18, extra-doc-files is not supported +-- so whatever the user wants as doc files should be dumped into +-- extra-src-files. +-- +fixupDocFiles :: PkgDescription -> PkgDescription +fixupDocFiles pkgDesc + | _pkgCabalVersion pkgDesc < CabalSpecV1_18 = pkgDesc + { _pkgExtraSrcFiles =_pkgExtraSrcFiles pkgDesc + <> fromMaybe mempty (_pkgExtraDocFiles pkgDesc) + , _pkgExtraDocFiles = Nothing + } + | otherwise = pkgDesc diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs index bb60282aa99..9a650b3a4a3 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs @@ -26,6 +26,7 @@ import UnitTests.Distribution.Client.Init.Utils import Distribution.Client.Init.FlagExtractors import Distribution.Simple.Setup import Distribution.CabalSpecVersion +import qualified Data.Set as Set -- -------------------------------------------------------------------- -- @@ -89,8 +90,8 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" _pkgHomePage desc @?= "qux.com" _pkgSynopsis desc @?= "We are Qux, and this is our package" _pkgCategory desc @?= "Control" - _pkgExtraSrcFiles desc @?= [] - _pkgExtraDocFiles desc @?= "CHANGELOG.md" :| [] + _pkgExtraSrcFiles desc @?= mempty + _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") _libSourceDirs lib @?= ["quxSrc"] _libLanguage lib @?= Haskell98 @@ -192,8 +193,8 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" _pkgHomePage desc @?= "qux.com" _pkgSynopsis desc @?= "Qux's package" _pkgCategory desc @?= "Control" - _pkgExtraSrcFiles desc @?= [] - _pkgExtraDocFiles desc @?= "CHANGELOG.md" :| [] + _pkgExtraSrcFiles desc @?= mempty + _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell98 @@ -286,8 +287,8 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" _pkgHomePage desc @?= "qux.com" _pkgSynopsis desc @?= "Qux's package" _pkgCategory desc @?= "Control" - _pkgExtraSrcFiles desc @?= [] - _pkgExtraDocFiles desc @?= "CHANGELOG.md" :| [] + _pkgExtraSrcFiles desc @?= mempty + _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell98 @@ -375,8 +376,8 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" _pkgHomePage desc @?= "qux.com" _pkgSynopsis desc @?= "Qux's package" _pkgCategory desc @?= "Control" - _pkgExtraSrcFiles desc @?= [] - _pkgExtraDocFiles desc @?= "CHANGELOG.md" :| [] + _pkgExtraSrcFiles desc @?= mempty + _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell98 @@ -456,8 +457,8 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" _pkgHomePage desc @?= "qux.com" _pkgSynopsis desc @?= "Qux's package" _pkgCategory desc @?= "Control" - _pkgExtraSrcFiles desc @?= [] - _pkgExtraDocFiles desc @?= "CHANGELOG.md" :| [] + _pkgExtraSrcFiles desc @?= mempty + _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell98 @@ -529,8 +530,8 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" _pkgHomePage desc @?= "qux.com" _pkgSynopsis desc @?= "Qux's package" _pkgCategory desc @?= "Control" - _pkgExtraSrcFiles desc @?= [] - _pkgExtraDocFiles desc @?= "CHANGELOG.md" :| [] + _pkgExtraSrcFiles desc @?= mempty + _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") _exeMainIs exe @?= HsFilePath "Main.hs" Standard _exeApplicationDirs exe @?= ["exe"] diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs index ee498828b7b..3acea740156 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs @@ -21,6 +21,7 @@ import Distribution.CabalSpecVersion import Distribution.ModuleName (fromString) import Distribution.Simple.Flag import Data.List (foldl') +import qualified Data.Set as Set tests :: Verbosity @@ -86,8 +87,8 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _pkgHomePage desc @?= "qux.com" _pkgSynopsis desc @?= "We are Qux, and this is our package" _pkgCategory desc @?= "Control" - _pkgExtraSrcFiles desc @?= [] - _pkgExtraDocFiles desc @?= "CHANGELOG.md" NEL.:| [] + _pkgExtraSrcFiles desc @?= mempty + _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") _libSourceDirs lib @?= ["quxSrc"] _libLanguage lib @?= Haskell98 @@ -165,8 +166,8 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _pkgHomePage desc @?= "qux.com" _pkgSynopsis desc @?= "We are Qux, and this is our package" _pkgCategory desc @?= "Control" - _pkgExtraSrcFiles desc @?= [] - _pkgExtraDocFiles desc @?= "CHANGELOG.md" NEL.:| [] + _pkgExtraSrcFiles desc @?= mempty + _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") _libSourceDirs lib @?= ["quxSrc"] _libLanguage lib @?= Haskell98 @@ -323,8 +324,8 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _pkgHomePage desc @?= "" _pkgSynopsis desc @?= "" _pkgCategory desc @?= "" - _pkgExtraSrcFiles desc @?= [] - _pkgExtraDocFiles desc @?= "CHANGELOG.md" NEL.:| [] + _pkgExtraSrcFiles desc @?= mempty + _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell2010 @@ -452,8 +453,8 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _pkgHomePage desc @?= "" _pkgSynopsis desc @?= "" _pkgCategory desc @?= "" - _pkgExtraSrcFiles desc @?= [] - _pkgExtraDocFiles desc @?= "CHANGELOG.md" NEL.:| [] + _pkgExtraSrcFiles desc @?= mempty + _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell2010 @@ -581,8 +582,8 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _pkgHomePage desc @?= "" _pkgSynopsis desc @?= "" _pkgCategory desc @?= "" - _pkgExtraSrcFiles desc @?= [] - _pkgExtraDocFiles desc @?= "CHANGELOG.md" NEL.:| [] + _pkgExtraSrcFiles desc @?= mempty + _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell2010 @@ -683,8 +684,8 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _pkgHomePage desc @?= "" _pkgSynopsis desc @?= "" _pkgCategory desc @?= "" - _pkgExtraSrcFiles desc @?= [] - _pkgExtraDocFiles desc @?= "CHANGELOG.md" NEL.:| [] + _pkgExtraSrcFiles desc @?= mempty + _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") _libSourceDirs lib @?= ["src"] _libLanguage lib @?= Haskell2010 @@ -769,8 +770,8 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _pkgHomePage desc @?= "" _pkgSynopsis desc @?= "" _pkgCategory desc @?= "" - _pkgExtraSrcFiles desc @?= [] - _pkgExtraDocFiles desc @?= "CHANGELOG.md" NEL.:| [] + _pkgExtraSrcFiles desc @?= mempty + _pkgExtraDocFiles desc @?= pure (Set.singleton "CHANGELOG.md") _exeMainIs exe @?= HsFilePath "Main.hs" Standard _exeApplicationDirs exe @?= ["app"] @@ -992,12 +993,12 @@ nonInteractiveTests pkgIx srcDb comp = testGroup "Check top level getter functio ] , testGroup "Check extraDocFileHeuristics output" [ testSimple "No extra sources" extraDocFileHeuristics - (defaultChangelog NEL.:| []) + (pure (Set.singleton "CHANGELOG.md")) [ "test-package" , "[]" ] , testSimple "Extra doc files present" extraDocFileHeuristics - ("README.md" NEL.:| []) + (pure $ Set.singleton "README.md") [ "test-package" , "[\"README.md\"]" ] diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs index d7c01a2f97b..bc5ac54a727 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs @@ -24,6 +24,7 @@ import Distribution.Simple.Setup import qualified Data.List.NonEmpty as NEL import Distribution.Types.Dependency import Distribution.Client.Init.Utils (mkPackageNameDep) +import qualified Data.Set as Set tests :: Verbosity @@ -125,8 +126,8 @@ simplePkgDesc pkgName = PkgDescription defaultVersion defaultLicense "" "" "" "" "" - [] - (defaultChangelog NEL.:| []) + mempty + (Just $ Set.singleton defaultChangelog) simpleLibTarget :: LibTarget simpleLibTarget = LibTarget From d32ec7038a509f755518819adfa912bc6e8372fe Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Wed, 5 May 2021 11:09:20 -0400 Subject: [PATCH 11/37] output warning for doc files specified with cabal spec < 1.18 --- .../Client/Init/Interactive/Command.hs | 2 +- .../Client/Init/NonInteractive/Command.hs | 2 +- .../src/Distribution/Client/Init/Simple.hs | 4 ++-- .../src/Distribution/Client/Init/Utils.hs | 22 ++++++++++++------- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs index f5c1aa0e546..4de23226236 100644 --- a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs @@ -94,7 +94,7 @@ createProject v pkgIx srcDb initFlags = do isMinimal <- getMinimal initFlags doOverwrite <- getOverwrite initFlags pkgDir <- getPackageDir initFlags - pkgDesc <- fixupDocFiles <$> genPkgDescription initFlags srcDb + pkgDesc <- fixupDocFiles v =<< genPkgDescription initFlags srcDb let pkgName = _pkgName pkgDesc mkOpts cs = WriteOpts diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs index f83f3aa3cf1..16b7e70c08e 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs @@ -102,7 +102,7 @@ createProject comp v pkgIx srcDb initFlags = do isMinimal <- getMinimal initFlags doOverwrite <- getOverwrite initFlags pkgDir <- packageDirHeuristics initFlags - pkgDesc <- fixupDocFiles <$> genPkgDescription initFlags srcDb + pkgDesc <- fixupDocFiles v =<< genPkgDescription initFlags srcDb comments <- noCommentsHeuristics initFlags let pkgName = _pkgName pkgDesc diff --git a/cabal-install/src/Distribution/Client/Init/Simple.hs b/cabal-install/src/Distribution/Client/Init/Simple.hs index 8a28c8db7e7..fca3b752a1c 100644 --- a/cabal-install/src/Distribution/Client/Init/Simple.hs +++ b/cabal-install/src/Distribution/Client/Init/Simple.hs @@ -14,7 +14,7 @@ import Distribution.Verbosity import Distribution.Simple.PackageIndex import Distribution.Client.Types.SourcePackageDb (SourcePackageDb(..)) import qualified Data.List.NonEmpty as NEL -import Distribution.Client.Init.Utils (currentDirPkgName, mkPackageNameDep) +import Distribution.Client.Init.Utils (currentDirPkgName, mkPackageNameDep, fixupDocFiles) import Distribution.Client.Init.Defaults import Distribution.Simple.Flag (fromFlagOrDefault, flagElim) import Distribution.Client.Init.FlagExtractors @@ -33,7 +33,7 @@ createProject v _pkgIx _srcDb initFlags = do isMinimal <- getMinimal initFlags doOverwrite <- getOverwrite initFlags pkgDir <- getPackageDir initFlags - pkgDesc <- genSimplePkgDesc initFlags + pkgDesc <- fixupDocFiles v =<< genSimplePkgDesc initFlags let pkgName = _pkgName pkgDesc mkOpts cs = WriteOpts diff --git a/cabal-install/src/Distribution/Client/Init/Utils.hs b/cabal-install/src/Distribution/Client/Init/Utils.hs index c48b2a89b30..924fa1b92f5 100644 --- a/cabal-install/src/Distribution/Client/Init/Utils.hs +++ b/cabal-install/src/Distribution/Client/Init/Utils.hs @@ -269,11 +269,17 @@ mkPackageNameDep pkg = mkDependency pkg anyVersion (NES.singleton LMainLibName) -- so whatever the user wants as doc files should be dumped into -- extra-src-files. -- -fixupDocFiles :: PkgDescription -> PkgDescription -fixupDocFiles pkgDesc - | _pkgCabalVersion pkgDesc < CabalSpecV1_18 = pkgDesc - { _pkgExtraSrcFiles =_pkgExtraSrcFiles pkgDesc - <> fromMaybe mempty (_pkgExtraDocFiles pkgDesc) - , _pkgExtraDocFiles = Nothing - } - | otherwise = pkgDesc +fixupDocFiles :: Interactive m => Verbosity -> PkgDescription -> m PkgDescription +fixupDocFiles v pkgDesc + | _pkgCabalVersion pkgDesc < CabalSpecV1_18 = do + message v $ concat + [ "Cabal spec versions < 1.18 do not support extra-doc-files. " + , "Doc files will be treated as extra-src-files." + ] + + return $ pkgDesc + { _pkgExtraSrcFiles =_pkgExtraSrcFiles pkgDesc + <> fromMaybe mempty (_pkgExtraDocFiles pkgDesc) + , _pkgExtraDocFiles = Nothing + } + | otherwise = return pkgDesc From 977de79170c7c585d17cf726a52bd076bd208cca Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Wed, 5 May 2021 11:52:30 -0400 Subject: [PATCH 12/37] add formatters + fix text for extra doc + extra src files --- .../src/Distribution/Client/Init/Defaults.hs | 2 +- .../src/Distribution/Client/Init/Format.hs | 12 +-- .../Distribution/Client/Init/Interactive.hs | 83 ++++++++++++++++++- .../Client/Init/NonInteractive.hs | 2 +- .../cabal-lib-and-exe-no-comments.golden | 5 +- .../cabal-lib-and-exe-with-comments.golden | 7 +- .../golden/cabal/cabal-lib-no-comments.golden | 5 +- .../cabal/cabal-lib-with-comments.golden | 7 +- .../pkg-desc/pkg-old-cabal-with-flags.golden | 7 +- .../golden/pkg-desc/pkg-with-comments.golden | 7 +- .../golden/pkg-desc/pkg-with-flags.golden | 7 +- .../fixtures/init/golden/pkg-desc/pkg.golden | 7 +- 12 files changed, 125 insertions(+), 26 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/Defaults.hs b/cabal-install/src/Distribution/Client/Init/Defaults.hs index f58bdf89a30..4af745ac924 100644 --- a/cabal-install/src/Distribution/Client/Init/Defaults.hs +++ b/cabal-install/src/Distribution/Client/Init/Defaults.hs @@ -127,7 +127,7 @@ defaultCategories = defaultCabalVersions :: [CabalSpecVersion] defaultCabalVersions = - [ CabalSpecV1_10 + [ CabalSpecV1_24 , CabalSpecV2_0 , CabalSpecV2_2 , CabalSpecV2_4 diff --git a/cabal-install/src/Distribution/Client/Init/Format.hs b/cabal-install/src/Distribution/Client/Init/Format.hs index 8ad1f4908e4..714a4497e7e 100644 --- a/cabal-install/src/Distribution/Client/Init/Format.hs +++ b/cabal-install/src/Distribution/Client/Init/Format.hs @@ -328,14 +328,10 @@ mkPkgDescription opts pkgDesc = True opts - , case _pkgExtraSrcFiles pkgDesc of - fs - | null fs -> PrettyEmpty - | otherwise -> - field "extra-source-files" formatExtraSourceFiles (toList fs) - ["Extra source files to be distributed with the package, such as examples, or a tutorial module."] - True - opts + , field "extra-source-files" formatExtraSourceFiles (toList $ _pkgExtraSrcFiles pkgDesc) + ["Extra source files to be distributed with the package, such as examples, or a tutorial module."] + True + opts ] where cabalSpec = _pkgCabalVersion pkgDesc diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs index 9a650b3a4a3..c058793ae58 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs @@ -56,13 +56,13 @@ createProjectTest -> TestTree createProjectTest pkgIx srcDb = testGroup "createProject tests" [ testGroup "with flags" - [ testCase "Check the non-interactive workflow" $ do + [ testCase "Check the interactive workflow" $ do let dummyFlags' = dummyFlags { packageType = Flag LibraryAndExecutable , minimal = Flag False , overwrite = Flag False , packageDir = Flag "/home/test/test-package" - , extraSrc = Flag ["CHANGELOG.md"] + , extraSrc = NoFlag , exposedModules = Flag [] , otherModules = Flag [] , otherExts = Flag [] @@ -474,6 +474,85 @@ createProjectTest pkgIx srcDb = testGroup "createProject tests" test @?= Nothing Left e -> assertFailure $ show e + , testCase "Check the interactive library workflow - cabal < 1.18" $ do + let inputs = fromList + -- package type + [ "1" + -- package dir + , "test-package" + -- package description + -- cabal version + , "4" + -- package name + , "test-package" + , "test-package" + -- version + , "3.1.2.3" + -- license + , "3" + -- author + , "Foobar" + -- email + , "foobar@qux.com" + -- homepage + , "qux.com" + -- synopsis + , "Qux's package" + -- category + , "3" + -- library target + -- source dir + , "1" + -- language + , "2" + -- test suite + , "n" + -- comments + , "y" + ] + + flags = emptyFlags + { cabalVersion = Flag CabalSpecV1_10 + , extraDoc = Flag [defaultChangelog] + , extraSrc = Flag ["README.md"] + } + + case (_runPrompt $ createProject silent pkgIx srcDb flags) inputs of + Right (ProjectSettings opts desc (Just lib) Nothing Nothing, _) -> do + _optOverwrite opts @?= False + _optMinimal opts @?= False + _optNoComments opts @?= False + _optVerbosity opts @?= silent + _optPkgDir opts @?= "/home/test/test-package" + _optPkgType opts @?= Library + _optPkgName opts @?= mkPackageName "test-package" + + _pkgCabalVersion desc @?= CabalSpecV1_10 + _pkgName desc @?= mkPackageName "test-package" + _pkgVersion desc @?= mkVersion [3,1,2,3] + _pkgLicense desc @?! SPDX.NONE + _pkgAuthor desc @?= "Foobar" + _pkgEmail desc @?= "foobar@qux.com" + _pkgHomePage desc @?= "qux.com" + _pkgSynopsis desc @?= "Qux's package" + _pkgCategory desc @?= "Control" + _pkgExtraSrcFiles desc @?= Set.fromList [defaultChangelog, "README.md"] + _pkgExtraDocFiles desc @?= Nothing + + _libSourceDirs lib @?= ["src"] + _libLanguage lib @?= Haskell98 + _libExposedModules lib @?= myLibModule :| [] + _libOtherModules lib @?= [] + _libOtherExts lib @?= [] + _libDependencies lib @?! [] + _libBuildTools lib @?= [] + + Right (ProjectSettings _ _ lib exe test, _) -> do + lib @?! Nothing + exe @?= Nothing + test @?= Nothing + Left e -> assertFailure $ show e + , testCase "Check the interactive executable workflow" $ do let inputs = fromList -- package type diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs index 3acea740156..e0337f343fd 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs @@ -31,7 +31,7 @@ tests -> SourcePackageDb -> TestTree tests _v _initFlags comp pkgIx srcDb = - testGroup "cabal init non-interactive" + testGroup "Distribution.Client.Init.NonInteractive.Command" [ testGroup "driver function test" [ driverFunctionTest pkgIx srcDb comp ] diff --git a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden index 8c75394d2c8..72b5c6a3dba 100644 --- a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden +++ b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden @@ -15,7 +15,10 @@ maintainer: foo-kmett@kmett.kmett -- copyright: category: Data build-type: Simple -extra-source-files: CHANGELOG.md +extra-doc-files: CHANGELOG.md + +-- Extra source files to be distributed with the package, such as examples, or a tutorial module. +-- extra-source-files: library exposed-modules: MyLib diff --git a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden index f0b2b216bda..0addbe1ccae 100644 --- a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden +++ b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden @@ -42,8 +42,11 @@ maintainer: foo-kmett@kmett.kmett category: Data build-type: Simple --- Extra files to be distributed with the package, such as examples or a README. -extra-source-files: CHANGELOG.md +-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. +extra-doc-files: CHANGELOG.md + +-- Extra source files to be distributed with the package, such as examples, or a tutorial module. +-- extra-source-files: library -- Modules exported by the library. diff --git a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden index 336bd3fb210..d67fd8cfb38 100644 --- a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden +++ b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden @@ -15,7 +15,10 @@ maintainer: foo-kmett@kmett.kmett -- copyright: category: Data build-type: Simple -extra-source-files: CHANGELOG.md +extra-doc-files: CHANGELOG.md + +-- Extra source files to be distributed with the package, such as examples, or a tutorial module. +-- extra-source-files: library exposed-modules: MyLib diff --git a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden index 14b06a911c5..e3b335e0cbd 100644 --- a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden +++ b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden @@ -42,8 +42,11 @@ maintainer: foo-kmett@kmett.kmett category: Data build-type: Simple --- Extra files to be distributed with the package, such as examples or a README. -extra-source-files: CHANGELOG.md +-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. +extra-doc-files: CHANGELOG.md + +-- Extra source files to be distributed with the package, such as examples, or a tutorial module. +-- extra-source-files: library -- Modules exported by the library. diff --git a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden index 776f6abd320..799181abd6d 100644 --- a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden +++ b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden @@ -41,5 +41,8 @@ maintainer: foobar@qux.com -- copyright: category: Control --- Extra files to be distributed with the package, such as examples or a README. -extra-source-files: CHANGELOG.md +-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. +extra-doc-files: CHANGELOG.md + +-- Extra source files to be distributed with the package, such as examples, or a tutorial module. +-- extra-source-files: diff --git a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden index 47924235c7f..56c3d296429 100644 --- a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden +++ b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden @@ -42,5 +42,8 @@ maintainer: foo-kmett@kmett.kmett category: Data build-type: Simple --- Extra files to be distributed with the package, such as examples or a README. -extra-source-files: CHANGELOG.md +-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. +extra-doc-files: CHANGELOG.md + +-- Extra source files to be distributed with the package, such as examples, or a tutorial module. +-- extra-source-files: diff --git a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden index 52613c0f0d7..643d538c8e8 100644 --- a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden +++ b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden @@ -42,5 +42,8 @@ maintainer: foobar@qux.com category: Control build-type: Simple --- Extra files to be distributed with the package, such as examples or a README. -extra-source-files: CHANGELOG.md +-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. +extra-doc-files: CHANGELOG.md + +-- Extra source files to be distributed with the package, such as examples, or a tutorial module. +-- extra-source-files: diff --git a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg.golden b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg.golden index 47924235c7f..56c3d296429 100644 --- a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg.golden +++ b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg.golden @@ -42,5 +42,8 @@ maintainer: foo-kmett@kmett.kmett category: Data build-type: Simple --- Extra files to be distributed with the package, such as examples or a README. -extra-source-files: CHANGELOG.md +-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. +extra-doc-files: CHANGELOG.md + +-- Extra source files to be distributed with the package, such as examples, or a tutorial module. +-- extra-source-files: From 6bb2df8c7fedfd2bc5d9b4db099a8cead7427d69 Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Wed, 5 May 2021 13:24:24 -0400 Subject: [PATCH 13/37] remove little version parser, fix up some hanging cruft --- .../Client/Init/NonInteractive/Heuristics.hs | 30 +++++++--------- .../src/Distribution/Client/Init/Types.hs | 7 ++-- .../src/Distribution/Client/Init/Utils.hs | 36 +------------------ .../src/Distribution/Client/Utils.hs | 6 ++++ 4 files changed, 21 insertions(+), 58 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs index 78f74b11d2d..977bbb1dcce 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs @@ -26,16 +26,14 @@ module Distribution.Client.Init.NonInteractive.Heuristics , guessApplicationDirectories ) where -import Prelude (read) import Distribution.Client.Compat.Prelude hiding (readFile, (<|>), many) import Distribution.Utils.Generic (safeLast) import Distribution.Simple.Setup (fromFlagOrDefault) -import Text.Parsec import qualified Data.List as L import Distribution.Client.Init.Defaults -import Distribution.Client.Init.Types hiding (break) +import Distribution.Client.Init.Types import Distribution.Client.Init.Utils import qualified Distribution.SPDX as SPDX import System.FilePath @@ -52,7 +50,6 @@ import qualified Data.Set as Set guessMainFile :: Interactive m => FilePath -> m HsFilePath guessMainFile pkgDir = do files <- filter isMain <$> listFilesRecursive pkgDir - return $ if null files then defaultMainIs else toHsFilePath $ L.head files @@ -62,15 +59,12 @@ guessMainFile pkgDir = do guessCabalSpecVersion :: Interactive m => m CabalSpecVersion guessCabalSpecVersion = do (_, verString, _) <- readProcessWithExitCode "cabal" ["--version"] "" - case runParser versionParser () "" verString of - Right ver@(_:_) -> return $ - read $ "CabalSpecV" ++ format' ver - _ -> return defaultCabalVersion - - where - format' [] = [] - format' ('.':xs) = '_' : takeWhile (/= '.') xs - format' (x:xs) = x : format' xs + case simpleParsec $ takeWhile (not . isSpace) $ dropWhile (not . isDigit) verString of + Just v -> pure $ fromMaybe defaultCabalVersion $ case versionNumbers v of + [x,y,_,_] -> cabalSpecFromVersionDigits [x,y] + [x,y,_] -> cabalSpecFromVersionDigits [x,y] + _ -> Just defaultCabalVersion + Nothing -> pure defaultCabalVersion -- | Guess the language specification based on the GHC version guessLanguage :: Interactive m => Compiler -> m Language @@ -94,7 +88,7 @@ guessPackageName = fmap (mkPackageName . repair . fromMaybe "" . safeLast . spli repair = repair' ('x' :) id repair' invalid valid x = case dropWhile (not . isAlphaNum) x of "" -> repairComponent "" - x' -> let (c, r) = first repairComponent $ break (not . isAlphaNum) x' + x' -> let (c, r) = first repairComponent $ span isAlphaNum x' in c ++ repairRest r where repairComponent c | all isDigit c = invalid c @@ -109,7 +103,7 @@ guessLicense _ = return SPDX.NONE guessExtraDocFiles :: Interactive m => InitFlags -> m (Maybe (Set FilePath)) guessExtraDocFiles flags = do - pkgDir <- fromFlagOrDefault getCurrentDirectory $ fmap return $ packageDir flags + pkgDir <- fromFlagOrDefault getCurrentDirectory $ return <$> packageDir flags files <- getDirectoryContents pkgDir let extraDocCandidates = ["CHANGES", "CHANGELOG", "README"] @@ -127,7 +121,7 @@ guessPackageType flags = do srcCandidates = [defaultSourceDir, "src", "source"] testCandidates = [defaultTestDir, "test", "tests"] - pkgDir <- fromFlagOrDefault getCurrentDirectory $ fmap return $ packageDir flags + pkgDir <- fromFlagOrDefault getCurrentDirectory $ return <$> packageDir flags files <- listFilesInside (\x -> return $ lastDir x `notElem` testCandidates) pkgDir let hasExe = not $ null [f | f <- files, isMain $ takeFileName f] @@ -143,7 +137,7 @@ guessPackageType flags = do guessApplicationDirectories :: Interactive m => InitFlags -> m [FilePath] guessApplicationDirectories flags = do pkgDirs <- fromFlagOrDefault getCurrentDirectory - (fmap return $ packageDir flags) + (return <$> packageDir flags) pkgDirsContents <- listDirectory pkgDirs let candidates = [defaultApplicationDir, "app", "src-exe"] in @@ -154,7 +148,7 @@ guessApplicationDirectories flags = do -- | Try to guess the source directories, using a default value as fallback. guessSourceDirectories :: Interactive m => InitFlags -> m [FilePath] guessSourceDirectories flags = do - pkgDir <- fromFlagOrDefault getCurrentDirectory $ fmap return $ packageDir flags + pkgDir <- fromFlagOrDefault getCurrentDirectory $ return <$> packageDir flags doesDirectoryExist (pkgDir "src") >>= return . \case False -> [defaultSourceDir] diff --git a/cabal-install/src/Distribution/Client/Init/Types.hs b/cabal-install/src/Distribution/Client/Init/Types.hs index e6c1b696874..1dcdb283922 100644 --- a/cabal-install/src/Distribution/Client/Init/Types.hs +++ b/cabal-install/src/Distribution/Client/Init/Types.hs @@ -395,13 +395,10 @@ popBool = pop >>= \case s -> throwPrompt $ BreakException $ "popBool: " ++ s popList :: PurePrompt [String] -popList = pop >>= \a -> case safeRead a of +popList = pop >>= \a -> case P.safeRead a of Nothing -> throwPrompt $ BreakException ("popList: " ++ show a) Just as -> return as - where - safeRead s - | [(x, "")] <- reads s = Just x - | otherwise = Nothing + -- | A pure exception thrown exclusively by the pure prompter -- to cancel infinite loops in the prompting process. diff --git a/cabal-install/src/Distribution/Client/Init/Utils.hs b/cabal-install/src/Distribution/Client/Init/Utils.hs index 924fa1b92f5..34cc44d2e85 100644 --- a/cabal-install/src/Distribution/Client/Init/Utils.hs +++ b/cabal-install/src/Distribution/Client/Init/Utils.hs @@ -11,7 +11,6 @@ module Distribution.Client.Init.Utils , isMain , isHaskell , isSourceFile -, versionParser , trim , currentDirPkgName , filePathToPkgName @@ -42,7 +41,7 @@ import Distribution.Verbosity import Distribution.Version import Distribution.Client.Init.Defaults import Distribution.Client.Init.Types -import Text.Parsec +import Distribution.Client.Utils (pvpize) import Distribution.Types.PackageName import Distribution.Types.Dependency (Dependency, mkDependency) import qualified Distribution.Compat.NonEmptySet as NES @@ -223,39 +222,6 @@ chooseDep flags (m, mipi) = case mipi of Flag x -> x < CabalSpecV2_0 NoFlag -> defaultCabalVersion < CabalSpecV2_0 --- | Given a version, return an API-compatible (according to PVP) version range. --- --- If the boolean argument denotes whether to use a desugared --- representation (if 'True') or the new-style @^>=@-form (if --- 'False'). --- --- Example: @pvpize True (mkVersion [0,4,1])@ produces the version range @>= 0.4 && < 0.5@ (which is the --- same as @0.4.*@). -pvpize :: Bool -> Version -> VersionRange -pvpize False v = majorBoundVersion v -pvpize True v = orLaterVersion v' - `intersectVersionRanges` - earlierVersion (incVersion 1 v') - where - v' = alterVersion (take 2) v - - -- Increment the nth version component (counting from 0). - incVersion :: Int -> Version -> Version - incVersion n = alterVersion (incVersion' n) - where - incVersion' 0 [] = [1] - incVersion' 0 (v'':_) = [v'' + 1] - incVersion' m [] = replicate m 0 ++ [1] - incVersion' m (v'':vs) = v'' : incVersion' (m-1) vs - -versionParser :: Parsec String () String -versionParser = do - skipMany (noneOf "1234567890") - many $ choice - [ oneOf "1234567890" - , oneOf "." - ] - filePathToPkgName :: FilePath -> P.PackageName filePathToPkgName = PN.mkPackageName . Prelude.last . splitDirectories diff --git a/cabal-install/src/Distribution/Client/Utils.hs b/cabal-install/src/Distribution/Client/Utils.hs index 9803a55d46c..0b5fde29c9e 100644 --- a/cabal-install/src/Distribution/Client/Utils.hs +++ b/cabal-install/src/Distribution/Client/Utils.hs @@ -27,6 +27,7 @@ module Distribution.Client.Utils , getCurrentYear , listFilesRecursive , listFilesInside + , safeRead ) where import Prelude () @@ -450,3 +451,8 @@ partitionM f (x:xs) = do -- https://hackage.haskell.org/package/extra-1.7.9 notM :: Functor m => m Bool -> m Bool notM = fmap not + +safeRead :: Read a => String -> Maybe a +safeRead s + | [(x, "")] <- reads s = Just x + | otherwise = Nothing From bb3afeed0123aaeff2b1e25634ffbbcb046200a7 Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Wed, 5 May 2021 13:51:49 -0400 Subject: [PATCH 14/37] fix formatter extra-doc-files --- cabal-install/src/Distribution/Client/Init/Format.hs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/Format.hs b/cabal-install/src/Distribution/Client/Init/Format.hs index 714a4497e7e..62a0b7252b0 100644 --- a/cabal-install/src/Distribution/Client/Init/Format.hs +++ b/cabal-install/src/Distribution/Client/Init/Format.hs @@ -320,13 +320,11 @@ mkPkgDescription opts pkgDesc = opts , case _pkgExtraDocFiles pkgDesc of Nothing -> PrettyEmpty - Just fs - | null fs -> PrettyEmpty - | otherwise -> - field "extra-doc-files" formatExtraSourceFiles (toList fs) - ["Extra doc files to be distributed with the package, such as a CHANGELOG or a README."] - True - opts + Just fs -> + field "extra-doc-files" formatExtraSourceFiles (toList fs) + ["Extra doc files to be distributed with the package, such as a CHANGELOG or a README."] + True + opts , field "extra-source-files" formatExtraSourceFiles (toList $ _pkgExtraSrcFiles pkgDesc) ["Extra source files to be distributed with the package, such as examples, or a tutorial module."] From 6fff94d808c6408523075d6fedeba1fac6e9a422 Mon Sep 17 00:00:00 2001 From: Patrick Augusto Date: Thu, 6 May 2021 18:11:33 -0300 Subject: [PATCH 15/37] Adjusting module name detection to ignore comments --- cabal-install/src/Distribution/Client/Init/Utils.hs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/Utils.hs b/cabal-install/src/Distribution/Client/Init/Utils.hs index 34cc44d2e85..2e3b2432d5b 100644 --- a/cabal-install/src/Distribution/Client/Init/Utils.hs +++ b/cabal-install/src/Distribution/Client/Init/Utils.hs @@ -106,9 +106,10 @@ retrieveModuleName m = do fromString . trim . grabModuleName <$> readFile m where - stop c = (c /= '\\') && (c /= ' ') + stop c = (c /= '\n') && (c /= ' ') grabModuleName [] = [] + grabModuleName ('-':'-':xs) = grabModuleName $ dropWhile' (/= '\n') xs grabModuleName ('m':'o':'d':'u':'l':'e':' ':xs) = takeWhile' stop xs grabModuleName (_:xs) = grabModuleName xs @@ -118,9 +119,10 @@ retrieveModuleImports m = do map (fromString . trim) . grabModuleImports <$> readFile m where - stop c = (c /= '\\') && (c /= ' ') && (c /= '(') + stop c = (c /= '\n') && (c /= ' ') && (c /= '(') grabModuleImports [] = [] + grabModuleImports ('-':'-':xs) = grabModuleImports $ dropWhile' (/= '\n') xs grabModuleImports ('i':'m':'p':'o':'r':'t':' ':xs) = case trim xs of -- in case someone uses a weird formatting ('q':'u':'a':'l':'i':'f':'i':'e':'d':' ':ys) -> takeWhile' stop ys : grabModuleImports (dropWhile' stop ys) _ -> takeWhile' stop xs : grabModuleImports (dropWhile' stop xs) @@ -132,9 +134,10 @@ retrieveModuleExtensions m = do catMaybes <$> map (simpleParsec . trim) . grabModuleExtensions <$> readFile m where - stop c = (c /= '\\') && (c /= ' ') && (c /= ',') + stop c = (c /= '\n') && (c /= ' ') && (c /= ',') grabModuleExtensions [] = [] + grabModuleExtensions ('-':'-':xs) = grabModuleExtensions $ dropWhile' (/= '\n') xs grabModuleExtensions ('L':'A':'N':'G':'U':'A':'G':'E':' ':xs) = takeWhile' stop xs : grabModuleExtensions (dropWhile' stop xs) grabModuleExtensions (',':xs) = takeWhile' stop xs : grabModuleExtensions (dropWhile' stop xs) grabModuleExtensions (_:xs) = grabModuleExtensions xs From 06c9595cb5f0e2056d875a34026f23bf0c2d3b1d Mon Sep 17 00:00:00 2001 From: Patrick Augusto Date: Thu, 6 May 2021 18:46:46 -0300 Subject: [PATCH 16/37] Adding boundaries for the other-extensions parser --- cabal-install/src/Distribution/Client/Init/Utils.hs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/Utils.hs b/cabal-install/src/Distribution/Client/Init/Utils.hs index 2e3b2432d5b..3cb25c82c40 100644 --- a/cabal-install/src/Distribution/Client/Init/Utils.hs +++ b/cabal-install/src/Distribution/Client/Init/Utils.hs @@ -134,13 +134,17 @@ retrieveModuleExtensions m = do catMaybes <$> map (simpleParsec . trim) . grabModuleExtensions <$> readFile m where - stop c = (c /= '\n') && (c /= ' ') && (c /= ',') + stop c = (c /= '\n') && (c /= ' ') && (c /= ',') && (c /= '#') grabModuleExtensions [] = [] grabModuleExtensions ('-':'-':xs) = grabModuleExtensions $ dropWhile' (/= '\n') xs - grabModuleExtensions ('L':'A':'N':'G':'U':'A':'G':'E':' ':xs) = takeWhile' stop xs : grabModuleExtensions (dropWhile' stop xs) - grabModuleExtensions (',':xs) = takeWhile' stop xs : grabModuleExtensions (dropWhile' stop xs) + grabModuleExtensions ('L':'A':'N':'G':'U':'A':'G':'E':xs) = takeWhile' stop xs : grabModuleExtensions' (dropWhile' stop xs) grabModuleExtensions (_:xs) = grabModuleExtensions xs + + grabModuleExtensions' [] = [] + grabModuleExtensions' ('#':xs) = grabModuleExtensions xs + grabModuleExtensions' (',':xs) = takeWhile' stop xs : grabModuleExtensions' (dropWhile' stop xs) + grabModuleExtensions' (_:xs) = grabModuleExtensions xs takeWhile' :: (Char -> Bool) -> String -> String takeWhile' p = takeWhile p . trim From a9daeffcda1cc3aeb1171d7dceaebc6a8d55f48f Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Fri, 7 May 2021 12:07:47 -0400 Subject: [PATCH 17/37] fix build-tool vs build-tool-depends problem --- .../Distribution/Client/Init/FileCreators.hs | 4 +- .../Client/Init/FlagExtractors.hs | 12 ++- .../src/Distribution/Client/Init/Format.hs | 12 ++- .../Client/Init/Interactive/Command.hs | 7 +- .../Client/Init/NonInteractive/Command.hs | 11 +-- .../src/Distribution/Client/Init/Simple.hs | 75 ++++++++++--------- .../src/Distribution/Client/Init/Types.hs | 7 +- .../src/Distribution/Client/Init/Utils.hs | 17 ++++- .../Distribution/Client/Init/Golden.hs | 43 +++++------ .../Client/Init/NonInteractive.hs | 21 +++--- .../Distribution/Client/Init/Simple.hs | 10 +-- .../exe/exe-build-tools-with-comments.golden | 10 +-- .../lib/lib-build-tools-with-comments.golden | 10 +-- .../test-build-tools-with-comments.golden | 12 +-- 14 files changed, 143 insertions(+), 108 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/FileCreators.hs b/cabal-install/src/Distribution/Client/Init/FileCreators.hs index 7ce2c26be9c..29bad1e0b1c 100644 --- a/cabal-install/src/Distribution/Client/Init/FileCreators.hs +++ b/cabal-install/src/Distribution/Client/Init/FileCreators.hs @@ -52,7 +52,9 @@ writeProject (ProjectSettings opts pkgDesc libTarget exeTarget testTarget) | otherwise = do -- clear prompt history a bit" - message opts "" + message opts + $ "\nUsing cabal specification: " + ++ show (_optCabalSpec opts) writeLicense opts pkgDesc writeChangeLog opts pkgDesc diff --git a/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs b/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs index d74eebe3136..b00196450ec 100644 --- a/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs +++ b/cabal-install/src/Distribution/Client/Init/FlagExtractors.hs @@ -180,8 +180,16 @@ getOtherModules :: Interactive m => InitFlags -> m [ModuleName] getOtherModules = return . fromFlagOrDefault [] . otherModules -- | Retrieve the list of build tools -getBuildTools :: Interactive m => InitFlags -> m [String] -getBuildTools = return . fromFlagOrDefault [] . buildTools +getBuildTools :: Interactive m => InitFlags -> m [Dependency] +getBuildTools = flagElim (return []) (foldM go []) . buildTools + where + go acc dep = case eitherParsec dep of + Left e -> do + putStrLn $ "Failed to parse dependency: " ++ e + putStrLn "Skipping..." + + return acc + Right d -> return $ acc ++ [d] -- | Retrieve the list of dependencies getDependencies diff --git a/cabal-install/src/Distribution/Client/Init/Format.hs b/cabal-install/src/Distribution/Client/Init/Format.hs index 62a0b7252b0..ade3281dbfa 100644 --- a/cabal-install/src/Distribution/Client/Init/Format.hs +++ b/cabal-install/src/Distribution/Client/Init/Format.hs @@ -138,7 +138,7 @@ mkLibStanza opts (LibTarget srcDirs lang expMods otherMods exts deps tools) = True opts - , field "build-tools" listFieldS tools + , field (buildToolTag opts) formatDependencyList tools ["Extra tools (e.g. alex, hsc2hs, ...) needed to build the source."] False opts @@ -177,7 +177,7 @@ mkExeStanza opts (ExeTarget exeMain appDirs lang otherMods exts deps tools) = True opts - , field "build-tools" listFieldS tools + , field (buildToolTag opts) formatDependencyList tools ["Extra tools (e.g. alex, hsc2hs, ...) needed to build the source."] False opts @@ -190,7 +190,6 @@ mkExeStanza opts (ExeTarget exeMain appDirs lang otherMods exts deps tools) = where exeName = pretty $ _optPkgName opts - mkTestStanza :: WriteOpts -> TestTarget -> PrettyField FieldAnnotation mkTestStanza opts (TestTarget testMain dirs lang otherMods exts deps tools) = PrettySection annNoComments (toUTF8BS "test-suite") [suiteName] @@ -229,7 +228,7 @@ mkTestStanza opts (TestTarget testMain dirs lang otherMods exts deps tools) = True opts - , field "build-tools" listFieldS tools + , field (buildToolTag opts) formatDependencyList tools ["Extra tools (e.g. alex, hsc2hs, ...) needed to build the source."] False opts @@ -343,3 +342,8 @@ listFieldS = text . intercalate ", " unsafeFromHs :: HsFilePath -> Doc unsafeFromHs = text . _hsFilePath + +buildToolTag :: WriteOpts -> FieldName +buildToolTag opts + | _optCabalSpec opts < CabalSpecV3_0 = "build-tools" + | otherwise = "build-tool-depends" diff --git a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs index 4de23226236..6f24916c0f8 100644 --- a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs @@ -97,6 +97,7 @@ createProject v pkgIx srcDb initFlags = do pkgDesc <- fixupDocFiles v =<< genPkgDescription initFlags srcDb let pkgName = _pkgName pkgDesc + cabalSpec = _pkgCabalVersion pkgDesc mkOpts cs = WriteOpts doOverwrite isMinimal cs v pkgDir pkgType pkgName @@ -110,7 +111,7 @@ createProject v pkgIx srcDb initFlags = do comments <- noCommentsPrompt initFlags return $ ProjectSettings - (mkOpts comments) pkgDesc + (mkOpts comments cabalSpec) pkgDesc (Just libTarget) Nothing testTarget Executable -> do @@ -118,7 +119,7 @@ createProject v pkgIx srcDb initFlags = do comments <- noCommentsPrompt initFlags return $ ProjectSettings - (mkOpts comments) pkgDesc Nothing + (mkOpts comments cabalSpec) pkgDesc Nothing (Just exeTarget) Nothing LibraryAndExecutable -> do @@ -133,7 +134,7 @@ createProject v pkgIx srcDb initFlags = do comments <- noCommentsPrompt initFlags return $ ProjectSettings - (mkOpts comments) pkgDesc (Just libTarget) + (mkOpts comments cabalSpec) pkgDesc (Just libTarget) (Just exeTarget) testTarget where -- Add package name as dependency of test suite diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs index 16b7e70c08e..c000e54f4e7 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs @@ -106,6 +106,7 @@ createProject comp v pkgIx srcDb initFlags = do comments <- noCommentsHeuristics initFlags let pkgName = _pkgName pkgDesc + cabalSpec = _pkgCabalVersion pkgDesc mkOpts cs = WriteOpts doOverwrite isMinimal cs v pkgDir pkgType pkgName @@ -116,14 +117,14 @@ createProject comp v pkgIx srcDb initFlags = do testTarget <- genTestTarget initFlags comp pkgIx return $ ProjectSettings - (mkOpts comments) pkgDesc + (mkOpts comments cabalSpec) pkgDesc (Just libTarget) Nothing testTarget Executable -> do exeTarget <- genExeTarget initFlags comp pkgIx return $ ProjectSettings - (mkOpts comments) pkgDesc Nothing + (mkOpts comments cabalSpec) pkgDesc Nothing (Just exeTarget) Nothing LibraryAndExecutable -> do @@ -132,7 +133,7 @@ createProject comp v pkgIx srcDb initFlags = do testTarget <- genTestTarget initFlags comp pkgIx return $ ProjectSettings - (mkOpts comments) pkgDesc (Just libTarget) + (mkOpts comments cabalSpec) pkgDesc (Just libTarget) (Just exeTarget) testTarget genPkgDescription @@ -412,9 +413,9 @@ testOtherModulesHeuristics flags = case otherModules flags of else return [] -- | Retrieve the list of build tools -buildToolsHeuristics :: Interactive m => InitFlags -> FilePath -> m [String] +buildToolsHeuristics :: Interactive m => InitFlags -> FilePath -> m [Dependency] buildToolsHeuristics flags fp = case buildTools flags of - Flag x -> return x + Flag{} -> getBuildTools flags NoFlag -> retrieveBuildTools fp -- | Retrieve the list of dependencies diff --git a/cabal-install/src/Distribution/Client/Init/Simple.hs b/cabal-install/src/Distribution/Client/Init/Simple.hs index fca3b752a1c..5d238981983 100644 --- a/cabal-install/src/Distribution/Client/Init/Simple.hs +++ b/cabal-install/src/Distribution/Client/Init/Simple.hs @@ -36,6 +36,7 @@ createProject v _pkgIx _srcDb initFlags = do pkgDesc <- fixupDocFiles v =<< genSimplePkgDesc initFlags let pkgName = _pkgName pkgDesc + cabalSpec = _pkgCabalVersion pkgDesc mkOpts cs = WriteOpts doOverwrite isMinimal cs v pkgDir pkgType pkgName @@ -45,13 +46,13 @@ createProject v _pkgIx _srcDb initFlags = do libTarget <- genSimpleLibTarget initFlags testTarget <- addLibDepToTest pkgName <$> genSimpleTestTarget initFlags return $ ProjectSettings - (mkOpts False) pkgDesc + (mkOpts False cabalSpec) pkgDesc (Just libTarget) Nothing testTarget Executable -> do exeTarget <- genSimpleExeTarget initFlags return $ ProjectSettings - (mkOpts False) pkgDesc + (mkOpts False cabalSpec) pkgDesc Nothing (Just exeTarget) Nothing LibraryAndExecutable -> do @@ -59,7 +60,7 @@ createProject v _pkgIx _srcDb initFlags = do testTarget <- addLibDepToTest pkgName <$> genSimpleTestTarget initFlags exeTarget <- addLibDepToExe pkgName <$> genSimpleExeTarget initFlags return $ ProjectSettings - (mkOpts False) pkgDesc + (mkOpts False cabalSpec) pkgDesc (Just libTarget) (Just exeTarget) testTarget where -- Add package name as dependency of test suite @@ -97,44 +98,50 @@ genSimplePkgDesc flags = mkPkgDesc <$> currentDirPkgName (flagElim defaultExtraDoc extractExtraDoc (extraDoc flags)) genSimpleLibTarget :: Interactive m => InitFlags -> m LibTarget -genSimpleLibTarget flags = return $ LibTarget - { _libSourceDirs = fromFlagOrDefault [defaultSourceDir] $ sourceDirs flags - , _libLanguage = fromFlagOrDefault defaultLanguage $ language flags - , _libExposedModules = flagElim (myLibModule NEL.:| []) extractMods $ - exposedModules flags - , _libOtherModules = fromFlagOrDefault [] $ otherModules flags - , _libOtherExts = fromFlagOrDefault [] $ otherExts flags - , _libDependencies = fromFlagOrDefault [] $ dependencies flags - , _libBuildTools= fromFlagOrDefault [] $ buildTools flags - } +genSimpleLibTarget flags = do + buildToolDeps <- getBuildTools flags + return $ LibTarget + { _libSourceDirs = fromFlagOrDefault [defaultSourceDir] $ sourceDirs flags + , _libLanguage = fromFlagOrDefault defaultLanguage $ language flags + , _libExposedModules = + flagElim (myLibModule NEL.:| []) extractMods $ exposedModules flags + , _libOtherModules = fromFlagOrDefault [] $ otherModules flags + , _libOtherExts = fromFlagOrDefault [] $ otherExts flags + , _libDependencies = fromFlagOrDefault [] $ dependencies flags + , _libBuildTools = buildToolDeps + } where extractMods [] = myLibModule NEL.:| [] extractMods as = NEL.fromList as genSimpleExeTarget :: Interactive m => InitFlags -> m ExeTarget -genSimpleExeTarget flags = return $ ExeTarget - { _exeMainIs = flagElim defaultMainIs toHsFilePath $ mainIs flags - , _exeApplicationDirs = fromFlagOrDefault [defaultApplicationDir] $ - applicationDirs flags - , _exeLanguage = fromFlagOrDefault defaultLanguage $ language flags - , _exeOtherModules = fromFlagOrDefault [] $ otherModules flags - , _exeOtherExts = fromFlagOrDefault [] $ otherExts flags - , _exeDependencies = fromFlagOrDefault [] $ dependencies flags - , _exeBuildTools = fromFlagOrDefault [] $ buildTools flags - } +genSimpleExeTarget flags = do + buildToolDeps <- getBuildTools flags + return $ ExeTarget + { _exeMainIs = flagElim defaultMainIs toHsFilePath $ mainIs flags + , _exeApplicationDirs = + fromFlagOrDefault [defaultApplicationDir] $ applicationDirs flags + , _exeLanguage = fromFlagOrDefault defaultLanguage $ language flags + , _exeOtherModules = fromFlagOrDefault [] $ otherModules flags + , _exeOtherExts = fromFlagOrDefault [] $ otherExts flags + , _exeDependencies = fromFlagOrDefault [] $ dependencies flags + , _exeBuildTools = buildToolDeps + } genSimpleTestTarget :: Interactive m => InitFlags -> m (Maybe TestTarget) -genSimpleTestTarget flags = go <$> initializeTestSuitePrompt flags +genSimpleTestTarget flags = go =<< initializeTestSuitePrompt flags where go initialized - | not initialized = Nothing - | otherwise = Just $ TestTarget - { _testMainIs = flagElim defaultMainIs toHsFilePath $ mainIs flags - , _testDirs = fromFlagOrDefault [defaultTestDir] $ testDirs flags - , _testLanguage = fromFlagOrDefault defaultLanguage $ language flags - , _testOtherModules = fromFlagOrDefault [] $ otherModules flags - , _testOtherExts = fromFlagOrDefault [] $ otherExts flags - , _testDependencies = fromFlagOrDefault [] $ dependencies flags - , _testBuildTools = fromFlagOrDefault [] $ buildTools flags - } + | not initialized = return Nothing + | otherwise = do + buildToolDeps <- getBuildTools flags + return $ Just $ TestTarget + { _testMainIs = flagElim defaultMainIs toHsFilePath $ mainIs flags + , _testDirs = fromFlagOrDefault [defaultTestDir] $ testDirs flags + , _testLanguage = fromFlagOrDefault defaultLanguage $ language flags + , _testOtherModules = fromFlagOrDefault [] $ otherModules flags + , _testOtherExts = fromFlagOrDefault [] $ otherExts flags + , _testDependencies = fromFlagOrDefault [] $ dependencies flags + , _testBuildTools = buildToolDeps + } diff --git a/cabal-install/src/Distribution/Client/Init/Types.hs b/cabal-install/src/Distribution/Client/Init/Types.hs index 1dcdb283922..b31d94d1533 100644 --- a/cabal-install/src/Distribution/Client/Init/Types.hs +++ b/cabal-install/src/Distribution/Client/Init/Types.hs @@ -155,7 +155,7 @@ data LibTarget = LibTarget , _libOtherModules :: [ModuleName] , _libOtherExts :: [Extension] , _libDependencies :: [P.Dependency] - , _libBuildTools :: [String] + , _libBuildTools :: [P.Dependency] } deriving (Show, Eq) -- | 'ExeTarget' represents the relevant options set by the @@ -168,7 +168,7 @@ data ExeTarget = ExeTarget , _exeOtherModules :: [ModuleName] , _exeOtherExts :: [Extension] , _exeDependencies :: [P.Dependency] - , _exeBuildTools :: [String] + , _exeBuildTools :: [P.Dependency] } deriving (Show, Eq) -- | 'TestTarget' represents the relevant options set by the @@ -181,7 +181,7 @@ data TestTarget = TestTarget , _testOtherModules :: [ModuleName] , _testOtherExts :: [Extension] , _testDependencies :: [P.Dependency] - , _testBuildTools :: [String] + , _testBuildTools :: [P.Dependency] } deriving (Show, Eq) -- -------------------------------------------------------------------- -- @@ -195,6 +195,7 @@ data WriteOpts = WriteOpts , _optPkgDir :: FilePath , _optPkgType :: PackageType , _optPkgName :: P.PackageName + , _optCabalSpec :: CabalSpecVersion } deriving (Eq, Show) data ProjectSettings = ProjectSettings diff --git a/cabal-install/src/Distribution/Client/Init/Utils.hs b/cabal-install/src/Distribution/Client/Init/Utils.hs index 3cb25c82c40..a3ab2efd837 100644 --- a/cabal-install/src/Distribution/Client/Init/Utils.hs +++ b/cabal-install/src/Distribution/Client/Init/Utils.hs @@ -16,6 +16,7 @@ module Distribution.Client.Init.Utils , filePathToPkgName , mkPackageNameDep , fixupDocFiles +, mkStringyDep ) where @@ -81,11 +82,16 @@ isHaskell f = isSuffixOf ".hs" f || isSuffixOf ".lhs" f isBuildTool :: String -> Bool isBuildTool f = not . null . knownSuffixHandlers $ takeExtension f -retrieveBuildTools :: Interactive m => FilePath -> m [String] +retrieveBuildTools :: Interactive m => FilePath -> m [Dependency] retrieveBuildTools fp = do - files <- map takeExtension <$> listFilesRecursive fp + files <- fmap takeExtension <$> listFilesRecursive fp - return [knownSuffixHandlers f | f <- files, isBuildTool f] + let tools = + [ mkStringyDep (knownSuffixHandlers f) + | f <- files, isBuildTool f + ] + + return tools retrieveSourceFiles :: Interactive m => FilePath -> m [SourceFileEntry] retrieveSourceFiles fp = do @@ -140,7 +146,7 @@ retrieveModuleExtensions m = do grabModuleExtensions ('-':'-':xs) = grabModuleExtensions $ dropWhile' (/= '\n') xs grabModuleExtensions ('L':'A':'N':'G':'U':'A':'G':'E':xs) = takeWhile' stop xs : grabModuleExtensions' (dropWhile' stop xs) grabModuleExtensions (_:xs) = grabModuleExtensions xs - + grabModuleExtensions' [] = [] grabModuleExtensions' ('#':xs) = grabModuleExtensions xs grabModuleExtensions' (',':xs) = takeWhile' stop xs : grabModuleExtensions' (dropWhile' stop xs) @@ -256,3 +262,6 @@ fixupDocFiles v pkgDesc , _pkgExtraDocFiles = Nothing } | otherwise = return pkgDesc + +mkStringyDep :: String -> Dependency +mkStringyDep = mkPackageNameDep . PN.mkPackageName diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs index 8db25bdc10a..ed7dba5d383 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs @@ -31,6 +31,7 @@ import Distribution.CabalSpecVersion import System.FilePath import UnitTests.Distribution.Client.Init.Utils +import Distribution.Client.Init.Defaults -- -------------------------------------------------------------------- -- -- golden test suite @@ -78,22 +79,22 @@ goldenPkgDescTests goldenPkgDescTests v srcDb pkgDir pkgName = testGroup "package description golden tests" [ goldenVsString "Empty flags, non-simple, no comments" (goldenPkgDesc "pkg.golden") $ - let opts = WriteOpts False False False v pkgDir Library pkgName + let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion in runPkgDesc opts emptyFlags pkgArgs , goldenVsString "Empty flags, non-simple, with comments" (goldenPkgDesc "pkg-with-comments.golden") $ - let opts = WriteOpts False False False v pkgDir Library pkgName + let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion in runPkgDesc opts emptyFlags pkgArgs , goldenVsString "Dummy flags, with comments" (goldenPkgDesc "pkg-with-flags.golden") $ - let opts = WriteOpts False False False v pkgDir Library pkgName + let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion in runPkgDesc opts dummyFlags pkgArgs , goldenVsString "Dummy flags, old cabal version, with comments" (goldenPkgDesc "pkg-old-cabal-with-flags.golden") $ - let opts = WriteOpts False False False v pkgDir Library pkgName + let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion in runPkgDesc opts (dummyFlags {cabalVersion = Flag CabalSpecV2_0}) pkgArgs ] where @@ -111,27 +112,27 @@ goldenExeTests goldenExeTests v pkgIx pkgDir pkgName = testGroup "exe golden tests" [ goldenVsString "Empty flags, not simple, no options" (goldenExe "exe.golden") $ - let opts = WriteOpts False False True v pkgDir Executable pkgName + let opts = WriteOpts False False True v pkgDir Executable pkgName defaultCabalVersion in runGoldenExe opts exeArgs emptyFlags , goldenVsString "Empty flags, not simple, with comments + no minimal" (goldenExe "exe-with-comments.golden") $ - let opts = WriteOpts False False False v pkgDir Executable pkgName + let opts = WriteOpts False False False v pkgDir Executable pkgName defaultCabalVersion in runGoldenExe opts exeArgs emptyFlags , goldenVsString "Empty flags, not simple, with minimal + no comments" (goldenExe "exe-minimal-no-comments.golden") $ - let opts = WriteOpts False True True v pkgDir Executable pkgName + let opts = WriteOpts False True True v pkgDir Executable pkgName defaultCabalVersion in runGoldenExe opts exeArgs emptyFlags , goldenVsString "Empty flags, not simple, with minimal + comments" (goldenExe "exe-simple-with-comments.golden") $ - let opts = WriteOpts False True False v pkgDir Executable pkgName + let opts = WriteOpts False True False v pkgDir Executable pkgName defaultCabalVersion in runGoldenExe opts exeArgs emptyFlags , goldenVsString "Build tools flag, not simple, with comments + no minimal" (goldenExe "exe-build-tools-with-comments.golden") $ - let opts = WriteOpts False False False v pkgDir Executable pkgName + let opts = WriteOpts False False False v pkgDir Executable pkgName defaultCabalVersion in runGoldenExe opts exeArgs (emptyFlags {buildTools = Flag ["happy"]}) ] where @@ -149,31 +150,31 @@ goldenLibTests goldenLibTests v pkgIx pkgDir pkgName = testGroup "lib golden tests" [ goldenVsString "Empty flags, not simple, no options" (goldenLib "lib.golden") $ - let opts = WriteOpts False False True v pkgDir Library pkgName + let opts = WriteOpts False False True v pkgDir Library pkgName defaultCabalVersion in runGoldenLib opts libArgs emptyFlags , goldenVsString "Empty flags, simple, no options" (goldenLib "lib-simple.golden") $ - let opts = WriteOpts False False True v pkgDir Library pkgName + let opts = WriteOpts False False True v pkgDir Library pkgName defaultCabalVersion in runGoldenLib opts libArgs emptyFlags , goldenVsString "Empty flags, not simple, with comments + no minimal" (goldenLib "lib-with-comments.golden") $ - let opts = WriteOpts False False False v pkgDir Library pkgName + let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion in runGoldenLib opts libArgs emptyFlags , goldenVsString "Empty flags, not simple, with minimal + no comments" (goldenLib "lib-minimal-no-comments.golden") $ - let opts = WriteOpts False True True v pkgDir Library pkgName + let opts = WriteOpts False True True v pkgDir Library pkgName defaultCabalVersion in runGoldenLib opts libArgs emptyFlags , goldenVsString "Empty flags, not simple, with minimal + comments" (goldenLib "lib-simple-with-comments.golden") $ - let opts = WriteOpts False True False v pkgDir Library pkgName + let opts = WriteOpts False True False v pkgDir Library pkgName defaultCabalVersion in runGoldenLib opts libArgs emptyFlags , goldenVsString "Build tools flag, not simple, with comments + no minimal" (goldenLib "lib-build-tools-with-comments.golden") $ - let opts = WriteOpts False False False v pkgDir Library pkgName + let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion in runGoldenLib opts libArgs (emptyFlags {buildTools = Flag ["happy"]}) ] where @@ -191,32 +192,32 @@ goldenTestTests goldenTestTests v pkgIx pkgDir pkgName = testGroup "test golden tests" [ goldenVsString "Empty flags, not simple, no options" (goldenTest "test.golden") $ - let opts = WriteOpts False False True v pkgDir Library pkgName + let opts = WriteOpts False False True v pkgDir Library pkgName defaultCabalVersion in runGoldenTest opts testArgs emptyFlags , goldenVsString "Empty flags, not simple, with comments + no minimal" (goldenTest "test-with-comments.golden") $ - let opts = WriteOpts False False False v pkgDir Library pkgName + let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion in runGoldenTest opts testArgs emptyFlags , goldenVsString "Empty flags, not simple, with minimal + no comments" (goldenTest "test-minimal-no-comments.golden") $ - let opts = WriteOpts False True True v pkgDir Library pkgName + let opts = WriteOpts False True True v pkgDir Library pkgName defaultCabalVersion in runGoldenTest opts testArgs emptyFlags , goldenVsString "Empty flags, not simple, with minimal + comments" (goldenTest "test-simple-with-comments.golden") $ - let opts = WriteOpts False True False v pkgDir Library pkgName + let opts = WriteOpts False True False v pkgDir Library pkgName defaultCabalVersion in runGoldenTest opts testArgs emptyFlags , goldenVsString "Empty flags, not simple, with minimal + comments" (goldenTest "test-simple-with-comments.golden") $ - let opts = WriteOpts False True False v pkgDir Library pkgName + let opts = WriteOpts False True False v pkgDir Library pkgName defaultCabalVersion in runGoldenTest opts testArgs emptyFlags , goldenVsString "Build tools flag, not simple, with comments + no minimal" (goldenTest "test-build-tools-with-comments.golden") $ - let opts = WriteOpts False False False v pkgDir Library pkgName + let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion in runGoldenTest opts testArgs (emptyFlags {buildTools = Flag ["happy"]}) ] where diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs index e0337f343fd..5578317eee9 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs @@ -22,6 +22,7 @@ import Distribution.ModuleName (fromString) import Distribution.Simple.Flag import Data.List (foldl') import qualified Data.Set as Set +import Distribution.Client.Init.Utils (mkStringyDep) tests :: Verbosity @@ -333,7 +334,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _libOtherModules lib @?= map fromString ["Baz.Internal"] _libOtherExts lib @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _libDependencies lib @?! [] - _libBuildTools lib @?= ["happy"] + _libBuildTools lib @?= [mkStringyDep "happy"] _exeMainIs exe @?= HsFilePath "Main.hs" Standard _exeApplicationDirs exe @?= ["app"] @@ -341,7 +342,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _exeOtherModules exe @?= map fromString ["Foo", "Bar"] _exeOtherExts exe @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _exeDependencies exe @?! [] - _exeBuildTools exe @?= ["happy"] + _exeBuildTools exe @?= [mkStringyDep "happy"] _testMainIs test @?= HsFilePath "Main.hs" Standard _testDirs test @?= ["test"] @@ -349,7 +350,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _testOtherModules test @?= map fromString ["Foo", "Bar"] _testOtherExts test @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _testDependencies test @?! [] - _testBuildTools test @?= ["happy"] + _testBuildTools test @?= [mkStringyDep "happy"] Right (ProjectSettings _ _ lib exe test, _) -> do lib @?! Nothing @@ -462,7 +463,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _libOtherModules lib @?= map fromString ["Baz.Internal"] _libOtherExts lib @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _libDependencies lib @?! [] - _libBuildTools lib @?= ["happy"] + _libBuildTools lib @?= [mkStringyDep "happy"] _testMainIs test @?= HsFilePath "Main.hs" Standard _testDirs test @?= ["test"] @@ -470,7 +471,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _testOtherModules test @?= map fromString ["Foo", "Bar"] _testOtherExts test @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _testDependencies test @?! [] - _testBuildTools test @?= ["happy"] + _testBuildTools test @?= [mkStringyDep "happy"] Right (ProjectSettings _ _ lib exe test, _) -> do lib @?! Nothing @@ -591,7 +592,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _libOtherModules lib @?= map fromString ["Baz.Internal"] _libOtherExts lib @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _libDependencies lib @?! [] - _libBuildTools lib @?= ["happy"] + _libBuildTools lib @?= [mkStringyDep "happy"] _exeMainIs exe @?= HsFilePath "Main.hs" Standard _exeApplicationDirs exe @?= ["app"] @@ -599,7 +600,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _exeOtherModules exe @?= map fromString ["Foo", "Bar"] _exeOtherExts exe @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _exeDependencies exe @?! [] - _exeBuildTools exe @?= ["happy"] + _exeBuildTools exe @?= [mkStringyDep "happy"] Right (ProjectSettings _ _ lib exe test, _) -> do lib @?! Nothing @@ -693,7 +694,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _libOtherModules lib @?= map fromString ["Baz.Internal"] _libOtherExts lib @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _libDependencies lib @?! [] - _libBuildTools lib @?= ["happy"] + _libBuildTools lib @?= [mkStringyDep "happy"] Right (ProjectSettings _ _ lib exe test, _) -> do lib @?! Nothing @@ -779,7 +780,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _exeOtherModules exe @?= map fromString ["Foo", "Bar"] _exeOtherExts exe @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _exeDependencies exe @?! [] - _exeBuildTools exe @?= ["happy"] + _exeBuildTools exe @?= [mkStringyDep "happy"] Right (ProjectSettings _ _ lib exe test, _) -> do lib @?= Nothing @@ -1100,7 +1101,7 @@ nonInteractiveTests pkgIx srcDb comp = testGroup "Check top level getter functio [ "[]" ] ] - , testSimple "Check buildToolsHeuristics output" (`buildToolsHeuristics` "") ["happy"] + , testSimple "Check buildToolsHeuristics output" (`buildToolsHeuristics` "") [mkStringyDep "happy"] ["[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]"] , testSimple "Check otherExtsHeuristics output" (`otherExtsHeuristics` "") (map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards]) diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs index bc5ac54a727..5d5a1e6d7f3 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Simple.hs @@ -55,7 +55,7 @@ simpleCreateProjectTests v pkgIx srcDb pkgName = flags = emptyFlags { packageType = Flag Library } settings = ProjectSettings - (WriteOpts False False False v "/home/test/1" Library pkgName) + (WriteOpts False False False v "/home/test/1" Library pkgName defaultCabalVersion) (simplePkgDesc pkgName) (Just simpleLibTarget) Nothing Nothing @@ -67,7 +67,7 @@ simpleCreateProjectTests v pkgIx srcDb pkgName = let inputs = fromList ["1", "simple-test", "y", "1"] flags = emptyFlags { packageType = Flag Library } settings = ProjectSettings - (WriteOpts False False False v "/home/test/1" Library pkgName) + (WriteOpts False False False v "/home/test/1" Library pkgName defaultCabalVersion) (simplePkgDesc pkgName) (Just simpleLibTarget) Nothing (Just $ simpleTestTarget (Just pkgName)) @@ -79,7 +79,7 @@ simpleCreateProjectTests v pkgIx srcDb pkgName = let inputs = fromList ["2", "simple-test"] flags = emptyFlags { packageType = Flag Executable } settings = ProjectSettings - (WriteOpts False False False v "/home/test/2" Executable pkgName) + (WriteOpts False False False v "/home/test/2" Executable pkgName defaultCabalVersion) (simplePkgDesc pkgName) Nothing (Just $ simpleExeTarget Nothing) Nothing @@ -91,7 +91,7 @@ simpleCreateProjectTests v pkgIx srcDb pkgName = let inputs = fromList ["2", "simple-test", "n"] flags = emptyFlags { packageType = Flag LibraryAndExecutable } settings = ProjectSettings - (WriteOpts False False False v "/home/test/2" LibraryAndExecutable pkgName) + (WriteOpts False False False v "/home/test/2" LibraryAndExecutable pkgName defaultCabalVersion) (simplePkgDesc pkgName) (Just simpleLibTarget) (Just $ simpleExeTarget (Just pkgName)) Nothing @@ -102,7 +102,7 @@ simpleCreateProjectTests v pkgIx srcDb pkgName = let inputs = fromList ["2", "simple-test", "y", "1"] flags = emptyFlags { packageType = Flag LibraryAndExecutable } settings = ProjectSettings - (WriteOpts False False False v "/home/test/2" LibraryAndExecutable pkgName) + (WriteOpts False False False v "/home/test/2" LibraryAndExecutable pkgName defaultCabalVersion) (simplePkgDesc pkgName) (Just simpleLibTarget) (Just $ simpleExeTarget (Just pkgName)) (Just $ simpleTestTarget (Just pkgName)) diff --git a/cabal-install/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden b/cabal-install/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden index cbf34dde765..a256fb30604 100644 --- a/cabal-install/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden +++ b/cabal-install/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden @@ -1,6 +1,6 @@ executable y -- .hs or .lhs file containing the Main module. - main-is: Main.hs + main-is: Main.hs -- Modules included in this executable, other than Main. -- other-modules: @@ -9,13 +9,13 @@ executable y -- other-extensions: -- Other library packages from which modules are imported. - build-depends: base + build-depends: base -- Directories containing source files. - hs-source-dirs: exe + hs-source-dirs: exe -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. - build-tools: happy + build-tool-depends: happy -- Base language which the package is written in. - default-language: Haskell2010 + default-language: Haskell2010 diff --git a/cabal-install/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden b/cabal-install/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden index 436ed85d096..a828e09ebc2 100644 --- a/cabal-install/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden +++ b/cabal-install/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden @@ -1,6 +1,6 @@ library -- Modules exported by the library. - exposed-modules: MyLib + exposed-modules: MyLib -- Modules included in this library but not exported. -- other-modules: @@ -9,13 +9,13 @@ library -- other-extensions: -- Other library packages from which modules are imported. - build-depends: base + build-depends: base -- Directories containing source files. - hs-source-dirs: src + hs-source-dirs: src -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. - build-tools: happy + build-tool-depends: happy -- Base language which the package is written in. - default-language: Haskell98 + default-language: Haskell98 diff --git a/cabal-install/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden b/cabal-install/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden index 5171d02708a..f3cbb8ade97 100644 --- a/cabal-install/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden +++ b/cabal-install/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden @@ -1,6 +1,6 @@ test-suite y-test -- Base language which the package is written in. - default-language: Haskell2010 + default-language: Haskell2010 -- Modules included in this executable, other than Main. -- other-modules: @@ -9,16 +9,16 @@ test-suite y-test -- other-extensions: -- The interface type and version of the test suite. - type: exitcode-stdio-1.0 + type: exitcode-stdio-1.0 -- Directories containing source files. - hs-source-dirs: test + hs-source-dirs: test -- The entrypoint to the test suite. - main-is: Main.hs + main-is: Main.hs -- Test dependencies. - build-depends: base + build-depends: base -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. - build-tools: happy + build-tool-depends: happy From 035a6bc9910727d96bcc188a91abe4c1f3a000f9 Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Fri, 7 May 2021 12:42:30 -0400 Subject: [PATCH 18/37] fix build-tool-depends inferrance --- .../Client/Init/NonInteractive/Command.hs | 40 ++++++++++------- .../src/Distribution/Client/Init/Utils.hs | 43 ++++++++++++------- .../Client/Init/NonInteractive.hs | 27 ++++++------ 3 files changed, 65 insertions(+), 45 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs index c000e54f4e7..90522f791e5 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs @@ -113,24 +113,24 @@ createProject comp v pkgIx srcDb initFlags = do case pkgType of Library -> do - libTarget <- genLibTarget initFlags comp pkgIx - testTarget <- genTestTarget initFlags comp pkgIx + libTarget <- genLibTarget initFlags comp pkgIx cabalSpec + testTarget <- genTestTarget initFlags comp pkgIx cabalSpec return $ ProjectSettings (mkOpts comments cabalSpec) pkgDesc (Just libTarget) Nothing testTarget Executable -> do - exeTarget <- genExeTarget initFlags comp pkgIx + exeTarget <- genExeTarget initFlags comp pkgIx cabalSpec return $ ProjectSettings (mkOpts comments cabalSpec) pkgDesc Nothing (Just exeTarget) Nothing LibraryAndExecutable -> do - libTarget <- genLibTarget initFlags comp pkgIx - exeTarget <- genExeTarget initFlags comp pkgIx - testTarget <- genTestTarget initFlags comp pkgIx + libTarget <- genLibTarget initFlags comp pkgIx cabalSpec + exeTarget <- genExeTarget initFlags comp pkgIx cabalSpec + testTarget <- genTestTarget initFlags comp pkgIx cabalSpec return $ ProjectSettings (mkOpts comments cabalSpec) pkgDesc (Just libTarget) @@ -159,8 +159,9 @@ genLibTarget => InitFlags -> Compiler -> InstalledPackageIndex + -> CabalSpecVersion -> m LibTarget -genLibTarget flags comp pkgs = do +genLibTarget flags comp pkgs v = do srcDirs <- srcDirsHeuristics flags let srcDir = fromMaybe defaultSourceDir $ safeHead srcDirs LibTarget srcDirs @@ -169,16 +170,17 @@ genLibTarget flags comp pkgs = do <*> libOtherModulesHeuristics flags <*> otherExtsHeuristics flags srcDir <*> dependenciesHeuristics flags srcDir pkgs - <*> buildToolsHeuristics flags srcDir + <*> buildToolsHeuristics flags srcDir v genExeTarget :: Interactive m => InitFlags -> Compiler -> InstalledPackageIndex + -> CabalSpecVersion -> m ExeTarget -genExeTarget flags comp pkgs = do - appDirs <- appDirsHeuristics flags +genExeTarget flags comp pkgs v = do + appDirs <- appDirsHeuristics flags let appDir = fromMaybe defaultApplicationDir $ safeHead appDirs ExeTarget <$> mainFileHeuristics flags @@ -187,15 +189,16 @@ genExeTarget flags comp pkgs = do <*> exeOtherModulesHeuristics flags <*> otherExtsHeuristics flags appDir <*> dependenciesHeuristics flags appDir pkgs - <*> buildToolsHeuristics flags appDir + <*> buildToolsHeuristics flags appDir v genTestTarget :: Interactive m => InitFlags -> Compiler -> InstalledPackageIndex + -> CabalSpecVersion -> m (Maybe TestTarget) -genTestTarget flags comp pkgs = do +genTestTarget flags comp pkgs v = do initialized <- initializeTestSuiteHeuristics flags testDirs' <- testDirsHeuristics flags let testDir = fromMaybe defaultTestDir $ safeHead testDirs' @@ -208,7 +211,7 @@ genTestTarget flags comp pkgs = do <*> testOtherModulesHeuristics flags <*> otherExtsHeuristics flags testDir <*> dependenciesHeuristics flags testDir pkgs - <*> buildToolsHeuristics flags testDir + <*> buildToolsHeuristics flags testDir v -- -------------------------------------------------------------------- -- -- Get flags from init config @@ -413,10 +416,15 @@ testOtherModulesHeuristics flags = case otherModules flags of else return [] -- | Retrieve the list of build tools -buildToolsHeuristics :: Interactive m => InitFlags -> FilePath -> m [Dependency] -buildToolsHeuristics flags fp = case buildTools flags of +buildToolsHeuristics + :: Interactive m + => InitFlags + -> FilePath + -> CabalSpecVersion + -> m [Dependency] +buildToolsHeuristics flags fp v = case buildTools flags of Flag{} -> getBuildTools flags - NoFlag -> retrieveBuildTools fp + NoFlag -> retrieveBuildTools v fp -- | Retrieve the list of dependencies dependenciesHeuristics :: Interactive m => InitFlags -> FilePath -> InstalledPackageIndex -> m [Dependency] diff --git a/cabal-install/src/Distribution/Client/Init/Utils.hs b/cabal-install/src/Distribution/Client/Init/Utils.hs index a3ab2efd837..f0504d73893 100644 --- a/cabal-install/src/Distribution/Client/Init/Utils.hs +++ b/cabal-install/src/Distribution/Client/Init/Utils.hs @@ -59,15 +59,26 @@ data SourceFileEntry = SourceFileEntry } deriving Show -- Unfortunately we cannot use the version exported by Distribution.Simple.Program -knownSuffixHandlers :: String -> String -knownSuffixHandlers ".gc" = "greencard" -knownSuffixHandlers ".chs" = "chs" -knownSuffixHandlers ".hsc" = "hsc2hs" -knownSuffixHandlers ".x" = "alex" -knownSuffixHandlers ".y" = "happy" -knownSuffixHandlers ".ly" = "happy" -knownSuffixHandlers ".cpphs" = "cpp" -knownSuffixHandlers _ = "" +knownSuffixHandlers :: CabalSpecVersion -> String -> String +knownSuffixHandlers v s + | v < CabalSpecV3_0 = case s of + ".gc" -> "greencard" + ".chs" -> "chs" + ".hsc" -> "hsc2hs" + ".x" -> "alex" + ".y" -> "happy" + ".ly" -> "happy" + ".cpphs" -> "cpp" + _ -> "" + | otherwise = case s of + ".gc" -> "greencard:greencard" + ".chs" -> "chs:chs" + ".hsc" -> "hsc2hs:hsc2hs" + ".x" -> "alex:alex" + ".y" -> "happy:happy" + ".ly" -> "happy:happy" + ".cpphs" -> "cpp:cpp" + _ -> "" -- | Check if a given file has main file characteristics @@ -79,16 +90,16 @@ isMain f = (isInfixOf "Main" f || isInfixOf "main" f) isHaskell :: String -> Bool isHaskell f = isSuffixOf ".hs" f || isSuffixOf ".lhs" f -isBuildTool :: String -> Bool -isBuildTool f = not . null . knownSuffixHandlers $ takeExtension f +isBuildTool :: CabalSpecVersion -> String -> Bool +isBuildTool v = not . null . knownSuffixHandlers v . takeExtension -retrieveBuildTools :: Interactive m => FilePath -> m [Dependency] -retrieveBuildTools fp = do +retrieveBuildTools :: Interactive m => CabalSpecVersion -> FilePath -> m [Dependency] +retrieveBuildTools v fp = do files <- fmap takeExtension <$> listFilesRecursive fp let tools = - [ mkStringyDep (knownSuffixHandlers f) - | f <- files, isBuildTool f + [ mkStringyDep (knownSuffixHandlers v f) + | f <- files, isBuildTool v f ] return tools @@ -264,4 +275,4 @@ fixupDocFiles v pkgDesc | otherwise = return pkgDesc mkStringyDep :: String -> Dependency -mkStringyDep = mkPackageNameDep . PN.mkPackageName +mkStringyDep = mkPackageNameDep . mkPackageName diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs index 5578317eee9..138e74daf0a 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs @@ -334,7 +334,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _libOtherModules lib @?= map fromString ["Baz.Internal"] _libOtherExts lib @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _libDependencies lib @?! [] - _libBuildTools lib @?= [mkStringyDep "happy"] + _libBuildTools lib @?= [mkStringyDep "happy:happy"] _exeMainIs exe @?= HsFilePath "Main.hs" Standard _exeApplicationDirs exe @?= ["app"] @@ -342,7 +342,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _exeOtherModules exe @?= map fromString ["Foo", "Bar"] _exeOtherExts exe @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _exeDependencies exe @?! [] - _exeBuildTools exe @?= [mkStringyDep "happy"] + _exeBuildTools exe @?= [mkStringyDep "happy:happy"] _testMainIs test @?= HsFilePath "Main.hs" Standard _testDirs test @?= ["test"] @@ -350,7 +350,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _testOtherModules test @?= map fromString ["Foo", "Bar"] _testOtherExts test @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _testDependencies test @?! [] - _testBuildTools test @?= [mkStringyDep "happy"] + _testBuildTools test @?= [mkStringyDep "happy:happy"] Right (ProjectSettings _ _ lib exe test, _) -> do lib @?! Nothing @@ -463,7 +463,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _libOtherModules lib @?= map fromString ["Baz.Internal"] _libOtherExts lib @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _libDependencies lib @?! [] - _libBuildTools lib @?= [mkStringyDep "happy"] + _libBuildTools lib @?= [mkStringyDep "happy:happy"] _testMainIs test @?= HsFilePath "Main.hs" Standard _testDirs test @?= ["test"] @@ -471,7 +471,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _testOtherModules test @?= map fromString ["Foo", "Bar"] _testOtherExts test @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _testDependencies test @?! [] - _testBuildTools test @?= [mkStringyDep "happy"] + _testBuildTools test @?= [mkStringyDep "happy:happy"] Right (ProjectSettings _ _ lib exe test, _) -> do lib @?! Nothing @@ -592,7 +592,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _libOtherModules lib @?= map fromString ["Baz.Internal"] _libOtherExts lib @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _libDependencies lib @?! [] - _libBuildTools lib @?= [mkStringyDep "happy"] + _libBuildTools lib @?= [mkStringyDep "happy:happy"] _exeMainIs exe @?= HsFilePath "Main.hs" Standard _exeApplicationDirs exe @?= ["app"] @@ -600,7 +600,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _exeOtherModules exe @?= map fromString ["Foo", "Bar"] _exeOtherExts exe @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _exeDependencies exe @?! [] - _exeBuildTools exe @?= [mkStringyDep "happy"] + _exeBuildTools exe @?= [mkStringyDep "happy:happy"] Right (ProjectSettings _ _ lib exe test, _) -> do lib @?! Nothing @@ -694,7 +694,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _libOtherModules lib @?= map fromString ["Baz.Internal"] _libOtherExts lib @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _libDependencies lib @?! [] - _libBuildTools lib @?= [mkStringyDep "happy"] + _libBuildTools lib @?= [mkStringyDep "happy:happy"] Right (ProjectSettings _ _ lib exe test, _) -> do lib @?! Nothing @@ -780,7 +780,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" _exeOtherModules exe @?= map fromString ["Foo", "Bar"] _exeOtherExts exe @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards] _exeDependencies exe @?! [] - _exeBuildTools exe @?= [mkStringyDep "happy"] + _exeBuildTools exe @?= [mkStringyDep "happy:happy"] Right (ProjectSettings _ _ lib exe test, _) -> do lib @?= Nothing @@ -857,7 +857,7 @@ fileCreatorTests pkgIx srcDb comp = testGroup "generators" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] - case (_runPrompt $ genLibTarget emptyFlags comp pkgIx) inputs of + case (_runPrompt $ genLibTarget emptyFlags comp pkgIx defaultCabalVersion) inputs of Left e -> assertFailure $ show e Right{} -> return () ] @@ -891,7 +891,7 @@ fileCreatorTests pkgIx srcDb comp = testGroup "generators" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] - case (_runPrompt $ genExeTarget emptyFlags comp pkgIx) inputs of + case (_runPrompt $ genExeTarget emptyFlags comp pkgIx defaultCabalVersion) inputs of Left e -> assertFailure $ show e Right{} -> return () ] @@ -919,8 +919,9 @@ fileCreatorTests pkgIx srcDb comp = testGroup "generators" -- build tools , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/bar.y\"]" ] + flags = emptyFlags {initializeTestSuite = Flag True} - case (_runPrompt $ genTestTarget (emptyFlags {initializeTestSuite = Flag True}) comp pkgIx) inputs of + case (_runPrompt $ genTestTarget flags comp pkgIx defaultCabalVersion) inputs of Left e -> assertFailure $ show e Right{} -> return () ] @@ -1101,7 +1102,7 @@ nonInteractiveTests pkgIx srcDb comp = testGroup "Check top level getter functio [ "[]" ] ] - , testSimple "Check buildToolsHeuristics output" (`buildToolsHeuristics` "") [mkStringyDep "happy"] + , testSimple "Check buildToolsHeuristics output" (\a -> buildToolsHeuristics a "" defaultCabalVersion) [mkStringyDep "happy:happy"] ["[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]"] , testSimple "Check otherExtsHeuristics output" (`otherExtsHeuristics` "") (map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards]) From 79f69b9714e86999c037364b715defd13329cf87 Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Fri, 7 May 2021 12:52:32 -0400 Subject: [PATCH 19/37] fix build-tool-depends inferrance --- .../tests/UnitTests/Distribution/Client/Init/Golden.hs | 2 +- .../init/golden/cabal/cabal-lib-and-exe-no-comments.golden | 2 +- .../init/golden/cabal/cabal-lib-and-exe-with-comments.golden | 2 +- .../fixtures/init/golden/cabal/cabal-lib-no-comments.golden | 2 +- .../fixtures/init/golden/cabal/cabal-lib-with-comments.golden | 2 +- .../fixtures/init/golden/pkg-desc/pkg-with-comments.golden | 2 +- cabal-install/tests/fixtures/init/golden/pkg-desc/pkg.golden | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs index ed7dba5d383..7bc32428998 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs @@ -312,7 +312,7 @@ testArgs = fromList ["y", "1", "test", "1"] pkgArgs :: NonEmpty String pkgArgs = fromList - [ "4" + [ "5" , "foo-package" , "y" , "0.1.0.0" diff --git a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden index 72b5c6a3dba..97d868a683d 100644 --- a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden +++ b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden @@ -1,4 +1,4 @@ -cabal-version: 2.4 +cabal-version: 3.0 name: y version: 0.1.0.0 synopsis: synopsis diff --git a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden index 0addbe1ccae..799d0fa9573 100644 --- a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden +++ b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden @@ -1,4 +1,4 @@ -cabal-version: 2.4 +cabal-version: 3.0 -- Initial package description 'y' generated by -- 'cabal init'. For further documentation, see: diff --git a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden index d67fd8cfb38..c903411c9ca 100644 --- a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden +++ b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden @@ -1,4 +1,4 @@ -cabal-version: 2.4 +cabal-version: 3.0 name: y version: 0.1.0.0 synopsis: synopsis diff --git a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden index e3b335e0cbd..f6cc2ada1bd 100644 --- a/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden +++ b/cabal-install/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden @@ -1,4 +1,4 @@ -cabal-version: 2.4 +cabal-version: 3.0 -- Initial package description 'y' generated by -- 'cabal init'. For further documentation, see: diff --git a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden index 56c3d296429..45630780ea4 100644 --- a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden +++ b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden @@ -1,4 +1,4 @@ -cabal-version: 2.4 +cabal-version: 3.0 -- Initial package description 'y' generated by -- 'cabal init'. For further documentation, see: diff --git a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg.golden b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg.golden index 56c3d296429..45630780ea4 100644 --- a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg.golden +++ b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg.golden @@ -1,4 +1,4 @@ -cabal-version: 2.4 +cabal-version: 3.0 -- Initial package description 'y' generated by -- 'cabal init'. For further documentation, see: From 9042b79c1cea15207941c299e4aa8301b7c855b1 Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Fri, 7 May 2021 14:07:22 -0400 Subject: [PATCH 20/37] TODO for patrick --- .../src/Distribution/Client/Init/FileCreators.hs | 3 ++- .../src/Distribution/Client/Init/Utils.hs | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/FileCreators.hs b/cabal-install/src/Distribution/Client/Init/FileCreators.hs index 29bad1e0b1c..310af500976 100644 --- a/cabal-install/src/Distribution/Client/Init/FileCreators.hs +++ b/cabal-install/src/Distribution/Client/Init/FileCreators.hs @@ -40,6 +40,7 @@ import System.Directory hiding (doesDirectoryExist, doesFileExist, createDirecto import System.FilePath ((), (<.>)) import Distribution.Client.Init.Format +import Distribution.CabalSpecVersion (showCabalSpecVersion) -- -------------------------------------------------------------------- -- @@ -54,7 +55,7 @@ writeProject (ProjectSettings opts pkgDesc libTarget exeTarget testTarget) -- clear prompt history a bit" message opts $ "\nUsing cabal specification: " - ++ show (_optCabalSpec opts) + ++ showCabalSpecVersion (_optCabalSpec opts) writeLicense opts pkgDesc writeChangeLog opts pkgDesc diff --git a/cabal-install/src/Distribution/Client/Init/Utils.hs b/cabal-install/src/Distribution/Client/Init/Utils.hs index f0504d73893..0f9618d9021 100644 --- a/cabal-install/src/Distribution/Client/Init/Utils.hs +++ b/cabal-install/src/Distribution/Client/Init/Utils.hs @@ -21,7 +21,7 @@ module Distribution.Client.Init.Utils import qualified Prelude -import Distribution.Client.Compat.Prelude hiding (empty, readFile, Parsec, many) +import Distribution.Client.Compat.Prelude hiding (putStrLn, empty, readFile, Parsec, many) import Distribution.Utils.Generic (isInfixOf) import Control.Monad (forM) @@ -118,11 +118,21 @@ retrieveSourceFiles fp = do return $ SourceFileEntry {..} -- | Given a module, retrieve its name -retrieveModuleName :: Interactive m => FilePath -> m ModuleName +retrieveModuleName :: Interactive m => FilePath -> m (Maybe ModuleName) retrieveModuleName m = do - fromString . trim . grabModuleName <$> readFile m + rawModule <- trim . grabModuleName <$> readFile m + + if rawModule == dirToModuleName m + then return $ Just $ fromString rawModule + else do + putStrLn + $ "Warning: found module that doesn't match directory structure: " + ++ rawModule + return Nothing where + dirToModuleName = error "TODO" + stop c = (c /= '\n') && (c /= ' ') grabModuleName [] = [] From 0e9de06e7dcaaa802eb60c5d6551cd187294af9b Mon Sep 17 00:00:00 2001 From: Patrick Augusto Date: Sat, 8 May 2021 00:48:28 -0300 Subject: [PATCH 21/37] Adding checks for module name correctness and file existence --- .../Client/Init/NonInteractive/Command.hs | 8 +-- .../src/Distribution/Client/Init/Utils.hs | 59 ++++++++++++------- 2 files changed, 42 insertions(+), 25 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs index 90522f791e5..664cbe566c2 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs @@ -339,7 +339,7 @@ exposedModulesHeuristics flags = do srcDir <- fromMaybe defaultSourceDir . safeHead <$> srcDirsHeuristics flags modules <- filter isHaskell <$> listFilesRecursive srcDir - modulesNames <- traverse retrieveModuleName modules + modulesNames <- catMaybes <$> traverse retrieveModuleName modules otherModules' <- libOtherModulesHeuristics flags return $ filter (`notElem` otherModules') modulesNames @@ -368,7 +368,7 @@ libOtherModulesHeuristics flags = case otherModules flags of then do otherModules' <- filter isHaskell <$> listFilesRecursive libDir filter ((`elem` otherCandidates) . last . components) - <$> traverse retrieveModuleName otherModules' + . catMaybes <$> traverse retrieveModuleName otherModules' else return [] -- | Retrieve the list of other modules for Executables, it lists everything @@ -390,7 +390,7 @@ exeOtherModulesHeuristics flags = case otherModules flags of then do otherModules' <- filter (\f -> not (isMain f) && isHaskell f) <$> listFilesRecursive exeDir - traverse retrieveModuleName otherModules' + catMaybes <$> traverse retrieveModuleName otherModules' else return [] -- | Retrieve the list of other modules for Tests, it lists everything @@ -412,7 +412,7 @@ testOtherModulesHeuristics flags = case otherModules flags of then do otherModules' <- filter (\f -> not (isMain f) && isHaskell f) <$> listFilesRecursive testDir' - traverse retrieveModuleName otherModules' + catMaybes <$> traverse retrieveModuleName otherModules' else return [] -- | Retrieve the list of build tools diff --git a/cabal-install/src/Distribution/Client/Init/Utils.hs b/cabal-install/src/Distribution/Client/Init/Utils.hs index 0f9618d9021..ea9ed552e66 100644 --- a/cabal-install/src/Distribution/Client/Init/Utils.hs +++ b/cabal-install/src/Distribution/Client/Init/Utils.hs @@ -106,32 +106,49 @@ retrieveBuildTools v fp = do retrieveSourceFiles :: Interactive m => FilePath -> m [SourceFileEntry] retrieveSourceFiles fp = do - files <- filter isHaskell <$> listFilesRecursive fp - - forM files $ \f -> do - let fileExtension = takeExtension f - relativeSourcePath <- makeRelative f <$> getCurrentDirectory - moduleName <- retrieveModuleName f - imports <- retrieveModuleImports f - extensions <- retrieveModuleExtensions f - - return $ SourceFileEntry {..} + exists <- doesDirectoryExist fp + if exists + then do + files <- filter isHaskell <$> listFilesRecursive fp + + entries <- forM files $ \f -> do + exists' <- doesFileExist f + if exists' + then do + maybeModuleName <- retrieveModuleName f + case maybeModuleName of + Nothing -> return Nothing + Just moduleName -> do + + let fileExtension = takeExtension f + relativeSourcePath <- makeRelative f <$> getCurrentDirectory + imports <- retrieveModuleImports f + extensions <- retrieveModuleExtensions f + + return . Just $ SourceFileEntry {..} + else + return Nothing + + return . catMaybes $ entries + + else + return [] -- | Given a module, retrieve its name retrieveModuleName :: Interactive m => FilePath -> m (Maybe ModuleName) retrieveModuleName m = do - rawModule <- trim . grabModuleName <$> readFile m - - if rawModule == dirToModuleName m - then return $ Just $ fromString rawModule - else do - putStrLn - $ "Warning: found module that doesn't match directory structure: " - ++ rawModule - return Nothing - + rawModule <- trim . grabModuleName <$> readFile m + + if isInfixOf rawModule (dirToModuleName m) + then + return $ Just $ fromString rawModule + else do + putStrLn + $ "Warning: found module that doesn't match directory structure: " + ++ rawModule + return Nothing where - dirToModuleName = error "TODO" + dirToModuleName = map (\x -> if x == '/' || x == '\\' then '.' else x) stop c = (c /= '\n') && (c /= ' ') From e2806fa03a1743800314e77982bdf2af08323844 Mon Sep 17 00:00:00 2001 From: Patrick Augusto Date: Sat, 8 May 2021 16:20:31 -0300 Subject: [PATCH 22/37] Adapting tests for the new dependency checks --- .../Client/Init/NonInteractive.hs | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs index 138e74daf0a..a78ad6a0a53 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs @@ -250,7 +250,9 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" -- dependencies + , "True" , "[\"src/Foo.hs\"]" + , "True" , "test-package" , "module Main where" , "import Control.Monad.Extra" @@ -276,7 +278,9 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" -- dependencies + , "True" , "[\"app/Main.hs\"]" + , "True" , "test-package" , "module Main where" , "import Control.Monad.Extra" @@ -297,7 +301,9 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" -- dependencies + , "True" , "[\"test/Main.hs\"]" + , "True" , "test-package" , "module Main where" , "import Test.Tasty\nimport Test.Tasty.HUnit" @@ -405,7 +411,9 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" -- dependencies + , "True" , "[\"src/Foo.hs\"]" + , "True" , "test-package" , "module Main where" , "import Control.Monad.Extra" @@ -426,7 +434,9 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" -- dependencies + , "True" , "[\"test/Main.hs\"]" + , "True" , "test-package" , "module Main where" , "import Test.Tasty\nimport Test.Tasty.HUnit" @@ -529,7 +539,9 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" -- dependencies + , "True" , "[\"src/Foo.hs\"]" + , "True" , "test-package" , "module Main where" , "import Control.Monad.Extra" @@ -555,7 +567,9 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" -- dependencies + , "True" , "[\"app/Main.hs\"]" + , "True" , "test-package" , "module Main where" , "import Control.Monad.Extra" @@ -657,7 +671,9 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" -- dependencies + , "True" , "[\"src/Foo.hs\"]" + , "True" , "test-package" , "module Main where" , "import Control.Monad.Extra" @@ -743,7 +759,9 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" -- dependencies + , "True" , "[\"app/Main.hs\"]" + , "True" , "test-package" , "module Main where" , "import Control.Monad.Extra" @@ -848,7 +866,9 @@ fileCreatorTests pkgIx srcDb comp = testGroup "generators" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" -- dependencies + , "True" , "[\"src/Foo.hs\"]" + , "True" , "test-package" , "module Main where" , "import Control.Monad.Extra" @@ -882,7 +902,9 @@ fileCreatorTests pkgIx srcDb comp = testGroup "generators" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" -- dependencies + , "True" , "[\"app/Main.hs\"]" + , "True" , "test-package" , "module Main where" , "import Control.Monad.Extra" @@ -911,7 +933,9 @@ fileCreatorTests pkgIx srcDb comp = testGroup "generators" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" -- dependencies + , "True" , "[\"test/Main.hs\"]" + , "True" , "test-package" , "module Main where" , "import Test.Tasty\nimport Test.Tasty.HUnit" @@ -1099,7 +1123,8 @@ nonInteractiveTests pkgIx srcDb comp = testGroup "Check top level getter functio if unPackageName n == "base" then v else a) . (\x -> dependenciesHeuristics x "" pkgIx)) (baseVersion comp) - [ "[]" + [ "True" + , "[]" ] ] , testSimple "Check buildToolsHeuristics output" (\a -> buildToolsHeuristics a "" defaultCabalVersion) [mkStringyDep "happy:happy"] From fcce141e25ef134c98a5eb9cf2514d1c305a4fe6 Mon Sep 17 00:00:00 2001 From: Patrick Augusto Date: Tue, 11 May 2021 18:44:16 -0300 Subject: [PATCH 23/37] Adding more checks for the existence of paths --- .../Client/Init/NonInteractive/Command.hs | 26 ++++++++++++++----- .../Client/Init/NonInteractive/Heuristics.hs | 13 +++++++--- .../src/Distribution/Client/Init/Utils.hs | 18 ++++++++----- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs index 664cbe566c2..a733ce3fdb2 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs @@ -338,11 +338,18 @@ exposedModulesHeuristics flags = do NoFlag -> do srcDir <- fromMaybe defaultSourceDir . safeHead <$> srcDirsHeuristics flags - modules <- filter isHaskell <$> listFilesRecursive srcDir - modulesNames <- catMaybes <$> traverse retrieveModuleName modules + exists <- doesDirectoryExist srcDir - otherModules' <- libOtherModulesHeuristics flags - return $ filter (`notElem` otherModules') modulesNames + if exists + then do + modules <- filter isHaskell <$> listFilesRecursive srcDir + modulesNames <- catMaybes <$> traverse retrieveModuleName modules + + otherModules' <- libOtherModulesHeuristics flags + return $ filter (`notElem` otherModules') modulesNames + + else + return [] return $ if null mods then myLibModule NEL.:| [] @@ -447,7 +454,12 @@ otherExtsHeuristics :: Interactive m => InitFlags -> FilePath -> m [Extension] otherExtsHeuristics flags fp = case otherExts flags of Flag x -> return x NoFlag -> do - sources <- listFilesRecursive fp - extensions' <- traverse retrieveModuleExtensions . filter isHaskell $ sources + exists <- doesDirectoryExist fp + if exists + then do + sources <- listFilesRecursive fp + extensions' <- traverse retrieveModuleExtensions . filter isHaskell $ sources - return $ nub . join $ extensions' + return $ nub . join $ extensions' + else + return [] diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs index 977bbb1dcce..c51082d2892 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs @@ -49,10 +49,15 @@ import qualified Data.Set as Set -- | Guess the main file, returns a default value if none is found. guessMainFile :: Interactive m => FilePath -> m HsFilePath guessMainFile pkgDir = do - files <- filter isMain <$> listFilesRecursive pkgDir - return $ if null files - then defaultMainIs - else toHsFilePath $ L.head files + exists <- doesDirectoryExist pkgDir + if exists + then do + files <- filter isMain <$> listFilesRecursive pkgDir + return $ if null files + then defaultMainIs + else toHsFilePath $ L.head files + else + return defaultMainIs -- | Juggling characters around to guess the desired cabal version based on -- the system's cabal version. diff --git a/cabal-install/src/Distribution/Client/Init/Utils.hs b/cabal-install/src/Distribution/Client/Init/Utils.hs index ea9ed552e66..25a1fbdad32 100644 --- a/cabal-install/src/Distribution/Client/Init/Utils.hs +++ b/cabal-install/src/Distribution/Client/Init/Utils.hs @@ -95,14 +95,20 @@ isBuildTool v = not . null . knownSuffixHandlers v . takeExtension retrieveBuildTools :: Interactive m => CabalSpecVersion -> FilePath -> m [Dependency] retrieveBuildTools v fp = do - files <- fmap takeExtension <$> listFilesRecursive fp + exists <- doesDirectoryExist fp + if exists + then do + files <- fmap takeExtension <$> listFilesRecursive fp - let tools = - [ mkStringyDep (knownSuffixHandlers v f) - | f <- files, isBuildTool v f - ] + let tools = + [ mkStringyDep (knownSuffixHandlers v f) + | f <- files, isBuildTool v f + ] - return tools + return tools + + else + return [] retrieveSourceFiles :: Interactive m => FilePath -> m [SourceFileEntry] retrieveSourceFiles fp = do From a63fe9b9540dc88d3910623ad60dfa8b9c09fddb Mon Sep 17 00:00:00 2001 From: Patrick Augusto Date: Tue, 11 May 2021 23:13:47 -0300 Subject: [PATCH 24/37] Adjusting tests for the remaining checks --- .../Client/Init/NonInteractive.hs | 57 +++++++++++++++++-- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs index a78ad6a0a53..2a28967c968 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs @@ -66,7 +66,8 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , dependencies = Flag [] } inputs = NEL.fromList - [ "[\"quxTest/Main.hs\"]" + [ "True" + , "[\"quxTest/Main.hs\"]" ] case (_runPrompt $ createProject comp silent pkgIx srcDb dummyFlags') inputs of @@ -143,6 +144,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" -- exe other modules , "False" -- test main file + , "True" , "[\"quxTest/Main.hs\"]" -- test other modules , "False" @@ -230,6 +232,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" -- exposed modules , "src" , "True" + , "True" , "[\"src/Foo.hs\", \"src/Bar.hs\"]" , "module Foo where" , "module Bar where" @@ -246,6 +249,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "module Bar where" , "module Baz.Internal where" -- other extensions + , "True" , "[\"src/Foo.hs\", \"src/Bar.hs\"]" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" @@ -258,6 +262,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "import Control.Monad.Extra" , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" -- build tools + , "True" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" -- executable target -- application dirs @@ -266,6 +271,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" -- main file , "test-package" , "[\"test-package/app/\"]" + , "True" , "[]" -- other modules , "test-package" @@ -274,6 +280,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "module Foo where" , "module Bar where" -- other extensions + , "True" , "[\"app/Foo.hs\", \"app/Bar.hs\"]" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" @@ -286,9 +293,11 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "import Control.Monad.Extra" , "{-# LANGUAGE OverloadedStrings, DataKinds #-}" -- build tools + , "True" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" -- test target -- main file + , "True" , "[\"test-package/test/\"]" -- other modules , "test-package" @@ -297,6 +306,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "module Foo where" , "module Bar where" -- other extensions + , "True" , "[\"test/Foo.hs\", \"test/Bar.hs\"]" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" @@ -309,6 +319,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "import Test.Tasty\nimport Test.Tasty.HUnit" , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" -- build tools + , "True" , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/bar.y\"]" ] @@ -391,6 +402,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" -- exposed modules , "src" , "True" + , "True" , "[\"src/Foo.hs\", \"src/Bar.hs\"]" , "module Foo where" , "module Bar where" @@ -407,6 +419,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "module Bar where" , "module Baz.Internal where" -- other extensions + , "True" , "[\"src/Foo.hs\", \"src/Bar.hs\"]" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" @@ -419,9 +432,11 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "import Control.Monad.Extra" , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" -- build tools + , "True" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" -- test target -- main file + , "True" , "[\"test-package/test/\"]" -- other modules , "test-package" @@ -430,6 +445,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "module Foo where" , "module Bar where" -- other extensions + , "True" , "[\"test/Foo.hs\", \"test/Bar.hs\"]" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" @@ -442,6 +458,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "import Test.Tasty\nimport Test.Tasty.HUnit" , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" -- build tools + , "True" , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/bar.y\"]" ] @@ -519,6 +536,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" -- exposed modules , "src" , "True" + , "True" , "[\"src/Foo.hs\", \"src/Bar.hs\"]" , "module Foo where" , "module Bar where" @@ -535,6 +553,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "module Bar where" , "module Baz.Internal where" -- other extensions + , "True" , "[\"src/Foo.hs\", \"src/Bar.hs\"]" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" @@ -547,6 +566,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "import Control.Monad.Extra" , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" -- build tools + , "True" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" -- executable target -- application dirs @@ -555,6 +575,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" -- main file , "test-package" , "[\"test-package/app/\"]" + , "True" , "[]" -- other modules , "test-package" @@ -563,6 +584,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "module Foo where" , "module Bar where" -- other extensions + , "True" , "[\"app/Foo.hs\", \"app/Bar.hs\"]" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" @@ -575,6 +597,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "import Control.Monad.Extra" , "{-# LANGUAGE OverloadedStrings, DataKinds #-}" -- build tools + , "True" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] @@ -651,6 +674,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" -- exposed modules , "src" , "True" + , "True" , "[\"src/Foo.hs\", \"src/Bar.hs\"]" , "module Foo where" , "module Bar where" @@ -667,6 +691,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "module Bar where" , "module Baz.Internal where" -- other extensions + , "True" , "[\"src/Foo.hs\", \"src/Bar.hs\"]" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" @@ -679,6 +704,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "import Control.Monad.Extra" , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" -- build tools + , "True" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] @@ -747,6 +773,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" -- main file , "test-package" , "[\"test-package/app/\"]" + , "True" , "[]" -- other modules , "test-package" @@ -755,6 +782,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "module Foo where" , "module Bar where" -- other extensions + , "True" , "[\"app/Foo.hs\", \"app/Bar.hs\"]" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" @@ -767,6 +795,7 @@ driverFunctionTest pkgIx srcDb comp = testGroup "createProject" , "import Control.Monad.Extra" , "{-# LANGUAGE OverloadedStrings, DataKinds #-}" -- build tools + , "True" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] @@ -846,6 +875,7 @@ fileCreatorTests pkgIx srcDb comp = testGroup "generators" -- exposed modules , "src" , "True" + , "True" , "[\"src/Foo.hs\", \"src/Bar.hs\"]" , "module Foo where" , "module Bar where" @@ -862,6 +892,7 @@ fileCreatorTests pkgIx srcDb comp = testGroup "generators" , "module Bar where" , "module Baz.Internal where" -- other extensions + , "True" , "[\"src/Foo.hs\", \"src/Bar.hs\"]" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" @@ -874,6 +905,7 @@ fileCreatorTests pkgIx srcDb comp = testGroup "generators" , "import Control.Monad.Extra" , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" -- build tools + , "True" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] @@ -890,6 +922,7 @@ fileCreatorTests pkgIx srcDb comp = testGroup "generators" -- main file , "test-package" , "[\"test-package/app/\"]" + , "True" , "[]" -- other modules , "test-package" @@ -898,6 +931,7 @@ fileCreatorTests pkgIx srcDb comp = testGroup "generators" , "module Foo where" , "module Bar where" -- other extensions + , "True" , "[\"app/Foo.hs\", \"app/Bar.hs\"]" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" @@ -910,6 +944,7 @@ fileCreatorTests pkgIx srcDb comp = testGroup "generators" , "import Control.Monad.Extra" , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" -- build tools + , "True" , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" ] @@ -921,7 +956,8 @@ fileCreatorTests pkgIx srcDb comp = testGroup "generators" [ testCase "Check test package flags workflow" $ do let inputs = NEL.fromList -- main file - [ "[]" + [ "True" + , "[]" -- other modules , "test-package" , "True" @@ -929,6 +965,7 @@ fileCreatorTests pkgIx srcDb comp = testGroup "generators" , "module Foo where" , "module Bar where" -- other extensions + , "True" , "[\"test/Foo.hs\", \"test/Bar.hs\"]" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" @@ -941,6 +978,7 @@ fileCreatorTests pkgIx srcDb comp = testGroup "generators" , "import Test.Tasty\nimport Test.Tasty.HUnit" , "{-# LANGUAGE OverloadedStrings, LambdaCase #-}" -- build tools + , "True" , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/bar.y\"]" ] flags = emptyFlags {initializeTestSuite = Flag True} @@ -1034,18 +1072,21 @@ nonInteractiveTests pkgIx srcDb comp = testGroup "Check top level getter functio (toHsFilePath "Main.hs") [ "test-package" , "[\"test-package/app/\"]" + , "True" , "[]" ] , testSimple "Main file already defined" mainFileHeuristics (toHsFilePath "app/Main.hs") [ "test-package" , "[\"test-package/app/\"]" + , "True" , "[\"app/Main.hs\"]" ] , testSimple "Main lhs file already defined" mainFileHeuristics (toHsFilePath "app/Main.lhs") [ "test-package" , "[\"test-package/app/\"]" + , "True" , "[\"app/Main.lhs\"]" ] ] @@ -1054,6 +1095,7 @@ nonInteractiveTests pkgIx srcDb comp = testGroup "Check top level getter functio (myLibModule NEL.:| []) [ "src" , "True" + , "True" , "[]" , "test-package" , "True" @@ -1063,6 +1105,7 @@ nonInteractiveTests pkgIx srcDb comp = testGroup "Check top level getter functio (NEL.fromList $ map fromString ["Foo", "Bar"]) [ "src" , "True" + , "True" , "[\"src/Foo.hs\", \"src/Bar.hs\"]" , "module Foo where" , "module Bar where" @@ -1127,11 +1170,15 @@ nonInteractiveTests pkgIx srcDb comp = testGroup "Check top level getter functio , "[]" ] ] - , testSimple "Check buildToolsHeuristics output" (\a -> buildToolsHeuristics a "" defaultCabalVersion) [mkStringyDep "happy:happy"] - ["[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]"] + , testSimple "Check buildToolsHeuristics output" (\a -> buildToolsHeuristics a "" defaultCabalVersion) + [mkStringyDep "happy:happy"] + [ "True" + , "[\"app/Main.hs\", \"src/Foo.hs\", \"src/bar.y\"]" + ] , testSimple "Check otherExtsHeuristics output" (`otherExtsHeuristics` "") (map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards]) - [ "[\"src/Foo.hs\", \"src/Bar.hs\"]" + [ "True" + , "[\"src/Foo.hs\", \"src/Bar.hs\"]" , "\"{-# LANGUAGE OverloadedStrings, LambdaCase #-}\n{-# LANGUAGE RankNTypes #-}\"" , "\"{-# LANGUAGE RecordWildCards #-}\"" ] From 836d6b6d5728444d18d0262084672f418c580d65 Mon Sep 17 00:00:00 2001 From: Patrick Augusto Date: Wed, 12 May 2021 17:54:49 -0300 Subject: [PATCH 25/37] Pinpointing in which modules the packages couldn't be found --- .../Distribution/Client/Init/Interactive/Command.hs | 2 +- .../Client/Init/NonInteractive/Command.hs | 11 +++++------ cabal-install/src/Distribution/Client/Init/Utils.hs | 12 ++++++------ 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs index 6f24916c0f8..1dc16f35cc3 100644 --- a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs @@ -455,4 +455,4 @@ dependenciesPrompt -> InitFlags -> m [Dependency] dependenciesPrompt pkgIx flags = getDependencies flags $ - retrieveDependencies flags [fromString "Prelude"] pkgIx + retrieveDependencies flags [(fromString "Prelude", fromString "Prelude")] pkgIx diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs index a733ce3fdb2..a9add3f4b52 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs @@ -442,12 +442,11 @@ dependenciesHeuristics flags fp pkgIx = getDependencies flags $ do Flag x -> x NoFlag -> map moduleName sources - retrieveDependencies flags - ( nub -- skips duplicates - ( fromString "Prelude" -- gets base as dependency - : (filter (`notElem` mods) -- skips modules from this own package - . concatMap imports $ sources))) - pkgIx + groupedDeps = concatMap (\s -> map (\i -> (moduleName s, i)) (imports s)) sources + filteredDeps = filter ((`notElem` mods) . snd) groupedDeps + preludeNub = nubBy (\a b -> snd a == snd b) $ (fromString "Prelude", fromString "Prelude") : filteredDeps + + retrieveDependencies flags preludeNub pkgIx -- | Retrieve the list of extensions otherExtsHeuristics :: Interactive m => InitFlags -> FilePath -> m [Extension] diff --git a/cabal-install/src/Distribution/Client/Init/Utils.hs b/cabal-install/src/Distribution/Client/Init/Utils.hs index 25a1fbdad32..6a2dcd65a79 100644 --- a/cabal-install/src/Distribution/Client/Init/Utils.hs +++ b/cabal-install/src/Distribution/Client/Init/Utils.hs @@ -213,15 +213,15 @@ isSourceFile :: Maybe [FilePath] -> SourceFileEntry -> Bool isSourceFile Nothing sf = isSourceFile (Just ["."]) sf isSourceFile (Just srcDirs) sf = any (equalFilePath (relativeSourcePath sf)) srcDirs -retrieveDependencies :: Interactive m => InitFlags -> [ModuleName] -> InstalledPackageIndex -> m [P.Dependency] +retrieveDependencies :: Interactive m => InitFlags -> [(ModuleName, ModuleName)] -> InstalledPackageIndex -> m [P.Dependency] retrieveDependencies flags mods' pkgIx = do let mods = mods' modMap :: M.Map ModuleName [InstalledPackageInfo] modMap = M.map (filter exposed) $ moduleNameIndex pkgIx - modDeps :: [(ModuleName, Maybe [InstalledPackageInfo])] - modDeps = map (\mn -> (mn, M.lookup mn modMap)) mods + modDeps :: [(ModuleName, ModuleName, Maybe [InstalledPackageInfo])] + modDeps = map (\(mn, ds) -> (mn, ds, M.lookup ds modMap)) mods -- modDeps = map (id &&& flip M.lookup modMap) mods message (fromFlagOrDefault silent $ initVerbosity flags) "\nGuessing dependencies..." @@ -233,9 +233,9 @@ retrieveDependencies flags mods' pkgIx = do chooseDep :: Interactive m => InitFlags - -> (ModuleName, Maybe [InstalledPackageInfo]) + -> (ModuleName, ModuleName, Maybe [InstalledPackageInfo]) -> m (Maybe P.Dependency) -chooseDep flags (m, mipi) = case mipi of +chooseDep flags (importer, m, mipi) = case mipi of -- We found some packages: group them by name. Just ps@(_:_) -> case NE.groupBy (\x y -> P.pkgName x == P.pkgName y) $ map P.packageId ps of @@ -268,7 +268,7 @@ chooseDep flags (m, mipi) = case mipi of return Nothing _ -> do - message v ("\nWarning: no package found providing " ++ prettyShow m ++ ".") + message v ("\nWarning: no package found providing " ++ prettyShow m ++ " in " ++ prettyShow importer ++ ".") return Nothing where From 7d91d3ca38751f1a3584eee5b06a2e3564821b4d Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Thu, 13 May 2021 23:28:50 -0400 Subject: [PATCH 26/37] remove golden file cruft --- .../init/golden/exe/exe-simple.golden | 13 ------------ .../init/golden/pkg-desc/pkg-simple.golden | 21 ------------------- .../init/golden/test/test-simple.golden | 14 ------------- 3 files changed, 48 deletions(-) delete mode 100644 cabal-install/tests/fixtures/init/golden/exe/exe-simple.golden delete mode 100644 cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-simple.golden delete mode 100644 cabal-install/tests/fixtures/init/golden/test/test-simple.golden diff --git a/cabal-install/tests/fixtures/init/golden/exe/exe-simple.golden b/cabal-install/tests/fixtures/init/golden/exe/exe-simple.golden deleted file mode 100644 index e6dfaa77ebe..00000000000 --- a/cabal-install/tests/fixtures/init/golden/exe/exe-simple.golden +++ /dev/null @@ -1,13 +0,0 @@ -executable y - main-is: Main.hs - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- Other library packages from which modules are imported. - -- build-depends: - hs-source-dirs: app - default-language: Haskell2010 diff --git a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-simple.golden b/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-simple.golden deleted file mode 100644 index b44bf495121..00000000000 --- a/cabal-install/tests/fixtures/init/golden/pkg-desc/pkg-simple.golden +++ /dev/null @@ -1,21 +0,0 @@ -cabal-version: 3.0 -name: 4 -version: 0.1.0.0 - --- A short (one-line) description of the package. --- synopsis: - --- A longer description of the package. --- description: -license: NONE - --- The package author(s). --- author: - --- An email address to which users can send suggestions, bug reports, and patches. --- maintainer: - --- A copyright notice. --- copyright: -build-type: Simple -extra-source-files: CHANGELOG.md diff --git a/cabal-install/tests/fixtures/init/golden/test/test-simple.golden b/cabal-install/tests/fixtures/init/golden/test/test-simple.golden deleted file mode 100644 index 44095ab9a95..00000000000 --- a/cabal-install/tests/fixtures/init/golden/test/test-simple.golden +++ /dev/null @@ -1,14 +0,0 @@ -test-suite y-test - default-language: Haskell2010 - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: Main.hs - - -- Test dependencies. - -- build-depends: From 0d2086659da433a85da4f99aad5c11758b2a67fa Mon Sep 17 00:00:00 2001 From: Patrick Augusto Date: Fri, 14 May 2021 01:18:02 -0300 Subject: [PATCH 27/37] Parametrizing verbosity for dependencies function --- .../Client/Init/Interactive/Command.hs | 3 ++- .../Client/Init/NonInteractive/Command.hs | 5 +++-- .../src/Distribution/Client/Init/Utils.hs | 15 +++++++-------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs index 1dc16f35cc3..d38b31d6959 100644 --- a/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs @@ -58,6 +58,7 @@ import Distribution.Simple.Setup (Flag(..)) import Distribution.Simple.PackageIndex (InstalledPackageIndex) import Distribution.Client.Types (SourcePackageDb(..)) import Distribution.Solver.Types.PackageIndex (elemByPackageName) +import Distribution.Verbosity import Language.Haskell.Extension (Language(..)) @@ -455,4 +456,4 @@ dependenciesPrompt -> InitFlags -> m [Dependency] dependenciesPrompt pkgIx flags = getDependencies flags $ - retrieveDependencies flags [(fromString "Prelude", fromString "Prelude")] pkgIx + retrieveDependencies silent flags [(fromString "Prelude", fromString "Prelude")] pkgIx diff --git a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs index a9add3f4b52..d828c9d5fb3 100644 --- a/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs +++ b/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs @@ -51,11 +51,12 @@ import Distribution.Client.Init.Defaults import Distribution.Client.Init.NonInteractive.Heuristics import Distribution.Client.Init.Utils import Distribution.Client.Init.FlagExtractors -import Distribution.Simple.Setup (Flag(..)) +import Distribution.Simple.Setup (Flag(..), fromFlagOrDefault) import Distribution.Simple.PackageIndex (InstalledPackageIndex) import Distribution.Client.Types (SourcePackageDb(..)) import Distribution.Solver.Types.PackageIndex (elemByPackageName) import Distribution.Utils.Generic (safeHead) +import Distribution.Verbosity import Language.Haskell.Extension (Language(..), Extension(..)) @@ -446,7 +447,7 @@ dependenciesHeuristics flags fp pkgIx = getDependencies flags $ do filteredDeps = filter ((`notElem` mods) . snd) groupedDeps preludeNub = nubBy (\a b -> snd a == snd b) $ (fromString "Prelude", fromString "Prelude") : filteredDeps - retrieveDependencies flags preludeNub pkgIx + retrieveDependencies (fromFlagOrDefault normal $ initVerbosity flags) flags preludeNub pkgIx -- | Retrieve the list of extensions otherExtsHeuristics :: Interactive m => InitFlags -> FilePath -> m [Extension] diff --git a/cabal-install/src/Distribution/Client/Init/Utils.hs b/cabal-install/src/Distribution/Client/Init/Utils.hs index 6a2dcd65a79..50b2571d299 100644 --- a/cabal-install/src/Distribution/Client/Init/Utils.hs +++ b/cabal-install/src/Distribution/Client/Init/Utils.hs @@ -213,8 +213,8 @@ isSourceFile :: Maybe [FilePath] -> SourceFileEntry -> Bool isSourceFile Nothing sf = isSourceFile (Just ["."]) sf isSourceFile (Just srcDirs) sf = any (equalFilePath (relativeSourcePath sf)) srcDirs -retrieveDependencies :: Interactive m => InitFlags -> [(ModuleName, ModuleName)] -> InstalledPackageIndex -> m [P.Dependency] -retrieveDependencies flags mods' pkgIx = do +retrieveDependencies :: Interactive m => Verbosity -> InitFlags -> [(ModuleName, ModuleName)] -> InstalledPackageIndex -> m [P.Dependency] +retrieveDependencies v flags mods' pkgIx = do let mods = mods' modMap :: M.Map ModuleName [InstalledPackageInfo] @@ -224,18 +224,19 @@ retrieveDependencies flags mods' pkgIx = do modDeps = map (\(mn, ds) -> (mn, ds, M.lookup ds modMap)) mods -- modDeps = map (id &&& flip M.lookup modMap) mods - message (fromFlagOrDefault silent $ initVerbosity flags) "\nGuessing dependencies..." - nub . catMaybes <$> traverse (chooseDep flags) modDeps + message v "\nGuessing dependencies..." + nub . catMaybes <$> traverse (chooseDep v flags) modDeps -- Given a module and a list of installed packages providing it, -- choose a dependency (i.e. package + version range) to use for that -- module. chooseDep :: Interactive m - => InitFlags + => Verbosity + -> InitFlags -> (ModuleName, ModuleName, Maybe [InstalledPackageInfo]) -> m (Maybe P.Dependency) -chooseDep flags (importer, m, mipi) = case mipi of +chooseDep v flags (importer, m, mipi) = case mipi of -- We found some packages: group them by name. Just ps@(_:_) -> case NE.groupBy (\x y -> P.pkgName x == P.pkgName y) $ map P.packageId ps of @@ -272,8 +273,6 @@ chooseDep flags (importer, m, mipi) = case mipi of return Nothing where - v = fromFlagOrDefault normal (initVerbosity flags) - -- desugar if cabal version lower than 2.0 desugar = case cabalVersion flags of Flag x -> x < CabalSpecV2_0 From a0f1ef26f3e3b29fc777e142c036413fb1107720 Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Fri, 14 May 2021 00:41:49 -0400 Subject: [PATCH 28/37] undo reversion --- cabal-install/src/Distribution/Client/Init.hs | 11 +++++------ .../Distribution/Client/Init/FileCreators.hs | 19 +++++++++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init.hs b/cabal-install/src/Distribution/Client/Init.hs index bf8c1f9d397..b217827f422 100644 --- a/cabal-install/src/Distribution/Client/Init.hs +++ b/cabal-install/src/Distribution/Client/Init.hs @@ -56,10 +56,9 @@ initCmd v packageDBs repoCtxt comp progdb initFlags = do -- If `--simple` is not set, default to interactive. When the flag -- is explicitly set to `--non-interactive`, then we choose non-interactive. -- - createProject = case interactive initFlags of - NoFlag -> Interactive.createProject - Flag True - | fromFlagOrDefault False (simpleProject initFlags) -> + createProject + | fromFlagOrDefault False (simpleProject initFlags) = Simple.createProject - | otherwise -> Interactive.createProject - Flag False -> NonInteractive.createProject comp + | otherwise = case interactive initFlags of + Flag False -> NonInteractive.createProject comp + _ -> Interactive.createProject diff --git a/cabal-install/src/Distribution/Client/Init/FileCreators.hs b/cabal-install/src/Distribution/Client/Init/FileCreators.hs index 310af500976..f9232d50faa 100644 --- a/cabal-install/src/Distribution/Client/Init/FileCreators.hs +++ b/cabal-install/src/Distribution/Client/Init/FileCreators.hs @@ -26,6 +26,7 @@ module Distribution.Client.Init.FileCreators import Prelude hiding (writeFile) import Distribution.Client.Compat.Prelude hiding (head, empty, writeFile) +import qualified Data.Set as Set (member) import Distribution.Client.Utils (getCurrentYear) import Distribution.Client.Init.Defaults import Distribution.Client.Init.Licenses @@ -56,6 +57,7 @@ writeProject (ProjectSettings opts pkgDesc libTarget exeTarget testTarget) message opts $ "\nUsing cabal specification: " ++ showCabalSpecVersion (_optCabalSpec opts) + ++ "\n" writeLicense opts pkgDesc writeChangeLog opts pkgDesc @@ -204,9 +206,9 @@ writeLicense writeOpts pkgDesc = do -- writeChangeLog :: WriteOpts -> PkgDescription -> IO () writeChangeLog opts pkgDesc - | defaultChangelog `elem` _pkgExtraSrcFiles pkgDesc = do - message opts ("Creating " ++ defaultChangelog ++"...") - writeFileSafe opts defaultChangelog changeLog + | Just docs <- _pkgExtraDocFiles pkgDesc + , defaultChangelog `Set.member` docs = go + | defaultChangelog `elem` _pkgExtraSrcFiles pkgDesc = go | otherwise = return () where changeLog = unlines @@ -217,6 +219,10 @@ writeChangeLog opts pkgDesc , "* First version. Released on an unsuspecting world." ] + go = do + message opts ("Creating " ++ defaultChangelog ++"...") + writeFileSafe opts defaultChangelog changeLog + -- -------------------------------------------------------------------- -- -- Utilities @@ -265,9 +271,10 @@ writeDirectoriesSafe opts dirs = for_ dirs $ \dir -> do exists <- doesDirectoryExist dir moveExistingDir dir exists - let action = if doOverwrite - then "Overwriting" - else "Creating or using already existing" + let action + | doOverwrite = "Overwriting" + | exists = "Using pre-existing" + | otherwise = "Creating" message opts $ action ++ " directory ./" ++ dir ++ "..." unless exists $ From 5995adaba5b0f7a2d8f66ad51c1900bcbb180376 Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Fri, 14 May 2021 00:57:51 -0400 Subject: [PATCH 29/37] respect minimal flag --- cabal-install/src/Distribution/Client/Init/Format.hs | 9 +++++---- .../init/golden/exe/exe-simple-with-comments.golden | 7 ------- .../init/golden/lib/lib-simple-with-comments.golden | 7 ------- .../init/golden/test/test-simple-with-comments.golden | 9 --------- 4 files changed, 5 insertions(+), 27 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/Format.hs b/cabal-install/src/Distribution/Client/Init/Format.hs index ade3281dbfa..aef0138384f 100644 --- a/cabal-install/src/Distribution/Client/Init/Format.hs +++ b/cabal-install/src/Distribution/Client/Init/Format.hs @@ -67,10 +67,11 @@ fieldD fieldName fieldContents fieldComments includeField opts -- If there is no content, optionally produce a commented out field. fieldSEmptyContents fieldComments | otherwise = - -- If the "--no-comments" flag is set, strip comments. - let comments = if hasNoComments - then [] - else fieldComments + -- If the "--no-comments" or "--minimal" flag is set, strip comments. + let comments + | isMinimal = [] + | hasNoComments = [] + | otherwise = fieldComments -- If the "--minimal" flag is set, strip comments. in fieldSWithContents comments diff --git a/cabal-install/tests/fixtures/init/golden/exe/exe-simple-with-comments.golden b/cabal-install/tests/fixtures/init/golden/exe/exe-simple-with-comments.golden index 19fdb84a1a6..88d69ab18db 100644 --- a/cabal-install/tests/fixtures/init/golden/exe/exe-simple-with-comments.golden +++ b/cabal-install/tests/fixtures/init/golden/exe/exe-simple-with-comments.golden @@ -1,12 +1,5 @@ executable y - -- .hs or .lhs file containing the Main module. main-is: Main.hs - - -- Other library packages from which modules are imported. build-depends: base - - -- Directories containing source files. hs-source-dirs: exe - - -- Base language which the package is written in. default-language: Haskell2010 diff --git a/cabal-install/tests/fixtures/init/golden/lib/lib-simple-with-comments.golden b/cabal-install/tests/fixtures/init/golden/lib/lib-simple-with-comments.golden index 5583deefa19..99e5d7fffb8 100644 --- a/cabal-install/tests/fixtures/init/golden/lib/lib-simple-with-comments.golden +++ b/cabal-install/tests/fixtures/init/golden/lib/lib-simple-with-comments.golden @@ -1,12 +1,5 @@ library - -- Modules exported by the library. exposed-modules: MyLib - - -- Other library packages from which modules are imported. build-depends: base - - -- Directories containing source files. hs-source-dirs: src - - -- Base language which the package is written in. default-language: Haskell98 diff --git a/cabal-install/tests/fixtures/init/golden/test/test-simple-with-comments.golden b/cabal-install/tests/fixtures/init/golden/test/test-simple-with-comments.golden index 6388f8583de..b092956a6d2 100644 --- a/cabal-install/tests/fixtures/init/golden/test/test-simple-with-comments.golden +++ b/cabal-install/tests/fixtures/init/golden/test/test-simple-with-comments.golden @@ -1,15 +1,6 @@ test-suite y-test - -- Base language which the package is written in. default-language: Haskell2010 - - -- The interface type and version of the test suite. type: exitcode-stdio-1.0 - - -- Directories containing source files. hs-source-dirs: test - - -- The entrypoint to the test suite. main-is: Main.hs - - -- Test dependencies. build-depends: base From 03dbdd7570ea53d6a4b7b6b77476b1a390d30356 Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Fri, 14 May 2021 01:02:18 -0400 Subject: [PATCH 30/37] regen golden tests with better names --- .../UnitTests/Distribution/Client/Init/Golden.hs | 11 +++-------- ...golden => exe-simple-minimal-with-comments.golden} | 0 ...golden => lib-simple-minimal-with-comments.golden} | 0 ...olden => test-simple-minimal-with-comments.golden} | 0 4 files changed, 3 insertions(+), 8 deletions(-) rename cabal-install/tests/fixtures/init/golden/exe/{exe-simple-with-comments.golden => exe-simple-minimal-with-comments.golden} (100%) rename cabal-install/tests/fixtures/init/golden/lib/{lib-simple-with-comments.golden => lib-simple-minimal-with-comments.golden} (100%) rename cabal-install/tests/fixtures/init/golden/test/{test-simple-with-comments.golden => test-simple-minimal-with-comments.golden} (100%) diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs index 7bc32428998..8bf66089bb8 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs @@ -126,7 +126,7 @@ goldenExeTests v pkgIx pkgDir pkgName = testGroup "exe golden tests" in runGoldenExe opts exeArgs emptyFlags , goldenVsString "Empty flags, not simple, with minimal + comments" - (goldenExe "exe-simple-with-comments.golden") $ + (goldenExe "exe-simple-minimal-with-comments.golden") $ let opts = WriteOpts False True False v pkgDir Executable pkgName defaultCabalVersion in runGoldenExe opts exeArgs emptyFlags @@ -168,7 +168,7 @@ goldenLibTests v pkgIx pkgDir pkgName = testGroup "lib golden tests" in runGoldenLib opts libArgs emptyFlags , goldenVsString "Empty flags, not simple, with minimal + comments" - (goldenLib "lib-simple-with-comments.golden") $ + (goldenLib "lib-simple-minimal-with-comments.golden") $ let opts = WriteOpts False True False v pkgDir Library pkgName defaultCabalVersion in runGoldenLib opts libArgs emptyFlags @@ -206,12 +206,7 @@ goldenTestTests v pkgIx pkgDir pkgName = testGroup "test golden tests" in runGoldenTest opts testArgs emptyFlags , goldenVsString "Empty flags, not simple, with minimal + comments" - (goldenTest "test-simple-with-comments.golden") $ - let opts = WriteOpts False True False v pkgDir Library pkgName defaultCabalVersion - in runGoldenTest opts testArgs emptyFlags - - , goldenVsString "Empty flags, not simple, with minimal + comments" - (goldenTest "test-simple-with-comments.golden") $ + (goldenTest "test-simple-minimal-with-comments.golden") $ let opts = WriteOpts False True False v pkgDir Library pkgName defaultCabalVersion in runGoldenTest opts testArgs emptyFlags diff --git a/cabal-install/tests/fixtures/init/golden/exe/exe-simple-with-comments.golden b/cabal-install/tests/fixtures/init/golden/exe/exe-simple-minimal-with-comments.golden similarity index 100% rename from cabal-install/tests/fixtures/init/golden/exe/exe-simple-with-comments.golden rename to cabal-install/tests/fixtures/init/golden/exe/exe-simple-minimal-with-comments.golden diff --git a/cabal-install/tests/fixtures/init/golden/lib/lib-simple-with-comments.golden b/cabal-install/tests/fixtures/init/golden/lib/lib-simple-minimal-with-comments.golden similarity index 100% rename from cabal-install/tests/fixtures/init/golden/lib/lib-simple-with-comments.golden rename to cabal-install/tests/fixtures/init/golden/lib/lib-simple-minimal-with-comments.golden diff --git a/cabal-install/tests/fixtures/init/golden/test/test-simple-with-comments.golden b/cabal-install/tests/fixtures/init/golden/test/test-simple-minimal-with-comments.golden similarity index 100% rename from cabal-install/tests/fixtures/init/golden/test/test-simple-with-comments.golden rename to cabal-install/tests/fixtures/init/golden/test/test-simple-minimal-with-comments.golden From 509a2dd7023a0344967735b48e50f050627ad99a Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Fri, 14 May 2021 23:35:26 -0400 Subject: [PATCH 31/37] fix warnings --- cabal-install/src/Distribution/Client/Init/Utils.hs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/Utils.hs b/cabal-install/src/Distribution/Client/Init/Utils.hs index 50b2571d299..b3ae305293d 100644 --- a/cabal-install/src/Distribution/Client/Init/Utils.hs +++ b/cabal-install/src/Distribution/Client/Init/Utils.hs @@ -37,8 +37,7 @@ import Distribution.InstalledPackageInfo (InstalledPackageInfo, exposed) import qualified Distribution.Package as P import qualified Distribution.Types.PackageName as PN import Distribution.Simple.PackageIndex (InstalledPackageIndex, moduleNameIndex) -import Distribution.Simple.Setup (Flag(..), fromFlagOrDefault) -import Distribution.Verbosity +import Distribution.Simple.Setup (Flag(..)) import Distribution.Version import Distribution.Client.Init.Defaults import Distribution.Client.Init.Types @@ -106,7 +105,7 @@ retrieveBuildTools v fp = do ] return tools - + else return [] @@ -134,9 +133,9 @@ retrieveSourceFiles fp = do return . Just $ SourceFileEntry {..} else return Nothing - + return . catMaybes $ entries - + else return [] @@ -146,7 +145,7 @@ retrieveModuleName m = do rawModule <- trim . grabModuleName <$> readFile m if isInfixOf rawModule (dirToModuleName m) - then + then return $ Just $ fromString rawModule else do putStrLn From 911894049cb1719fae3fa2238309dbffd172795d Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Sun, 16 May 2021 00:38:47 -0400 Subject: [PATCH 32/37] fix some prompt bugs, last minute file creation bugs --- .../Distribution/Client/Init/FileCreators.hs | 48 ++++++++++--------- .../src/Distribution/Client/Init/Prompt.hs | 4 +- cabal-install/tem/CHANGELOG.md | 5 ++ cabal-install/tem/CHANGELOG.md.save0 | 5 ++ cabal-install/tem/LICENSE | 30 ++++++++++++ cabal-install/tem/LICENSE.save0 | 20 ++++++++ cabal-install/tem/app/Main.hs | 8 ++++ cabal-install/tem/exe.save0/Main.hs | 8 ++++ cabal-install/tem/exe.save1/Main.hs | 8 ++++ cabal-install/tem/exe/Main.hs | 8 ++++ cabal-install/tem/src.save0/MyLib.hs | 4 ++ cabal-install/tem/src.save1/MyLib.hs | 4 ++ cabal-install/tem/src.save2/MyLib.hs | 4 ++ cabal-install/tem/src/MyLib.hs | 4 ++ cabal-install/tem/tem.cabal | 33 +++++++++++++ cabal-install/tem/tem.cabal.save0 | 32 +++++++++++++ cabal-install/tem/test.save0/Main.hs | 4 ++ cabal-install/tem/test.save1/Main.hs | 4 ++ cabal-install/tem/test.save2/Main.hs | 4 ++ cabal-install/tem/test/Main.hs | 4 ++ 20 files changed, 217 insertions(+), 24 deletions(-) create mode 100644 cabal-install/tem/CHANGELOG.md create mode 100644 cabal-install/tem/CHANGELOG.md.save0 create mode 100644 cabal-install/tem/LICENSE create mode 100644 cabal-install/tem/LICENSE.save0 create mode 100644 cabal-install/tem/app/Main.hs create mode 100644 cabal-install/tem/exe.save0/Main.hs create mode 100644 cabal-install/tem/exe.save1/Main.hs create mode 100644 cabal-install/tem/exe/Main.hs create mode 100644 cabal-install/tem/src.save0/MyLib.hs create mode 100644 cabal-install/tem/src.save1/MyLib.hs create mode 100644 cabal-install/tem/src.save2/MyLib.hs create mode 100644 cabal-install/tem/src/MyLib.hs create mode 100644 cabal-install/tem/tem.cabal create mode 100644 cabal-install/tem/tem.cabal.save0 create mode 100644 cabal-install/tem/test.save0/Main.hs create mode 100644 cabal-install/tem/test.save1/Main.hs create mode 100644 cabal-install/tem/test.save2/Main.hs create mode 100644 cabal-install/tem/test/Main.hs diff --git a/cabal-install/src/Distribution/Client/Init/FileCreators.hs b/cabal-install/src/Distribution/Client/Init/FileCreators.hs index f9232d50faa..3d8b6ac3b5c 100644 --- a/cabal-install/src/Distribution/Client/Init/FileCreators.hs +++ b/cabal-install/src/Distribution/Client/Init/FileCreators.hs @@ -147,9 +147,12 @@ writeCabalFile opts fields = do exists <- doesFileExist cabalFileName if exists && doOverwrite then do - removeFile cabalFileName writeFileSafe opts cabalFileName cabalContents - else writeFileSafe opts cabalFileName cabalContents + else message opts $ concat + [ "Warning: " + , cabalFileName + , " already exists. Skipping..." + ] where doOverwrite = _optOverwrite opts @@ -244,8 +247,8 @@ writeFileSafe opts fileName content = do doOverwrite = _optOverwrite opts moveExistingFile exists - | exists && doOverwrite = do - newName <- findNewName fileName (0 :: Int) + | exists, doOverwrite = do + newName <- findNewPath fileName message opts $ concat [ "Warning: " , fileName @@ -254,22 +257,16 @@ writeFileSafe opts fileName content = do ] copyFile fileName newName - | exists && not doOverwrite = message opts $ concat + | exists, not doOverwrite = message opts $ concat [ "Warning: " , fileName , " already exists. Skipping..." ] | otherwise = return () - findNewName oldName n = do - let newName = oldName <.> ("save" ++ show n) - e <- doesFileExist newName - if e then findNewName oldName (n+1) else return newName - writeDirectoriesSafe :: WriteOpts -> [String] -> IO () writeDirectoriesSafe opts dirs = for_ dirs $ \dir -> do exists <- doesDirectoryExist dir - moveExistingDir dir exists let action | doOverwrite = "Overwriting" @@ -277,26 +274,33 @@ writeDirectoriesSafe opts dirs = for_ dirs $ \dir -> do | otherwise = "Creating" message opts $ action ++ " directory ./" ++ dir ++ "..." - unless exists $ - createDirectory dir + go dir exists where doOverwrite = _optOverwrite opts - moveExistingDir oldDir exists + go dir exists | exists && doOverwrite = do - newDir <- findNewDir oldDir (0 :: Int) + newDir <- findNewPath dir message opts $ concat [ "Warning: " - , oldDir + , dir , " already exists. Backing up old version in " , newDir ] - renameDirectory oldDir newDir - | exists && doOverwrite = removeDirectoryRecursive oldDir - | otherwise = return () + renameDirectory dir newDir + createDirectory dir + | exists, not doOverwrite = message opts $ concat + [ "Warning: " + , dir + , "already exists. Skipping..." + ] + | otherwise = createDirectory dir - findNewDir oldDir n = do - let newDir = oldDir <.> ("save" ++ show n) +findNewPath :: Interactive m => FilePath -> m FilePath +findNewPath dir = go (0 :: Int) + where + go n = do + let newDir = dir <.> ("save" ++ show n) e <- doesDirectoryExist newDir - if e then findNewDir oldDir (n+1) else return newDir + if e then go (succ n) else return newDir diff --git a/cabal-install/src/Distribution/Client/Init/Prompt.hs b/cabal-install/src/Distribution/Client/Init/Prompt.hs index efe539a51a0..ba10d17a817 100644 --- a/cabal-install/src/Distribution/Client/Init/Prompt.hs +++ b/cabal-install/src/Distribution/Client/Init/Prompt.hs @@ -101,7 +101,7 @@ promptList msg choices def modDef hasOther = do let cs = if hasOther then choices ++ ["Other (specify)"] else choices - in zip [1::Int .. numChoices + 1] cs + in zip [1::Int .. length choices + 1] cs numChoices = length choices @@ -111,7 +111,7 @@ promptList msg choices def modDef hasOther = do else concat [ input , " is not a valid choice. Please choose a number from 1 to " - , show (numChoices +1) + , show (length prettyChoices) , "." ] diff --git a/cabal-install/tem/CHANGELOG.md b/cabal-install/tem/CHANGELOG.md new file mode 100644 index 00000000000..679b6b324d8 --- /dev/null +++ b/cabal-install/tem/CHANGELOG.md @@ -0,0 +1,5 @@ +# Revision history for tem + +## 0.1.0.0 -- YYYY-mm-dd + +* First version. Released on an unsuspecting world. diff --git a/cabal-install/tem/CHANGELOG.md.save0 b/cabal-install/tem/CHANGELOG.md.save0 new file mode 100644 index 00000000000..679b6b324d8 --- /dev/null +++ b/cabal-install/tem/CHANGELOG.md.save0 @@ -0,0 +1,5 @@ +# Revision history for tem + +## 0.1.0.0 -- YYYY-mm-dd + +* First version. Released on an unsuspecting world. diff --git a/cabal-install/tem/LICENSE b/cabal-install/tem/LICENSE new file mode 100644 index 00000000000..e5ed9fed6fe --- /dev/null +++ b/cabal-install/tem/LICENSE @@ -0,0 +1,30 @@ +Copyright (c) 2021, + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cabal-install/tem/LICENSE.save0 b/cabal-install/tem/LICENSE.save0 new file mode 100644 index 00000000000..5545d6c599e --- /dev/null +++ b/cabal-install/tem/LICENSE.save0 @@ -0,0 +1,20 @@ +Copyright (c) 2021 + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/cabal-install/tem/app/Main.hs b/cabal-install/tem/app/Main.hs new file mode 100644 index 00000000000..60d904e8c1c --- /dev/null +++ b/cabal-install/tem/app/Main.hs @@ -0,0 +1,8 @@ +module Main where + +import qualified MyLib (someFunc) + +main :: IO () +main = do + putStrLn "Hello, Haskell!" + MyLib.someFunc diff --git a/cabal-install/tem/exe.save0/Main.hs b/cabal-install/tem/exe.save0/Main.hs new file mode 100644 index 00000000000..60d904e8c1c --- /dev/null +++ b/cabal-install/tem/exe.save0/Main.hs @@ -0,0 +1,8 @@ +module Main where + +import qualified MyLib (someFunc) + +main :: IO () +main = do + putStrLn "Hello, Haskell!" + MyLib.someFunc diff --git a/cabal-install/tem/exe.save1/Main.hs b/cabal-install/tem/exe.save1/Main.hs new file mode 100644 index 00000000000..60d904e8c1c --- /dev/null +++ b/cabal-install/tem/exe.save1/Main.hs @@ -0,0 +1,8 @@ +module Main where + +import qualified MyLib (someFunc) + +main :: IO () +main = do + putStrLn "Hello, Haskell!" + MyLib.someFunc diff --git a/cabal-install/tem/exe/Main.hs b/cabal-install/tem/exe/Main.hs new file mode 100644 index 00000000000..60d904e8c1c --- /dev/null +++ b/cabal-install/tem/exe/Main.hs @@ -0,0 +1,8 @@ +module Main where + +import qualified MyLib (someFunc) + +main :: IO () +main = do + putStrLn "Hello, Haskell!" + MyLib.someFunc diff --git a/cabal-install/tem/src.save0/MyLib.hs b/cabal-install/tem/src.save0/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-install/tem/src.save0/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-install/tem/src.save1/MyLib.hs b/cabal-install/tem/src.save1/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-install/tem/src.save1/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-install/tem/src.save2/MyLib.hs b/cabal-install/tem/src.save2/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-install/tem/src.save2/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-install/tem/src/MyLib.hs b/cabal-install/tem/src/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-install/tem/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-install/tem/tem.cabal b/cabal-install/tem/tem.cabal new file mode 100644 index 00000000000..72d04033f27 --- /dev/null +++ b/cabal-install/tem/tem.cabal @@ -0,0 +1,33 @@ +cabal-version: 3.0 +name: tem +version: 0.1.0.0 +license: BSD-3-Clause +license-file: LICENSE +category: Data +build-type: Simple +extra-doc-files: CHANGELOG.md + +library + exposed-modules: MyLib + build-depends: base ^>=4.14.1.0 + hs-source-dirs: src + default-language: Haskell2010 + +executable tem + main-is: Main.hs + build-depends: + base ^>=4.14.1.0, + tem + + hs-source-dirs: exe + default-language: Haskell2010 + +test-suite tem-test + default-language: Haskell2010 + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: + base ^>=4.14.1.0, + tem + diff --git a/cabal-install/tem/tem.cabal.save0 b/cabal-install/tem/tem.cabal.save0 new file mode 100644 index 00000000000..2033ad799a1 --- /dev/null +++ b/cabal-install/tem/tem.cabal.save0 @@ -0,0 +1,32 @@ +cabal-version: 3.4 +name: tem +version: 0.1.0.0 +license: NONE +category: Data +build-type: Simple +extra-doc-files: CHANGELOG.md + +library + exposed-modules: MyLib + build-depends: base ^>=4.14.1.0 + hs-source-dirs: src + default-language: Haskell2010 + +executable tem + main-is: Main.hs + build-depends: + base ^>=4.14.1.0, + tem + + hs-source-dirs: exe + default-language: Haskell2010 + +test-suite tem-test + default-language: Haskell2010 + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: + base ^>=4.14.1.0, + tem + diff --git a/cabal-install/tem/test.save0/Main.hs b/cabal-install/tem/test.save0/Main.hs new file mode 100644 index 00000000000..3e2059e31f5 --- /dev/null +++ b/cabal-install/tem/test.save0/Main.hs @@ -0,0 +1,4 @@ +module Main (main) where + +main :: IO () +main = putStrLn "Test suite not yet implemented." diff --git a/cabal-install/tem/test.save1/Main.hs b/cabal-install/tem/test.save1/Main.hs new file mode 100644 index 00000000000..3e2059e31f5 --- /dev/null +++ b/cabal-install/tem/test.save1/Main.hs @@ -0,0 +1,4 @@ +module Main (main) where + +main :: IO () +main = putStrLn "Test suite not yet implemented." diff --git a/cabal-install/tem/test.save2/Main.hs b/cabal-install/tem/test.save2/Main.hs new file mode 100644 index 00000000000..3e2059e31f5 --- /dev/null +++ b/cabal-install/tem/test.save2/Main.hs @@ -0,0 +1,4 @@ +module Main (main) where + +main :: IO () +main = putStrLn "Test suite not yet implemented." diff --git a/cabal-install/tem/test/Main.hs b/cabal-install/tem/test/Main.hs new file mode 100644 index 00000000000..3e2059e31f5 --- /dev/null +++ b/cabal-install/tem/test/Main.hs @@ -0,0 +1,4 @@ +module Main (main) where + +main :: IO () +main = putStrLn "Test suite not yet implemented." From 6ffee7508131175880db7dadcd80670b1e73fedf Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Sun, 16 May 2021 00:38:57 -0400 Subject: [PATCH 33/37] fix some prompt bugs, last minute file creation bugs --- cabal-install/tem/CHANGELOG.md | 5 ----- cabal-install/tem/CHANGELOG.md.save0 | 5 ----- cabal-install/tem/LICENSE | 30 ------------------------- cabal-install/tem/LICENSE.save0 | 20 ----------------- cabal-install/tem/app/Main.hs | 8 ------- cabal-install/tem/exe.save0/Main.hs | 8 ------- cabal-install/tem/exe.save1/Main.hs | 8 ------- cabal-install/tem/exe/Main.hs | 8 ------- cabal-install/tem/src.save0/MyLib.hs | 4 ---- cabal-install/tem/src.save1/MyLib.hs | 4 ---- cabal-install/tem/src.save2/MyLib.hs | 4 ---- cabal-install/tem/src/MyLib.hs | 4 ---- cabal-install/tem/tem.cabal | 33 ---------------------------- cabal-install/tem/tem.cabal.save0 | 32 --------------------------- cabal-install/tem/test.save0/Main.hs | 4 ---- cabal-install/tem/test.save1/Main.hs | 4 ---- cabal-install/tem/test.save2/Main.hs | 4 ---- cabal-install/tem/test/Main.hs | 4 ---- 18 files changed, 189 deletions(-) delete mode 100644 cabal-install/tem/CHANGELOG.md delete mode 100644 cabal-install/tem/CHANGELOG.md.save0 delete mode 100644 cabal-install/tem/LICENSE delete mode 100644 cabal-install/tem/LICENSE.save0 delete mode 100644 cabal-install/tem/app/Main.hs delete mode 100644 cabal-install/tem/exe.save0/Main.hs delete mode 100644 cabal-install/tem/exe.save1/Main.hs delete mode 100644 cabal-install/tem/exe/Main.hs delete mode 100644 cabal-install/tem/src.save0/MyLib.hs delete mode 100644 cabal-install/tem/src.save1/MyLib.hs delete mode 100644 cabal-install/tem/src.save2/MyLib.hs delete mode 100644 cabal-install/tem/src/MyLib.hs delete mode 100644 cabal-install/tem/tem.cabal delete mode 100644 cabal-install/tem/tem.cabal.save0 delete mode 100644 cabal-install/tem/test.save0/Main.hs delete mode 100644 cabal-install/tem/test.save1/Main.hs delete mode 100644 cabal-install/tem/test.save2/Main.hs delete mode 100644 cabal-install/tem/test/Main.hs diff --git a/cabal-install/tem/CHANGELOG.md b/cabal-install/tem/CHANGELOG.md deleted file mode 100644 index 679b6b324d8..00000000000 --- a/cabal-install/tem/CHANGELOG.md +++ /dev/null @@ -1,5 +0,0 @@ -# Revision history for tem - -## 0.1.0.0 -- YYYY-mm-dd - -* First version. Released on an unsuspecting world. diff --git a/cabal-install/tem/CHANGELOG.md.save0 b/cabal-install/tem/CHANGELOG.md.save0 deleted file mode 100644 index 679b6b324d8..00000000000 --- a/cabal-install/tem/CHANGELOG.md.save0 +++ /dev/null @@ -1,5 +0,0 @@ -# Revision history for tem - -## 0.1.0.0 -- YYYY-mm-dd - -* First version. Released on an unsuspecting world. diff --git a/cabal-install/tem/LICENSE b/cabal-install/tem/LICENSE deleted file mode 100644 index e5ed9fed6fe..00000000000 --- a/cabal-install/tem/LICENSE +++ /dev/null @@ -1,30 +0,0 @@ -Copyright (c) 2021, - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * Neither the name of nor the names of other - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cabal-install/tem/LICENSE.save0 b/cabal-install/tem/LICENSE.save0 deleted file mode 100644 index 5545d6c599e..00000000000 --- a/cabal-install/tem/LICENSE.save0 +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2021 - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/cabal-install/tem/app/Main.hs b/cabal-install/tem/app/Main.hs deleted file mode 100644 index 60d904e8c1c..00000000000 --- a/cabal-install/tem/app/Main.hs +++ /dev/null @@ -1,8 +0,0 @@ -module Main where - -import qualified MyLib (someFunc) - -main :: IO () -main = do - putStrLn "Hello, Haskell!" - MyLib.someFunc diff --git a/cabal-install/tem/exe.save0/Main.hs b/cabal-install/tem/exe.save0/Main.hs deleted file mode 100644 index 60d904e8c1c..00000000000 --- a/cabal-install/tem/exe.save0/Main.hs +++ /dev/null @@ -1,8 +0,0 @@ -module Main where - -import qualified MyLib (someFunc) - -main :: IO () -main = do - putStrLn "Hello, Haskell!" - MyLib.someFunc diff --git a/cabal-install/tem/exe.save1/Main.hs b/cabal-install/tem/exe.save1/Main.hs deleted file mode 100644 index 60d904e8c1c..00000000000 --- a/cabal-install/tem/exe.save1/Main.hs +++ /dev/null @@ -1,8 +0,0 @@ -module Main where - -import qualified MyLib (someFunc) - -main :: IO () -main = do - putStrLn "Hello, Haskell!" - MyLib.someFunc diff --git a/cabal-install/tem/exe/Main.hs b/cabal-install/tem/exe/Main.hs deleted file mode 100644 index 60d904e8c1c..00000000000 --- a/cabal-install/tem/exe/Main.hs +++ /dev/null @@ -1,8 +0,0 @@ -module Main where - -import qualified MyLib (someFunc) - -main :: IO () -main = do - putStrLn "Hello, Haskell!" - MyLib.someFunc diff --git a/cabal-install/tem/src.save0/MyLib.hs b/cabal-install/tem/src.save0/MyLib.hs deleted file mode 100644 index e657c4403f6..00000000000 --- a/cabal-install/tem/src.save0/MyLib.hs +++ /dev/null @@ -1,4 +0,0 @@ -module MyLib (someFunc) where - -someFunc :: IO () -someFunc = putStrLn "someFunc" diff --git a/cabal-install/tem/src.save1/MyLib.hs b/cabal-install/tem/src.save1/MyLib.hs deleted file mode 100644 index e657c4403f6..00000000000 --- a/cabal-install/tem/src.save1/MyLib.hs +++ /dev/null @@ -1,4 +0,0 @@ -module MyLib (someFunc) where - -someFunc :: IO () -someFunc = putStrLn "someFunc" diff --git a/cabal-install/tem/src.save2/MyLib.hs b/cabal-install/tem/src.save2/MyLib.hs deleted file mode 100644 index e657c4403f6..00000000000 --- a/cabal-install/tem/src.save2/MyLib.hs +++ /dev/null @@ -1,4 +0,0 @@ -module MyLib (someFunc) where - -someFunc :: IO () -someFunc = putStrLn "someFunc" diff --git a/cabal-install/tem/src/MyLib.hs b/cabal-install/tem/src/MyLib.hs deleted file mode 100644 index e657c4403f6..00000000000 --- a/cabal-install/tem/src/MyLib.hs +++ /dev/null @@ -1,4 +0,0 @@ -module MyLib (someFunc) where - -someFunc :: IO () -someFunc = putStrLn "someFunc" diff --git a/cabal-install/tem/tem.cabal b/cabal-install/tem/tem.cabal deleted file mode 100644 index 72d04033f27..00000000000 --- a/cabal-install/tem/tem.cabal +++ /dev/null @@ -1,33 +0,0 @@ -cabal-version: 3.0 -name: tem -version: 0.1.0.0 -license: BSD-3-Clause -license-file: LICENSE -category: Data -build-type: Simple -extra-doc-files: CHANGELOG.md - -library - exposed-modules: MyLib - build-depends: base ^>=4.14.1.0 - hs-source-dirs: src - default-language: Haskell2010 - -executable tem - main-is: Main.hs - build-depends: - base ^>=4.14.1.0, - tem - - hs-source-dirs: exe - default-language: Haskell2010 - -test-suite tem-test - default-language: Haskell2010 - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: Main.hs - build-depends: - base ^>=4.14.1.0, - tem - diff --git a/cabal-install/tem/tem.cabal.save0 b/cabal-install/tem/tem.cabal.save0 deleted file mode 100644 index 2033ad799a1..00000000000 --- a/cabal-install/tem/tem.cabal.save0 +++ /dev/null @@ -1,32 +0,0 @@ -cabal-version: 3.4 -name: tem -version: 0.1.0.0 -license: NONE -category: Data -build-type: Simple -extra-doc-files: CHANGELOG.md - -library - exposed-modules: MyLib - build-depends: base ^>=4.14.1.0 - hs-source-dirs: src - default-language: Haskell2010 - -executable tem - main-is: Main.hs - build-depends: - base ^>=4.14.1.0, - tem - - hs-source-dirs: exe - default-language: Haskell2010 - -test-suite tem-test - default-language: Haskell2010 - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: Main.hs - build-depends: - base ^>=4.14.1.0, - tem - diff --git a/cabal-install/tem/test.save0/Main.hs b/cabal-install/tem/test.save0/Main.hs deleted file mode 100644 index 3e2059e31f5..00000000000 --- a/cabal-install/tem/test.save0/Main.hs +++ /dev/null @@ -1,4 +0,0 @@ -module Main (main) where - -main :: IO () -main = putStrLn "Test suite not yet implemented." diff --git a/cabal-install/tem/test.save1/Main.hs b/cabal-install/tem/test.save1/Main.hs deleted file mode 100644 index 3e2059e31f5..00000000000 --- a/cabal-install/tem/test.save1/Main.hs +++ /dev/null @@ -1,4 +0,0 @@ -module Main (main) where - -main :: IO () -main = putStrLn "Test suite not yet implemented." diff --git a/cabal-install/tem/test.save2/Main.hs b/cabal-install/tem/test.save2/Main.hs deleted file mode 100644 index 3e2059e31f5..00000000000 --- a/cabal-install/tem/test.save2/Main.hs +++ /dev/null @@ -1,4 +0,0 @@ -module Main (main) where - -main :: IO () -main = putStrLn "Test suite not yet implemented." diff --git a/cabal-install/tem/test/Main.hs b/cabal-install/tem/test/Main.hs deleted file mode 100644 index 3e2059e31f5..00000000000 --- a/cabal-install/tem/test/Main.hs +++ /dev/null @@ -1,4 +0,0 @@ -module Main (main) where - -main :: IO () -main = putStrLn "Test suite not yet implemented." From 0e20b016f70557d9d2596976b4f7a8271ab7fb20 Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Sun, 16 May 2021 14:01:56 -0400 Subject: [PATCH 34/37] Remove redundant imports --- cabal-install/src/Distribution/Client/Init/FileCreators.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cabal-install/src/Distribution/Client/Init/FileCreators.hs b/cabal-install/src/Distribution/Client/Init/FileCreators.hs index 3d8b6ac3b5c..609d662e734 100644 --- a/cabal-install/src/Distribution/Client/Init/FileCreators.hs +++ b/cabal-install/src/Distribution/Client/Init/FileCreators.hs @@ -27,6 +27,7 @@ import Prelude hiding (writeFile) import Distribution.Client.Compat.Prelude hiding (head, empty, writeFile) import qualified Data.Set as Set (member) + import Distribution.Client.Utils (getCurrentYear) import Distribution.Client.Init.Defaults import Distribution.Client.Init.Licenses @@ -36,12 +37,11 @@ import qualified Distribution.Client.Init.Types as T import Distribution.Fields.Pretty (PrettyField(..), showFields') import qualified Distribution.SPDX as SPDX import Distribution.Types.PackageName +import Distribution.Client.Init.Format +import Distribution.CabalSpecVersion (showCabalSpecVersion) -import System.Directory hiding (doesDirectoryExist, doesFileExist, createDirectory, renameDirectory, copyFile) import System.FilePath ((), (<.>)) -import Distribution.Client.Init.Format -import Distribution.CabalSpecVersion (showCabalSpecVersion) -- -------------------------------------------------------------------- -- From f2c8bb7e8a1b0995eafdb788b1a79685d68c0b54 Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Mon, 17 May 2021 10:25:20 -0400 Subject: [PATCH 35/37] improve filecreation consistency and safety checks --- .../Distribution/Client/Init/FileCreators.hs | 61 +++--- .../src/Distribution/Client/Init/Types.hs | 3 + cabal-install/tem/CHANGELOG.md | 5 + cabal-install/tem/CHANGELOG.md.save0 | 5 + cabal-install/tem/LICENSE | 202 ++++++++++++++++++ cabal-install/tem/LICENSE.save0 | 202 ++++++++++++++++++ cabal-install/tem/app.save0/Main.hs | 8 + cabal-install/tem/app/Main.hs | 8 + cabal-install/tem/src.save0/MyLib.hs | 4 + cabal-install/tem/src/MyLib.hs | 4 + cabal-install/tem/tem.cabal | 32 +++ cabal-install/tem/tem.cabal.save0 | 33 +++ cabal-install/tem/test.save0/Main.hs | 4 + cabal-install/tem/test/Main.hs | 4 + .../cabal-lib-and-exe-no-comments.golden | 64 ++++++ .../cabal-lib-and-exe-with-comments.golden | 114 ++++++++++ .../golden/cabal/cabal-lib-no-comments.golden | 49 +++++ .../cabal/cabal-lib-with-comments.golden | 93 ++++++++ .../exe/exe-build-tools-with-comments.golden | 21 ++ .../golden/exe/exe-minimal-no-comments.golden | 5 + .../exe-simple-minimal-with-comments.golden | 5 + .../init/golden/exe/exe-with-comments.golden | 18 ++ .../tests/fixtures/init/golden/exe/exe.golden | 11 + .../lib/lib-build-tools-with-comments.golden | 21 ++ .../golden/lib/lib-minimal-no-comments.golden | 5 + .../lib-simple-minimal-with-comments.golden | 5 + .../init/golden/lib/lib-simple.golden | 11 + .../init/golden/lib/lib-with-comments.golden | 18 ++ .../tests/fixtures/init/golden/lib/lib.golden | 11 + .../pkg-desc/pkg-old-cabal-with-flags.golden | 48 +++++ .../golden/pkg-desc/pkg-with-comments.golden | 49 +++++ .../golden/pkg-desc/pkg-with-flags.golden | 49 +++++ .../fixtures/init/golden/pkg-desc/pkg.golden | 49 +++++ .../test-build-tools-with-comments.golden | 24 +++ .../test/test-minimal-no-comments.golden | 6 + .../test-simple-minimal-with-comments.golden | 6 + .../golden/test/test-with-comments.golden | 21 ++ .../fixtures/init/golden/test/test.golden | 12 ++ 38 files changed, 1254 insertions(+), 36 deletions(-) create mode 100644 cabal-install/tem/CHANGELOG.md create mode 100644 cabal-install/tem/CHANGELOG.md.save0 create mode 100644 cabal-install/tem/LICENSE create mode 100644 cabal-install/tem/LICENSE.save0 create mode 100644 cabal-install/tem/app.save0/Main.hs create mode 100644 cabal-install/tem/app/Main.hs create mode 100644 cabal-install/tem/src.save0/MyLib.hs create mode 100644 cabal-install/tem/src/MyLib.hs create mode 100644 cabal-install/tem/tem.cabal create mode 100644 cabal-install/tem/tem.cabal.save0 create mode 100644 cabal-install/tem/test.save0/Main.hs create mode 100644 cabal-install/tem/test/Main.hs create mode 100644 cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/exe/exe-simple-minimal-with-comments.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/exe/exe-with-comments.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/exe/exe.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/lib/lib-simple-minimal-with-comments.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/lib/lib-simple.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/lib/lib-with-comments.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/lib/lib.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/test/test-minimal-no-comments.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/test/test-simple-minimal-with-comments.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/test/test-with-comments.golden create mode 100644 cabal-install/tem/tests/fixtures/init/golden/test/test.golden diff --git a/cabal-install/src/Distribution/Client/Init/FileCreators.hs b/cabal-install/src/Distribution/Client/Init/FileCreators.hs index 609d662e734..d4f0843c068 100644 --- a/cabal-install/src/Distribution/Client/Init/FileCreators.hs +++ b/cabal-install/src/Distribution/Client/Init/FileCreators.hs @@ -28,7 +28,7 @@ import Distribution.Client.Compat.Prelude hiding (head, empty, writeFile) import qualified Data.Set as Set (member) -import Distribution.Client.Utils (getCurrentYear) +import Distribution.Client.Utils (getCurrentYear, removeExistingFile) import Distribution.Client.Init.Defaults import Distribution.Client.Init.Licenses ( bsd2, bsd3, gplv2, gplv3, lgpl21, lgpl3, agplv3, apache20, mit, mpl20, isc ) @@ -42,8 +42,6 @@ import Distribution.CabalSpecVersion (showCabalSpecVersion) import System.FilePath ((), (<.>)) - - -- -------------------------------------------------------------------- -- -- File generation @@ -142,20 +140,9 @@ writeCabalFile -> [PrettyField FieldAnnotation] -- ^ .cabal fields -> IO () -writeCabalFile opts fields = do - message opts $ "\nGenerating " ++ cabalFileName ++ "..." - exists <- doesFileExist cabalFileName - - if exists && doOverwrite then do - writeFileSafe opts cabalFileName cabalContents - else message opts $ concat - [ "Warning: " - , cabalFileName - , " already exists. Skipping..." - ] +writeCabalFile opts fields = + writeFileSafe opts cabalFileName cabalContents where - doOverwrite = _optOverwrite opts - cabalContents = showFields' annCommentLines postProcessFieldLines @@ -238,16 +225,24 @@ message opts = T.message (_optVerbosity opts) -- the overwrite flag is set. writeFileSafe :: WriteOpts -> FilePath -> String -> IO () writeFileSafe opts fileName content = do - litExists <- doesFileExist fileName - moveExistingFile litExists + exists <- doesFileExist fileName + + let action + | doOverwrite = "Overwriting" + | exists = "Creating fresh" + | otherwise = "Creating" - when (doOverwrite || not litExists) $ - writeFile fileName content + go exists + + message opts $ action ++ " file " ++ fileName ++ "..." + writeFile fileName content where doOverwrite = _optOverwrite opts - moveExistingFile exists + go exists | exists, doOverwrite = do + removeExistingFile fileName + | exists, not doOverwrite = do newName <- findNewPath fileName message opts $ concat [ "Warning: " @@ -257,11 +252,7 @@ writeFileSafe opts fileName content = do ] copyFile fileName newName - | exists, not doOverwrite = message opts $ concat - [ "Warning: " - , fileName - , " already exists. Skipping..." - ] + removeExistingFile fileName | otherwise = return () writeDirectoriesSafe :: WriteOpts -> [String] -> IO () @@ -270,16 +261,20 @@ writeDirectoriesSafe opts dirs = for_ dirs $ \dir -> do let action | doOverwrite = "Overwriting" - | exists = "Using pre-existing" + | exists = "Creating fresh" | otherwise = "Creating" - message opts $ action ++ " directory ./" ++ dir ++ "..." go dir exists + + message opts $ action ++ " directory ./" ++ dir ++ "..." + createDirectory dir where doOverwrite = _optOverwrite opts go dir exists - | exists && doOverwrite = do + | exists, doOverwrite = do + removeDirectory dir + | exists, not doOverwrite = do newDir <- findNewPath dir message opts $ concat [ "Warning: " @@ -289,13 +284,7 @@ writeDirectoriesSafe opts dirs = for_ dirs $ \dir -> do ] renameDirectory dir newDir - createDirectory dir - | exists, not doOverwrite = message opts $ concat - [ "Warning: " - , dir - , "already exists. Skipping..." - ] - | otherwise = createDirectory dir + | otherwise = return () findNewPath :: Interactive m => FilePath -> m FilePath findNewPath dir = go (0 :: Int) diff --git a/cabal-install/src/Distribution/Client/Init/Types.hs b/cabal-install/src/Distribution/Client/Init/Types.hs index b31d94d1533..7f64dd4bfc6 100644 --- a/cabal-install/src/Distribution/Client/Init/Types.hs +++ b/cabal-install/src/Distribution/Client/Init/Types.hs @@ -314,6 +314,7 @@ class Monad m => Interactive m where putStr :: String -> m () putStrLn :: String -> m () createDirectory :: FilePath -> m () + removeDirectory :: FilePath -> m () writeFile :: FilePath -> String -> m () copyFile :: FilePath -> FilePath -> m () renameDirectory :: FilePath -> FilePath -> m () @@ -341,6 +342,7 @@ instance Interactive IO where putStr = P.putStr putStrLn = P.putStrLn createDirectory = P.createDirectory + removeDirectory = P.removeDirectoryRecursive writeFile = P.writeFile copyFile = P.copyFile renameDirectory = P.renameDirectory @@ -372,6 +374,7 @@ instance Interactive PurePrompt where putStr !_ = return () putStrLn !_ = return () createDirectory !_ = return () + removeDirectory !_ = return () writeFile !_ !_ = return () copyFile !_ !_ = return () renameDirectory !_ !_ = return () diff --git a/cabal-install/tem/CHANGELOG.md b/cabal-install/tem/CHANGELOG.md new file mode 100644 index 00000000000..679b6b324d8 --- /dev/null +++ b/cabal-install/tem/CHANGELOG.md @@ -0,0 +1,5 @@ +# Revision history for tem + +## 0.1.0.0 -- YYYY-mm-dd + +* First version. Released on an unsuspecting world. diff --git a/cabal-install/tem/CHANGELOG.md.save0 b/cabal-install/tem/CHANGELOG.md.save0 new file mode 100644 index 00000000000..679b6b324d8 --- /dev/null +++ b/cabal-install/tem/CHANGELOG.md.save0 @@ -0,0 +1,5 @@ +# Revision history for tem + +## 0.1.0.0 -- YYYY-mm-dd + +* First version. Released on an unsuspecting world. diff --git a/cabal-install/tem/LICENSE b/cabal-install/tem/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/cabal-install/tem/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/cabal-install/tem/LICENSE.save0 b/cabal-install/tem/LICENSE.save0 new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/cabal-install/tem/LICENSE.save0 @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/cabal-install/tem/app.save0/Main.hs b/cabal-install/tem/app.save0/Main.hs new file mode 100644 index 00000000000..60d904e8c1c --- /dev/null +++ b/cabal-install/tem/app.save0/Main.hs @@ -0,0 +1,8 @@ +module Main where + +import qualified MyLib (someFunc) + +main :: IO () +main = do + putStrLn "Hello, Haskell!" + MyLib.someFunc diff --git a/cabal-install/tem/app/Main.hs b/cabal-install/tem/app/Main.hs new file mode 100644 index 00000000000..60d904e8c1c --- /dev/null +++ b/cabal-install/tem/app/Main.hs @@ -0,0 +1,8 @@ +module Main where + +import qualified MyLib (someFunc) + +main :: IO () +main = do + putStrLn "Hello, Haskell!" + MyLib.someFunc diff --git a/cabal-install/tem/src.save0/MyLib.hs b/cabal-install/tem/src.save0/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-install/tem/src.save0/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-install/tem/src/MyLib.hs b/cabal-install/tem/src/MyLib.hs new file mode 100644 index 00000000000..e657c4403f6 --- /dev/null +++ b/cabal-install/tem/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/cabal-install/tem/tem.cabal b/cabal-install/tem/tem.cabal new file mode 100644 index 00000000000..2c097484516 --- /dev/null +++ b/cabal-install/tem/tem.cabal @@ -0,0 +1,32 @@ +cabal-version: 3.0 +name: tem +version: 0.1.0.0 +license: Apache-2.0 +license-file: LICENSE +build-type: Simple +extra-doc-files: CHANGELOG.md + +library + exposed-modules: MyLib + build-depends: base ^>=4.14.1.0 + hs-source-dirs: src + default-language: Haskell2010 + +executable tem + main-is: Main.hs + build-depends: + base ^>=4.14.1.0, + tem + + hs-source-dirs: app + default-language: Haskell2010 + +test-suite tem-test + default-language: Haskell2010 + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: + base ^>=4.14.1.0, + tem + diff --git a/cabal-install/tem/tem.cabal.save0 b/cabal-install/tem/tem.cabal.save0 new file mode 100644 index 00000000000..e4718176e8a --- /dev/null +++ b/cabal-install/tem/tem.cabal.save0 @@ -0,0 +1,33 @@ +cabal-version: 3.0 +name: tem +version: 0.1.0.0 +license: Apache-2.0 +license-file: LICENSE +category: Data +build-type: Simple +extra-doc-files: CHANGELOG.md + +library + exposed-modules: MyLib + build-depends: base ^>=4.14.1.0 + hs-source-dirs: src + default-language: Haskell2010 + +executable tem + main-is: Main.hs + build-depends: + base ^>=4.14.1.0, + tem + + hs-source-dirs: app + default-language: Haskell2010 + +test-suite tem-test + default-language: Haskell2010 + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: + base ^>=4.14.1.0, + tem + diff --git a/cabal-install/tem/test.save0/Main.hs b/cabal-install/tem/test.save0/Main.hs new file mode 100644 index 00000000000..3e2059e31f5 --- /dev/null +++ b/cabal-install/tem/test.save0/Main.hs @@ -0,0 +1,4 @@ +module Main (main) where + +main :: IO () +main = putStrLn "Test suite not yet implemented." diff --git a/cabal-install/tem/test/Main.hs b/cabal-install/tem/test/Main.hs new file mode 100644 index 00000000000..3e2059e31f5 --- /dev/null +++ b/cabal-install/tem/test/Main.hs @@ -0,0 +1,4 @@ +module Main (main) where + +main :: IO () +main = putStrLn "Test suite not yet implemented." diff --git a/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden new file mode 100644 index 00000000000..97d868a683d --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden @@ -0,0 +1,64 @@ +cabal-version: 3.0 +name: y +version: 0.1.0.0 +synopsis: synopsis + +-- A longer description of the package. +-- description: +homepage: home +license: BSD-3-Clause +license-file: LICENSE +author: foo-kmett +maintainer: foo-kmett@kmett.kmett + +-- A copyright notice. +-- copyright: +category: Data +build-type: Simple +extra-doc-files: CHANGELOG.md + +-- Extra source files to be distributed with the package, such as examples, or a tutorial module. +-- extra-source-files: + +library + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: base + hs-source-dirs: src + default-language: Haskell98 + +executable y + main-is: Main.hs + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: + base, + y + + hs-source-dirs: exe + default-language: Haskell2010 + +test-suite y-test + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: + base, + y + diff --git a/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden new file mode 100644 index 00000000000..799d0fa9573 --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden @@ -0,0 +1,114 @@ +cabal-version: 3.0 + +-- Initial package description 'y' generated by +-- 'cabal init'. For further documentation, see: +-- http://haskell.org/cabal/users-guide/ +-- +-- The name of the package. +name: y + +-- The package version. +-- See the Haskell package versioning policy (PVP) for standards +-- guiding when and how versions should be incremented. +-- https://pvp.haskell.org +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 0.1.0.0 + +-- A short (one-line) description of the package. +synopsis: synopsis + +-- A longer description of the package. +-- description: + +-- URL for the project homepage or repository. +homepage: home + +-- The license under which the package is released. +license: BSD-3-Clause + +-- The file containing the license text. +license-file: LICENSE + +-- The package author(s). +author: foo-kmett + +-- An email address to which users can send suggestions, bug reports, and patches. +maintainer: foo-kmett@kmett.kmett + +-- A copyright notice. +-- copyright: +category: Data +build-type: Simple + +-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. +extra-doc-files: CHANGELOG.md + +-- Extra source files to be distributed with the package, such as examples, or a tutorial module. +-- extra-source-files: + +library + -- Modules exported by the library. + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: base + + -- Directories containing source files. + hs-source-dirs: src + + -- Base language which the package is written in. + default-language: Haskell98 + +executable y + -- .hs or .lhs file containing the Main module. + main-is: Main.hs + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: + base, + y + + -- Directories containing source files. + hs-source-dirs: exe + + -- Base language which the package is written in. + default-language: Haskell2010 + +test-suite y-test + -- Base language which the package is written in. + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- The interface type and version of the test suite. + type: exitcode-stdio-1.0 + + -- Directories containing source files. + hs-source-dirs: test + + -- The entrypoint to the test suite. + main-is: Main.hs + + -- Test dependencies. + build-depends: + base, + y + diff --git a/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden new file mode 100644 index 00000000000..c903411c9ca --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden @@ -0,0 +1,49 @@ +cabal-version: 3.0 +name: y +version: 0.1.0.0 +synopsis: synopsis + +-- A longer description of the package. +-- description: +homepage: home +license: BSD-3-Clause +license-file: LICENSE +author: foo-kmett +maintainer: foo-kmett@kmett.kmett + +-- A copyright notice. +-- copyright: +category: Data +build-type: Simple +extra-doc-files: CHANGELOG.md + +-- Extra source files to be distributed with the package, such as examples, or a tutorial module. +-- extra-source-files: + +library + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: base + hs-source-dirs: src + default-language: Haskell98 + +test-suite y-test + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: + base, + y + diff --git a/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden new file mode 100644 index 00000000000..f6cc2ada1bd --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden @@ -0,0 +1,93 @@ +cabal-version: 3.0 + +-- Initial package description 'y' generated by +-- 'cabal init'. For further documentation, see: +-- http://haskell.org/cabal/users-guide/ +-- +-- The name of the package. +name: y + +-- The package version. +-- See the Haskell package versioning policy (PVP) for standards +-- guiding when and how versions should be incremented. +-- https://pvp.haskell.org +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 0.1.0.0 + +-- A short (one-line) description of the package. +synopsis: synopsis + +-- A longer description of the package. +-- description: + +-- URL for the project homepage or repository. +homepage: home + +-- The license under which the package is released. +license: BSD-3-Clause + +-- The file containing the license text. +license-file: LICENSE + +-- The package author(s). +author: foo-kmett + +-- An email address to which users can send suggestions, bug reports, and patches. +maintainer: foo-kmett@kmett.kmett + +-- A copyright notice. +-- copyright: +category: Data +build-type: Simple + +-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. +extra-doc-files: CHANGELOG.md + +-- Extra source files to be distributed with the package, such as examples, or a tutorial module. +-- extra-source-files: + +library + -- Modules exported by the library. + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: base + + -- Directories containing source files. + hs-source-dirs: src + + -- Base language which the package is written in. + default-language: Haskell98 + +test-suite y-test + -- Base language which the package is written in. + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- The interface type and version of the test suite. + type: exitcode-stdio-1.0 + + -- Directories containing source files. + hs-source-dirs: test + + -- The entrypoint to the test suite. + main-is: Main.hs + + -- Test dependencies. + build-depends: + base, + y + diff --git a/cabal-install/tem/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden new file mode 100644 index 00000000000..a256fb30604 --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden @@ -0,0 +1,21 @@ +executable y + -- .hs or .lhs file containing the Main module. + main-is: Main.hs + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: base + + -- Directories containing source files. + hs-source-dirs: exe + + -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. + build-tool-depends: happy + + -- Base language which the package is written in. + default-language: Haskell2010 diff --git a/cabal-install/tem/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden new file mode 100644 index 00000000000..88d69ab18db --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden @@ -0,0 +1,5 @@ +executable y + main-is: Main.hs + build-depends: base + hs-source-dirs: exe + default-language: Haskell2010 diff --git a/cabal-install/tem/tests/fixtures/init/golden/exe/exe-simple-minimal-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/exe/exe-simple-minimal-with-comments.golden new file mode 100644 index 00000000000..88d69ab18db --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/exe/exe-simple-minimal-with-comments.golden @@ -0,0 +1,5 @@ +executable y + main-is: Main.hs + build-depends: base + hs-source-dirs: exe + default-language: Haskell2010 diff --git a/cabal-install/tem/tests/fixtures/init/golden/exe/exe-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/exe/exe-with-comments.golden new file mode 100644 index 00000000000..deb7bb063da --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/exe/exe-with-comments.golden @@ -0,0 +1,18 @@ +executable y + -- .hs or .lhs file containing the Main module. + main-is: Main.hs + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: base + + -- Directories containing source files. + hs-source-dirs: exe + + -- Base language which the package is written in. + default-language: Haskell2010 diff --git a/cabal-install/tem/tests/fixtures/init/golden/exe/exe.golden b/cabal-install/tem/tests/fixtures/init/golden/exe/exe.golden new file mode 100644 index 00000000000..3f4d9c54fe6 --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/exe/exe.golden @@ -0,0 +1,11 @@ +executable y + main-is: Main.hs + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: base + hs-source-dirs: exe + default-language: Haskell2010 diff --git a/cabal-install/tem/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden new file mode 100644 index 00000000000..a828e09ebc2 --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden @@ -0,0 +1,21 @@ +library + -- Modules exported by the library. + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: base + + -- Directories containing source files. + hs-source-dirs: src + + -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. + build-tool-depends: happy + + -- Base language which the package is written in. + default-language: Haskell98 diff --git a/cabal-install/tem/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden new file mode 100644 index 00000000000..99e5d7fffb8 --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden @@ -0,0 +1,5 @@ +library + exposed-modules: MyLib + build-depends: base + hs-source-dirs: src + default-language: Haskell98 diff --git a/cabal-install/tem/tests/fixtures/init/golden/lib/lib-simple-minimal-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/lib/lib-simple-minimal-with-comments.golden new file mode 100644 index 00000000000..99e5d7fffb8 --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/lib/lib-simple-minimal-with-comments.golden @@ -0,0 +1,5 @@ +library + exposed-modules: MyLib + build-depends: base + hs-source-dirs: src + default-language: Haskell98 diff --git a/cabal-install/tem/tests/fixtures/init/golden/lib/lib-simple.golden b/cabal-install/tem/tests/fixtures/init/golden/lib/lib-simple.golden new file mode 100644 index 00000000000..8dd9dbcecbd --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/lib/lib-simple.golden @@ -0,0 +1,11 @@ +library + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: base + hs-source-dirs: src + default-language: Haskell98 diff --git a/cabal-install/tem/tests/fixtures/init/golden/lib/lib-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/lib/lib-with-comments.golden new file mode 100644 index 00000000000..d64fb60b613 --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/lib/lib-with-comments.golden @@ -0,0 +1,18 @@ +library + -- Modules exported by the library. + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- Other library packages from which modules are imported. + build-depends: base + + -- Directories containing source files. + hs-source-dirs: src + + -- Base language which the package is written in. + default-language: Haskell98 diff --git a/cabal-install/tem/tests/fixtures/init/golden/lib/lib.golden b/cabal-install/tem/tests/fixtures/init/golden/lib/lib.golden new file mode 100644 index 00000000000..8dd9dbcecbd --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/lib/lib.golden @@ -0,0 +1,11 @@ +library + exposed-modules: MyLib + + -- Modules included in this library but not exported. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + build-depends: base + hs-source-dirs: src + default-language: Haskell98 diff --git a/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden b/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden new file mode 100644 index 00000000000..799181abd6d --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden @@ -0,0 +1,48 @@ +cabal-version: 2.0 + +-- Initial package description 'y' generated by +-- 'cabal init'. For further documentation, see: +-- http://haskell.org/cabal/users-guide/ +-- +-- The name of the package. +name: QuxPackage + +-- The package version. +-- See the Haskell package versioning policy (PVP) for standards +-- guiding when and how versions should be incremented. +-- https://pvp.haskell.org +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 4.2.6 + +-- A short (one-line) description of the package. +synopsis: We are Qux, and this is our package + +-- A longer description of the package. +-- description: + +-- URL for the project homepage or repository. +homepage: qux.com + +-- The license under which the package is released. +license: MIT + +-- The file containing the license text. +license-file: LICENSE + +-- The package author(s). +author: Foobar + +-- An email address to which users can send suggestions, bug reports, and patches. +maintainer: foobar@qux.com + +-- A copyright notice. +-- copyright: +category: Control + +-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. +extra-doc-files: CHANGELOG.md + +-- Extra source files to be distributed with the package, such as examples, or a tutorial module. +-- extra-source-files: diff --git a/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden new file mode 100644 index 00000000000..45630780ea4 --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden @@ -0,0 +1,49 @@ +cabal-version: 3.0 + +-- Initial package description 'y' generated by +-- 'cabal init'. For further documentation, see: +-- http://haskell.org/cabal/users-guide/ +-- +-- The name of the package. +name: y + +-- The package version. +-- See the Haskell package versioning policy (PVP) for standards +-- guiding when and how versions should be incremented. +-- https://pvp.haskell.org +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 0.1.0.0 + +-- A short (one-line) description of the package. +synopsis: synopsis + +-- A longer description of the package. +-- description: + +-- URL for the project homepage or repository. +homepage: home + +-- The license under which the package is released. +license: BSD-3-Clause + +-- The file containing the license text. +license-file: LICENSE + +-- The package author(s). +author: foo-kmett + +-- An email address to which users can send suggestions, bug reports, and patches. +maintainer: foo-kmett@kmett.kmett + +-- A copyright notice. +-- copyright: +category: Data +build-type: Simple + +-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. +extra-doc-files: CHANGELOG.md + +-- Extra source files to be distributed with the package, such as examples, or a tutorial module. +-- extra-source-files: diff --git a/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden b/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden new file mode 100644 index 00000000000..643d538c8e8 --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden @@ -0,0 +1,49 @@ +cabal-version: 2.2 + +-- Initial package description 'y' generated by +-- 'cabal init'. For further documentation, see: +-- http://haskell.org/cabal/users-guide/ +-- +-- The name of the package. +name: QuxPackage + +-- The package version. +-- See the Haskell package versioning policy (PVP) for standards +-- guiding when and how versions should be incremented. +-- https://pvp.haskell.org +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 4.2.6 + +-- A short (one-line) description of the package. +synopsis: We are Qux, and this is our package + +-- A longer description of the package. +-- description: + +-- URL for the project homepage or repository. +homepage: qux.com + +-- The license under which the package is released. +license: MIT + +-- The file containing the license text. +license-file: LICENSE + +-- The package author(s). +author: Foobar + +-- An email address to which users can send suggestions, bug reports, and patches. +maintainer: foobar@qux.com + +-- A copyright notice. +-- copyright: +category: Control +build-type: Simple + +-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. +extra-doc-files: CHANGELOG.md + +-- Extra source files to be distributed with the package, such as examples, or a tutorial module. +-- extra-source-files: diff --git a/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg.golden b/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg.golden new file mode 100644 index 00000000000..45630780ea4 --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg.golden @@ -0,0 +1,49 @@ +cabal-version: 3.0 + +-- Initial package description 'y' generated by +-- 'cabal init'. For further documentation, see: +-- http://haskell.org/cabal/users-guide/ +-- +-- The name of the package. +name: y + +-- The package version. +-- See the Haskell package versioning policy (PVP) for standards +-- guiding when and how versions should be incremented. +-- https://pvp.haskell.org +-- PVP summary: +-+------- breaking API changes +-- | | +----- non-breaking API additions +-- | | | +--- code changes with no API change +version: 0.1.0.0 + +-- A short (one-line) description of the package. +synopsis: synopsis + +-- A longer description of the package. +-- description: + +-- URL for the project homepage or repository. +homepage: home + +-- The license under which the package is released. +license: BSD-3-Clause + +-- The file containing the license text. +license-file: LICENSE + +-- The package author(s). +author: foo-kmett + +-- An email address to which users can send suggestions, bug reports, and patches. +maintainer: foo-kmett@kmett.kmett + +-- A copyright notice. +-- copyright: +category: Data +build-type: Simple + +-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. +extra-doc-files: CHANGELOG.md + +-- Extra source files to be distributed with the package, such as examples, or a tutorial module. +-- extra-source-files: diff --git a/cabal-install/tem/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden new file mode 100644 index 00000000000..f3cbb8ade97 --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden @@ -0,0 +1,24 @@ +test-suite y-test + -- Base language which the package is written in. + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- The interface type and version of the test suite. + type: exitcode-stdio-1.0 + + -- Directories containing source files. + hs-source-dirs: test + + -- The entrypoint to the test suite. + main-is: Main.hs + + -- Test dependencies. + build-depends: base + + -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. + build-tool-depends: happy diff --git a/cabal-install/tem/tests/fixtures/init/golden/test/test-minimal-no-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/test/test-minimal-no-comments.golden new file mode 100644 index 00000000000..b092956a6d2 --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/test/test-minimal-no-comments.golden @@ -0,0 +1,6 @@ +test-suite y-test + default-language: Haskell2010 + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: base diff --git a/cabal-install/tem/tests/fixtures/init/golden/test/test-simple-minimal-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/test/test-simple-minimal-with-comments.golden new file mode 100644 index 00000000000..b092956a6d2 --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/test/test-simple-minimal-with-comments.golden @@ -0,0 +1,6 @@ +test-suite y-test + default-language: Haskell2010 + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: base diff --git a/cabal-install/tem/tests/fixtures/init/golden/test/test-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/test/test-with-comments.golden new file mode 100644 index 00000000000..2381ebd092e --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/test/test-with-comments.golden @@ -0,0 +1,21 @@ +test-suite y-test + -- Base language which the package is written in. + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + + -- The interface type and version of the test suite. + type: exitcode-stdio-1.0 + + -- Directories containing source files. + hs-source-dirs: test + + -- The entrypoint to the test suite. + main-is: Main.hs + + -- Test dependencies. + build-depends: base diff --git a/cabal-install/tem/tests/fixtures/init/golden/test/test.golden b/cabal-install/tem/tests/fixtures/init/golden/test/test.golden new file mode 100644 index 00000000000..7a36e096fb2 --- /dev/null +++ b/cabal-install/tem/tests/fixtures/init/golden/test/test.golden @@ -0,0 +1,12 @@ +test-suite y-test + default-language: Haskell2010 + + -- Modules included in this executable, other than Main. + -- other-modules: + + -- LANGUAGE extensions used by modules in this package. + -- other-extensions: + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: base From 76468fbedbbc92e613fceaf43057de24caeebc1a Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Mon, 17 May 2021 10:25:36 -0400 Subject: [PATCH 36/37] remove tem dir --- cabal-install/tem/CHANGELOG.md | 5 - cabal-install/tem/CHANGELOG.md.save0 | 5 - cabal-install/tem/LICENSE | 202 ------------------ cabal-install/tem/LICENSE.save0 | 202 ------------------ cabal-install/tem/app.save0/Main.hs | 8 - cabal-install/tem/app/Main.hs | 8 - cabal-install/tem/src.save0/MyLib.hs | 4 - cabal-install/tem/src/MyLib.hs | 4 - cabal-install/tem/tem.cabal | 32 --- cabal-install/tem/tem.cabal.save0 | 33 --- cabal-install/tem/test.save0/Main.hs | 4 - cabal-install/tem/test/Main.hs | 4 - .../cabal-lib-and-exe-no-comments.golden | 64 ------ .../cabal-lib-and-exe-with-comments.golden | 114 ---------- .../golden/cabal/cabal-lib-no-comments.golden | 49 ----- .../cabal/cabal-lib-with-comments.golden | 93 -------- .../exe/exe-build-tools-with-comments.golden | 21 -- .../golden/exe/exe-minimal-no-comments.golden | 5 - .../exe-simple-minimal-with-comments.golden | 5 - .../init/golden/exe/exe-with-comments.golden | 18 -- .../tests/fixtures/init/golden/exe/exe.golden | 11 - .../lib/lib-build-tools-with-comments.golden | 21 -- .../golden/lib/lib-minimal-no-comments.golden | 5 - .../lib-simple-minimal-with-comments.golden | 5 - .../init/golden/lib/lib-simple.golden | 11 - .../init/golden/lib/lib-with-comments.golden | 18 -- .../tests/fixtures/init/golden/lib/lib.golden | 11 - .../pkg-desc/pkg-old-cabal-with-flags.golden | 48 ----- .../golden/pkg-desc/pkg-with-comments.golden | 49 ----- .../golden/pkg-desc/pkg-with-flags.golden | 49 ----- .../fixtures/init/golden/pkg-desc/pkg.golden | 49 ----- .../test-build-tools-with-comments.golden | 24 --- .../test/test-minimal-no-comments.golden | 6 - .../test-simple-minimal-with-comments.golden | 6 - .../golden/test/test-with-comments.golden | 21 -- .../fixtures/init/golden/test/test.golden | 12 -- 36 files changed, 1226 deletions(-) delete mode 100644 cabal-install/tem/CHANGELOG.md delete mode 100644 cabal-install/tem/CHANGELOG.md.save0 delete mode 100644 cabal-install/tem/LICENSE delete mode 100644 cabal-install/tem/LICENSE.save0 delete mode 100644 cabal-install/tem/app.save0/Main.hs delete mode 100644 cabal-install/tem/app/Main.hs delete mode 100644 cabal-install/tem/src.save0/MyLib.hs delete mode 100644 cabal-install/tem/src/MyLib.hs delete mode 100644 cabal-install/tem/tem.cabal delete mode 100644 cabal-install/tem/tem.cabal.save0 delete mode 100644 cabal-install/tem/test.save0/Main.hs delete mode 100644 cabal-install/tem/test/Main.hs delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/exe/exe-simple-minimal-with-comments.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/exe/exe-with-comments.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/exe/exe.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/lib/lib-simple-minimal-with-comments.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/lib/lib-simple.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/lib/lib-with-comments.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/lib/lib.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/test/test-minimal-no-comments.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/test/test-simple-minimal-with-comments.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/test/test-with-comments.golden delete mode 100644 cabal-install/tem/tests/fixtures/init/golden/test/test.golden diff --git a/cabal-install/tem/CHANGELOG.md b/cabal-install/tem/CHANGELOG.md deleted file mode 100644 index 679b6b324d8..00000000000 --- a/cabal-install/tem/CHANGELOG.md +++ /dev/null @@ -1,5 +0,0 @@ -# Revision history for tem - -## 0.1.0.0 -- YYYY-mm-dd - -* First version. Released on an unsuspecting world. diff --git a/cabal-install/tem/CHANGELOG.md.save0 b/cabal-install/tem/CHANGELOG.md.save0 deleted file mode 100644 index 679b6b324d8..00000000000 --- a/cabal-install/tem/CHANGELOG.md.save0 +++ /dev/null @@ -1,5 +0,0 @@ -# Revision history for tem - -## 0.1.0.0 -- YYYY-mm-dd - -* First version. Released on an unsuspecting world. diff --git a/cabal-install/tem/LICENSE b/cabal-install/tem/LICENSE deleted file mode 100644 index d6456956733..00000000000 --- a/cabal-install/tem/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/cabal-install/tem/LICENSE.save0 b/cabal-install/tem/LICENSE.save0 deleted file mode 100644 index d6456956733..00000000000 --- a/cabal-install/tem/LICENSE.save0 +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/cabal-install/tem/app.save0/Main.hs b/cabal-install/tem/app.save0/Main.hs deleted file mode 100644 index 60d904e8c1c..00000000000 --- a/cabal-install/tem/app.save0/Main.hs +++ /dev/null @@ -1,8 +0,0 @@ -module Main where - -import qualified MyLib (someFunc) - -main :: IO () -main = do - putStrLn "Hello, Haskell!" - MyLib.someFunc diff --git a/cabal-install/tem/app/Main.hs b/cabal-install/tem/app/Main.hs deleted file mode 100644 index 60d904e8c1c..00000000000 --- a/cabal-install/tem/app/Main.hs +++ /dev/null @@ -1,8 +0,0 @@ -module Main where - -import qualified MyLib (someFunc) - -main :: IO () -main = do - putStrLn "Hello, Haskell!" - MyLib.someFunc diff --git a/cabal-install/tem/src.save0/MyLib.hs b/cabal-install/tem/src.save0/MyLib.hs deleted file mode 100644 index e657c4403f6..00000000000 --- a/cabal-install/tem/src.save0/MyLib.hs +++ /dev/null @@ -1,4 +0,0 @@ -module MyLib (someFunc) where - -someFunc :: IO () -someFunc = putStrLn "someFunc" diff --git a/cabal-install/tem/src/MyLib.hs b/cabal-install/tem/src/MyLib.hs deleted file mode 100644 index e657c4403f6..00000000000 --- a/cabal-install/tem/src/MyLib.hs +++ /dev/null @@ -1,4 +0,0 @@ -module MyLib (someFunc) where - -someFunc :: IO () -someFunc = putStrLn "someFunc" diff --git a/cabal-install/tem/tem.cabal b/cabal-install/tem/tem.cabal deleted file mode 100644 index 2c097484516..00000000000 --- a/cabal-install/tem/tem.cabal +++ /dev/null @@ -1,32 +0,0 @@ -cabal-version: 3.0 -name: tem -version: 0.1.0.0 -license: Apache-2.0 -license-file: LICENSE -build-type: Simple -extra-doc-files: CHANGELOG.md - -library - exposed-modules: MyLib - build-depends: base ^>=4.14.1.0 - hs-source-dirs: src - default-language: Haskell2010 - -executable tem - main-is: Main.hs - build-depends: - base ^>=4.14.1.0, - tem - - hs-source-dirs: app - default-language: Haskell2010 - -test-suite tem-test - default-language: Haskell2010 - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: Main.hs - build-depends: - base ^>=4.14.1.0, - tem - diff --git a/cabal-install/tem/tem.cabal.save0 b/cabal-install/tem/tem.cabal.save0 deleted file mode 100644 index e4718176e8a..00000000000 --- a/cabal-install/tem/tem.cabal.save0 +++ /dev/null @@ -1,33 +0,0 @@ -cabal-version: 3.0 -name: tem -version: 0.1.0.0 -license: Apache-2.0 -license-file: LICENSE -category: Data -build-type: Simple -extra-doc-files: CHANGELOG.md - -library - exposed-modules: MyLib - build-depends: base ^>=4.14.1.0 - hs-source-dirs: src - default-language: Haskell2010 - -executable tem - main-is: Main.hs - build-depends: - base ^>=4.14.1.0, - tem - - hs-source-dirs: app - default-language: Haskell2010 - -test-suite tem-test - default-language: Haskell2010 - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: Main.hs - build-depends: - base ^>=4.14.1.0, - tem - diff --git a/cabal-install/tem/test.save0/Main.hs b/cabal-install/tem/test.save0/Main.hs deleted file mode 100644 index 3e2059e31f5..00000000000 --- a/cabal-install/tem/test.save0/Main.hs +++ /dev/null @@ -1,4 +0,0 @@ -module Main (main) where - -main :: IO () -main = putStrLn "Test suite not yet implemented." diff --git a/cabal-install/tem/test/Main.hs b/cabal-install/tem/test/Main.hs deleted file mode 100644 index 3e2059e31f5..00000000000 --- a/cabal-install/tem/test/Main.hs +++ /dev/null @@ -1,4 +0,0 @@ -module Main (main) where - -main :: IO () -main = putStrLn "Test suite not yet implemented." diff --git a/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden deleted file mode 100644 index 97d868a683d..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden +++ /dev/null @@ -1,64 +0,0 @@ -cabal-version: 3.0 -name: y -version: 0.1.0.0 -synopsis: synopsis - --- A longer description of the package. --- description: -homepage: home -license: BSD-3-Clause -license-file: LICENSE -author: foo-kmett -maintainer: foo-kmett@kmett.kmett - --- A copyright notice. --- copyright: -category: Data -build-type: Simple -extra-doc-files: CHANGELOG.md - --- Extra source files to be distributed with the package, such as examples, or a tutorial module. --- extra-source-files: - -library - exposed-modules: MyLib - - -- Modules included in this library but not exported. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - build-depends: base - hs-source-dirs: src - default-language: Haskell98 - -executable y - main-is: Main.hs - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - build-depends: - base, - y - - hs-source-dirs: exe - default-language: Haskell2010 - -test-suite y-test - default-language: Haskell2010 - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: Main.hs - build-depends: - base, - y - diff --git a/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden deleted file mode 100644 index 799d0fa9573..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden +++ /dev/null @@ -1,114 +0,0 @@ -cabal-version: 3.0 - --- Initial package description 'y' generated by --- 'cabal init'. For further documentation, see: --- http://haskell.org/cabal/users-guide/ --- --- The name of the package. -name: y - --- The package version. --- See the Haskell package versioning policy (PVP) for standards --- guiding when and how versions should be incremented. --- https://pvp.haskell.org --- PVP summary: +-+------- breaking API changes --- | | +----- non-breaking API additions --- | | | +--- code changes with no API change -version: 0.1.0.0 - --- A short (one-line) description of the package. -synopsis: synopsis - --- A longer description of the package. --- description: - --- URL for the project homepage or repository. -homepage: home - --- The license under which the package is released. -license: BSD-3-Clause - --- The file containing the license text. -license-file: LICENSE - --- The package author(s). -author: foo-kmett - --- An email address to which users can send suggestions, bug reports, and patches. -maintainer: foo-kmett@kmett.kmett - --- A copyright notice. --- copyright: -category: Data -build-type: Simple - --- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. -extra-doc-files: CHANGELOG.md - --- Extra source files to be distributed with the package, such as examples, or a tutorial module. --- extra-source-files: - -library - -- Modules exported by the library. - exposed-modules: MyLib - - -- Modules included in this library but not exported. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- Other library packages from which modules are imported. - build-depends: base - - -- Directories containing source files. - hs-source-dirs: src - - -- Base language which the package is written in. - default-language: Haskell98 - -executable y - -- .hs or .lhs file containing the Main module. - main-is: Main.hs - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- Other library packages from which modules are imported. - build-depends: - base, - y - - -- Directories containing source files. - hs-source-dirs: exe - - -- Base language which the package is written in. - default-language: Haskell2010 - -test-suite y-test - -- Base language which the package is written in. - default-language: Haskell2010 - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- The interface type and version of the test suite. - type: exitcode-stdio-1.0 - - -- Directories containing source files. - hs-source-dirs: test - - -- The entrypoint to the test suite. - main-is: Main.hs - - -- Test dependencies. - build-depends: - base, - y - diff --git a/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden deleted file mode 100644 index c903411c9ca..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden +++ /dev/null @@ -1,49 +0,0 @@ -cabal-version: 3.0 -name: y -version: 0.1.0.0 -synopsis: synopsis - --- A longer description of the package. --- description: -homepage: home -license: BSD-3-Clause -license-file: LICENSE -author: foo-kmett -maintainer: foo-kmett@kmett.kmett - --- A copyright notice. --- copyright: -category: Data -build-type: Simple -extra-doc-files: CHANGELOG.md - --- Extra source files to be distributed with the package, such as examples, or a tutorial module. --- extra-source-files: - -library - exposed-modules: MyLib - - -- Modules included in this library but not exported. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - build-depends: base - hs-source-dirs: src - default-language: Haskell98 - -test-suite y-test - default-language: Haskell2010 - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: Main.hs - build-depends: - base, - y - diff --git a/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden deleted file mode 100644 index f6cc2ada1bd..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden +++ /dev/null @@ -1,93 +0,0 @@ -cabal-version: 3.0 - --- Initial package description 'y' generated by --- 'cabal init'. For further documentation, see: --- http://haskell.org/cabal/users-guide/ --- --- The name of the package. -name: y - --- The package version. --- See the Haskell package versioning policy (PVP) for standards --- guiding when and how versions should be incremented. --- https://pvp.haskell.org --- PVP summary: +-+------- breaking API changes --- | | +----- non-breaking API additions --- | | | +--- code changes with no API change -version: 0.1.0.0 - --- A short (one-line) description of the package. -synopsis: synopsis - --- A longer description of the package. --- description: - --- URL for the project homepage or repository. -homepage: home - --- The license under which the package is released. -license: BSD-3-Clause - --- The file containing the license text. -license-file: LICENSE - --- The package author(s). -author: foo-kmett - --- An email address to which users can send suggestions, bug reports, and patches. -maintainer: foo-kmett@kmett.kmett - --- A copyright notice. --- copyright: -category: Data -build-type: Simple - --- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. -extra-doc-files: CHANGELOG.md - --- Extra source files to be distributed with the package, such as examples, or a tutorial module. --- extra-source-files: - -library - -- Modules exported by the library. - exposed-modules: MyLib - - -- Modules included in this library but not exported. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- Other library packages from which modules are imported. - build-depends: base - - -- Directories containing source files. - hs-source-dirs: src - - -- Base language which the package is written in. - default-language: Haskell98 - -test-suite y-test - -- Base language which the package is written in. - default-language: Haskell2010 - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- The interface type and version of the test suite. - type: exitcode-stdio-1.0 - - -- Directories containing source files. - hs-source-dirs: test - - -- The entrypoint to the test suite. - main-is: Main.hs - - -- Test dependencies. - build-depends: - base, - y - diff --git a/cabal-install/tem/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden deleted file mode 100644 index a256fb30604..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden +++ /dev/null @@ -1,21 +0,0 @@ -executable y - -- .hs or .lhs file containing the Main module. - main-is: Main.hs - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- Other library packages from which modules are imported. - build-depends: base - - -- Directories containing source files. - hs-source-dirs: exe - - -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. - build-tool-depends: happy - - -- Base language which the package is written in. - default-language: Haskell2010 diff --git a/cabal-install/tem/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden deleted file mode 100644 index 88d69ab18db..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden +++ /dev/null @@ -1,5 +0,0 @@ -executable y - main-is: Main.hs - build-depends: base - hs-source-dirs: exe - default-language: Haskell2010 diff --git a/cabal-install/tem/tests/fixtures/init/golden/exe/exe-simple-minimal-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/exe/exe-simple-minimal-with-comments.golden deleted file mode 100644 index 88d69ab18db..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/exe/exe-simple-minimal-with-comments.golden +++ /dev/null @@ -1,5 +0,0 @@ -executable y - main-is: Main.hs - build-depends: base - hs-source-dirs: exe - default-language: Haskell2010 diff --git a/cabal-install/tem/tests/fixtures/init/golden/exe/exe-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/exe/exe-with-comments.golden deleted file mode 100644 index deb7bb063da..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/exe/exe-with-comments.golden +++ /dev/null @@ -1,18 +0,0 @@ -executable y - -- .hs or .lhs file containing the Main module. - main-is: Main.hs - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- Other library packages from which modules are imported. - build-depends: base - - -- Directories containing source files. - hs-source-dirs: exe - - -- Base language which the package is written in. - default-language: Haskell2010 diff --git a/cabal-install/tem/tests/fixtures/init/golden/exe/exe.golden b/cabal-install/tem/tests/fixtures/init/golden/exe/exe.golden deleted file mode 100644 index 3f4d9c54fe6..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/exe/exe.golden +++ /dev/null @@ -1,11 +0,0 @@ -executable y - main-is: Main.hs - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - build-depends: base - hs-source-dirs: exe - default-language: Haskell2010 diff --git a/cabal-install/tem/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden deleted file mode 100644 index a828e09ebc2..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden +++ /dev/null @@ -1,21 +0,0 @@ -library - -- Modules exported by the library. - exposed-modules: MyLib - - -- Modules included in this library but not exported. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- Other library packages from which modules are imported. - build-depends: base - - -- Directories containing source files. - hs-source-dirs: src - - -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. - build-tool-depends: happy - - -- Base language which the package is written in. - default-language: Haskell98 diff --git a/cabal-install/tem/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden deleted file mode 100644 index 99e5d7fffb8..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden +++ /dev/null @@ -1,5 +0,0 @@ -library - exposed-modules: MyLib - build-depends: base - hs-source-dirs: src - default-language: Haskell98 diff --git a/cabal-install/tem/tests/fixtures/init/golden/lib/lib-simple-minimal-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/lib/lib-simple-minimal-with-comments.golden deleted file mode 100644 index 99e5d7fffb8..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/lib/lib-simple-minimal-with-comments.golden +++ /dev/null @@ -1,5 +0,0 @@ -library - exposed-modules: MyLib - build-depends: base - hs-source-dirs: src - default-language: Haskell98 diff --git a/cabal-install/tem/tests/fixtures/init/golden/lib/lib-simple.golden b/cabal-install/tem/tests/fixtures/init/golden/lib/lib-simple.golden deleted file mode 100644 index 8dd9dbcecbd..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/lib/lib-simple.golden +++ /dev/null @@ -1,11 +0,0 @@ -library - exposed-modules: MyLib - - -- Modules included in this library but not exported. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - build-depends: base - hs-source-dirs: src - default-language: Haskell98 diff --git a/cabal-install/tem/tests/fixtures/init/golden/lib/lib-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/lib/lib-with-comments.golden deleted file mode 100644 index d64fb60b613..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/lib/lib-with-comments.golden +++ /dev/null @@ -1,18 +0,0 @@ -library - -- Modules exported by the library. - exposed-modules: MyLib - - -- Modules included in this library but not exported. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- Other library packages from which modules are imported. - build-depends: base - - -- Directories containing source files. - hs-source-dirs: src - - -- Base language which the package is written in. - default-language: Haskell98 diff --git a/cabal-install/tem/tests/fixtures/init/golden/lib/lib.golden b/cabal-install/tem/tests/fixtures/init/golden/lib/lib.golden deleted file mode 100644 index 8dd9dbcecbd..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/lib/lib.golden +++ /dev/null @@ -1,11 +0,0 @@ -library - exposed-modules: MyLib - - -- Modules included in this library but not exported. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - build-depends: base - hs-source-dirs: src - default-language: Haskell98 diff --git a/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden b/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden deleted file mode 100644 index 799181abd6d..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden +++ /dev/null @@ -1,48 +0,0 @@ -cabal-version: 2.0 - --- Initial package description 'y' generated by --- 'cabal init'. For further documentation, see: --- http://haskell.org/cabal/users-guide/ --- --- The name of the package. -name: QuxPackage - --- The package version. --- See the Haskell package versioning policy (PVP) for standards --- guiding when and how versions should be incremented. --- https://pvp.haskell.org --- PVP summary: +-+------- breaking API changes --- | | +----- non-breaking API additions --- | | | +--- code changes with no API change -version: 4.2.6 - --- A short (one-line) description of the package. -synopsis: We are Qux, and this is our package - --- A longer description of the package. --- description: - --- URL for the project homepage or repository. -homepage: qux.com - --- The license under which the package is released. -license: MIT - --- The file containing the license text. -license-file: LICENSE - --- The package author(s). -author: Foobar - --- An email address to which users can send suggestions, bug reports, and patches. -maintainer: foobar@qux.com - --- A copyright notice. --- copyright: -category: Control - --- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. -extra-doc-files: CHANGELOG.md - --- Extra source files to be distributed with the package, such as examples, or a tutorial module. --- extra-source-files: diff --git a/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden deleted file mode 100644 index 45630780ea4..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden +++ /dev/null @@ -1,49 +0,0 @@ -cabal-version: 3.0 - --- Initial package description 'y' generated by --- 'cabal init'. For further documentation, see: --- http://haskell.org/cabal/users-guide/ --- --- The name of the package. -name: y - --- The package version. --- See the Haskell package versioning policy (PVP) for standards --- guiding when and how versions should be incremented. --- https://pvp.haskell.org --- PVP summary: +-+------- breaking API changes --- | | +----- non-breaking API additions --- | | | +--- code changes with no API change -version: 0.1.0.0 - --- A short (one-line) description of the package. -synopsis: synopsis - --- A longer description of the package. --- description: - --- URL for the project homepage or repository. -homepage: home - --- The license under which the package is released. -license: BSD-3-Clause - --- The file containing the license text. -license-file: LICENSE - --- The package author(s). -author: foo-kmett - --- An email address to which users can send suggestions, bug reports, and patches. -maintainer: foo-kmett@kmett.kmett - --- A copyright notice. --- copyright: -category: Data -build-type: Simple - --- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. -extra-doc-files: CHANGELOG.md - --- Extra source files to be distributed with the package, such as examples, or a tutorial module. --- extra-source-files: diff --git a/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden b/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden deleted file mode 100644 index 643d538c8e8..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden +++ /dev/null @@ -1,49 +0,0 @@ -cabal-version: 2.2 - --- Initial package description 'y' generated by --- 'cabal init'. For further documentation, see: --- http://haskell.org/cabal/users-guide/ --- --- The name of the package. -name: QuxPackage - --- The package version. --- See the Haskell package versioning policy (PVP) for standards --- guiding when and how versions should be incremented. --- https://pvp.haskell.org --- PVP summary: +-+------- breaking API changes --- | | +----- non-breaking API additions --- | | | +--- code changes with no API change -version: 4.2.6 - --- A short (one-line) description of the package. -synopsis: We are Qux, and this is our package - --- A longer description of the package. --- description: - --- URL for the project homepage or repository. -homepage: qux.com - --- The license under which the package is released. -license: MIT - --- The file containing the license text. -license-file: LICENSE - --- The package author(s). -author: Foobar - --- An email address to which users can send suggestions, bug reports, and patches. -maintainer: foobar@qux.com - --- A copyright notice. --- copyright: -category: Control -build-type: Simple - --- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. -extra-doc-files: CHANGELOG.md - --- Extra source files to be distributed with the package, such as examples, or a tutorial module. --- extra-source-files: diff --git a/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg.golden b/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg.golden deleted file mode 100644 index 45630780ea4..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/pkg-desc/pkg.golden +++ /dev/null @@ -1,49 +0,0 @@ -cabal-version: 3.0 - --- Initial package description 'y' generated by --- 'cabal init'. For further documentation, see: --- http://haskell.org/cabal/users-guide/ --- --- The name of the package. -name: y - --- The package version. --- See the Haskell package versioning policy (PVP) for standards --- guiding when and how versions should be incremented. --- https://pvp.haskell.org --- PVP summary: +-+------- breaking API changes --- | | +----- non-breaking API additions --- | | | +--- code changes with no API change -version: 0.1.0.0 - --- A short (one-line) description of the package. -synopsis: synopsis - --- A longer description of the package. --- description: - --- URL for the project homepage or repository. -homepage: home - --- The license under which the package is released. -license: BSD-3-Clause - --- The file containing the license text. -license-file: LICENSE - --- The package author(s). -author: foo-kmett - --- An email address to which users can send suggestions, bug reports, and patches. -maintainer: foo-kmett@kmett.kmett - --- A copyright notice. --- copyright: -category: Data -build-type: Simple - --- Extra doc files to be distributed with the package, such as a CHANGELOG or a README. -extra-doc-files: CHANGELOG.md - --- Extra source files to be distributed with the package, such as examples, or a tutorial module. --- extra-source-files: diff --git a/cabal-install/tem/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden deleted file mode 100644 index f3cbb8ade97..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden +++ /dev/null @@ -1,24 +0,0 @@ -test-suite y-test - -- Base language which the package is written in. - default-language: Haskell2010 - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- The interface type and version of the test suite. - type: exitcode-stdio-1.0 - - -- Directories containing source files. - hs-source-dirs: test - - -- The entrypoint to the test suite. - main-is: Main.hs - - -- Test dependencies. - build-depends: base - - -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. - build-tool-depends: happy diff --git a/cabal-install/tem/tests/fixtures/init/golden/test/test-minimal-no-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/test/test-minimal-no-comments.golden deleted file mode 100644 index b092956a6d2..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/test/test-minimal-no-comments.golden +++ /dev/null @@ -1,6 +0,0 @@ -test-suite y-test - default-language: Haskell2010 - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: Main.hs - build-depends: base diff --git a/cabal-install/tem/tests/fixtures/init/golden/test/test-simple-minimal-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/test/test-simple-minimal-with-comments.golden deleted file mode 100644 index b092956a6d2..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/test/test-simple-minimal-with-comments.golden +++ /dev/null @@ -1,6 +0,0 @@ -test-suite y-test - default-language: Haskell2010 - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: Main.hs - build-depends: base diff --git a/cabal-install/tem/tests/fixtures/init/golden/test/test-with-comments.golden b/cabal-install/tem/tests/fixtures/init/golden/test/test-with-comments.golden deleted file mode 100644 index 2381ebd092e..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/test/test-with-comments.golden +++ /dev/null @@ -1,21 +0,0 @@ -test-suite y-test - -- Base language which the package is written in. - default-language: Haskell2010 - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- The interface type and version of the test suite. - type: exitcode-stdio-1.0 - - -- Directories containing source files. - hs-source-dirs: test - - -- The entrypoint to the test suite. - main-is: Main.hs - - -- Test dependencies. - build-depends: base diff --git a/cabal-install/tem/tests/fixtures/init/golden/test/test.golden b/cabal-install/tem/tests/fixtures/init/golden/test/test.golden deleted file mode 100644 index 7a36e096fb2..00000000000 --- a/cabal-install/tem/tests/fixtures/init/golden/test/test.golden +++ /dev/null @@ -1,12 +0,0 @@ -test-suite y-test - default-language: Haskell2010 - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: Main.hs - build-depends: base From 1ae7433a405e076cc9eeb52a6d9d272f99309fb6 Mon Sep 17 00:00:00 2001 From: Emily Pillmore Date: Mon, 17 May 2021 11:04:41 -0400 Subject: [PATCH 37/37] remove stale test directory --- .../cabal-lib-and-exe-no-comments.golden | 61 ---------- .../cabal-lib-and-exe-with-comments.golden | 111 ------------------ .../golden/cabal/cabal-lib-no-comments.golden | 46 -------- .../cabal/cabal-lib-with-comments.golden | 90 -------------- .../exe/exe-build-tools-with-comments.golden | 21 ---- .../golden/exe/exe-minimal-no-comments.golden | 5 - .../exe/exe-simple-with-comments.golden | 12 -- .../init/golden/exe/exe-with-comments.golden | 18 --- tests/fixtures/init/golden/exe/exe.golden | 11 -- .../lib/lib-build-tools-with-comments.golden | 21 ---- .../golden/lib/lib-minimal-no-comments.golden | 5 - .../lib/lib-simple-with-comments.golden | 12 -- .../init/golden/lib/lib-simple.golden | 11 -- .../init/golden/lib/lib-with-comments.golden | 18 --- tests/fixtures/init/golden/lib/lib.golden | 11 -- .../pkg-desc/pkg-old-cabal-with-flags.golden | 45 ------- .../golden/pkg-desc/pkg-with-comments.golden | 46 -------- .../golden/pkg-desc/pkg-with-flags.golden | 46 -------- .../fixtures/init/golden/pkg-desc/pkg.golden | 46 -------- .../test-build-tools-with-comments.golden | 24 ---- .../test/test-minimal-no-comments.golden | 6 - .../test/test-simple-with-comments.golden | 15 --- .../golden/test/test-with-comments.golden | 21 ---- tests/fixtures/init/golden/test/test.golden | 12 -- 24 files changed, 714 deletions(-) delete mode 100644 tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden delete mode 100644 tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden delete mode 100644 tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden delete mode 100644 tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden delete mode 100644 tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden delete mode 100644 tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden delete mode 100644 tests/fixtures/init/golden/exe/exe-simple-with-comments.golden delete mode 100644 tests/fixtures/init/golden/exe/exe-with-comments.golden delete mode 100644 tests/fixtures/init/golden/exe/exe.golden delete mode 100644 tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden delete mode 100644 tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden delete mode 100644 tests/fixtures/init/golden/lib/lib-simple-with-comments.golden delete mode 100644 tests/fixtures/init/golden/lib/lib-simple.golden delete mode 100644 tests/fixtures/init/golden/lib/lib-with-comments.golden delete mode 100644 tests/fixtures/init/golden/lib/lib.golden delete mode 100644 tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden delete mode 100644 tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden delete mode 100644 tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden delete mode 100644 tests/fixtures/init/golden/pkg-desc/pkg.golden delete mode 100644 tests/fixtures/init/golden/test/test-build-tools-with-comments.golden delete mode 100644 tests/fixtures/init/golden/test/test-minimal-no-comments.golden delete mode 100644 tests/fixtures/init/golden/test/test-simple-with-comments.golden delete mode 100644 tests/fixtures/init/golden/test/test-with-comments.golden delete mode 100644 tests/fixtures/init/golden/test/test.golden diff --git a/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden b/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden deleted file mode 100644 index 32e4d1ca857..00000000000 --- a/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-no-comments.golden +++ /dev/null @@ -1,61 +0,0 @@ -cabal-version: 2.4 -name: y -version: 0.1.0.0 -synopsis: synopsis - --- A longer description of the package. --- description: -homepage: home -license: BSD-3-Clause -license-file: LICENSE -author: foo-kmett -maintainer: foo-kmett@kmett.kmett - --- A copyright notice. --- copyright: -category: Data -build-type: Simple -extra-source-files: CHANGELOG.md - -library - exposed-modules: MyLib - - -- Modules included in this library but not exported. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - build-depends: base ^>=4.14.1.0 - hs-source-dirs: src - default-language: Haskell98 - -executable y - main-is: Main.hs - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - build-depends: - base ^>=4.14.1.0, - y - - hs-source-dirs: exe - default-language: Haskell2010 - -test-suite y-test - default-language: Haskell2010 - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: Main.hs - build-depends: - base ^>=4.14.1.0, - y - diff --git a/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden b/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden deleted file mode 100644 index 7dcde8264b2..00000000000 --- a/tests/fixtures/init/golden/cabal/cabal-lib-and-exe-with-comments.golden +++ /dev/null @@ -1,111 +0,0 @@ -cabal-version: 2.4 - --- Initial package description 'y' generated by --- 'cabal init'. For further documentation, see: --- http://haskell.org/cabal/users-guide/ --- --- The name of the package. -name: y - --- The package version. --- See the Haskell package versioning policy (PVP) for standards --- guiding when and how versions should be incremented. --- https://pvp.haskell.org --- PVP summary: +-+------- breaking API changes --- | | +----- non-breaking API additions --- | | | +--- code changes with no API change -version: 0.1.0.0 - --- A short (one-line) description of the package. -synopsis: synopsis - --- A longer description of the package. --- description: - --- URL for the project homepage or repository. -homepage: home - --- The license under which the package is released. -license: BSD-3-Clause - --- The file containing the license text. -license-file: LICENSE - --- The package author(s). -author: foo-kmett - --- An email address to which users can send suggestions, bug reports, and patches. -maintainer: foo-kmett@kmett.kmett - --- A copyright notice. --- copyright: -category: Data -build-type: Simple - --- Extra files to be distributed with the package, such as examples or a README. -extra-source-files: CHANGELOG.md - -library - -- Modules exported by the library. - exposed-modules: MyLib - - -- Modules included in this library but not exported. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- Other library packages from which modules are imported. - build-depends: base ^>=4.14.1.0 - - -- Directories containing source files. - hs-source-dirs: src - - -- Base language which the package is written in. - default-language: Haskell98 - -executable y - -- .hs or .lhs file containing the Main module. - main-is: Main.hs - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- Other library packages from which modules are imported. - build-depends: - base ^>=4.14.1.0, - y - - -- Directories containing source files. - hs-source-dirs: exe - - -- Base language which the package is written in. - default-language: Haskell2010 - -test-suite y-test - -- Base language which the package is written in. - default-language: Haskell2010 - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- The interface type and version of the test suite. - type: exitcode-stdio-1.0 - - -- Directories containing source files. - hs-source-dirs: test - - -- The entrypoint to the test suite. - main-is: Main.hs - - -- Test dependencies. - build-depends: - base ^>=4.14.1.0, - y - diff --git a/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden b/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden deleted file mode 100644 index 6cceb218542..00000000000 --- a/tests/fixtures/init/golden/cabal/cabal-lib-no-comments.golden +++ /dev/null @@ -1,46 +0,0 @@ -cabal-version: 2.4 -name: y -version: 0.1.0.0 -synopsis: synopsis - --- A longer description of the package. --- description: -homepage: home -license: BSD-3-Clause -license-file: LICENSE -author: foo-kmett -maintainer: foo-kmett@kmett.kmett - --- A copyright notice. --- copyright: -category: Data -build-type: Simple -extra-source-files: CHANGELOG.md - -library - exposed-modules: MyLib - - -- Modules included in this library but not exported. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - build-depends: base ^>=4.14.1.0 - hs-source-dirs: src - default-language: Haskell98 - -test-suite y-test - default-language: Haskell2010 - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: Main.hs - build-depends: - base ^>=4.14.1.0, - y - diff --git a/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden b/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden deleted file mode 100644 index 0ec5e6be0eb..00000000000 --- a/tests/fixtures/init/golden/cabal/cabal-lib-with-comments.golden +++ /dev/null @@ -1,90 +0,0 @@ -cabal-version: 2.4 - --- Initial package description 'y' generated by --- 'cabal init'. For further documentation, see: --- http://haskell.org/cabal/users-guide/ --- --- The name of the package. -name: y - --- The package version. --- See the Haskell package versioning policy (PVP) for standards --- guiding when and how versions should be incremented. --- https://pvp.haskell.org --- PVP summary: +-+------- breaking API changes --- | | +----- non-breaking API additions --- | | | +--- code changes with no API change -version: 0.1.0.0 - --- A short (one-line) description of the package. -synopsis: synopsis - --- A longer description of the package. --- description: - --- URL for the project homepage or repository. -homepage: home - --- The license under which the package is released. -license: BSD-3-Clause - --- The file containing the license text. -license-file: LICENSE - --- The package author(s). -author: foo-kmett - --- An email address to which users can send suggestions, bug reports, and patches. -maintainer: foo-kmett@kmett.kmett - --- A copyright notice. --- copyright: -category: Data -build-type: Simple - --- Extra files to be distributed with the package, such as examples or a README. -extra-source-files: CHANGELOG.md - -library - -- Modules exported by the library. - exposed-modules: MyLib - - -- Modules included in this library but not exported. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- Other library packages from which modules are imported. - build-depends: base ^>=4.14.1.0 - - -- Directories containing source files. - hs-source-dirs: src - - -- Base language which the package is written in. - default-language: Haskell98 - -test-suite y-test - -- Base language which the package is written in. - default-language: Haskell2010 - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- The interface type and version of the test suite. - type: exitcode-stdio-1.0 - - -- Directories containing source files. - hs-source-dirs: test - - -- The entrypoint to the test suite. - main-is: Main.hs - - -- Test dependencies. - build-depends: - base ^>=4.14.1.0, - y - diff --git a/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden b/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden deleted file mode 100644 index b2e99868127..00000000000 --- a/tests/fixtures/init/golden/exe/exe-build-tools-with-comments.golden +++ /dev/null @@ -1,21 +0,0 @@ -executable y - -- .hs or .lhs file containing the Main module. - main-is: Main.hs - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- Other library packages from which modules are imported. - build-depends: base ^>=4.14.1.0 - - -- Directories containing source files. - hs-source-dirs: exe - - -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. - build-tools: happy - - -- Base language which the package is written in. - default-language: Haskell2010 diff --git a/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden b/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden deleted file mode 100644 index 35810f1662a..00000000000 --- a/tests/fixtures/init/golden/exe/exe-minimal-no-comments.golden +++ /dev/null @@ -1,5 +0,0 @@ -executable y - main-is: Main.hs - build-depends: base ^>=4.14.1.0 - hs-source-dirs: exe - default-language: Haskell2010 diff --git a/tests/fixtures/init/golden/exe/exe-simple-with-comments.golden b/tests/fixtures/init/golden/exe/exe-simple-with-comments.golden deleted file mode 100644 index a791a4a0eed..00000000000 --- a/tests/fixtures/init/golden/exe/exe-simple-with-comments.golden +++ /dev/null @@ -1,12 +0,0 @@ -executable y - -- .hs or .lhs file containing the Main module. - main-is: Main.hs - - -- Other library packages from which modules are imported. - build-depends: base ^>=4.14.1.0 - - -- Directories containing source files. - hs-source-dirs: exe - - -- Base language which the package is written in. - default-language: Haskell2010 diff --git a/tests/fixtures/init/golden/exe/exe-with-comments.golden b/tests/fixtures/init/golden/exe/exe-with-comments.golden deleted file mode 100644 index d7a0a16e9b8..00000000000 --- a/tests/fixtures/init/golden/exe/exe-with-comments.golden +++ /dev/null @@ -1,18 +0,0 @@ -executable y - -- .hs or .lhs file containing the Main module. - main-is: Main.hs - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- Other library packages from which modules are imported. - build-depends: base ^>=4.14.1.0 - - -- Directories containing source files. - hs-source-dirs: exe - - -- Base language which the package is written in. - default-language: Haskell2010 diff --git a/tests/fixtures/init/golden/exe/exe.golden b/tests/fixtures/init/golden/exe/exe.golden deleted file mode 100644 index c61210c04ea..00000000000 --- a/tests/fixtures/init/golden/exe/exe.golden +++ /dev/null @@ -1,11 +0,0 @@ -executable y - main-is: Main.hs - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - build-depends: base ^>=4.14.1.0 - hs-source-dirs: exe - default-language: Haskell2010 diff --git a/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden b/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden deleted file mode 100644 index 8d41c633f60..00000000000 --- a/tests/fixtures/init/golden/lib/lib-build-tools-with-comments.golden +++ /dev/null @@ -1,21 +0,0 @@ -library - -- Modules exported by the library. - exposed-modules: MyLib - - -- Modules included in this library but not exported. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- Other library packages from which modules are imported. - build-depends: base ^>=4.14.1.0 - - -- Directories containing source files. - hs-source-dirs: src - - -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. - build-tools: happy - - -- Base language which the package is written in. - default-language: Haskell98 diff --git a/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden b/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden deleted file mode 100644 index 64c71f80310..00000000000 --- a/tests/fixtures/init/golden/lib/lib-minimal-no-comments.golden +++ /dev/null @@ -1,5 +0,0 @@ -library - exposed-modules: MyLib - build-depends: base ^>=4.14.1.0 - hs-source-dirs: src - default-language: Haskell98 diff --git a/tests/fixtures/init/golden/lib/lib-simple-with-comments.golden b/tests/fixtures/init/golden/lib/lib-simple-with-comments.golden deleted file mode 100644 index f6daa328415..00000000000 --- a/tests/fixtures/init/golden/lib/lib-simple-with-comments.golden +++ /dev/null @@ -1,12 +0,0 @@ -library - -- Modules exported by the library. - exposed-modules: MyLib - - -- Other library packages from which modules are imported. - build-depends: base ^>=4.14.1.0 - - -- Directories containing source files. - hs-source-dirs: src - - -- Base language which the package is written in. - default-language: Haskell98 diff --git a/tests/fixtures/init/golden/lib/lib-simple.golden b/tests/fixtures/init/golden/lib/lib-simple.golden deleted file mode 100644 index 61271518061..00000000000 --- a/tests/fixtures/init/golden/lib/lib-simple.golden +++ /dev/null @@ -1,11 +0,0 @@ -library - exposed-modules: MyLib - - -- Modules included in this library but not exported. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - build-depends: base ^>=4.14.1.0 - hs-source-dirs: src - default-language: Haskell98 diff --git a/tests/fixtures/init/golden/lib/lib-with-comments.golden b/tests/fixtures/init/golden/lib/lib-with-comments.golden deleted file mode 100644 index 84ba9445f2a..00000000000 --- a/tests/fixtures/init/golden/lib/lib-with-comments.golden +++ /dev/null @@ -1,18 +0,0 @@ -library - -- Modules exported by the library. - exposed-modules: MyLib - - -- Modules included in this library but not exported. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- Other library packages from which modules are imported. - build-depends: base ^>=4.14.1.0 - - -- Directories containing source files. - hs-source-dirs: src - - -- Base language which the package is written in. - default-language: Haskell98 diff --git a/tests/fixtures/init/golden/lib/lib.golden b/tests/fixtures/init/golden/lib/lib.golden deleted file mode 100644 index 61271518061..00000000000 --- a/tests/fixtures/init/golden/lib/lib.golden +++ /dev/null @@ -1,11 +0,0 @@ -library - exposed-modules: MyLib - - -- Modules included in this library but not exported. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - build-depends: base ^>=4.14.1.0 - hs-source-dirs: src - default-language: Haskell98 diff --git a/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden b/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden deleted file mode 100644 index 776f6abd320..00000000000 --- a/tests/fixtures/init/golden/pkg-desc/pkg-old-cabal-with-flags.golden +++ /dev/null @@ -1,45 +0,0 @@ -cabal-version: 2.0 - --- Initial package description 'y' generated by --- 'cabal init'. For further documentation, see: --- http://haskell.org/cabal/users-guide/ --- --- The name of the package. -name: QuxPackage - --- The package version. --- See the Haskell package versioning policy (PVP) for standards --- guiding when and how versions should be incremented. --- https://pvp.haskell.org --- PVP summary: +-+------- breaking API changes --- | | +----- non-breaking API additions --- | | | +--- code changes with no API change -version: 4.2.6 - --- A short (one-line) description of the package. -synopsis: We are Qux, and this is our package - --- A longer description of the package. --- description: - --- URL for the project homepage or repository. -homepage: qux.com - --- The license under which the package is released. -license: MIT - --- The file containing the license text. -license-file: LICENSE - --- The package author(s). -author: Foobar - --- An email address to which users can send suggestions, bug reports, and patches. -maintainer: foobar@qux.com - --- A copyright notice. --- copyright: -category: Control - --- Extra files to be distributed with the package, such as examples or a README. -extra-source-files: CHANGELOG.md diff --git a/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden b/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden deleted file mode 100644 index 47924235c7f..00000000000 --- a/tests/fixtures/init/golden/pkg-desc/pkg-with-comments.golden +++ /dev/null @@ -1,46 +0,0 @@ -cabal-version: 2.4 - --- Initial package description 'y' generated by --- 'cabal init'. For further documentation, see: --- http://haskell.org/cabal/users-guide/ --- --- The name of the package. -name: y - --- The package version. --- See the Haskell package versioning policy (PVP) for standards --- guiding when and how versions should be incremented. --- https://pvp.haskell.org --- PVP summary: +-+------- breaking API changes --- | | +----- non-breaking API additions --- | | | +--- code changes with no API change -version: 0.1.0.0 - --- A short (one-line) description of the package. -synopsis: synopsis - --- A longer description of the package. --- description: - --- URL for the project homepage or repository. -homepage: home - --- The license under which the package is released. -license: BSD-3-Clause - --- The file containing the license text. -license-file: LICENSE - --- The package author(s). -author: foo-kmett - --- An email address to which users can send suggestions, bug reports, and patches. -maintainer: foo-kmett@kmett.kmett - --- A copyright notice. --- copyright: -category: Data -build-type: Simple - --- Extra files to be distributed with the package, such as examples or a README. -extra-source-files: CHANGELOG.md diff --git a/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden b/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden deleted file mode 100644 index 52613c0f0d7..00000000000 --- a/tests/fixtures/init/golden/pkg-desc/pkg-with-flags.golden +++ /dev/null @@ -1,46 +0,0 @@ -cabal-version: 2.2 - --- Initial package description 'y' generated by --- 'cabal init'. For further documentation, see: --- http://haskell.org/cabal/users-guide/ --- --- The name of the package. -name: QuxPackage - --- The package version. --- See the Haskell package versioning policy (PVP) for standards --- guiding when and how versions should be incremented. --- https://pvp.haskell.org --- PVP summary: +-+------- breaking API changes --- | | +----- non-breaking API additions --- | | | +--- code changes with no API change -version: 4.2.6 - --- A short (one-line) description of the package. -synopsis: We are Qux, and this is our package - --- A longer description of the package. --- description: - --- URL for the project homepage or repository. -homepage: qux.com - --- The license under which the package is released. -license: MIT - --- The file containing the license text. -license-file: LICENSE - --- The package author(s). -author: Foobar - --- An email address to which users can send suggestions, bug reports, and patches. -maintainer: foobar@qux.com - --- A copyright notice. --- copyright: -category: Control -build-type: Simple - --- Extra files to be distributed with the package, such as examples or a README. -extra-source-files: CHANGELOG.md diff --git a/tests/fixtures/init/golden/pkg-desc/pkg.golden b/tests/fixtures/init/golden/pkg-desc/pkg.golden deleted file mode 100644 index 47924235c7f..00000000000 --- a/tests/fixtures/init/golden/pkg-desc/pkg.golden +++ /dev/null @@ -1,46 +0,0 @@ -cabal-version: 2.4 - --- Initial package description 'y' generated by --- 'cabal init'. For further documentation, see: --- http://haskell.org/cabal/users-guide/ --- --- The name of the package. -name: y - --- The package version. --- See the Haskell package versioning policy (PVP) for standards --- guiding when and how versions should be incremented. --- https://pvp.haskell.org --- PVP summary: +-+------- breaking API changes --- | | +----- non-breaking API additions --- | | | +--- code changes with no API change -version: 0.1.0.0 - --- A short (one-line) description of the package. -synopsis: synopsis - --- A longer description of the package. --- description: - --- URL for the project homepage or repository. -homepage: home - --- The license under which the package is released. -license: BSD-3-Clause - --- The file containing the license text. -license-file: LICENSE - --- The package author(s). -author: foo-kmett - --- An email address to which users can send suggestions, bug reports, and patches. -maintainer: foo-kmett@kmett.kmett - --- A copyright notice. --- copyright: -category: Data -build-type: Simple - --- Extra files to be distributed with the package, such as examples or a README. -extra-source-files: CHANGELOG.md diff --git a/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden b/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden deleted file mode 100644 index 1377709f290..00000000000 --- a/tests/fixtures/init/golden/test/test-build-tools-with-comments.golden +++ /dev/null @@ -1,24 +0,0 @@ -test-suite y-test - -- Base language which the package is written in. - default-language: Haskell2010 - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- The interface type and version of the test suite. - type: exitcode-stdio-1.0 - - -- Directories containing source files. - hs-source-dirs: test - - -- The entrypoint to the test suite. - main-is: Main.hs - - -- Test dependencies. - build-depends: base ^>=4.14.1.0 - - -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source. - build-tools: happy diff --git a/tests/fixtures/init/golden/test/test-minimal-no-comments.golden b/tests/fixtures/init/golden/test/test-minimal-no-comments.golden deleted file mode 100644 index b7560beb966..00000000000 --- a/tests/fixtures/init/golden/test/test-minimal-no-comments.golden +++ /dev/null @@ -1,6 +0,0 @@ -test-suite y-test - default-language: Haskell2010 - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: Main.hs - build-depends: base ^>=4.14.1.0 diff --git a/tests/fixtures/init/golden/test/test-simple-with-comments.golden b/tests/fixtures/init/golden/test/test-simple-with-comments.golden deleted file mode 100644 index 0ebefd519b6..00000000000 --- a/tests/fixtures/init/golden/test/test-simple-with-comments.golden +++ /dev/null @@ -1,15 +0,0 @@ -test-suite y-test - -- Base language which the package is written in. - default-language: Haskell2010 - - -- The interface type and version of the test suite. - type: exitcode-stdio-1.0 - - -- Directories containing source files. - hs-source-dirs: test - - -- The entrypoint to the test suite. - main-is: Main.hs - - -- Test dependencies. - build-depends: base ^>=4.14.1.0 diff --git a/tests/fixtures/init/golden/test/test-with-comments.golden b/tests/fixtures/init/golden/test/test-with-comments.golden deleted file mode 100644 index df91ae84267..00000000000 --- a/tests/fixtures/init/golden/test/test-with-comments.golden +++ /dev/null @@ -1,21 +0,0 @@ -test-suite y-test - -- Base language which the package is written in. - default-language: Haskell2010 - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - - -- The interface type and version of the test suite. - type: exitcode-stdio-1.0 - - -- Directories containing source files. - hs-source-dirs: test - - -- The entrypoint to the test suite. - main-is: Main.hs - - -- Test dependencies. - build-depends: base ^>=4.14.1.0 diff --git a/tests/fixtures/init/golden/test/test.golden b/tests/fixtures/init/golden/test/test.golden deleted file mode 100644 index 6bafb438873..00000000000 --- a/tests/fixtures/init/golden/test/test.golden +++ /dev/null @@ -1,12 +0,0 @@ -test-suite y-test - default-language: Haskell2010 - - -- Modules included in this executable, other than Main. - -- other-modules: - - -- LANGUAGE extensions used by modules in this package. - -- other-extensions: - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: Main.hs - build-depends: base ^>=4.14.1.0