hpack 0.17.1 → 0.18.0
raw patch · 9 files changed
+360/−62 lines, 9 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Hpack.Config: [sectionGhcjsOptions] :: Section a -> [GhcjsOption]
+ Hpack.Config: [sectionJsSources] :: Section a -> [FilePath]
- Hpack: hpack :: FilePath -> Bool -> IO ()
+ Hpack: hpack :: Maybe FilePath -> Bool -> IO ()
- Hpack: hpackResult :: FilePath -> IO Result
+ Hpack: hpackResult :: Maybe FilePath -> IO Result
- Hpack.Config: Package :: String -> String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> [String] -> [String] -> [String] -> BuildType -> Maybe String -> Maybe FilePath -> Maybe String -> [Flag] -> [FilePath] -> [FilePath] -> Maybe SourceRepository -> Maybe CustomSetup -> Maybe (Section Library) -> [Section Executable] -> [Section Executable] -> [Section Executable] -> Package
+ Hpack.Config: Package :: String -> String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> [String] -> [String] -> [String] -> BuildType -> Maybe String -> [FilePath] -> Maybe String -> [Flag] -> [FilePath] -> [FilePath] -> Maybe SourceRepository -> Maybe CustomSetup -> Maybe (Section Library) -> [Section Executable] -> [Section Executable] -> [Section Executable] -> Package
- Hpack.Config: Section :: a -> [FilePath] -> [Dependency] -> [String] -> [String] -> [GhcOption] -> [GhcProfOption] -> [CppOption] -> [CcOption] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [LdOption] -> Maybe Bool -> [Conditional] -> [Dependency] -> Section a
+ Hpack.Config: Section :: a -> [FilePath] -> [Dependency] -> [String] -> [String] -> [GhcOption] -> [GhcProfOption] -> [GhcjsOption] -> [CppOption] -> [CcOption] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [LdOption] -> Maybe Bool -> [Conditional] -> [Dependency] -> Section a
- Hpack.Config: [packageLicenseFile] :: Package -> Maybe FilePath
+ Hpack.Config: [packageLicenseFile] :: Package -> [FilePath]
- Hpack.Run: run :: FilePath -> IO ([String], FilePath, String)
+ Hpack.Run: run :: Maybe FilePath -> FilePath -> IO ([String], FilePath, String)
Files
- CHANGELOG.md +19/−0
- hpack.cabal +5/−2
- src/Hpack.hs +29/−14
- src/Hpack/Config.hs +73/−30
- src/Hpack/Run.hs +12/−4
- src/Hpack/Util.hs +2/−0
- test/Hpack/ConfigSpec.hs +152/−5
- test/Hpack/RunSpec.hs +24/−1
- test/HpackSpec.hs +44/−6
+ CHANGELOG.md view
@@ -0,0 +1,19 @@+## Change in 0.18.0+ - Make `executable` a shortcut of `executables: { package-name: ... }`+ - Add support for `ghcjs-options` and `js-sources` (see #161)+ - Allow `license-file` to be a list+ - Accept input file on command-line (see #106)+ - Add Paths_* when no modules are specified (see #86)++## Changes in 0.17.1+ - Do not descend into irrelevant directories when inferring modules (see #165)++## Changes in 0.17.0+ - Added custom-setup section+ - Add support for `!include` directives++## Changes in 0.16.0+ - Warn when `name` is missing+ - Support globs in `c-sources`+ - Use binary I/O for cabal files avoiding problems with non-UTF-8 locales+ - Fix rendering of `.` as directory (cabal syntax issue)
hpack.cabal view
@@ -1,9 +1,9 @@--- This file has been generated from package.yaml by hpack version 0.17.0.+-- This file has been generated from package.yaml by hpack version 0.18.0. -- -- see: https://github.com/sol/hpack name: hpack-version: 0.17.1+version: 0.18.0 synopsis: An alternative format for Haskell packages description: See README at <https://github.com/sol/hpack#readme> category: Development@@ -14,6 +14,9 @@ license-file: LICENSE build-type: Simple cabal-version: >= 1.10++extra-source-files:+ CHANGELOG.md source-repository head type: git
src/Hpack.hs view
@@ -11,6 +11,7 @@ , parseVerbosity , extractVersion , parseVersion+, splitDirectory #endif ) where @@ -28,6 +29,8 @@ import System.Environment import System.Exit import System.IO+import System.FilePath+import System.Directory import Text.ParserCombinators.ReadP import Paths_hpack (version)@@ -38,9 +41,9 @@ programVersion :: Version -> String programVersion v = "hpack version " ++ Version.showVersion v -header :: Version -> String-header v = unlines [- "-- This file has been generated from " ++ packageConfig ++ " by " ++ programVersion v ++ "."+header :: FilePath -> Version -> String+header p v = unlines [+ "-- This file has been generated from " ++ p ++ " by " ++ programVersion v ++ "." , "--" , "-- see: https://github.com/sol/hpack" , ""@@ -53,8 +56,8 @@ ["--version"] -> putStrLn (programVersion version) ["--help"] -> printHelp _ -> case parseVerbosity args of- (verbose, [dir]) -> hpack dir verbose- (verbose, []) -> hpack "" verbose+ (verbose, [dir]) -> hpack (Just dir) verbose+ (verbose, []) -> hpack Nothing verbose _ -> do printHelp exitFailure@@ -87,10 +90,10 @@ [v] -> Just v _ -> Nothing -hpack :: FilePath -> Bool -> IO ()+hpack :: Maybe FilePath -> Bool -> IO () hpack = hpackWithVersion version -hpackResult :: FilePath -> IO Result+hpackResult :: Maybe FilePath -> IO Result hpackResult = hpackWithVersionResult version data Result = Result {@@ -101,9 +104,9 @@ data Status = Generated | AlreadyGeneratedByNewerHpack | OutputUnchanged -hpackWithVersion :: Version -> FilePath -> Bool -> IO ()-hpackWithVersion v dir verbose = do- r <- hpackWithVersionResult v dir+hpackWithVersion :: Version -> Maybe FilePath -> Bool -> IO ()+hpackWithVersion v p verbose = do+ r <- hpackWithVersionResult v p forM_ (resultWarnings r) $ \warning -> hPutStrLn stderr ("WARNING: " ++ warning) when verbose $ putStrLn $ case resultStatus r of@@ -111,9 +114,21 @@ OutputUnchanged -> resultCabalFile r ++ " is up-to-date" AlreadyGeneratedByNewerHpack -> resultCabalFile r ++ " was generated with a newer version of hpack, please upgrade and try again." -hpackWithVersionResult :: Version -> FilePath -> IO Result-hpackWithVersionResult v dir = do- (warnings, cabalFile, new) <- run dir+splitDirectory :: Maybe FilePath -> IO (Maybe FilePath, FilePath)+splitDirectory Nothing = return (Nothing, packageConfig)+splitDirectory (Just p) = do+ isDirectory <- doesDirectoryExist p+ return $ if isDirectory+ then (Just p, packageConfig)+ else let+ file = takeFileName p+ dir = takeDirectory p+ in (guard (p /= file) >> Just dir, if null file then packageConfig else file)++hpackWithVersionResult :: Version -> Maybe FilePath -> IO Result+hpackWithVersionResult v p = do+ (dir, file) <- splitDirectory p+ (warnings, cabalFile, new) <- run dir file old <- fmap splitHeader <$> tryReadFile cabalFile let oldVersion = fmap fst old >>= extractVersion status <-@@ -121,7 +136,7 @@ if (fmap snd old == Just (lines new)) then return OutputUnchanged else do- B.writeFile cabalFile $ encodeUtf8 $ T.pack $ header v ++ new+ B.writeFile cabalFile $ encodeUtf8 $ T.pack $ header file v ++ new return Generated else return AlreadyGeneratedByNewerHpack
src/Hpack/Config.hs view
@@ -80,7 +80,7 @@ , packageCopyright = [] , packageBuildType = Simple , packageLicense = Nothing- , packageLicenseFile = Nothing+ , packageLicenseFile = [] , packageTestedWith = Nothing , packageFlags = [] , packageExtraSourceFiles = []@@ -119,7 +119,7 @@ ++ maybe [] sectionDependencies packageLibrary section :: a -> Section a-section a = Section a [] [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing [] []+section a = Section a [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing [] [] packageConfig :: FilePath packageConfig = "package.yaml"@@ -230,9 +230,11 @@ , commonOptionsOtherExtensions :: Maybe (List String) , commonOptionsGhcOptions :: Maybe (List GhcOption) , commonOptionsGhcProfOptions :: Maybe (List GhcProfOption)+, commonOptionsGhcjsOptions :: Maybe (List GhcjsOption) , commonOptionsCppOptions :: Maybe (List CppOption) , commonOptionsCcOptions :: Maybe (List CcOption) , commonOptionsCSources :: Maybe (List FilePath)+, commonOptionsJsSources :: Maybe (List FilePath) , commonOptionsExtraLibDirs :: Maybe (List FilePath) , commonOptionsExtraLibraries :: Maybe (List FilePath) , commonOptionsIncludeDirs :: Maybe (List FilePath)@@ -308,6 +310,8 @@ "Custom" -> return Custom _ -> fail "build-type must be one of: Simple, Configure, Make, Custom" +type ExecutableConfig = CaptureUnknownFields (Section ExecutableSection)+ data PackageConfig = PackageConfig { packageConfigName :: Maybe String , packageConfigVersion :: Maybe String@@ -322,7 +326,7 @@ , packageConfigCopyright :: Maybe (List String) , packageConfigBuildType :: Maybe BuildType , packageConfigLicense :: Maybe String-, packageConfigLicenseFile :: Maybe String+, packageConfigLicenseFile :: Maybe (List String) , packageConfigTestedWith :: Maybe String , packageConfigFlags :: Maybe (Map String (CaptureUnknownFields FlagSection)) , packageConfigExtraSourceFiles :: Maybe (List FilePath)@@ -331,7 +335,8 @@ , packageConfigGit :: Maybe String , packageConfigCustomSetup :: Maybe (CaptureUnknownFields CustomSetupSection) , packageConfigLibrary :: Maybe (CaptureUnknownFields (Section LibrarySection))-, packageConfigExecutables :: Maybe (Map String (CaptureUnknownFields (Section ExecutableSection)))+, packageConfigExecutable :: Maybe ExecutableConfig+, packageConfigExecutables :: Maybe (Map String ExecutableConfig) , packageConfigTests :: Maybe (Map String (CaptureUnknownFields (Section ExecutableSection))) , packageConfigBenchmarks :: Maybe (Map String (CaptureUnknownFields (Section ExecutableSection))) } deriving (Eq, Show, Generic)@@ -425,7 +430,7 @@ , packageCopyright :: [String] , packageBuildType :: BuildType , packageLicense :: Maybe String-, packageLicenseFile :: Maybe FilePath+, packageLicenseFile :: [FilePath] , packageTestedWith :: Maybe String , packageFlags :: [Flag] , packageExtraSourceFiles :: [FilePath]@@ -463,9 +468,11 @@ , sectionOtherExtensions :: [String] , sectionGhcOptions :: [GhcOption] , sectionGhcProfOptions :: [GhcProfOption]+, sectionGhcjsOptions :: [GhcjsOption] , sectionCppOptions :: [CppOption] , sectionCcOptions :: [CcOption] , sectionCSources :: [FilePath]+, sectionJsSources :: [FilePath] , sectionExtraLibDirs :: [FilePath] , sectionExtraLibraries :: [FilePath] , sectionIncludeDirs :: [FilePath]@@ -514,24 +521,30 @@ mkPackage :: FilePath -> (CaptureUnknownFields (Section PackageConfig)) -> IO ([String], Package) mkPackage dir (CaptureUnknownFields unknownFields globalOptions@Section{sectionData = PackageConfig{..}}) = do+ libraryResult <- mapM (toLibrary dir packageName_ globalOptions) mLibrarySection let- nameWarnings :: [String]- name :: String- (nameWarnings, name) = maybe (["Package name not specified, inferred " ++ show inferredName], inferredName) ((,) []) packageConfigName- where inferredName = takeBaseName dir+ executableWarnings :: [String]+ executableSections :: [(String, Section ExecutableSection)]+ (executableWarnings, executableSections) = (warnings, map (fmap captureUnknownFieldsValue) sections)+ where+ sections = case (packageConfigExecutable, packageConfigExecutables) of+ (Nothing, Nothing) -> []+ (Just executable, _) -> [(packageName_, executable)]+ (Nothing, Just executables) -> Map.toList executables - mCustomSetup :: Maybe CustomSetup- mCustomSetup = toCustomSetup <$> mCustomSetupSection+ warnings = ignoringExecutablesWarning ++ unknownFieldWarnings+ ignoringExecutablesWarning = case (packageConfigExecutable, packageConfigExecutables) of+ (Just _, Just _) -> ["Ignoring field \"executables\" in favor of \"executable\""]+ _ -> []+ unknownFieldWarnings = formatUnknownSectionFields (isJust packageConfigExecutables) "executable" sections - libraryResult <- mapM (toLibrary dir name globalOptions) mLibrarySection- let mLibrary :: Maybe (Section Library) mLibrary = fmap snd libraryResult libraryWarnings :: [String] libraryWarnings = maybe [] fst libraryResult - (executablesWarnings, executables) <- toExecutables dir globalOptions (map (fmap captureUnknownFieldsValue) executableSections)+ (executablesWarnings, executables) <- toExecutables dir globalOptions executableSections (testsWarnings, tests) <- toExecutables dir globalOptions (map (fmap captureUnknownFieldsValue) testsSections) (benchmarksWarnings, benchmarks) <- toExecutables dir globalOptions (map (fmap captureUnknownFieldsValue) benchmarkSections) @@ -553,8 +566,13 @@ let defaultBuildType :: BuildType defaultBuildType = maybe Simple (const Custom) mCustomSetup + configLicenseFiles :: Maybe (List String)+ configLicenseFiles = packageConfigLicenseFile <|> do+ guard licenseFileExists+ Just (List ["LICENSE"])+ pkg = Package {- packageName = name+ packageName = packageName_ , packageVersion = fromMaybe "0.0.0" packageConfigVersion , packageSynopsis = packageConfigSynopsis , packageDescription = packageConfigDescription@@ -567,7 +585,7 @@ , packageCopyright = fromMaybeList packageConfigCopyright , packageBuildType = fromMaybe defaultBuildType packageConfigBuildType , packageLicense = packageConfigLicense- , packageLicenseFile = packageConfigLicenseFile <|> (guard licenseFileExists >> Just "LICENSE")+ , packageLicenseFile = fromMaybeList configLicenseFiles , packageTestedWith = packageConfigTestedWith , packageFlags = flags , packageExtraSourceFiles = extraSourceFiles@@ -586,10 +604,11 @@ ++ flagWarnings ++ maybe [] (formatUnknownFields "custom-setup section") (captureUnknownFieldsFields <$> packageConfigCustomSetup) ++ maybe [] (formatUnknownFields "library section") (captureUnknownFieldsFields <$> packageConfigLibrary)- ++ formatUnknownSectionFields "executable" executableSections- ++ formatUnknownSectionFields "test" testsSections+ ++ formatUnknownSectionFields True "test" testsSections+ ++ formatUnknownSectionFields True "benchmark" benchmarkSections ++ formatMissingSourceDirs missingSourceDirs ++ libraryWarnings+ ++ executableWarnings ++ executablesWarnings ++ testsWarnings ++ benchmarksWarnings@@ -598,9 +617,16 @@ return (warnings, pkg) where- executableSections :: [(String, CaptureUnknownFields (Section ExecutableSection))]- executableSections = toList packageConfigExecutables+ nameWarnings :: [String]+ packageName_ :: String+ (nameWarnings, packageName_) = case packageConfigName of+ Nothing -> let inferredName = takeBaseName dir in+ (["Package name not specified, inferred " ++ show inferredName], inferredName)+ Just n -> ([], n) + mCustomSetup :: Maybe CustomSetup+ mCustomSetup = toCustomSetup <$> mCustomSetupSection+ testsSections :: [(String, CaptureUnknownFields (Section ExecutableSection))] testsSections = toList packageConfigTests @@ -630,11 +656,13 @@ where f field = "Ignoring unknown field " ++ show field ++ " in " ++ name - formatUnknownSectionFields :: String -> [(String, CaptureUnknownFields a)] -> [String]- formatUnknownSectionFields sectionType = concatMap f . map (fmap captureUnknownFieldsFields)+ formatUnknownSectionFields :: Bool -> String -> [(String, CaptureUnknownFields a)] -> [String]+ formatUnknownSectionFields showSect sectionType = concatMap f . map (fmap captureUnknownFieldsFields) where f :: (String, [String]) -> [String]- f (sect, fields) = formatUnknownFields (sectionType ++ " section " ++ show sect) fields+ f (sect, fields) = formatUnknownFields+ (sectionType ++ " section" ++ if showSect then " " ++ show sect else "")+ fields formatMissingSourceDirs = map f where@@ -671,12 +699,23 @@ (warnings, files) <- expandGlobs "c-sources" dir sectionCSources return (warnings, sect {sectionCSources = files}) +expandJsSources :: FilePath -> Section a -> IO ([String], Section a)+expandJsSources dir sect@Section{..} = do+ (warnings, files) <- expandGlobs "js-sources" dir sectionJsSources+ return (warnings, sect {sectionJsSources = files})++expandForeignSources :: FilePath -> Section a -> IO ([String], Section a)+expandForeignSources dir sect = do+ (cWarnings, sect_) <- expandCSources dir sect+ (jsWarnings, sect__) <- expandJsSources dir sect_+ return (cWarnings ++ jsWarnings, sect__)+ toCustomSetup :: CustomSetupSection -> CustomSetup toCustomSetup CustomSetupSection{..} = CustomSetup { customSetupDependencies = fromMaybeList customSetupSectionDependencies } toLibrary :: FilePath -> String -> Section global -> Section LibrarySection -> IO ([String], Section Library)-toLibrary dir name globalOptions library = traverse fromLibrarySection sect >>= expandCSources dir+toLibrary dir name globalOptions library = traverse fromLibrarySection sect >>= expandForeignSources dir where sect :: Section LibrarySection sect = mergeSections globalOptions library@@ -693,7 +732,7 @@ toExecutables :: FilePath -> Section global -> [(String, Section ExecutableSection)] -> IO ([String], [Section Executable]) toExecutables dir globalOptions executables = do- result <- mapM toExecutable sections >>= mapM (expandCSources dir)+ result <- mapM toExecutable sections >>= mapM (expandForeignSources dir) let (warnings, xs) = unzip result return (concat warnings, xs) where@@ -724,9 +763,11 @@ , sectionOtherExtensions = sectionOtherExtensions globalOptions ++ sectionOtherExtensions options , sectionGhcOptions = sectionGhcOptions globalOptions ++ sectionGhcOptions options , sectionGhcProfOptions = sectionGhcProfOptions globalOptions ++ sectionGhcProfOptions options+ , sectionGhcjsOptions = sectionGhcjsOptions globalOptions ++ sectionGhcjsOptions options , sectionCppOptions = sectionCppOptions globalOptions ++ sectionCppOptions options , sectionCcOptions = sectionCcOptions globalOptions ++ sectionCcOptions options , sectionCSources = sectionCSources globalOptions ++ sectionCSources options+ , sectionJsSources = sectionJsSources globalOptions ++ sectionJsSources options , sectionExtraLibDirs = sectionExtraLibDirs globalOptions ++ sectionExtraLibDirs options , sectionExtraLibraries = sectionExtraLibraries globalOptions ++ sectionExtraLibraries options , sectionIncludeDirs = sectionIncludeDirs globalOptions ++ sectionIncludeDirs options@@ -748,9 +789,11 @@ , sectionOtherExtensions = fromMaybeList commonOptionsOtherExtensions , sectionGhcOptions = fromMaybeList commonOptionsGhcOptions , sectionGhcProfOptions = fromMaybeList commonOptionsGhcProfOptions+ , sectionGhcjsOptions = fromMaybeList commonOptionsGhcjsOptions , sectionCppOptions = fromMaybeList commonOptionsCppOptions , sectionCcOptions = fromMaybeList commonOptionsCcOptions , sectionCSources = fromMaybeList commonOptionsCSources+ , sectionJsSources = fromMaybeList commonOptionsJsSources , sectionExtraLibDirs = fromMaybeList commonOptionsExtraLibDirs , sectionExtraLibraries = fromMaybeList commonOptionsExtraLibraries , sectionIncludeDirs = fromMaybeList commonOptionsIncludeDirs@@ -779,12 +822,12 @@ determineModules :: String -> [String] -> Maybe (List String) -> Maybe (List String) -> ([String], [String]) determineModules name modules mExposedModules mOtherModules = case (mExposedModules, mOtherModules) of- (Nothing, Nothing) -> (modules, [])+ (Nothing, Nothing) -> (modules, [pathsModuleFromPackageName name]) _ -> (exposedModules, otherModules)- where- otherModules = maybe ((modules \\ exposedModules) ++ pathsModule) fromList mOtherModules- exposedModules = maybe (modules \\ otherModules) fromList mExposedModules- pathsModule = [pathsModuleFromPackageName name] \\ exposedModules+ where+ otherModules = maybe ((modules \\ exposedModules) ++ pathsModule) fromList mOtherModules+ exposedModules = maybe (modules \\ otherModules) fromList mExposedModules+ pathsModule = [pathsModuleFromPackageName name] \\ exposedModules getModules :: FilePath -> FilePath -> IO [String] getModules dir src_ = sort <$> do
src/Hpack/Run.hs view
@@ -34,9 +34,10 @@ import Hpack.Render import Hpack.FormattingHints -run :: FilePath -> IO ([String], FilePath, String)-run dir = do- mPackage <- readPackageConfig (dir </> packageConfig)+run :: Maybe FilePath -> FilePath -> IO ([String], FilePath, String)+run mDir c = do+ let dir = fromMaybe "" mDir+ mPackage <- readPackageConfig (dir </> c) case mPackage of Right (warnings, pkg) -> do let cabalFile = dir </> (packageName pkg ++ ".cabal")@@ -105,7 +106,9 @@ , ("maintainer", formatList packageMaintainer) , ("copyright", formatList packageCopyright) , ("license", packageLicense)- , ("license-file", packageLicenseFile)+ , case packageLicenseFile of+ [file] -> ("license-file", Just file)+ files -> ("license-files", formatList files) , ("tested-with", packageTestedWith) , ("build-type", Just (show packageBuildType)) , ("cabal-version", cabalVersion)@@ -219,11 +222,13 @@ , renderOtherExtensions sectionOtherExtensions , renderGhcOptions sectionGhcOptions , renderGhcProfOptions sectionGhcProfOptions+ , renderGhcjsOptions sectionGhcjsOptions , renderCppOptions sectionCppOptions , renderCcOptions sectionCcOptions , renderDirectories "include-dirs" sectionIncludeDirs , Field "install-includes" (LineSeparatedList sectionInstallIncludes) , Field "c-sources" (LineSeparatedList sectionCSources)+ , Field "js-sources" (LineSeparatedList sectionJsSources) , renderDirectories "extra-lib-dirs" sectionExtraLibDirs , Field "extra-libraries" (LineSeparatedList sectionExtraLibraries) , renderLdOptions sectionLdOptions@@ -268,6 +273,9 @@ renderGhcProfOptions :: [GhcProfOption] -> Element renderGhcProfOptions = Field "ghc-prof-options" . WordList++renderGhcjsOptions :: [GhcjsOption] -> Element+renderGhcjsOptions = Field "ghcjs-options" . WordList renderCppOptions :: [CppOption] -> Element renderCppOptions = Field "cpp-options" . WordList
src/Hpack/Util.hs view
@@ -3,6 +3,7 @@ List(..) , GhcOption , GhcProfOption+, GhcjsOption , CppOption , CcOption , LdOption@@ -54,6 +55,7 @@ type GhcOption = String type GhcProfOption = String+type GhcjsOption = String type CppOption = String type CcOption = String type LdOption = String
test/Hpack/ConfigSpec.hs view
@@ -6,7 +6,6 @@ , package , executable-, library ) where import Helper@@ -30,7 +29,7 @@ executable name main_ = Executable name main_ [] library :: Library-library = Library Nothing [] [] []+library = Library Nothing [] ["Paths_foo"] [] withPackage :: String -> IO () -> (([String], Package) -> Expectation) -> Expectation withPackage content beforeAction expectation = withTempDirectory $ \dir_ -> do@@ -117,6 +116,15 @@ captureUnknownFieldsValue <$> decodeEither input `shouldBe` Right (section Empty){sectionCSources = ["foo.c", "bar/*.c"]} + it "accepts js-sources" $ do+ let input = [i|+ js-sources:+ - foo.js+ - bar/*.js+ |]+ captureUnknownFieldsValue <$> decodeEither input+ `shouldBe` Right (section Empty){sectionJsSources = ["foo.js", "bar/*.js"]}+ it "accepts extra-lib-dirs" $ do let input = [i| extra-lib-dirs:@@ -296,6 +304,9 @@ it "adds the Paths_* module to the other-modules" $ do determineModules "foo" [] (Just $ List ["Foo"]) Nothing `shouldBe` (["Foo"], ["Paths_foo"]) + it "adds the Paths_* module to the other-modules when no modules are specified" $ do+ determineModules "foo" [] Nothing Nothing `shouldBe` ([], ["Paths_foo"])+ it "replaces dashes with underscores in Paths_*" $ do determineModules "foo-bar" [] (Just $ List ["Foo"]) Nothing `shouldBe` (["Foo"], ["Paths_foo_bar"]) @@ -470,14 +481,20 @@ (do touch "LICENSE" )- (packageLicenseFile >>> (`shouldBe` Just "LICENSE"))+ (packageLicenseFile >>> (`shouldBe` ["LICENSE"])) it "accepts license file" $ do withPackageConfig_ [i| license-file: FOO |]- (packageLicenseFile >>> (`shouldBe` Just "FOO"))+ (packageLicenseFile >>> (`shouldBe` ["FOO"])) + it "accepts list of license files" $ do+ withPackageConfig_ [i|+ license-file: [FOO, BAR]+ |]+ (packageLicenseFile >>> (`shouldBe` ["FOO", "BAR"]))+ it "accepts build-type: Simple" $ do withPackageConfig_ [i| build-type: Simple@@ -619,6 +636,30 @@ } ) + it "accepts ghcjs-options" $ do+ withPackageConfig_ [i|+ ghcjs-options: -dedupe+ library:+ ghcjs-options: -ghcjs1++ executables:+ foo:+ main: Main.hs+ ghcjs-options: -ghcjs2+++ tests:+ spec:+ main: Spec.hs+ ghcjs-options: -ghcjs3+ |]+ (`shouldBe` package {+ packageLibrary = Just (section library) {sectionGhcjsOptions = ["-dedupe", "-ghcjs1"]}+ , packageExecutables = [(section $ executable "foo" "Main.hs") {sectionGhcjsOptions = ["-dedupe", "-ghcjs2"]}]+ , packageTests = [(section $ executable "spec" "Spec.hs") {sectionGhcjsOptions = ["-dedupe", "-ghcjs3"]}]+ }+ )+ it "accepts ld-options" $ do withPackageConfig_ [i| library:@@ -787,6 +828,30 @@ ) (packageLibrary >>> (`shouldBe` Just (section library) {sectionCSources = ["cbits/bar.c", "cbits/foo.c"]})) + it "accepts js-sources" $ do+ withPackageConfig [i|+ library:+ js-sources:+ - jsbits/*.js+ |]+ (do+ touch "jsbits/foo.js"+ touch "jsbits/bar.js"+ )+ (packageLibrary >>> (`shouldBe` Just (section library) {sectionJsSources = ["jsbits/bar.js", "jsbits/foo.js"]}))++ it "accepts global js-sources" $ do+ withPackageConfig [i|+ js-sources:+ - jsbits/*.js+ library: {}+ |]+ (do+ touch "jsbits/foo.js"+ touch "jsbits/bar.js"+ )+ (packageLibrary >>> (`shouldBe` Just (section library) {sectionJsSources = ["jsbits/bar.js", "jsbits/foo.js"]}))+ it "allows to specify exposed" $ do withPackageConfig_ [i| library:@@ -865,7 +930,7 @@ ] ) - it "reads executable section" $ do+ it "reads executables section" $ do withPackageConfig_ [i| executables: foo:@@ -873,6 +938,44 @@ |] (packageExecutables >>> (`shouldBe` [section $ executable "foo" "driver/Main.hs"])) + it "reads executable section" $ do+ withPackageConfig_ [i|+ executable:+ main: driver/Main.hs+ |]+ (packageExecutables >>> (`shouldBe` [section $ executable "foo" "driver/Main.hs"]))++ it "warns on unknown executable fields" $ do+ withPackageWarnings_ [i|+ name: foo+ executable:+ main: Main.hs+ unknown: true+ |]+ (`shouldBe` ["Ignoring unknown field \"unknown\" in executable section"])++ context "with both executable and executables" $ do+ it "gives executable precedence" $ do+ withPackageConfig_ [i|+ executable:+ main: driver/Main1.hs+ executables:+ foo2:+ main: driver/Main2.hs+ |]+ (packageExecutables >>> (`shouldBe` [section $ executable "foo" "driver/Main1.hs"]))++ it "warns" $ do+ withPackageWarnings_ [i|+ name: foo+ executable:+ main: driver/Main1.hs+ executables:+ foo2:+ main: driver/Main2.hs+ |]+ (`shouldBe` ["Ignoring field \"executables\" in favor of \"executable\""])+ it "accepts arbitrary entry points as main" $ do withPackageConfig_ [i| executables:@@ -1040,6 +1143,50 @@ touch "cbits/bar.c" ) (`shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionCSources = ["cbits/bar.c", "cbits/foo.c"]}]})++ it "accepts js-sources" $ do+ withPackageConfig [i|+ executables:+ foo:+ main: driver/Main.hs+ js-sources:+ - jsbits/*.js+ |]+ (do+ touch "jsbits/foo.js"+ touch "jsbits/bar.js"+ )+ (`shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionJsSources = ["jsbits/bar.js", "jsbits/foo.js"]}]})++ it "accepts global js-sources" $ do+ withPackageConfig [i|+ js-sources:+ - jsbits/*.js+ executables:+ foo:+ main: driver/Main.hs+ |]+ (do+ touch "jsbits/foo.js"+ touch "jsbits/bar.js"+ )+ (`shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionJsSources = ["jsbits/bar.js", "jsbits/foo.js"]}]})++ context "when reading benchmark section" $ do+ it "warns on unknown fields" $ do+ withPackageWarnings_ [i|+ name: foo+ benchmarks:+ foo:+ main: Main.hs+ bar: 42+ baz: 23+ |]+ (`shouldBe` [+ "Ignoring unknown field \"bar\" in benchmark section \"foo\""+ , "Ignoring unknown field \"baz\" in benchmark section \"foo\""+ ]+ ) context "when reading test section" $ do it "warns on unknown fields" $ do
test/Hpack/RunSpec.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} module Hpack.RunSpec (spec) where -import Test.Hspec+import Helper import Data.List.Compat import Hpack.ConfigSpec hiding (spec)@@ -9,6 +9,9 @@ import Hpack.Render import Hpack.Run +library :: Library+library = Library Nothing [] [] []+ spec :: Spec spec = do describe "renderPackage" $ do@@ -60,6 +63,25 @@ , "cabal-version: >= 1.10" ] + it "includes license-file" $ do+ renderPackage_ package {packageLicenseFile = ["FOO"]} `shouldBe` unlines [+ "name: foo"+ , "version: 0.0.0"+ , "license-file: FOO"+ , "build-type: Simple"+ , "cabal-version: >= 1.10"+ ]++ it "aligns license-files" $ do+ renderPackage defaultRenderSettings 16 [] [] package {packageLicenseFile = ["FOO", "BAR"]} `shouldBe` unlines [+ "name: foo"+ , "version: 0.0.0"+ , "license-files: FOO,"+ , " BAR"+ , "build-type: Simple"+ , "cabal-version: >= 1.10"+ ]+ it "includes copyright holder" $ do renderPackage_ package {packageCopyright = ["(c) 2015 Simon Hengel"]} `shouldBe` unlines [ "name: foo"@@ -244,6 +266,7 @@ , " ghc-prof-options: -fprof-auto -rtsopts" , " default-language: Haskell2010" ]+ describe "renderConditional" $ do it "renders conditionals" $ do let conditional = Conditional "os(windows)" (section ()) {sectionDependencies = ["Win32"]} Nothing
test/HpackSpec.hs view
@@ -1,5 +1,7 @@ module HpackSpec (spec) where +import Helper+ import Prelude () import Prelude.Compat @@ -7,8 +9,6 @@ import Control.DeepSeq import Data.Version (Version(..), showVersion) -import Test.Hspec-import Test.Mockery.Directory import Test.QuickCheck import Hpack@@ -47,9 +47,9 @@ it "does not write a new cabal file" $ do inTempDirectory $ do writeFile "package.yaml" "name: foo"- hpackWithVersion (makeVersion [0,8,0]) "." False+ hpackWithVersion (makeVersion [0,8,0]) Nothing False old <- readFile "foo.cabal" >>= (return $!!)- hpackWithVersion (makeVersion [0,10,0]) "." False+ hpackWithVersion (makeVersion [0,10,0]) Nothing False readFile "foo.cabal" `shouldReturn` old context "when exsting cabal file was generated with a newer version of hpack" $ do@@ -59,7 +59,7 @@ "name: foo" , "version: 0.1.0" ]- hpackWithVersion (makeVersion [0,10,0]) "." False+ hpackWithVersion (makeVersion [0,10,0]) Nothing False old <- readFile "foo.cabal" >>= (return $!!) writeFile "package.yaml" $ unlines [@@ -67,5 +67,43 @@ , "version: 0.2.0" ] - hpackWithVersion (makeVersion [0,8,0]) "." False+ hpackWithVersion (makeVersion [0,8,0]) Nothing False readFile "foo.cabal" `shouldReturn` old++ describe "splitDirectory" $ do+ context "when given Nothing" $ do+ it "defaults file name to package.yaml" $ do+ splitDirectory Nothing `shouldReturn` (Nothing, "package.yaml")++ context "when given a directory" $ do+ it "defaults file name to package.yaml" $ do+ withTempDirectory $ \dir -> do+ splitDirectory (Just dir) `shouldReturn` (Just dir, "package.yaml")++ context "when given a file name" $ do+ it "defaults directory to Nothing" $ do+ inTempDirectory $ do+ touch "foo.yaml"+ splitDirectory (Just "foo.yaml") `shouldReturn` (Nothing, "foo.yaml")++ context "when given a path to a file" $ do+ it "splits directory from file name" $ do+ withTempDirectory $ \dir -> do+ let file = dir </> "foo.yaml"+ touch file+ splitDirectory (Just file) `shouldReturn` (Just dir, "foo.yaml")++ context "when path does not exist" $ do+ it "defaults directory to Nothing" $ do+ inTempDirectory $ do+ splitDirectory (Just "test/foo.yaml") `shouldReturn` (Just "test", "foo.yaml")++ context "when file does not exist" $ do+ it "defaults directory to Nothing" $ do+ inTempDirectory $ do+ splitDirectory (Just "test") `shouldReturn` (Nothing, "test")++ context "when directory does not exist" $ do+ it "defaults directory to Nothing" $ do+ inTempDirectory $ do+ splitDirectory (Just "test/") `shouldReturn` (Just "test", "package.yaml")