configuration-tools 0.3.1 → 0.4.0
raw patch · 11 files changed
+292/−543 lines, 11 filesdep −mtl-compatdep −transformers-compatdep ~Cabaldep ~basedep ~base-unicode-symbolssetup-changedPVP ok
version bump matches the API change (PVP)
Dependencies removed: mtl-compat, transformers-compat
Dependency ranges changed: Cabal, base, base-unicode-symbols, mtl, transformers
API changes (from Hackage documentation)
- Configuration.Utils.Monoid: instance Data.Semigroup.Semigroup a => Data.Semigroup.Semigroup (Configuration.Utils.Monoid.LeftMonoidalUpdate a)
- Configuration.Utils.Monoid: instance Data.Semigroup.Semigroup a => Data.Semigroup.Semigroup (Configuration.Utils.Monoid.RightMonoidalUpdate a)
+ Configuration.Utils.CommandLine: (*>) :: Applicative f => f a -> f b -> f b
+ Configuration.Utils.CommandLine: (<$) :: Functor f => a -> f b -> f a
+ Configuration.Utils.CommandLine: (<$>) :: Functor f => a -> b -> f a -> f b
+ Configuration.Utils.CommandLine: (<*) :: Applicative f => f a -> f b -> f a
+ Configuration.Utils.CommandLine: (<**>) :: Applicative f => f a -> f a -> b -> f b
+ Configuration.Utils.CommandLine: (<*>) :: Applicative f => f a -> b -> f a -> f b
+ Configuration.Utils.CommandLine: (<|>) :: Alternative f => f a -> f a -> f a
+ Configuration.Utils.CommandLine: CompletionInvoked :: CompletionResult -> ParserResult a
+ Configuration.Utils.CommandLine: CompletionResult :: String -> IO String -> CompletionResult
+ Configuration.Utils.CommandLine: Const :: a -> Const a
+ Configuration.Utils.CommandLine: ErrorMsg :: String -> ParseError
+ Configuration.Utils.CommandLine: ExpectsArgError :: String -> ParseError
+ Configuration.Utils.CommandLine: Failure :: ParserFailure ParserHelp -> ParserResult a
+ Configuration.Utils.CommandLine: InfoMsg :: String -> ParseError
+ Configuration.Utils.CommandLine: MissingError :: IsCmdStart -> SomeParser -> ParseError
+ Configuration.Utils.CommandLine: ParserFailure :: String -> (h, ExitCode, Int) -> ParserFailure h
+ Configuration.Utils.CommandLine: ParserHelp :: Chunk Doc -> Chunk Doc -> Chunk Doc -> Chunk Doc -> Chunk Doc -> Chunk Doc -> ParserHelp
+ Configuration.Utils.CommandLine: ParserInfo :: Parser a -> Bool -> Chunk Doc -> Chunk Doc -> Chunk Doc -> Int -> ArgPolicy -> ParserInfo a
+ Configuration.Utils.CommandLine: ParserPrefs :: String -> Bool -> Bool -> Bool -> Bool -> Int -> ParserPrefs
+ Configuration.Utils.CommandLine: ShowHelpText :: ParseError
+ Configuration.Utils.CommandLine: UnexpectedError :: String -> SomeParser -> ParseError
+ Configuration.Utils.CommandLine: UnknownError :: ParseError
+ Configuration.Utils.CommandLine: WrapArrow :: a b c -> WrappedArrow b c
+ Configuration.Utils.CommandLine: WrapMonad :: m a -> WrappedMonad a
+ Configuration.Utils.CommandLine: ZipList :: [a] -> ZipList a
+ Configuration.Utils.CommandLine: [execCompletion] :: CompletionResult -> String -> IO String
+ Configuration.Utils.CommandLine: [execFailure] :: ParserFailure h -> String -> (h, ExitCode, Int)
+ Configuration.Utils.CommandLine: [getConst] :: Const a -> a
+ Configuration.Utils.CommandLine: [getZipList] :: ZipList a -> [a]
+ Configuration.Utils.CommandLine: [helpBody] :: ParserHelp -> Chunk Doc
+ Configuration.Utils.CommandLine: [helpError] :: ParserHelp -> Chunk Doc
+ Configuration.Utils.CommandLine: [helpFooter] :: ParserHelp -> Chunk Doc
+ Configuration.Utils.CommandLine: [helpHeader] :: ParserHelp -> Chunk Doc
+ Configuration.Utils.CommandLine: [helpSuggestions] :: ParserHelp -> Chunk Doc
+ Configuration.Utils.CommandLine: [helpUsage] :: ParserHelp -> Chunk Doc
+ Configuration.Utils.CommandLine: [infoFailureCode] :: ParserInfo a -> Int
+ Configuration.Utils.CommandLine: [infoFooter] :: ParserInfo a -> Chunk Doc
+ Configuration.Utils.CommandLine: [infoFullDesc] :: ParserInfo a -> Bool
+ Configuration.Utils.CommandLine: [infoHeader] :: ParserInfo a -> Chunk Doc
+ Configuration.Utils.CommandLine: [infoParser] :: ParserInfo a -> Parser a
+ Configuration.Utils.CommandLine: [infoPolicy] :: ParserInfo a -> ArgPolicy
+ Configuration.Utils.CommandLine: [infoProgDesc] :: ParserInfo a -> Chunk Doc
+ Configuration.Utils.CommandLine: [prefBacktrack] :: ParserPrefs -> Bool
+ Configuration.Utils.CommandLine: [prefColumns] :: ParserPrefs -> Int
+ Configuration.Utils.CommandLine: [prefDisambiguate] :: ParserPrefs -> Bool
+ Configuration.Utils.CommandLine: [prefMultiSuffix] :: ParserPrefs -> String
+ Configuration.Utils.CommandLine: [prefShowHelpOnEmpty] :: ParserPrefs -> Bool
+ Configuration.Utils.CommandLine: [prefShowHelpOnError] :: ParserPrefs -> Bool
+ Configuration.Utils.CommandLine: [unwrapArrow] :: WrappedArrow b c -> a b c
+ Configuration.Utils.CommandLine: [unwrapMonad] :: WrappedMonad a -> m a
+ Configuration.Utils.CommandLine: abortOption :: () => ParseError -> Mod OptionFields a -> a -> Parser a -> a
+ Configuration.Utils.CommandLine: action :: HasCompleter f => String -> Mod f a
+ Configuration.Utils.CommandLine: argument :: () => ReadM a -> Mod ArgumentFields a -> Parser a
+ Configuration.Utils.CommandLine: auto :: Read a => ReadM a
+ Configuration.Utils.CommandLine: bashCompleter :: String -> Completer
+ Configuration.Utils.CommandLine: briefDesc :: () => InfoMod a
+ Configuration.Utils.CommandLine: class Applicative f => Alternative (f :: * -> *)
+ Configuration.Utils.CommandLine: class Functor f => Applicative (f :: * -> *)
+ Configuration.Utils.CommandLine: class HasCompleter (f :: * -> *)
+ Configuration.Utils.CommandLine: class HasMetavar (f :: * -> *)
+ Configuration.Utils.CommandLine: class HasName (f :: * -> *)
+ Configuration.Utils.CommandLine: class HasValue (f :: * -> *)
+ Configuration.Utils.CommandLine: columns :: Int -> PrefsMod
+ Configuration.Utils.CommandLine: command :: () => String -> ParserInfo a -> Mod CommandFields a
+ Configuration.Utils.CommandLine: commandGroup :: () => String -> Mod CommandFields a
+ Configuration.Utils.CommandLine: completeWith :: HasCompleter f => [String] -> Mod f a
+ Configuration.Utils.CommandLine: completer :: HasCompleter f => Completer -> Mod f a
+ Configuration.Utils.CommandLine: customExecParser :: () => ParserPrefs -> ParserInfo a -> IO a
+ Configuration.Utils.CommandLine: data ArgumentFields a
+ Configuration.Utils.CommandLine: data CommandFields a
+ Configuration.Utils.CommandLine: data Completer
+ Configuration.Utils.CommandLine: data FlagFields a
+ Configuration.Utils.CommandLine: data InfoMod a
+ Configuration.Utils.CommandLine: data Mod (f :: * -> *) a
+ Configuration.Utils.CommandLine: data OptionFields a
+ Configuration.Utils.CommandLine: data ParseError
+ Configuration.Utils.CommandLine: data ParserHelp
+ Configuration.Utils.CommandLine: data ParserInfo a
+ Configuration.Utils.CommandLine: data ParserPrefs
+ Configuration.Utils.CommandLine: data ParserResult a
+ Configuration.Utils.CommandLine: data PrefsMod
+ Configuration.Utils.CommandLine: data ReadM a
+ Configuration.Utils.CommandLine: defaultPrefs :: ParserPrefs
+ Configuration.Utils.CommandLine: disabled :: () => ReadM a
+ Configuration.Utils.CommandLine: disambiguate :: PrefsMod
+ Configuration.Utils.CommandLine: eitherReader :: () => String -> Either String a -> ReadM a
+ Configuration.Utils.CommandLine: empty :: Alternative f => f a
+ Configuration.Utils.CommandLine: execParser :: () => ParserInfo a -> IO a
+ Configuration.Utils.CommandLine: execParserPure :: () => ParserPrefs -> ParserInfo a -> [String] -> ParserResult a
+ Configuration.Utils.CommandLine: failureCode :: () => Int -> InfoMod a
+ Configuration.Utils.CommandLine: flag :: () => a -> a -> Mod FlagFields a -> Parser a
+ Configuration.Utils.CommandLine: flag' :: () => a -> Mod FlagFields a -> Parser a
+ Configuration.Utils.CommandLine: footer :: () => String -> InfoMod a
+ Configuration.Utils.CommandLine: footerDoc :: () => Maybe Doc -> InfoMod a
+ Configuration.Utils.CommandLine: forwardOptions :: () => InfoMod a
+ Configuration.Utils.CommandLine: fullDesc :: () => InfoMod a
+ Configuration.Utils.CommandLine: getParseResult :: () => ParserResult a -> Maybe a
+ Configuration.Utils.CommandLine: handleParseResult :: () => ParserResult a -> IO a
+ Configuration.Utils.CommandLine: header :: () => String -> InfoMod a
+ Configuration.Utils.CommandLine: headerDoc :: () => Maybe Doc -> InfoMod a
+ Configuration.Utils.CommandLine: help :: () => String -> Mod f a
+ Configuration.Utils.CommandLine: helpDoc :: () => Maybe Doc -> Mod f a
+ Configuration.Utils.CommandLine: helper :: () => Parser a -> a
+ Configuration.Utils.CommandLine: hidden :: () => Mod f a
+ Configuration.Utils.CommandLine: hsubparser :: () => Mod CommandFields a -> Parser a
+ Configuration.Utils.CommandLine: idm :: Monoid m => m
+ Configuration.Utils.CommandLine: infixl 4 <**>
+ Configuration.Utils.CommandLine: info :: () => Parser a -> InfoMod a -> ParserInfo a
+ Configuration.Utils.CommandLine: infoOption :: () => String -> Mod OptionFields a -> a -> Parser a -> a
+ Configuration.Utils.CommandLine: internal :: () => Mod f a
+ Configuration.Utils.CommandLine: liftA :: Applicative f => a -> b -> f a -> f b
+ Configuration.Utils.CommandLine: liftA2 :: Applicative f => a -> b -> c -> f a -> f b -> f c
+ Configuration.Utils.CommandLine: liftA3 :: Applicative f => a -> b -> c -> d -> f a -> f b -> f c -> f d
+ Configuration.Utils.CommandLine: listCompleter :: [String] -> Completer
+ Configuration.Utils.CommandLine: listIOCompleter :: IO [String] -> Completer
+ Configuration.Utils.CommandLine: long :: HasName f => String -> Mod f a
+ Configuration.Utils.CommandLine: many :: Alternative f => f a -> f [a]
+ Configuration.Utils.CommandLine: mappend :: Monoid a => a -> a -> a
+ Configuration.Utils.CommandLine: maybeReader :: () => String -> Maybe a -> ReadM a
+ Configuration.Utils.CommandLine: metavar :: HasMetavar f => String -> Mod f a
+ Configuration.Utils.CommandLine: mkCompleter :: String -> IO [String] -> Completer
+ Configuration.Utils.CommandLine: multiSuffix :: String -> PrefsMod
+ Configuration.Utils.CommandLine: newtype Const a (b :: k) :: forall k. () => * -> k -> *
+ Configuration.Utils.CommandLine: newtype CompletionResult
+ Configuration.Utils.CommandLine: newtype ParserFailure h
+ Configuration.Utils.CommandLine: newtype WrappedArrow (a :: * -> * -> *) b c
+ Configuration.Utils.CommandLine: newtype WrappedMonad (m :: * -> *) a
+ Configuration.Utils.CommandLine: newtype ZipList a
+ Configuration.Utils.CommandLine: noArgError :: () => ParseError -> Mod OptionFields a
+ Configuration.Utils.CommandLine: noBacktrack :: PrefsMod
+ Configuration.Utils.CommandLine: noIntersperse :: () => InfoMod a
+ Configuration.Utils.CommandLine: option :: () => ReadM a -> Mod OptionFields a -> Parser a
+ Configuration.Utils.CommandLine: optional :: Alternative f => f a -> f Maybe a
+ Configuration.Utils.CommandLine: overFailure :: () => ParserHelp -> ParserHelp -> ParserResult a -> ParserResult a
+ Configuration.Utils.CommandLine: parserFailure :: () => ParserPrefs -> ParserInfo a -> ParseError -> [Context] -> ParserFailure ParserHelp
+ Configuration.Utils.CommandLine: prefs :: PrefsMod -> ParserPrefs
+ Configuration.Utils.CommandLine: progDesc :: () => String -> InfoMod a
+ Configuration.Utils.CommandLine: progDescDoc :: () => Maybe Doc -> InfoMod a
+ Configuration.Utils.CommandLine: pure :: Applicative f => a -> f a
+ Configuration.Utils.CommandLine: readerAbort :: () => ParseError -> ReadM a
+ Configuration.Utils.CommandLine: readerError :: () => String -> ReadM a
+ Configuration.Utils.CommandLine: renderFailure :: ParserFailure ParserHelp -> String -> (String, ExitCode)
+ Configuration.Utils.CommandLine: short :: HasName f => Char -> Mod f a
+ Configuration.Utils.CommandLine: showDefault :: Show a => Mod f a
+ Configuration.Utils.CommandLine: showDefaultWith :: () => a -> String -> Mod f a
+ Configuration.Utils.CommandLine: showHelpOnEmpty :: PrefsMod
+ Configuration.Utils.CommandLine: showHelpOnError :: PrefsMod
+ Configuration.Utils.CommandLine: some :: Alternative f => f a -> f [a]
+ Configuration.Utils.CommandLine: str :: IsString s => ReadM s
+ Configuration.Utils.CommandLine: strArgument :: IsString s => Mod ArgumentFields s -> Parser s
+ Configuration.Utils.CommandLine: strOption :: IsString s => Mod OptionFields s -> Parser s
+ Configuration.Utils.CommandLine: style :: () => Doc -> Doc -> Mod f a
+ Configuration.Utils.CommandLine: subparser :: () => Mod CommandFields a -> Parser a
+ Configuration.Utils.CommandLine: switch :: Mod FlagFields Bool -> Parser Bool
+ Configuration.Utils.CommandLine: value :: HasValue f => a -> Mod f a
+ Configuration.Utils.Monoid: instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Configuration.Utils.Monoid.LeftMonoidalUpdate a)
+ Configuration.Utils.Monoid: instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Configuration.Utils.Monoid.RightMonoidalUpdate a)
Files
- CHANGELOG.md +14/−0
- INSTALL_ON_WINDOWS.md +0/−118
- Setup.hs +121/−130
- configuration-tools.cabal +28/−41
- constraints +0/−94
- examples/Example.hs +4/−0
- src/Configuration/Utils/Maybe.hs +0/−9
- src/Configuration/Utils/Operators.hs +0/−10
- src/Configuration/Utils/Setup.hs +121/−130
- src/Configuration/Utils/Validation.hs +0/−10
- test/TestExample.hs +4/−1
CHANGELOG.md view
@@ -1,3 +1,17 @@+0.4.0 (2018-08-21)+==================++* Drop support for GHC < 7.10 and base < 4.8+* Drop support for Cabal < 1.24+* Drop support for transformers < 0.4+* Don't run CI tests for Cabal < 2++* With Cabal 2.0 or later package info modules are placed in per component+ `autogen` directories. All package info modules are named just `PkgInfo`.+ For backward compatibility modules with the old legacy names (`PkgInfo_*`)+ are still generated but marked deprecated. With Cabal 1.24 only the legacy+ behavior is available and a deprecation warning is raised.+ 0.3.1 (2018-03-16) ==================
− INSTALL_ON_WINDOWS.md
@@ -1,118 +0,0 @@-When using the `Setup.hs` script from the *configuration-tools* package-with a source build from a git repository a git binary must be available-in the `PATH` environment of the installation command. This is, for instance,-the case for the test-suite of the *configuration-tools* package itself.--The first step in the following description installs a git binary that-is globally available in the system. Steps two through seven explain-how to setup a Haskell build environment on a Windows system in general.-Those steps are not specific to the *configuration-tools* package. Steps-eight and nine explain how to install and test the *configuration-tools*-package.--Windows-=======--The following steps make use of the `Git Bash` terminal. Beside of being-convenient for users that are familiar with POSIX systems, it is also a-requirement for installing the *network* package, which is a dependency of-*cabal*. Most other Haskell packages can be installed from a windows shell-(PowerShell or cmd shell) as well.--1. Install Git from: [Git for windows](http://git-scm.com/download/win)-- During the installation, when ask about the environment settings,- select the second option that makes the git command available at- the windows shell prompt. Otherwise the git binary is available- only when `cabal` is executed from the *Git Bash* terminal.--2. Download the- [GHC binary distribution for windows](http://www.haskell.org/ghc/dist/7.8.3/ghc-7.8.3-x86_64-unknown-mingw32.tar.bz2)- and unpack it in a convenient place.-- In the following we assume that it was unpacked in `C:\` into the default directory `C:\ghc-7.8.3`.--3. Obtain a windows cabal binary, for example from the Haskell Platform distribution- or a previous GHC installation (the version doesn't matter).--4. Open the *Git Bash* terminal. A link to it should have been created in the start menu- during the Git installation.--5. Include the `bin` directory and `mingw/bin` directory from the GHC binary distribution into- the `PATH` environment:-- ~~~{.sh}- export PATH=/c/ghc-7.8.3/bin:/c/ghc-7.8.3/mingw/bin:$PATH- ~~~--6. Make sure a cabal binary is available in the `PATH`-- ~~~{.sh}- which cabal- ~~~-- and check that `ghc`, `ld`, and `gcc` are used from the respective directories under - `/c/ghc-7.8.3/*`:-- ~~~{.sh}- which ghc- which ld- which gcc- ~~~--7. Install an updated version of `cabal`:-- ~~~{.sh}- cabal update- cabal install cabal-install- ~~~-- Make sure that the location into which the resulting cabal binary is installed- (the location is configured in `~/AppData/Roaming/cabal/config` and it is also- printed to the installation logs) is in your `PATH`.-- Check that you are now using the most recent version of cabal:-- ~~~{.sh}- which cabal- cabal --version- ~~~--8. Install the *configuration-tools* package from Hackage:-- ~~~{.sh}- cabal install configuration-tools --enable-tests- ~~~-- Alternativly, you my clone and install it from- [GitHub](https://github.com/alephcloud/hs-configuration-tools.git):-- ~~~{.sh}- git clone https://github.com/alephcloud/hs-configuration-tools.git- cd hs-configuration-tools- cabal install --enable-tests- ~~~--9. When you installed *configuration-tools* from source you may run the tests- from within the package directory as follows:-- ~~~{.sh}- cabal test- ~~~-- You can run the test with different command line options using cabals `--test-option`- flag. For instance[^1]:-- ~~~{.sh}- cabal test --show-details=always --test-option=--help- cabal test --show-details=always --test-option=--long-info- ~~~-- [^1]: Note: the windows terminal reacts ungracefully to Unicode characters. In order to have- it at least not crash the program you should run the following command before you- exectute any command that may print unicode characters (like the copyright symbol in the- test examples):-- ~~~{.sh}- chcp.com 65001- ~~~
Setup.hs view
@@ -1,9 +1,8 @@ -- ------------------------------------------------------ ----- Copyright © 2015-2016 Lars Kuhtz <lakuhtz@gmail.com>+-- Copyright © 2015-2018 Lars Kuhtz <lakuhtz@gmail.com> -- Copyright © 2014 AlephCloud Systems, Inc. -- ------------------------------------------------------ -- -{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-}@@ -14,19 +13,8 @@ -- process at the end of the configuration phase and generates a module with -- package information for each component of the cabal package. ----- The modules are created in the /autogen/ build directory where also the--- @Path_@ module is created by cabal's simple build setup. This is usually the--- directory @.\/dist\/build\/autogen@.------ For a library component the module is named just @PkgInfo@. For all other--- components the module is named @PkgInfo_COMPONENT_NAME@ where--- @COMPONENT_NAME@ is the name of the component with @-@ characters replaced by--- @_@.------ For instance, if a cabal package contains a library and an executable that is--- called /my-app/, the following modules are created: @PkgInfo@ and--- @PkgInfo_my_app@.---+-- The modules are created in the /autogen/ build directories where also the+-- @Path_@ modules are created by cabal's simple build setup. -- -- = Usage as Setup Script --@@ -111,7 +99,6 @@ ) where #ifndef MIN_VERSION_Cabal-#define NO_CABAL_MACROS 1 #define MIN_VERSION_Cabal(a,b,c) 0 #endif @@ -125,6 +112,7 @@ import Distribution.Text #if MIN_VERSION_Cabal(2,0,0)+import qualified Distribution.Compat.Graph as Graph import Distribution.Types.LocalBuildInfo import Distribution.Types.UnqualComponentName #endif@@ -146,15 +134,16 @@ import Prelude hiding (readFile, writeFile) -import System.Directory (doesFileExist, doesDirectoryExist, createDirectoryIfMissing, getCurrentDirectory, canonicalizePath)+import System.Directory+ ( doesFileExist+ , doesDirectoryExist+ , createDirectoryIfMissing+ , getCurrentDirectory+ , canonicalizePath+ ) import System.FilePath (isDrive, (</>), takeDirectory) import System.Exit (ExitCode(ExitSuccess)) -#ifdef NO_CABAL_MACROS-import Data.Maybe-import Data.Typeable-#endif- -- | Include this function when your setup doesn't contain any -- extra functionality. --@@ -168,14 +157,8 @@ -- If your setup doesn't contain any other function you can just import -- the 'main' function from this module. ----- The modules are created in the /autogen/ build directory where also the--- @Path_@ module is created by cabal's simple build setup. This is usually the--- directory @.\/dist\/build\/autogen@.------ For a library component the module is named just @PkgInfo@. For all other--- components the module is named @PkgInfo_COMPONENT_NAME@ where--- @COMPONENT_NAME@ is the name of the component with @-@ characters replaced by--- @_@.+-- The modules are created in the /autogen/ build directories where also the+-- @Path_@ modules are created by cabal's simple build setup. -- mkPkgInfoModules :: UserHooks@@ -184,6 +167,41 @@ { postConf = mkPkgInfoModulesPostConf (postConf hooks) } +-- -------------------------------------------------------------------------- --+-- Compat Implementations++#if !MIN_VERSION_Cabal(2,0,0)+unFlagName :: FlagName -> String+unFlagName (FlagName s) = s+#endif++#if !MIN_VERSION_Cabal(2,2,0)+unFlagAssignment :: FlagAssignment -> [(FlagName, Bool)]+unFlagAssignment = id+#endif++#if !MIN_VERSION_Cabal(2,2,0)+prettyShow :: Text a => a -> String+prettyShow = display+#endif++#if !MIN_VERSION_Cabal(2,0,0)+-- unUnqualComponentName :: UnqualComponentName -> String+unUnqualComponentName :: String -> String+unUnqualComponentName = id+#endif++prettyLicense :: I.InstalledPackageInfo -> String+#if MIN_VERSION_Cabal(2,2,0)+prettyLicense = either prettyShow prettyShow . I.license+#else+prettyLicense = prettyShow . I.license+#endif++-- -------------------------------------------------------------------------- --+-- Cabal 2.0++#if MIN_VERSION_Cabal(2,0,0) mkPkgInfoModulesPostConf :: (Args -> ConfigFlags -> PackageDescription -> LocalBuildInfo -> IO ()) -> Args@@ -192,6 +210,42 @@ -> LocalBuildInfo -> IO () mkPkgInfoModulesPostConf hook args flags pkgDesc bInfo = do+ mapM_ (updatePkgInfoModule pkgDesc bInfo) $ Graph.toList $ componentGraph bInfo+ hook args flags pkgDesc bInfo++updatePkgInfoModule :: PackageDescription -> LocalBuildInfo -> ComponentLocalBuildInfo -> IO ()+updatePkgInfoModule pkgDesc bInfo clbInfo = do+ createDirectoryIfMissing True dirName+ moduleBytes <- pkgInfoModule moduleName cName pkgDesc bInfo+ updateFile fileName moduleBytes++ -- legacy module+ legacyModuleBytes <- pkgInfoModule legacyModuleName cName pkgDesc bInfo+ updateFile legacyFileName legacyModuleBytes++ where+ dirName = autogenComponentModulesDir bInfo clbInfo+ cName = unUnqualComponentName <$> componentNameString (componentLocalName clbInfo)++ moduleName = pkgInfoModuleName+ fileName = dirName ++ "/" ++ moduleName ++ ".hs"++ legacyModuleName = legacyPkgInfoModuleName cName+ legacyFileName = dirName ++ "/" ++ legacyModuleName ++ ".hs"++-- -------------------------------------------------------------------------- --+-- Cabal 1.24++#else++mkPkgInfoModulesPostConf+ :: (Args -> ConfigFlags -> PackageDescription -> LocalBuildInfo -> IO ())+ -> Args+ -> ConfigFlags+ -> PackageDescription+ -> LocalBuildInfo+ -> IO ()+mkPkgInfoModulesPostConf hook args flags pkgDesc bInfo = do mkModules hook args flags pkgDesc bInfo where@@ -202,22 +256,41 @@ CTestName s -> updatePkgInfoModule (Just $ unUnqualComponentName s) pkgDesc bInfo CBenchName s -> updatePkgInfoModule (Just $ unUnqualComponentName s) pkgDesc bInfo -#if !MIN_VERSION_Cabal(2,0,0)- unUnqualComponentName = id+updatePkgInfoModule :: Maybe String -> PackageDescription -> LocalBuildInfo -> IO ()+updatePkgInfoModule cName pkgDesc bInfo = do+ createDirectoryIfMissing True dirName+ moduleBytes <- pkgInfoModule moduleName cName pkgDesc bInfo+ updateFile fileName moduleBytes+ where+ dirName = autogenModulesDir bInfo+ moduleName = legacyPkgInfoModuleName cName+ fileName = dirName ++ "/" ++ moduleName ++ ".hs" #endif -pkgInfoModuleName :: Maybe String -> String-pkgInfoModuleName Nothing = "PkgInfo"-pkgInfoModuleName (Just cn) = "PkgInfo_" ++ map tr cn+-- -------------------------------------------------------------------------- --+-- Generate PkgInfo Module++pkgInfoModuleName :: String+pkgInfoModuleName = "PkgInfo"++updateFile :: FilePath -> B.ByteString -> IO ()+updateFile fileName content = do+ doesFileExist fileName >>= \x -> if x+ then do+ oldRevisionFile <- B.readFile fileName+ when (oldRevisionFile /= content) update+ else+ update where+ update = B.writeFile fileName content++legacyPkgInfoModuleName :: Maybe String -> String+legacyPkgInfoModuleName Nothing = "PkgInfo"+legacyPkgInfoModuleName (Just cn) = "PkgInfo_" ++ map tr cn+ where tr '-' = '_' tr c = c --- FIXME: autoModulesDir is deprecated and should be replaced by--- autogenComponentModulesDir.-pkgInfoFileName :: Maybe String -> LocalBuildInfo -> FilePath-pkgInfoFileName cn bInfo = autogenModulesDir bInfo ++ "/" ++ pkgInfoModuleName cn ++ ".hs"- trim :: String -> String trim = f . f where f = reverse . dropWhile isSpace@@ -236,23 +309,8 @@ then return Nothing else getVcsOfDir (takeDirectory canonicDir) -#if !MIN_VERSION_Cabal(2,0,0)-unFlagName :: FlagName -> String-unFlagName (FlagName s) = s-#endif--#if !MIN_VERSION_Cabal(2,2,0)-unFlagAssignment :: FlagAssignment -> [(FlagName, Bool)]-unFlagAssignment = id-#endif--#if !MIN_VERSION_Cabal(2,2,0)-prettyShow :: Text a => a -> String-prettyShow = display-#endif--pkgInfoModule :: Maybe String -> PackageDescription -> LocalBuildInfo -> IO B.ByteString-pkgInfoModule cName pkgDesc bInfo = do+pkgInfoModule :: String -> Maybe String -> PackageDescription -> LocalBuildInfo -> IO B.ByteString+pkgInfoModule moduleName cName pkgDesc bInfo = do (tag, revision, branch) <- getVCS >>= \x -> case x of Just Mercurial -> hgInfo Just Git -> gitInfo@@ -268,10 +326,11 @@ [ "{-# LANGUAGE OverloadedStrings #-}" , "{-# LANGUAGE RankNTypes #-}" , ""- , "module " <> (pack . pkgInfoModuleName) cName <> " where"+ , "module " <> pack moduleName <> " " <> deprecatedMsg <> " where" , "" , " import Data.String (IsString)" , " import Data.Monoid"+ , " import Prelude hiding ((<>))" , "" , " name :: IsString a => Maybe a" , " name = " <> maybe "Nothing" (\x -> "Just \"" <> pack x <> "\"") cName@@ -365,83 +424,19 @@ displayOptimisationLevel NormalOptimisation = "normal" displayOptimisationLevel MaximumOptimisation = "maximum" -updatePkgInfoModule :: Maybe String -> PackageDescription -> LocalBuildInfo -> IO ()-updatePkgInfoModule cName pkgDesc bInfo = do- createDirectoryIfMissing True $ autogenModulesDir bInfo- newFile <- pkgInfoModule cName pkgDesc bInfo- let update = B.writeFile fileName newFile- doesFileExist fileName >>= \x -> if x- then do- oldRevisionFile <- B.readFile fileName- when (oldRevisionFile /= newFile) update- else- update- where- fileName = pkgInfoFileName cName bInfo+ deprecatedMsg = if moduleName /= pkgInfoModuleName+ then "{-# DEPRECATED \"Update to Cabal 2.0 or later and use just PkgInfo as module name.\" #-}"+ else "" licenseFilesText :: PackageDescription -> IO B.ByteString licenseFilesText pkgDesc = B.intercalate "\n------------------------------------------------------------\n" <$> mapM fileText-#ifdef NO_CABAL_MACROS- (getLicenseFiles pkgDesc)-#elif MIN_VERSION_Cabal(1,20,0) (licenseFiles pkgDesc)-#else- [licenseFile pkgDesc]-#endif where fileText file = doesFileExist file >>= \x -> if x then B.readFile file else return "" -#ifdef NO_CABAL_MACROS--- The name and the type of the @licenseFile :: String@ field of--- 'PackageDescription' changed in Cabal version 1.20 to @licenseFiles ::--- [String]@. Both versions are used with GHC-7.8. In Cabal version 1.24 the--- number of constructor fields changed for PackageDescription. When compiling--- @Setup.hs@ the @MIN_VERSION_...@ macros are not available. This function is--- an ugly hack to do conditional compilation without CPP. It depends on the--- @RecordWildCards@ and @Typeable@ extensions and abuses shaddowing of--- existing symbols.------ Alternative methods would include:------ * Use typeable to pattern match on the number of constructor arguments for--- 'PackageDescription',--- * use TH hacks ala @$( if versionBranch cabalVersion < [...] ... )@, and/or--- * make guesses about the cabal version based on the @__GLASGOW_HASKELL__@--- macro.---- Return license files of from the @PackageDescription@.----getLicenseFiles :: PackageDescription -> [FilePath]-getLicenseFiles pkgDesc = f pkgDesc- where- -- Recent versions of @PackageDescription@ define a @licenseFiles@ field.- -- For older versions the function @licenseFiles@ that is defined below is- -- used.- --- f PackageDescription{..} = licenseFiles-- -- If @PackageDescription@ doesn't define @licenseFiles@ this definition- -- will be used. In that case @PackageDescription@ is assumed to define- -- @licenseFile@.- --- licenseFiles :: [FilePath]- licenseFiles = fromMaybe (error "unsupported Cabal library version") $- return <$> cast (g pkgDesc)-- g PackageDescription{..} = licenseFile-- -- The only purpose of this function is to ensure that licenseFile is- -- defined in case PackageDescription doesn't have a @licenseFile@ field.- -- This function won't be called with any supported version of the Cabal- -- library.- --- licenseFile :: [FilePath]- licenseFile = error "unexpected Cabal library version"-#endif- hgInfo :: IO (String, String, String) hgInfo = do tag <- trim <$> readProcess "hg" ["id", "-r", "max(ancestors(\".\") and tag())", "-t"] ""@@ -466,11 +461,7 @@ pkgIdWithLicense :: I.InstalledPackageInfo -> String pkgIdWithLicense a = (display . packageId) a ++ " ["-#if MIN_VERSION_Cabal(2,2,0)- ++ (either prettyShow prettyShow . I.license) a-#else- ++ (prettyShow . I.license) a-#endif+ ++ prettyLicense a ++ (if cr /= "" then ", " ++ cr else "") ++ "]" where
configuration-tools.cabal view
@@ -4,7 +4,7 @@ -- ------------------------------------------------------ -- Name: configuration-tools-Version: 0.3.1+Version: 0.4.0 Synopsis: Tools for specifying and parsing configurations description: Tools for specifying and parsing configurations@@ -39,16 +39,25 @@ (c) 2014-2015 AlephCloud, Inc. Category: Configuration, Console Build-type: Custom--cabal-version: >= 1.18+cabal-version: 1.24+tested-with:+ GHC==8.4.3+ , GHC==8.2.2+ , GHC==8.0.2+ , GHC==7.10.3 extra-doc-files: README.md, CHANGELOG.md- INSTALL_ON_WINDOWS.md -extra-source-files:- constraints+custom-setup+ setup-depends:+ Cabal >= 1.24,+ base >= 4.8 && < 5.0,+ bytestring >= 0.10.0.2,+ directory >= 1.2.1.0,+ filepath >= 1.3.0.1,+ process >= 1.2.0.0 source-repository head type: git@@ -58,18 +67,13 @@ source-repository this type: git location: https://github.com/alephcloud/hs-configuration-tools.git- tag: 0.3.1+ tag: 0.4.0 flag remote-configs Description: enable loading of configuration files from HTTP URLs Default: True Manual: True -flag old-transformers- Description: use old transformers- Default: False- Manual: False- Library hs-source-dirs: src default-language: Haskell2010@@ -91,11 +95,11 @@ Configuration.Utils.Internal.HttpsCertPolicy build-depends:- Cabal >= 1.18,+ Cabal >= 1.24, aeson >= 0.7.0.6, ansi-wl-pprint >= 0.6, attoparsec >= 0.11.3.4,- base >= 4.6 && < 5.0,+ base >= 4.8 && < 5.0, base-unicode-symbols >= 0.2.2.4, bytestring >= 0.10.0.2, case-insensitive >= 1.2,@@ -103,25 +107,16 @@ directory >= 1.2.1.0, dlist >= 0.7.1, filepath >= 1.3.0.1,+ mtl >= 2.2, network-uri >= 2.6.0.1, optparse-applicative >= 0.11.0.2, process >= 1.2.0.0,+ profunctors >= 4.0.4,+ semigroups >= 0.18, text >= 1.0,+ transformers >= 0.4, unordered-containers >= 0.2.4.0,- yaml >= 0.8.8.3,- profunctors >= 4.0.4,- semigroups >= 0.18-- if flag(old-transformers)- build-depends:- mtl >= 2.1,- mtl-compat >= 0.2,- transformers >= 0.3 && < 0.4,- transformers-compat >= 0.4- else- build-depends:- mtl >= 2.2,- transformers >= 0.4+ yaml >= 0.8.8.3 if flag(remote-configs) build-depends:@@ -156,25 +151,17 @@ Tests.MonoidConfig build-depends:- base >= 4.6 && < 5.0,+ Cabal >= 1.24,+ base >= 4.8 && < 5.0, base-unicode-symbols >= 0.2.2.4, bytestring >= 0.10,- Cabal >= 1.18, configuration-tools,+ mtl >= 2.2, text >= 1.0,+ transformers >= 0.4, unordered-containers >= 0.2.4.0, yaml >= 0.8.8.3 - if flag(old-transformers)- build-depends:- mtl >= 2.1,- mtl-compat >= 0.2,- transformers-compat >= 0.4- else- build-depends:- mtl >= 2.2,- transformers >= 0.4- if flag(remote-configs) build-depends: enclosed-exceptions >= 1.0,@@ -195,7 +182,7 @@ hs-source-dirs: examples build-depends:- base >= 4.6 && < 5.0,+ base >= 4.8 && < 5.0, base-unicode-symbols >= 0.2.2.4, configuration-tools
− constraints
@@ -1,94 +0,0 @@-constraints: Cabal ==1.23.1.0,- array ==0.5.1.0,- base ==4.9.0.0,- ghc-prim ==0.5.0.0,- rts ==1.0,- integer-gmp ==1.0.0.1,- binary ==0.8.2.0,- bytestring ==0.10.7.0,- deepseq ==1.4.2.0,- containers ==0.5.7.1,- directory ==1.2.5.0,- filepath ==1.4.1.0,- time ==1.6,- unix ==2.7.2.0,- pretty ==1.1.3.2,- process ==1.4.2.0,- aeson ==0.11.0.0,- attoparsec ==0.13.0.1,- scientific ==0.3.4.4,- hashable ==1.2.4.0,- text ==1.2.2.0,- vector ==0.11.0.0,- primitive ==0.6.1.0,- transformers ==0.5.1.0,- dlist ==0.7.1.2,- fail ==4.9.0.0,- mtl ==2.2.1,- syb ==0.6,- template-haskell ==2.11.0.0,- ghc-boot ==8.0.0.20160204,- unordered-containers ==0.2.6.0,- ansi-wl-pprint ==0.6.7.3,- ansi-terminal ==0.6.2.3,- base-unicode-symbols ==0.2.2.4,- base64-bytestring ==1.0.0.1,- case-insensitive ==1.2.0.5,- connection ==0.2.5,- byteable ==0.1.1,- data-default-class ==0.0.1,- network ==2.6.2.1,- socks ==0.5.4,- cereal ==0.5.1.0,- tls ==1.3.4,- asn1-encoding ==0.9.3,- asn1-types ==0.3.2,- hourglass ==0.2.9,- memory ==0.11,- async ==2.1.0,- stm ==2.4.4.1,- cryptonite ==0.11,- x509 ==1.6.3,- asn1-parse ==0.9.4,- pem ==0.2.2,- x509-store ==1.6.1,- x509-validation ==1.6.3,- x509-system ==1.6.3,- data-default ==0.5.3,- data-default-instances-base ==0.0.1,- data-default-instances-containers ==0.0.1,- data-default-instances-dlist ==0.0.1,- data-default-instances-old-locale ==0.0.1,- old-locale ==1.0.0.7,- enclosed-exceptions ==1.0.1.1,- lifted-base ==0.2.3.6,- monad-control ==1.0.0.5,- transformers-base ==0.4.4,- transformers-compat ==0.5.1.4,- http-client ==0.4.27,- blaze-builder ==0.4.0.1,- cookie ==0.4.1.6,- exceptions ==0.8.2.1,- http-types ==0.9,- mime-types ==0.1.0.6,- network-uri ==2.6.0.3,- parsec ==3.1.9,- random ==1.0.1.1,- streaming-commons ==0.1.15.1,- zlib ==0.6.1.1,- http-client-tls ==0.2.2,- optparse-applicative ==0.12.1.0,- profunctors ==5.2,- base-orphans ==0.5.1,- bifunctors ==5.2.1,- comonad ==5,- contravariant ==1.4,- StateVar ==1.1.0.3,- semigroups ==0.18.1,- void ==0.7.1,- distributive ==0.5.0.2,- tagged ==0.8.3,- yaml ==0.8.16,- conduit ==1.2.6.2,- mmorph ==1.0.6,- resourcet ==1.1.7.2
examples/Example.hs view
@@ -44,7 +44,11 @@ -- This assumes usage of cabal with custom Setup.hs --+#if MIN_VERSION_Cabal(2,0,0)+import PkgInfo+#else import PkgInfo_url_example_test+#endif -- | Specification of the authentication section of a URL. --
src/Configuration/Utils/Maybe.hs view
@@ -1,17 +1,11 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE UnicodeSyntax #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -#ifndef MIN_VERSION_base-#define MIN_VERSION_base(x,y,z) 1-#endif- -- | -- Module: Configuration.Utils.Maybe -- Description: Configuration of Optional Values@@ -33,9 +27,6 @@ ) where -#if ! MIN_VERSION_base(4,8,0)-import Control.Applicative-#endif import Data.Aeson -- -------------------------------------------------------------------------- --
src/Configuration/Utils/Operators.hs view
@@ -1,13 +1,7 @@ {-# LANGUAGE CPP #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE UnicodeSyntax #-} -#ifndef MIN_VERSION_base-#define MIN_VERSION_base(x,y,z) 1-#endif- -- | -- Module: Configuration.Utils.Operators -- Description: Useful operators for defining functions in an applicative context@@ -28,10 +22,6 @@ , (<.>) , (⊙) ) where--#if ! MIN_VERSION_base(4,8,0)-import Control.Applicative-#endif -- -------------------------------------------------------------------------- -- -- Useful Operators
src/Configuration/Utils/Setup.hs view
@@ -1,9 +1,8 @@ -- ------------------------------------------------------ ----- Copyright © 2015-2016 Lars Kuhtz <lakuhtz@gmail.com>+-- Copyright © 2015-2018 Lars Kuhtz <lakuhtz@gmail.com> -- Copyright © 2014 AlephCloud Systems, Inc. -- ------------------------------------------------------ -- -{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-}@@ -14,19 +13,8 @@ -- process at the end of the configuration phase and generates a module with -- package information for each component of the cabal package. ----- The modules are created in the /autogen/ build directory where also the--- @Path_@ module is created by cabal's simple build setup. This is usually the--- directory @.\/dist\/build\/autogen@.------ For a library component the module is named just @PkgInfo@. For all other--- components the module is named @PkgInfo_COMPONENT_NAME@ where--- @COMPONENT_NAME@ is the name of the component with @-@ characters replaced by--- @_@.------ For instance, if a cabal package contains a library and an executable that is--- called /my-app/, the following modules are created: @PkgInfo@ and--- @PkgInfo_my_app@.---+-- The modules are created in the /autogen/ build directories where also the+-- @Path_@ modules are created by cabal's simple build setup. -- -- = Usage as Setup Script --@@ -111,7 +99,6 @@ ) where #ifndef MIN_VERSION_Cabal-#define NO_CABAL_MACROS 1 #define MIN_VERSION_Cabal(a,b,c) 0 #endif @@ -125,6 +112,7 @@ import Distribution.Text #if MIN_VERSION_Cabal(2,0,0)+import qualified Distribution.Compat.Graph as Graph import Distribution.Types.LocalBuildInfo import Distribution.Types.UnqualComponentName #endif@@ -146,15 +134,16 @@ import Prelude hiding (readFile, writeFile) -import System.Directory (doesFileExist, doesDirectoryExist, createDirectoryIfMissing, getCurrentDirectory, canonicalizePath)+import System.Directory+ ( doesFileExist+ , doesDirectoryExist+ , createDirectoryIfMissing+ , getCurrentDirectory+ , canonicalizePath+ ) import System.FilePath (isDrive, (</>), takeDirectory) import System.Exit (ExitCode(ExitSuccess)) -#ifdef NO_CABAL_MACROS-import Data.Maybe-import Data.Typeable-#endif- -- | Include this function when your setup doesn't contain any -- extra functionality. --@@ -168,14 +157,8 @@ -- If your setup doesn't contain any other function you can just import -- the 'main' function from this module. ----- The modules are created in the /autogen/ build directory where also the--- @Path_@ module is created by cabal's simple build setup. This is usually the--- directory @.\/dist\/build\/autogen@.------ For a library component the module is named just @PkgInfo@. For all other--- components the module is named @PkgInfo_COMPONENT_NAME@ where--- @COMPONENT_NAME@ is the name of the component with @-@ characters replaced by--- @_@.+-- The modules are created in the /autogen/ build directories where also the+-- @Path_@ modules are created by cabal's simple build setup. -- mkPkgInfoModules :: UserHooks@@ -184,6 +167,41 @@ { postConf = mkPkgInfoModulesPostConf (postConf hooks) } +-- -------------------------------------------------------------------------- --+-- Compat Implementations++#if !MIN_VERSION_Cabal(2,0,0)+unFlagName :: FlagName -> String+unFlagName (FlagName s) = s+#endif++#if !MIN_VERSION_Cabal(2,2,0)+unFlagAssignment :: FlagAssignment -> [(FlagName, Bool)]+unFlagAssignment = id+#endif++#if !MIN_VERSION_Cabal(2,2,0)+prettyShow :: Text a => a -> String+prettyShow = display+#endif++#if !MIN_VERSION_Cabal(2,0,0)+-- unUnqualComponentName :: UnqualComponentName -> String+unUnqualComponentName :: String -> String+unUnqualComponentName = id+#endif++prettyLicense :: I.InstalledPackageInfo -> String+#if MIN_VERSION_Cabal(2,2,0)+prettyLicense = either prettyShow prettyShow . I.license+#else+prettyLicense = prettyShow . I.license+#endif++-- -------------------------------------------------------------------------- --+-- Cabal 2.0++#if MIN_VERSION_Cabal(2,0,0) mkPkgInfoModulesPostConf :: (Args -> ConfigFlags -> PackageDescription -> LocalBuildInfo -> IO ()) -> Args@@ -192,6 +210,42 @@ -> LocalBuildInfo -> IO () mkPkgInfoModulesPostConf hook args flags pkgDesc bInfo = do+ mapM_ (updatePkgInfoModule pkgDesc bInfo) $ Graph.toList $ componentGraph bInfo+ hook args flags pkgDesc bInfo++updatePkgInfoModule :: PackageDescription -> LocalBuildInfo -> ComponentLocalBuildInfo -> IO ()+updatePkgInfoModule pkgDesc bInfo clbInfo = do+ createDirectoryIfMissing True dirName+ moduleBytes <- pkgInfoModule moduleName cName pkgDesc bInfo+ updateFile fileName moduleBytes++ -- legacy module+ legacyModuleBytes <- pkgInfoModule legacyModuleName cName pkgDesc bInfo+ updateFile legacyFileName legacyModuleBytes++ where+ dirName = autogenComponentModulesDir bInfo clbInfo+ cName = unUnqualComponentName <$> componentNameString (componentLocalName clbInfo)++ moduleName = pkgInfoModuleName+ fileName = dirName ++ "/" ++ moduleName ++ ".hs"++ legacyModuleName = legacyPkgInfoModuleName cName+ legacyFileName = dirName ++ "/" ++ legacyModuleName ++ ".hs"++-- -------------------------------------------------------------------------- --+-- Cabal 1.24++#else++mkPkgInfoModulesPostConf+ :: (Args -> ConfigFlags -> PackageDescription -> LocalBuildInfo -> IO ())+ -> Args+ -> ConfigFlags+ -> PackageDescription+ -> LocalBuildInfo+ -> IO ()+mkPkgInfoModulesPostConf hook args flags pkgDesc bInfo = do mkModules hook args flags pkgDesc bInfo where@@ -202,22 +256,41 @@ CTestName s -> updatePkgInfoModule (Just $ unUnqualComponentName s) pkgDesc bInfo CBenchName s -> updatePkgInfoModule (Just $ unUnqualComponentName s) pkgDesc bInfo -#if !MIN_VERSION_Cabal(2,0,0)- unUnqualComponentName = id+updatePkgInfoModule :: Maybe String -> PackageDescription -> LocalBuildInfo -> IO ()+updatePkgInfoModule cName pkgDesc bInfo = do+ createDirectoryIfMissing True dirName+ moduleBytes <- pkgInfoModule moduleName cName pkgDesc bInfo+ updateFile fileName moduleBytes+ where+ dirName = autogenModulesDir bInfo+ moduleName = legacyPkgInfoModuleName cName+ fileName = dirName ++ "/" ++ moduleName ++ ".hs" #endif -pkgInfoModuleName :: Maybe String -> String-pkgInfoModuleName Nothing = "PkgInfo"-pkgInfoModuleName (Just cn) = "PkgInfo_" ++ map tr cn+-- -------------------------------------------------------------------------- --+-- Generate PkgInfo Module++pkgInfoModuleName :: String+pkgInfoModuleName = "PkgInfo"++updateFile :: FilePath -> B.ByteString -> IO ()+updateFile fileName content = do+ doesFileExist fileName >>= \x -> if x+ then do+ oldRevisionFile <- B.readFile fileName+ when (oldRevisionFile /= content) update+ else+ update where+ update = B.writeFile fileName content++legacyPkgInfoModuleName :: Maybe String -> String+legacyPkgInfoModuleName Nothing = "PkgInfo"+legacyPkgInfoModuleName (Just cn) = "PkgInfo_" ++ map tr cn+ where tr '-' = '_' tr c = c --- FIXME: autoModulesDir is deprecated and should be replaced by--- autogenComponentModulesDir.-pkgInfoFileName :: Maybe String -> LocalBuildInfo -> FilePath-pkgInfoFileName cn bInfo = autogenModulesDir bInfo ++ "/" ++ pkgInfoModuleName cn ++ ".hs"- trim :: String -> String trim = f . f where f = reverse . dropWhile isSpace@@ -236,23 +309,8 @@ then return Nothing else getVcsOfDir (takeDirectory canonicDir) -#if !MIN_VERSION_Cabal(2,0,0)-unFlagName :: FlagName -> String-unFlagName (FlagName s) = s-#endif--#if !MIN_VERSION_Cabal(2,2,0)-unFlagAssignment :: FlagAssignment -> [(FlagName, Bool)]-unFlagAssignment = id-#endif--#if !MIN_VERSION_Cabal(2,2,0)-prettyShow :: Text a => a -> String-prettyShow = display-#endif--pkgInfoModule :: Maybe String -> PackageDescription -> LocalBuildInfo -> IO B.ByteString-pkgInfoModule cName pkgDesc bInfo = do+pkgInfoModule :: String -> Maybe String -> PackageDescription -> LocalBuildInfo -> IO B.ByteString+pkgInfoModule moduleName cName pkgDesc bInfo = do (tag, revision, branch) <- getVCS >>= \x -> case x of Just Mercurial -> hgInfo Just Git -> gitInfo@@ -268,10 +326,11 @@ [ "{-# LANGUAGE OverloadedStrings #-}" , "{-# LANGUAGE RankNTypes #-}" , ""- , "module " <> (pack . pkgInfoModuleName) cName <> " where"+ , "module " <> pack moduleName <> " " <> deprecatedMsg <> " where" , "" , " import Data.String (IsString)" , " import Data.Monoid"+ , " import Prelude hiding ((<>))" , "" , " name :: IsString a => Maybe a" , " name = " <> maybe "Nothing" (\x -> "Just \"" <> pack x <> "\"") cName@@ -365,83 +424,19 @@ displayOptimisationLevel NormalOptimisation = "normal" displayOptimisationLevel MaximumOptimisation = "maximum" -updatePkgInfoModule :: Maybe String -> PackageDescription -> LocalBuildInfo -> IO ()-updatePkgInfoModule cName pkgDesc bInfo = do- createDirectoryIfMissing True $ autogenModulesDir bInfo- newFile <- pkgInfoModule cName pkgDesc bInfo- let update = B.writeFile fileName newFile- doesFileExist fileName >>= \x -> if x- then do- oldRevisionFile <- B.readFile fileName- when (oldRevisionFile /= newFile) update- else- update- where- fileName = pkgInfoFileName cName bInfo+ deprecatedMsg = if moduleName /= pkgInfoModuleName+ then "{-# DEPRECATED \"Update to Cabal 2.0 or later and use just PkgInfo as module name.\" #-}"+ else "" licenseFilesText :: PackageDescription -> IO B.ByteString licenseFilesText pkgDesc = B.intercalate "\n------------------------------------------------------------\n" <$> mapM fileText-#ifdef NO_CABAL_MACROS- (getLicenseFiles pkgDesc)-#elif MIN_VERSION_Cabal(1,20,0) (licenseFiles pkgDesc)-#else- [licenseFile pkgDesc]-#endif where fileText file = doesFileExist file >>= \x -> if x then B.readFile file else return "" -#ifdef NO_CABAL_MACROS--- The name and the type of the @licenseFile :: String@ field of--- 'PackageDescription' changed in Cabal version 1.20 to @licenseFiles ::--- [String]@. Both versions are used with GHC-7.8. In Cabal version 1.24 the--- number of constructor fields changed for PackageDescription. When compiling--- @Setup.hs@ the @MIN_VERSION_...@ macros are not available. This function is--- an ugly hack to do conditional compilation without CPP. It depends on the--- @RecordWildCards@ and @Typeable@ extensions and abuses shaddowing of--- existing symbols.------ Alternative methods would include:------ * Use typeable to pattern match on the number of constructor arguments for--- 'PackageDescription',--- * use TH hacks ala @$( if versionBranch cabalVersion < [...] ... )@, and/or--- * make guesses about the cabal version based on the @__GLASGOW_HASKELL__@--- macro.---- Return license files of from the @PackageDescription@.----getLicenseFiles :: PackageDescription -> [FilePath]-getLicenseFiles pkgDesc = f pkgDesc- where- -- Recent versions of @PackageDescription@ define a @licenseFiles@ field.- -- For older versions the function @licenseFiles@ that is defined below is- -- used.- --- f PackageDescription{..} = licenseFiles-- -- If @PackageDescription@ doesn't define @licenseFiles@ this definition- -- will be used. In that case @PackageDescription@ is assumed to define- -- @licenseFile@.- --- licenseFiles :: [FilePath]- licenseFiles = fromMaybe (error "unsupported Cabal library version") $- return <$> cast (g pkgDesc)-- g PackageDescription{..} = licenseFile-- -- The only purpose of this function is to ensure that licenseFile is- -- defined in case PackageDescription doesn't have a @licenseFile@ field.- -- This function won't be called with any supported version of the Cabal- -- library.- --- licenseFile :: [FilePath]- licenseFile = error "unexpected Cabal library version"-#endif- hgInfo :: IO (String, String, String) hgInfo = do tag <- trim <$> readProcess "hg" ["id", "-r", "max(ancestors(\".\") and tag())", "-t"] ""@@ -466,11 +461,7 @@ pkgIdWithLicense :: I.InstalledPackageInfo -> String pkgIdWithLicense a = (display . packageId) a ++ " ["-#if MIN_VERSION_Cabal(2,2,0)- ++ (either prettyShow prettyShow . I.license) a-#else- ++ (prettyShow . I.license) a-#endif+ ++ prettyLicense a ++ (if cr /= "" then ", " ++ cr else "") ++ "]" where
src/Configuration/Utils/Validation.hs view
@@ -6,10 +6,6 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE UnicodeSyntax #-} -#ifndef MIN_VERSION_base-#define MIN_VERSION_base(x,y,z) 1-#endif- -- | -- Module: Configuration.Utils.Validation -- Copyright: Copyright © 2014 AlephCloud Systems, Inc.@@ -71,18 +67,12 @@ import Configuration.Utils.Internal -#if ! MIN_VERSION_base(4,8,0)-import Control.Applicative-#endif import Control.Monad.Error.Class import Control.Monad import Control.Monad.IO.Class import Control.Monad.Writer.Class import qualified Data.Foldable as F-#if ! MIN_VERSION_base(4,8,0)-import Data.Monoid-#endif import Data.Monoid.Unicode import qualified Data.Text as T
test/TestExample.hs view
@@ -2,7 +2,6 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-}-{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-}@@ -38,7 +37,11 @@ import Prelude.Unicode +#if MIN_VERSION_Cabal(2,0,0)+import PkgInfo+#else import PkgInfo_url_example_test+#endif -- -------------------------------------------------------------------------- -- -- main