diff --git a/Cabal/Cabal.cabal b/Cabal/Cabal.cabal index 82d0ee12083..8d5b583f222 100644 --- a/Cabal/Cabal.cabal +++ b/Cabal/Cabal.cabal @@ -38,6 +38,20 @@ extra-source-files: tests/PackageTests/AllowOlder/benchmarks/Bench.hs tests/PackageTests/AllowOlder/src/Foo.hs tests/PackageTests/AllowOlder/tests/Test.hs + tests/PackageTests/AutogenModules/Package/Dummy.hs + tests/PackageTests/AutogenModules/Package/MyBenchModule.hs + tests/PackageTests/AutogenModules/Package/MyExeModule.hs + tests/PackageTests/AutogenModules/Package/MyLibModule.hs + tests/PackageTests/AutogenModules/Package/MyLibrary.hs + tests/PackageTests/AutogenModules/Package/MyTestModule.hs + tests/PackageTests/AutogenModules/Package/my.cabal + tests/PackageTests/AutogenModules/SrcDist/Dummy.hs + tests/PackageTests/AutogenModules/SrcDist/MyBenchModule.hs + tests/PackageTests/AutogenModules/SrcDist/MyExeModule.hs + tests/PackageTests/AutogenModules/SrcDist/MyLibModule.hs + tests/PackageTests/AutogenModules/SrcDist/MyLibrary.hs + tests/PackageTests/AutogenModules/SrcDist/MyTestModule.hs + tests/PackageTests/AutogenModules/SrcDist/my.cabal tests/PackageTests/BenchmarkExeV10/Foo.hs tests/PackageTests/BenchmarkExeV10/benchmarks/bench-Foo.hs tests/PackageTests/BenchmarkExeV10/my.cabal @@ -435,6 +449,8 @@ test-suite package-tests type: exitcode-stdio-1.0 main-is: PackageTests.hs other-modules: + PackageTests.AutogenModules.Package.Check + PackageTests.AutogenModules.SrcDist.Check PackageTests.BenchmarkStanza.Check PackageTests.TestStanza.Check PackageTests.DeterministicAr.Check diff --git a/Cabal/Distribution/PackageDescription.hs b/Cabal/Distribution/PackageDescription.hs index 423ad21c72f..dc74121b548 100644 --- a/Cabal/Distribution/PackageDescription.hs +++ b/Cabal/Distribution/PackageDescription.hs @@ -36,6 +36,7 @@ module Distribution.PackageDescription ( hasPublicLib, hasLibs, libModules, + libModulesAutogen, -- ** Executables Executable(..), @@ -43,6 +44,7 @@ module Distribution.PackageDescription ( withExe, hasExes, exeModules, + exeModulesAutogen, -- * Tests TestSuite(..), @@ -54,6 +56,7 @@ module Distribution.PackageDescription ( hasTests, withTest, testModules, + testModulesAutogen, -- * Benchmarks Benchmark(..), @@ -65,6 +68,7 @@ module Distribution.PackageDescription ( hasBenchmarks, withBenchmark, benchmarkModules, + benchmarkModulesAutogen, -- * Build information BuildInfo(..), diff --git a/Cabal/Distribution/PackageDescription/Check.hs b/Cabal/Distribution/PackageDescription/Check.hs index 757ff7eff79..25299b5302e 100644 --- a/Cabal/Distribution/PackageDescription/Check.hs +++ b/Cabal/Distribution/PackageDescription/Check.hs @@ -41,6 +41,7 @@ import Distribution.PackageDescription.Configuration import Distribution.Compiler import Distribution.System import Distribution.License +import Distribution.Simple.BuildPaths (autogenPathsModuleName) import Distribution.Simple.CCompiler import Distribution.Simple.Utils hiding (findPackageDesc, notice) import Distribution.Version @@ -245,6 +246,14 @@ checkLibrary pkg lib = PackageDistInexcusable $ "To use the 'required-signatures' field the package needs to specify " ++ "at least 'cabal-version: >= 1.21'." + + -- check that all autogen-modules appear on other-modules or exposed-modules + , check + (not $ and $ map (flip elem (libModules lib)) (libModulesAutogen lib)) $ + PackageBuildImpossible $ + "An 'autogen-module' is neither on 'exposed-modules' or " + ++ "'other-modules'." + ] where @@ -282,6 +291,14 @@ checkExecutable pkg exe = PackageBuildImpossible $ "Duplicate modules in executable '" ++ exeName exe ++ "': " ++ commaSep (map display moduleDuplicates) + + -- check that all autogen-modules appear on other-modules + , check + (not $ and $ map (flip elem (exeModules exe)) (exeModulesAutogen exe)) $ + PackageBuildImpossible $ + "On executable '" ++ exeName exe ++ "' an 'autogen-module' is not " + ++ "on 'other-modules'" + ] where moduleDuplicates = dups (exeModules exe) @@ -319,6 +336,16 @@ checkTestSuite pkg test = PackageDistInexcusable $ "The package uses a C/C++/obj-C source file for the 'main-is' field. " ++ "To use this feature you must specify 'cabal-version: >= 1.18'." + + -- check that all autogen-modules appear on other-modules + , check + (not $ and $ map + (flip elem (testModules test)) + (testModulesAutogen test) + ) $ + PackageBuildImpossible $ + "On test suite '" ++ testName test ++ "' an 'autogen-module' is not " + ++ "on 'other-modules'" ] where moduleDuplicates = dups $ testModules test @@ -358,6 +385,16 @@ checkBenchmark _pkg bm = PackageBuildImpossible $ "The 'main-is' field must specify a '.hs' or '.lhs' file " ++ "(even if it is generated by a preprocessor)." + + -- check that all autogen-modules appear on other-modules + , check + (not $ and $ map + (flip elem (benchmarkModules bm)) + (benchmarkModulesAutogen bm) + ) $ + PackageBuildImpossible $ + "On benchmark '" ++ benchmarkName bm ++ "' an 'autogen-module' is " + ++ "not on 'other-modules'" ] where moduleDuplicates = dups $ benchmarkModules bm @@ -1110,6 +1147,18 @@ checkCabalVersion pkg = ++ "that specifies the dependencies of the Setup.hs script itself. " ++ "The 'setup-depends' field uses the same syntax as 'build-depends', " ++ "so a simple example would be 'setup-depends: base, Cabal'." + + , check (specVersion pkg >= Version [1,25] [] + && elem (autogenPathsModuleName pkg) allModuleNames + && not (elem (autogenPathsModuleName pkg) allModuleNamesAutogen) ) $ + PackageDistInexcusable $ + "Packages using 'cabal-version: >= 1.25' and the autogenerated " + ++ "module Paths_* must include it also on the 'autogen-modules' field " + ++ "besides 'exposed-modules' and 'other-modules'. This specifies that " + ++ "the module does not come with the package and is generated on " + ++ "setup. Modules built with a custom Setup.hs script also go here " + ++ "to ensure that commands like sdist don't fail." + ] where -- Perform a check on packages that use a version of the spec less than @@ -1244,6 +1293,15 @@ checkCabalVersion pkg = map DisableExtension [MonoPatBinds] + allModuleNames = + (case library pkg of + Nothing -> [] + (Just lib) -> libModules lib + ) + ++ concatMap otherModules (allBuildInfo pkg) + + allModuleNamesAutogen = concatMap autogenModules (allBuildInfo pkg) + -- | A variation on the normal 'Text' instance, shows any ()'s in the original -- textual syntax. We need to show these otherwise it's confusing to users when -- we complain of their presence but do not pretty print them! diff --git a/Cabal/Distribution/PackageDescription/Parse.hs b/Cabal/Distribution/PackageDescription/Parse.hs index 8b728b939ea..3ee906b245e 100644 --- a/Cabal/Distribution/PackageDescription/Parse.hs +++ b/Cabal/Distribution/PackageDescription/Parse.hs @@ -443,6 +443,9 @@ binfoFieldDescrs = , listFieldWithSep vcat "other-modules" disp parseModuleNameQ otherModules (\val binfo -> binfo{otherModules=val}) + , listFieldWithSep vcat "autogen-modules" + disp parseModuleNameQ + autogenModules (\val binfo -> binfo{autogenModules=val}) , optsField "ghc-prof-options" GHC profOptions (\val binfo -> binfo{profOptions=val}) , optsField "ghcjs-prof-options" GHCJS diff --git a/Cabal/Distribution/ParseUtils.hs b/Cabal/Distribution/ParseUtils.hs index 3d5e5e4b177..9c8a72f019a 100644 --- a/Cabal/Distribution/ParseUtils.hs +++ b/Cabal/Distribution/ParseUtils.hs @@ -288,6 +288,7 @@ ppField name fielddoc , "includes" , "install-includes" , "other-modules" + , "autogen-modules" , "depends" ] diff --git a/Cabal/Distribution/Simple/Build.hs b/Cabal/Distribution/Simple/Build.hs index 350e725f546..598c00932f7 100644 --- a/Cabal/Distribution/Simple/Build.hs +++ b/Cabal/Distribution/Simple/Build.hs @@ -583,7 +583,7 @@ writeAutogenFiles verbosity pkg lbi clbi = do createDirectoryIfMissingVerbose verbosity True (autogenComponentModulesDir lbi clbi) let pathsModulePath = autogenComponentModulesDir lbi clbi - ModuleName.toFilePath (autogenModuleName pkg) <.> "hs" + ModuleName.toFilePath (autogenPathsModuleName pkg) <.> "hs" rewriteFile pathsModulePath (Build.PathsModule.generate pkg lbi clbi) let cppHeaderPath = autogenComponentModulesDir lbi clbi cppHeaderName diff --git a/Cabal/Distribution/Simple/Build/PathsModule.hs b/Cabal/Distribution/Simple/Build/PathsModule.hs index e31a4527d52..3149eecb64e 100644 --- a/Cabal/Distribution/Simple/Build/PathsModule.hs +++ b/Cabal/Distribution/Simple/Build/PathsModule.hs @@ -226,7 +226,7 @@ generate pkg_descr lbi clbi = _ -> False supportsRelocatableProgs _ = False - paths_modulename = autogenModuleName pkg_descr + paths_modulename = autogenPathsModuleName pkg_descr get_prefix_stuff = get_prefix_win32 buildArch diff --git a/Cabal/Distribution/Simple/BuildPaths.hs b/Cabal/Distribution/Simple/BuildPaths.hs index 717f98452ac..68f9b895907 100644 --- a/Cabal/Distribution/Simple/BuildPaths.hs +++ b/Cabal/Distribution/Simple/BuildPaths.hs @@ -19,6 +19,7 @@ module Distribution.Simple.BuildPaths ( autogenComponentModulesDir, autogenModuleName, + autogenPathsModuleName, cppHeaderName, haddockName, @@ -87,9 +88,14 @@ autogenComponentModulesDir lbi clbi = componentBuildDir lbi clbi "autogen" cppHeaderName :: String cppHeaderName = "cabal_macros.h" +{-# DEPRECATED autogenModuleName "Use autogenPathsModuleName instead" #-} -- |The name of the auto-generated module associated with a package autogenModuleName :: PackageDescription -> ModuleName -autogenModuleName pkg_descr = +autogenModuleName = autogenPathsModuleName + +-- | The name of the auto-generated Paths_* module associated with a package +autogenPathsModuleName :: PackageDescription -> ModuleName +autogenPathsModuleName pkg_descr = ModuleName.fromString $ "Paths_" ++ map fixchar (display (packageName pkg_descr)) where fixchar '-' = '_' diff --git a/Cabal/Distribution/Simple/SrcDist.hs b/Cabal/Distribution/Simple/SrcDist.hs index 54a2f3f4e18..2703e6c7126 100644 --- a/Cabal/Distribution/Simple/SrcDist.hs +++ b/Cabal/Distribution/Simple/SrcDist.hs @@ -136,7 +136,7 @@ listPackageSources verbosity pkg_descr0 pps = do maybeExecutable <- listPackageSourcesMaybeExecutable pkg_descr return (ordinary, maybeExecutable) where - pkg_descr = filterAutogenModule pkg_descr0 + pkg_descr = filterAutogenModules pkg_descr0 -- | List those source files that may be executable (e.g. the configure script). listPackageSourcesMaybeExecutable :: PackageDescription -> IO [FilePath] @@ -259,7 +259,7 @@ prepareTree verbosity pkg_descr0 mb_lbi targetDir pps = do maybeCreateDefaultSetupScript targetDir where - pkg_descr = filterAutogenModule pkg_descr0 + pkg_descr = filterAutogenModules pkg_descr0 -- | Find the setup script file, if it exists. findSetupFile :: FilePath -> IO (Maybe FilePath) @@ -305,21 +305,24 @@ findIncludeFile (d:ds) f = do b <- doesFileExist path if b then return (f,path) else findIncludeFile ds f --- | Remove the auto-generated module ('Paths_*') from 'exposed-modules' and --- 'other-modules'. -filterAutogenModule :: PackageDescription -> PackageDescription -filterAutogenModule pkg_descr0 = mapLib filterAutogenModuleLib $ +-- | Remove the auto-generated modules (like 'Paths_*') from 'exposed-modules' +-- and 'other-modules'. +filterAutogenModules :: PackageDescription -> PackageDescription +filterAutogenModules pkg_descr0 = mapLib filterAutogenModuleLib $ mapAllBuildInfo filterAutogenModuleBI pkg_descr0 where mapLib f pkg = pkg { library = fmap f (library pkg) , subLibraries = map f (subLibraries pkg) } filterAutogenModuleLib lib = lib { - exposedModules = filter (/=autogenModule) (exposedModules lib) + exposedModules = filter (filterFunction (libBuildInfo lib)) (exposedModules lib) } filterAutogenModuleBI bi = bi { - otherModules = filter (/=autogenModule) (otherModules bi) + otherModules = filter (filterFunction bi) (otherModules bi) } - autogenModule = autogenModuleName pkg_descr0 + pathsModule = autogenPathsModuleName pkg_descr0 + filterFunction bi = \mn -> + mn /= pathsModule + && not (elem mn (autogenModules bi)) -- | Prepare a directory tree of source files for a snapshot version. -- It is expected that the appropriate snapshot version has already been set @@ -437,7 +440,8 @@ allSourcesBuildInfo bi pps modules = do nonEmpty _ f xs = f xs suffixes = ppSuffixes pps ++ ["hs", "lhs"] notFound m = die $ "Error: Could not find module: " ++ display m - ++ " with any suffix: " ++ show suffixes + ++ " with any suffix: " ++ show suffixes ++ ". If the module " + ++ "is autogenerated it should be added to 'autogen-modules'." printPackageProblems :: Verbosity -> PackageDescription -> IO () diff --git a/Cabal/Distribution/Types/Benchmark.hs b/Cabal/Distribution/Types/Benchmark.hs index 7f6a5032915..ce7c0bfe6f6 100644 --- a/Cabal/Distribution/Types/Benchmark.hs +++ b/Cabal/Distribution/Types/Benchmark.hs @@ -6,6 +6,7 @@ module Distribution.Types.Benchmark ( emptyBenchmark, benchmarkType, benchmarkModules, + benchmarkModulesAutogen ) where import Prelude () @@ -60,3 +61,8 @@ benchmarkType benchmark = case benchmarkInterface benchmark of -- | Get all the module names from a benchmark. benchmarkModules :: Benchmark -> [ModuleName] benchmarkModules benchmark = otherModules (benchmarkBuildInfo benchmark) + +-- | Get all the auto generated module names from a benchmark. +-- This are a subset of 'benchmarkModules'. +benchmarkModulesAutogen :: Benchmark -> [ModuleName] +benchmarkModulesAutogen benchmark = autogenModules (benchmarkBuildInfo benchmark) diff --git a/Cabal/Distribution/Types/BuildInfo.hs b/Cabal/Distribution/Types/BuildInfo.hs index b3e57248527..2b849e89a55 100644 --- a/Cabal/Distribution/Types/BuildInfo.hs +++ b/Cabal/Distribution/Types/BuildInfo.hs @@ -40,6 +40,7 @@ data BuildInfo = BuildInfo { jsSources :: [FilePath], hsSourceDirs :: [FilePath], -- ^ where to look for the Haskell module hierarchy otherModules :: [ModuleName], -- ^ non-exposed or non-main modules + autogenModules :: [ModuleName], -- ^ not present on sdist, Paths_* or user-generated with a custom Setup.hs defaultLanguage :: Maybe Language,-- ^ language used when not explicitly specified otherLanguages :: [Language], -- ^ other languages used within the package @@ -80,6 +81,7 @@ instance Monoid BuildInfo where jsSources = [], hsSourceDirs = [], otherModules = [], + autogenModules = [], defaultLanguage = Nothing, otherLanguages = [], defaultExtensions = [], @@ -114,6 +116,7 @@ instance Semigroup BuildInfo where jsSources = combineNub jsSources, hsSourceDirs = combineNub hsSourceDirs, otherModules = combineNub otherModules, + autogenModules = combineNub autogenModules, defaultLanguage = combineMby defaultLanguage, otherLanguages = combineNub otherLanguages, defaultExtensions = combineNub defaultExtensions, diff --git a/Cabal/Distribution/Types/Executable.hs b/Cabal/Distribution/Types/Executable.hs index 66de813984d..2baeffd11a3 100644 --- a/Cabal/Distribution/Types/Executable.hs +++ b/Cabal/Distribution/Types/Executable.hs @@ -5,6 +5,7 @@ module Distribution.Types.Executable ( Executable(..), emptyExecutable, exeModules, + exeModulesAutogen ) where import Prelude () @@ -46,3 +47,8 @@ emptyExecutable = mempty -- | Get all the module names from an exe exeModules :: Executable -> [ModuleName] exeModules exe = otherModules (buildInfo exe) + +-- | Get all the auto generated module names from an exe +-- This are a subset of 'exeModules'. +exeModulesAutogen :: Executable -> [ModuleName] +exeModulesAutogen exe = autogenModules (buildInfo exe) diff --git a/Cabal/Distribution/Types/Library.hs b/Cabal/Distribution/Types/Library.hs index 8e9a17694d3..a8f40126296 100644 --- a/Cabal/Distribution/Types/Library.hs +++ b/Cabal/Distribution/Types/Library.hs @@ -5,6 +5,7 @@ module Distribution.Types.Library ( Library(..), emptyLibrary, libModules, + libModulesAutogen ) where import Prelude () @@ -58,3 +59,8 @@ libModules :: Library -> [ModuleName] libModules lib = exposedModules lib ++ otherModules (libBuildInfo lib) ++ requiredSignatures lib + +-- | Get all the auto generated module names from the library, exposed or not. +-- This are a subset of 'libModules'. +libModulesAutogen :: Library -> [ModuleName] +libModulesAutogen lib = autogenModules (libBuildInfo lib) diff --git a/Cabal/Distribution/Types/TestSuite.hs b/Cabal/Distribution/Types/TestSuite.hs index 27f415cdf37..df33e1e4dba 100644 --- a/Cabal/Distribution/Types/TestSuite.hs +++ b/Cabal/Distribution/Types/TestSuite.hs @@ -6,6 +6,7 @@ module Distribution.Types.TestSuite ( emptyTestSuite, testType, testModules, + testModulesAutogen ) where import Prelude () @@ -65,3 +66,8 @@ testModules test = (case testInterface test of TestSuiteLibV09 _ m -> [m] _ -> []) ++ otherModules (testBuildInfo test) + +-- | Get all the auto generated module names from a test suite. +-- This are a subset of 'testModules'. +testModulesAutogen :: TestSuite -> [ModuleName] +testModulesAutogen test = autogenModules (testBuildInfo test) diff --git a/Cabal/changelog b/Cabal/changelog index a64f00da3e6..30eadaa4041 100644 --- a/Cabal/changelog +++ b/Cabal/changelog @@ -50,6 +50,17 @@ * 'getComponentLocalBuildInfo', 'withComponentsInBuildOrder' and 'componentsInBuildOrder' are deprecated in favor of a new interface in "Distribution.Types.LocalBuildInfo". + * New 'autogen-modules' field. Modules that are built automatically at + setup, like Paths_PACKAGENAME or others created with a build-type + custom, appear on 'other-modules' for the Library, Executable, + Test-Suite or Benchmark stanzas or also on 'exposed-modules' for + libraries but are not really on the package when distributed. This + makes commands like sdist fail because the file is not found, so with + this new field modules that appear there are treated the same way as + Paths_PACKAGENAME was and there is no need to create complex build + hooks. Just add the module names on 'other-modules' and + 'exposed-modules' as always and on the new 'autogen-modules' besides. + (#3656). 1.24.0.0 Ryan Thomas March 2016 * Support GHC 8. diff --git a/Cabal/doc/developing-packages.markdown b/Cabal/doc/developing-packages.markdown index 7bfcc6bcbdc..932384fd6b6 100644 --- a/Cabal/doc/developing-packages.markdown +++ b/Cabal/doc/developing-packages.markdown @@ -1955,6 +1955,43 @@ custom-setup [`build-depends`](#build-information) section for a description of the syntax expected by this field. +## Autogenerated modules + +Modules that are built automatically at setup, created with a custom setup +script, must appear on `other-modules` for the library, executable, test-suite +or benchmark stanzas or also on `exposed-modules` for libraries to be used, but +are not really on the package when distributed. This makes commands like sdist +fail because the file is not found. + +This special modules must appear again on the `autogen-modules` field of the +stanza that is using it, besides `other-modules` or `exposed-modules`. With +this there is no need to create complex build hooks for this poweruser case. + +Right now `main-is` modules are not supported on `autogen-modules`. + +~~~~~~~~~~~~~~~~ +Library + default-language: Haskell2010 + build-depends: base + exposed-modules: + MyLibrary + MyLibHelperModule + other-modules: + MyLibModule + autogen-modules: + MyLibHelperModule + +Executable Exe + default-language: Haskell2010 + main-is: Dummy.hs + build-depends: base + other-modules: + MyExeModule + MyExeHelperModule + autogen-modules: + MyExeHelperModule +~~~~~~~~~~~~~~~~ + ## Accessing data files from package code ## The placement on the target system of files listed in the `data-files` @@ -1976,10 +2013,11 @@ program is running. Note: If you decide to import the `Paths_`_pkgname_ module then it *must* be listed in the `other-modules` field just like any other module -in your package. +in your package and on `autogen-modules` as the file is autogenerated. -The `Paths_`_pkgname_ module is not platform independent so it does not -get included in the source tarballs generated by `sdist`. +The `Paths_`_pkgname_ module is not platform independent, as any other +autogenerated module, so it does not get included in the source tarballs +generated by `sdist`. The `Paths_`_pkgname_ module also includes some other useful functions and values, which record the version of the package and some other diff --git a/Cabal/tests/PackageTests/AutogenModules/Package/Check.hs b/Cabal/tests/PackageTests/AutogenModules/Package/Check.hs new file mode 100644 index 00000000000..652bf372c86 --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/Package/Check.hs @@ -0,0 +1,51 @@ +module PackageTests.AutogenModules.Package.Check where + +import PackageTests.PackageTester + +suite :: TestM () +suite = do + + configureResult <- shouldFail $ cabal' "configure" [] + sdistResult <- shouldFail $ cabal' "sdist" [] + + -- Package check messages. + let libAutogenMsg = + "An 'autogen-module' is neither on 'exposed-modules' or " + ++ "'other-modules'" + let exeAutogenMsg = + "On executable 'Exe' an 'autogen-module' is not on " + ++ "'other-modules'" + let testAutogenMsg = + "On test suite 'Test' an 'autogen-module' is not on " + ++ "'other-modules'" + let benchAutogenMsg = + "On benchmark 'Bench' an 'autogen-module' is not on " + ++ "'other-modules'" + let pathsAutogenMsg = + "Packages using 'cabal-version: >= 1.25' and the autogenerated" + + -- Asserts for the desired check messages after configure. + assertOutputContains libAutogenMsg configureResult + assertOutputContains exeAutogenMsg configureResult + assertOutputContains testAutogenMsg configureResult + assertOutputContains benchAutogenMsg configureResult + + -- Asserts for the desired check messages after sdist. + assertOutputContains "Distribution quality errors:" sdistResult + assertOutputContains libAutogenMsg sdistResult + assertOutputContains exeAutogenMsg sdistResult + assertOutputContains testAutogenMsg sdistResult + assertOutputContains benchAutogenMsg sdistResult + assertOutputContains pathsAutogenMsg sdistResult + -- Asserts for the undesired check messages after sdist. + assertOutputDoesNotContain "Distribution quality warnings:" sdistResult + + -- Asserts for the error messages of the modules not found. + assertOutputContains + "Error: Could not find module: MyLibHelperModule with any suffix" + sdistResult + assertOutputContains + "module is autogenerated it should be added to 'autogen-modules'" + sdistResult + + return () diff --git a/Cabal/tests/PackageTests/AutogenModules/Package/Dummy.hs b/Cabal/tests/PackageTests/AutogenModules/Package/Dummy.hs new file mode 100644 index 00000000000..2e87d262bd1 --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/Package/Dummy.hs @@ -0,0 +1,4 @@ +module Dummy where + +main :: IO () +main = error "" diff --git a/Cabal/tests/PackageTests/AutogenModules/Package/LICENSE b/Cabal/tests/PackageTests/AutogenModules/Package/LICENSE new file mode 100644 index 00000000000..6b1d0bfabc3 --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/Package/LICENSE @@ -0,0 +1 @@ +LICENSE diff --git a/Cabal/tests/PackageTests/AutogenModules/Package/MyBenchModule.hs b/Cabal/tests/PackageTests/AutogenModules/Package/MyBenchModule.hs new file mode 100644 index 00000000000..a27eb85951e --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/Package/MyBenchModule.hs @@ -0,0 +1,4 @@ +module MyBenchModule where + +main :: IO () +main = error "" diff --git a/Cabal/tests/PackageTests/AutogenModules/Package/MyExeModule.hs b/Cabal/tests/PackageTests/AutogenModules/Package/MyExeModule.hs new file mode 100644 index 00000000000..d1f79ce0c83 --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/Package/MyExeModule.hs @@ -0,0 +1,4 @@ +module MyExeModule where + +main :: IO () +main = error "" diff --git a/Cabal/tests/PackageTests/AutogenModules/Package/MyLibModule.hs b/Cabal/tests/PackageTests/AutogenModules/Package/MyLibModule.hs new file mode 100644 index 00000000000..4bba184d1db --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/Package/MyLibModule.hs @@ -0,0 +1,4 @@ +module MyLibModule where + +main :: IO () +main = error "" diff --git a/Cabal/tests/PackageTests/AutogenModules/Package/MyLibrary.hs b/Cabal/tests/PackageTests/AutogenModules/Package/MyLibrary.hs new file mode 100644 index 00000000000..e8af803726e --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/Package/MyLibrary.hs @@ -0,0 +1,4 @@ +module MyLibrary where + +main :: IO () +main = error "" diff --git a/Cabal/tests/PackageTests/AutogenModules/Package/MyTestModule.hs b/Cabal/tests/PackageTests/AutogenModules/Package/MyTestModule.hs new file mode 100644 index 00000000000..95c94a93184 --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/Package/MyTestModule.hs @@ -0,0 +1,4 @@ +module MyTestModule where + +main :: IO () +main = error "" diff --git a/Cabal/tests/PackageTests/AutogenModules/Package/my.cabal b/Cabal/tests/PackageTests/AutogenModules/Package/my.cabal new file mode 100644 index 00000000000..ff5f42ca4d9 --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/Package/my.cabal @@ -0,0 +1,60 @@ +name: AutogenModules +version: 0.1 +license: BSD3 +license-file: LICENSE +author: Federico Mastellone +maintainer: Federico Mastellone +synopsis: AutogenModules +category: PackageTests +build-type: Simple +cabal-version: >= 1.25 + +description: + Check that Cabal recognizes the autogen-modules fields below. + +Library + default-language: Haskell2010 + build-depends: base + exposed-modules: + MyLibrary + Paths_AutogenModules + MyLibHelperModule + other-modules: + MyLibModule + autogen-modules: + MyHelperModule + +Executable Exe + default-language: Haskell2010 + main-is: Dummy.hs + build-depends: base + other-modules: + MyExeModule + Paths_AutogenModules + MyExeHelperModule + autogen-modules: + MyHelperModule + +Test-Suite Test + default-language: Haskell2010 + main-is: Dummy.hs + type: exitcode-stdio-1.0 + build-depends: base + other-modules: + MyTestModule + Paths_AutogenModules + MyTestHelperModule + autogen-modules: + MyHelperModule + +Benchmark Bench + default-language: Haskell2010 + main-is: Dummy.hs + type: exitcode-stdio-1.0 + build-depends: base + other-modules: + MyBenchModule + Paths_AutogenModules + MyBenchHelperModule + autogen-modules: + MyHelperModule diff --git a/Cabal/tests/PackageTests/AutogenModules/Package/tmp b/Cabal/tests/PackageTests/AutogenModules/Package/tmp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/Cabal/tests/PackageTests/AutogenModules/SrcDist/Check.hs b/Cabal/tests/PackageTests/AutogenModules/SrcDist/Check.hs new file mode 100644 index 00000000000..cfaae18173e --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/SrcDist/Check.hs @@ -0,0 +1,104 @@ +module PackageTests.AutogenModules.SrcDist.Check where + +import Distribution.ModuleName +import Distribution.Simple.LocalBuildInfo +import Distribution.PackageDescription +import PackageTests.PackageTester + +suite :: TestM () +suite = do + + dist_dir <- distDir + + -- Calling sdist without running configure first makes test fail with: + -- "Exception: Run the 'configure' command first." + -- This is becuase we are calling getPersistBuildConfig + + configureResult <- cabal' "configure" [] + sdistResult <- cabal' "sdist" [] + + -- Now check that all the correct modules were parsed. + lbi <- liftIO $ getPersistBuildConfig dist_dir + let (Just gotLibrary) = library (localPkgDescr lbi) + let gotExecutable = head $ executables (localPkgDescr lbi) + let gotTestSuite = head $ testSuites (localPkgDescr lbi) + let gotBenchmark = head $ benchmarks (localPkgDescr lbi) + assertEqual "library 'autogen-modules' field does not match expected" + [fromString "MyLibHelperModule"] + (libModulesAutogen gotLibrary) + assertEqual "executable 'autogen-modules' field does not match expected" + [fromString "MyExeHelperModule"] + (exeModulesAutogen gotExecutable) + assertEqual "test-suite 'autogen-modules' field does not match expected" + [fromString "MyTestHelperModule"] + (testModulesAutogen gotTestSuite) + assertEqual "benchmark 'autogen-modules' field does not match expected" + [fromString "MyBenchHelperModule"] + (benchmarkModulesAutogen gotBenchmark) + + -- Package check messages. + let libAutogenMsg = + "An 'autogen-module' is neither on 'exposed-modules' or " + ++ "'other-modules'" + let exeAutogenMsg = + "On executable 'Exe' an 'autogen-module' is not on " + ++ "'other-modules'" + let testAutogenMsg = + "On test suite 'Test' an 'autogen-module' is not on " + ++ "'other-modules'" + let benchAutogenMsg = + "On benchmark 'Bench' an 'autogen-module' is not on " + ++ "'other-modules'" + let pathsAutogenMsg = + "Packages using 'cabal-version: >= 1.25' and the autogenerated" + + -- Asserts for the undesired check messages after configure. + assertOutputDoesNotContain libAutogenMsg configureResult + assertOutputDoesNotContain exeAutogenMsg configureResult + assertOutputDoesNotContain testAutogenMsg configureResult + assertOutputDoesNotContain benchAutogenMsg configureResult + assertOutputDoesNotContain pathsAutogenMsg configureResult + + -- Asserts for the undesired check messages after sdist. + assertOutputDoesNotContain "Distribution quality errors:" sdistResult + assertOutputDoesNotContain libAutogenMsg sdistResult + assertOutputDoesNotContain exeAutogenMsg sdistResult + assertOutputDoesNotContain testAutogenMsg sdistResult + assertOutputDoesNotContain benchAutogenMsg sdistResult + assertOutputDoesNotContain "Distribution quality warnings:" sdistResult + assertOutputDoesNotContain pathsAutogenMsg sdistResult + + -- Assert sdist --list-sources output. + -- If called before configure fails, dist directory is not created. + let listSourcesFileGot = dist_dir ++ "/" ++ "list-sources.txt" + cabal "sdist" ["--list-sources=" ++ listSourcesFileGot] + let listSourcesStrExpected = +#if defined(mingw32_HOST_OS) + ".\\MyLibrary.hs\n" + ++ ".\\MyLibModule.hs\n" + ++ ".\\Dummy.hs\n" + ++ ".\\MyExeModule.hs\n" + ++ ".\\Dummy.hs\n" + ++ ".\\MyTestModule.hs\n" + ++ ".\\Dummy.hs\n" + ++ ".\\MyBenchModule.hs\n" + ++ "LICENSE\n" + ++ ".\\my.cabal\n" +#else + "./MyLibrary.hs\n" + ++ "./MyLibModule.hs\n" + ++ "./Dummy.hs\n" + ++ "./MyExeModule.hs\n" + ++ "./Dummy.hs\n" + ++ "./MyTestModule.hs\n" + ++ "./Dummy.hs\n" + ++ "./MyBenchModule.hs\n" + ++ "LICENSE\n" + ++ "./my.cabal\n" +#endif + listSourcesStrGot <- liftIO $ readFile listSourcesFileGot + assertEqual "sdist --list-sources does not match the expected files" + listSourcesStrExpected + listSourcesStrGot + + return () diff --git a/Cabal/tests/PackageTests/AutogenModules/SrcDist/Dummy.hs b/Cabal/tests/PackageTests/AutogenModules/SrcDist/Dummy.hs new file mode 100644 index 00000000000..2e87d262bd1 --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/SrcDist/Dummy.hs @@ -0,0 +1,4 @@ +module Dummy where + +main :: IO () +main = error "" diff --git a/Cabal/tests/PackageTests/AutogenModules/SrcDist/LICENSE b/Cabal/tests/PackageTests/AutogenModules/SrcDist/LICENSE new file mode 100644 index 00000000000..6b1d0bfabc3 --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/SrcDist/LICENSE @@ -0,0 +1 @@ +LICENSE diff --git a/Cabal/tests/PackageTests/AutogenModules/SrcDist/MyBenchModule.hs b/Cabal/tests/PackageTests/AutogenModules/SrcDist/MyBenchModule.hs new file mode 100644 index 00000000000..a27eb85951e --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/SrcDist/MyBenchModule.hs @@ -0,0 +1,4 @@ +module MyBenchModule where + +main :: IO () +main = error "" diff --git a/Cabal/tests/PackageTests/AutogenModules/SrcDist/MyExeModule.hs b/Cabal/tests/PackageTests/AutogenModules/SrcDist/MyExeModule.hs new file mode 100644 index 00000000000..d1f79ce0c83 --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/SrcDist/MyExeModule.hs @@ -0,0 +1,4 @@ +module MyExeModule where + +main :: IO () +main = error "" diff --git a/Cabal/tests/PackageTests/AutogenModules/SrcDist/MyLibModule.hs b/Cabal/tests/PackageTests/AutogenModules/SrcDist/MyLibModule.hs new file mode 100644 index 00000000000..4bba184d1db --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/SrcDist/MyLibModule.hs @@ -0,0 +1,4 @@ +module MyLibModule where + +main :: IO () +main = error "" diff --git a/Cabal/tests/PackageTests/AutogenModules/SrcDist/MyLibrary.hs b/Cabal/tests/PackageTests/AutogenModules/SrcDist/MyLibrary.hs new file mode 100644 index 00000000000..e8af803726e --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/SrcDist/MyLibrary.hs @@ -0,0 +1,4 @@ +module MyLibrary where + +main :: IO () +main = error "" diff --git a/Cabal/tests/PackageTests/AutogenModules/SrcDist/MyTestModule.hs b/Cabal/tests/PackageTests/AutogenModules/SrcDist/MyTestModule.hs new file mode 100644 index 00000000000..95c94a93184 --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/SrcDist/MyTestModule.hs @@ -0,0 +1,4 @@ +module MyTestModule where + +main :: IO () +main = error "" diff --git a/Cabal/tests/PackageTests/AutogenModules/SrcDist/list-sources.txt b/Cabal/tests/PackageTests/AutogenModules/SrcDist/list-sources.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/Cabal/tests/PackageTests/AutogenModules/SrcDist/my.cabal b/Cabal/tests/PackageTests/AutogenModules/SrcDist/my.cabal new file mode 100644 index 00000000000..75b2d43eebb --- /dev/null +++ b/Cabal/tests/PackageTests/AutogenModules/SrcDist/my.cabal @@ -0,0 +1,60 @@ +name: AutogenModules +version: 0.1 +license: BSD3 +license-file: LICENSE +author: Federico Mastellone +maintainer: Federico Mastellone +synopsis: AutogenModules +category: PackageTests +build-type: Simple +cabal-version: >= 1.24 + +description: + Check that Cabal recognizes the autogen-modules fields below. + +Library + default-language: Haskell2010 + build-depends: base + exposed-modules: + MyLibrary + Paths_AutogenModules + MyLibHelperModule + other-modules: + MyLibModule + autogen-modules: + MyLibHelperModule + +Executable Exe + default-language: Haskell2010 + main-is: Dummy.hs + build-depends: base + other-modules: + MyExeModule + Paths_AutogenModules + MyExeHelperModule + autogen-modules: + MyExeHelperModule + +Test-Suite Test + default-language: Haskell2010 + main-is: Dummy.hs + type: exitcode-stdio-1.0 + build-depends: base + other-modules: + MyTestModule + Paths_AutogenModules + MyTestHelperModule + autogen-modules: + MyTestHelperModule + +Benchmark Bench + default-language: Haskell2010 + main-is: Dummy.hs + type: exitcode-stdio-1.0 + build-depends: base + other-modules: + MyBenchModule + Paths_AutogenModules + MyBenchHelperModule + autogen-modules: + MyBenchHelperModule diff --git a/Cabal/tests/PackageTests/Tests.hs b/Cabal/tests/PackageTests/Tests.hs index 9ec1f388c18..9ebe68fbfb3 100644 --- a/Cabal/tests/PackageTests/Tests.hs +++ b/Cabal/tests/PackageTests/Tests.hs @@ -2,6 +2,8 @@ module PackageTests.Tests(tests) where import PackageTests.PackageTester +import qualified PackageTests.AutogenModules.Package.Check +import qualified PackageTests.AutogenModules.SrcDist.Check import qualified PackageTests.BenchmarkStanza.Check import qualified PackageTests.TestStanza.Check import qualified PackageTests.DeterministicAr.Check @@ -40,6 +42,11 @@ tests config = do -- Test that Cabal determinstically generates object archives tc "DeterministicAr" PackageTests.DeterministicAr.Check.suite + -- Test that cabal shows all the 'autogen-modules' warnings. + tc "AutogenModules/Package" PackageTests.AutogenModules.Package.Check.suite + -- Test that Cabal parses and uses 'autogen-modules' fields correctly + tc "AutogenModules/SrcDist" PackageTests.AutogenModules.SrcDist.Check.suite + --------------------------------------------------------------------- -- * Test suite tests