packages feed

cabal-helper 0.1.0.0 → 0.1.0.1

raw patch · 6 files changed

+610/−2 lines, 6 filesdep ~Cabaldep ~basedep ~bytestring

Dependency ranges changed: Cabal, base, bytestring, data-default, directory, filepath, mtl, process, template-haskell, temporary, transformers

Files

+ CabalHelper/Common.hs view
@@ -0,0 +1,98 @@+-- cabal-helper: Simple interface to Cabal's configuration state+-- Copyright (C) 2015  Daniel Gröber <dxld ÄT darkboxed DOT org>+--+-- This program is free software: you can redistribute it and/or modify+-- it under the terms of the GNU Affero General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.+--+-- This program is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+-- GNU Affero General Public License for more details.+--+-- You should have received a copy of the GNU Affero General Public License+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.++{-# LANGUAGE DeriveDataTypeable, OverloadedStrings #-}+module CabalHelper.Common where++import Control.Applicative+import Control.Exception as E+import Control.Monad+import Data.List+import Data.Maybe+import Data.Version+import Data.Typeable+import Data.ByteString (ByteString)+import qualified Data.ByteString as BS+import qualified Data.ByteString.Char8 as BS8+import System.Environment+import System.IO+import System.Exit+import Text.ParserCombinators.ReadP++data Panic = Panic String deriving (Typeable, Show)+instance Exception Panic++panic :: String -> a+panic msg = throw $ Panic msg++handlePanic :: IO a -> IO a+handlePanic action =+    action `E.catch` \(Panic msg) -> errMsg msg >> exitFailure++errMsg :: String -> IO ()+errMsg str = do+  prog <- getProgName+  hPutStrLn stderr $ prog ++ ": " ++ str++align :: String -> String -> String -> String+align n an str = let+    h:rest = lines str+    [hm]   = match n h+    rest'  = [ move (hm - rm) r | r <- rest, rm <- match an r]+    in+      unlines (h:rest')+ where+   match p str' = maybeToList $+     fst <$> find ((p `isPrefixOf`) . snd) ([0..] `zip` tails str')+   move i str' | i > 0  = replicate i ' ' ++ str'+   move i str' = drop i str'+++-- | @getCabalConfigHeader "dist/setup-config"@ returns the cabal version and+-- compiler version+getCabalConfigHeader :: FilePath -> IO (Maybe (Version, Version))+getCabalConfigHeader file = bracket (openFile file ReadMode) hClose $ \h -> do+  parseHeader <$> BS.hGetLine h++parseHeader :: ByteString -> Maybe (Version, Version)+parseHeader header = case BS8.words header of+  ["Saved", "package", "config", "for", _pkgId ,+   "written", "by", cabalId,+   "using", compId]+    -> liftM2 (,) (ver cabalId) (ver compId)+  _ -> Nothing+ where+   ver i = snd <$> parsePkgId i++parsePkgId :: ByteString -> Maybe (ByteString, Version)+parsePkgId bs =+    case BS8.split '-' bs of+      [pkg, vers] -> Just (pkg, parseVer $ BS8.unpack vers)+      _ -> Nothing++parseVer :: String -> Version+parseVer vers = runReadP parseVersion vers++-- majorVer :: Version -> Version+-- majorVer (Version b _) = Version (take 2 b) []++-- sameMajorVersion :: Version -> Version -> Bool+-- sameMajorVersion a b = majorVer a == majorVer b++runReadP :: ReadP t -> String -> t+runReadP p i = case filter ((=="") . snd) $ readP_to_S p i of+                 (a,""):[] -> a+                 _ -> error $ "Error parsing: " ++ show i
+ CabalHelper/Data.hs view
@@ -0,0 +1,39 @@+-- cabal-helper: Simple interface to Cabal's configuration state+-- Copyright (C) 2015  Daniel Gröber <dxld ÄT darkboxed DOT org>+--+-- This program is free software: you can redistribute it and/or modify+-- it under the terms of the GNU Affero General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.+--+-- This program is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+-- GNU Affero General Public License for more details.+--+-- You should have received a copy of the GNU Affero General Public License+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.++{-# LANGUAGE TemplateHaskell #-}+module CabalHelper.Data where++import Control.Monad+import Data.Functor+import Language.Haskell.TH+import System.FilePath+import System.Directory+import System.IO.Temp++withHelperSources :: (FilePath -> IO a) -> IO a+withHelperSources action = withSystemTempDirectory "caba-helper" $ \dir -> do+    let chdir = dir </> "CabalHelper"+    createDirectory chdir+    forM_ sourceFiles $ \(fn, src) -> writeFile (chdir </> fn) src+    action dir++sourceFiles :: [(FilePath, String)]+sourceFiles =+  [ ("Main.hs",   $(LitE . StringL <$> runIO (readFile "CabalHelper/Main.hs")))+  , ("Common.hs", $(LitE . StringL <$> runIO (readFile "CabalHelper/Common.hs")))+  , ("Types.hs",  $(LitE . StringL <$> runIO (readFile "CabalHelper/Types.hs")))+  ]
+ CabalHelper/GuessGhc.hs view
@@ -0,0 +1,83 @@+module CabalHelper.GuessGhc (guessToolFromGhcPath) where++import Data.Maybe+import Data.Char+import Distribution.Simple.BuildPaths+import System.Directory+import System.FilePath++-- Copyright (c) 2003-2014, Isaac Jones, Simon Marlow, Martin Sjögren,+--                          Bjorn Bringert, Krasimir Angelov,+--                          Malcolm Wallace, Ross Patterson, Ian Lynagh,+--                          Duncan Coutts, Thomas Schilling,+--                          Johan Tibell, Mikhail Glushenkov+-- All rights reserved.++-- Redistribution and use in source and binary forms, with or without+-- modification, are permitted provided that the following conditions are+-- met:++--     * Redistributions of source code must retain the above copyright+--       notice, this list of conditions and the following disclaimer.++--     * Redistributions in binary form must reproduce the above+--       copyright notice, this list of conditions and the following+--       disclaimer in the documentation and/or other materials provided+--       with the distribution.++--     * Neither the name of Isaac Jones nor the names of other+--       contributors may be used to endorse or promote products derived+--       from this software without specific prior written permission.++-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+-- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+-- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++guessToolFromGhcPath :: FilePath -- ^ Tool name+                     -> FilePath -- ^ GHC exe path+                     -> IO (Maybe FilePath)+guessToolFromGhcPath toolname ghcPath+  = do let+           path              = ghcPath+           dir               = takeDirectory path+           versionSuffix     = takeVersionSuffix (dropExeExtension path)+           guessNormal       = dir </> toolname <.> exeExtension+           guessGhcVersioned = dir </> (toolname ++ "-ghc" ++ versionSuffix)+                               <.> exeExtension+           guessVersioned    = dir </> (toolname ++ versionSuffix)+                               <.> exeExtension+           guesses | null versionSuffix = [guessNormal]+                   | otherwise          = [guessGhcVersioned,+                                           guessVersioned,+                                           guessNormal]+       exists <- mapM doesFileExist guesses+       return $ listToMaybe [ file | (file, True) <- zip guesses exists ]++  where takeVersionSuffix :: FilePath -> String+        takeVersionSuffix = takeWhileEndLE isSuffixChar++        isSuffixChar :: Char -> Bool+        isSuffixChar c = isDigit c || c == '.' || c == '-'++        dropExeExtension :: FilePath -> FilePath+        dropExeExtension filepath =+          case splitExtension filepath of+            (filepath', extension) | extension == exeExtension -> filepath'+                                   | otherwise                 -> filepath++-- | @takeWhileEndLE p@ is equivalent to @reverse . takeWhile p . reverse@, but+-- is usually faster (as well as being easier to read).+takeWhileEndLE :: (a -> Bool) -> [a] -> [a]+takeWhileEndLE p = fst . foldr go ([], False)+  where+    go x (rest, done)+      | not done && p x = (x:rest, False)+      | otherwise = (rest, True)
+ CabalHelper/Main.hs view
@@ -0,0 +1,344 @@+-- cabal-helper: Simple interface to Cabal's configuration state+-- Copyright (C) 2015  Daniel Gröber <dxld ÄT darkboxed DOT org>+--+-- This program is free software: you can redistribute it and/or modify+-- it under the terms of the GNU Affero General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.+--+-- This program is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+-- GNU Affero General Public License for more details.+--+-- You should have received a copy of the GNU Affero General Public License+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.++{-# LANGUAGE CPP, BangPatterns, RecordWildCards #-}+{-# OPTIONS_GHC -fno-warn-deprecations #-}+import Distribution.Simple.Utils (cabalVersion)+import Distribution.Simple.Configure++import Distribution.Package (PackageIdentifier, InstalledPackageId, PackageId)+import Distribution.PackageDescription (PackageDescription,+                                        FlagAssignment,+                                        Executable(..),+                                        Library(..),+                                        TestSuite(..),+                                        Benchmark(..),+                                        BuildInfo(..),+                                        TestSuiteInterface(..),+                                        BenchmarkInterface(..),+                                        withLib)+import Distribution.PackageDescription.Parse (readPackageDescription)+import Distribution.PackageDescription.Configuration (flattenPackageDescription)++import Distribution.Simple.Program (requireProgram, ghcProgram)+import Distribution.Simple.Program.Types (ConfiguredProgram(..))+import Distribution.Simple.Configure (getPersistBuildConfig)+import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..),+                                           Component(..),+                                           ComponentName(..),+                                           ComponentLocalBuildInfo(..),+                                           componentBuildInfo,+                                           externalPackageDeps,+                                           withComponentsLBI,+                                           inplacePackageId)++import Distribution.Simple.GHC (componentGhcOptions)+import Distribution.Simple.Program.GHC (GhcOptions(..), renderGhcOptions)++import Distribution.Simple.Setup (ConfigFlags(..),Flag(..))+import Distribution.Simple.Build (initialBuildSteps)+import Distribution.Simple.BuildPaths (autogenModuleName, cppHeaderName, exeExtension)+import Distribution.Simple.Compiler (PackageDB(..))++import Distribution.ModuleName (components)+import qualified Distribution.ModuleName as C (ModuleName)+import Distribution.Text (display)+import Distribution.Verbosity (Verbosity, silent, deafening)++#if CABAL_MAJOR == 1 && CABAL_MINOR >= 22+import Distribution.Utils.NubList+#endif++import Control.Applicative ((<$>))+import Control.Monad+import Control.Exception (catch, PatternMatchFail(..))+import Data.List+import Data.Maybe+import Data.Monoid+import Data.IORef+import System.Environment+import System.Directory+import System.FilePath+import System.Exit+import System.IO+import System.IO.Unsafe (unsafeInterleaveIO, unsafePerformIO)+import Text.Printf++import CabalHelper.Common+import CabalHelper.Types++usage = do+  prog <- getProgName+  hPutStr stderr $ align "(" "|" ("Usage: " ++ prog ++ " " ++ usageMsg)+ where+   usageMsg = ""+     ++"DIST_DIR ( version\n"+     ++"         | print-lbi\n"+     ++"         | write-autogen-files\n"+     ++"         | ghc-options [--with-inplace]\n"+     ++"         | ghc-src-options [--with-inplace]\n"+     ++"         | ghc-pkg-options [--with-inplace]\n"+     ++"         | entrypoints\n"+     ++"         | source-dirs\n"+     ++"         ) ...\n"++commands :: [String]+commands = [ "print-bli"+           , "write-autogen-files"+           , "component-from-file"+           , "ghc-options"+           , "ghc-src-options"+           , "ghc-pkg-options"+           , "entrypoints"+           , "source-dirs"]++main :: IO ()+main = do+  args <- getArgs++  distdir:args' <- case args of+                    [] -> usage >> exitFailure+                    _ -> return args++  ddexists <- doesDirectoryExist distdir+  when (not ddexists) $ do+         errMsg $ "distdir '"++distdir++"' does not exist"+         exitFailure++  v <- maybe silent (const deafening) . lookup  "GHC_MOD_DEBUG" <$> getEnvironment+  lbi <- unsafeInterleaveIO $ getPersistBuildConfig distdir+  let pd = localPkgDescr lbi++  let+      -- a =<< b $$ c   ==  (a =<< b) $$ c+      -- a <$$> b $$ c  ==  a <$$> (b $$ c)+      infixr 2 $$+      ($$) = ($)+      infixr 1 <$$>+      (<$$>) = (<$>)++      collectCmdOptions :: [String] -> [[String]]+      collectCmdOptions =+          reverse . map reverse . foldl f [] . dropWhile isOpt+       where+         isOpt = ("--" `isPrefixOf`)+         f [] x = [[x]]+         f (a:as) x+             | isOpt x = (x:a):as+             | otherwise = [x]:(a:as)++  let cmds = collectCmdOptions args'++  if any (["version"] `isPrefixOf`) cmds+    then do+      putStrLn $+       printf "using version %s of the Cabal library" (display cabalVersion)+      exitSuccess+    else return ()++  print =<< flip mapM cmds $$ \cmd -> do+  case cmd of+    "write-autogen-files":[] -> do+      let pd = localPkgDescr lbi+       -- calls writeAutogenFiles+      initialBuildSteps distdir pd lbi v+      return Nothing++    "ghc-options":flags ->+      Just . GmCabalHelperStrings <$$> componentsMap lbi v distdir $$+      \c clbi bi -> let+           outdir = componentOutDir lbi c+           (clbi', adopts) = case flags of+                               ["--with-inplace"] -> (clbi, mempty)+                               [] -> removeInplaceDeps pd clbi+           opts = componentGhcOptions v lbi bi clbi' outdir+           in+              renderGhcOptions' lbi v $ opts `mappend` adopts++    "ghc-src-options":flags ->+      Just . GmCabalHelperStrings <$$> componentsMap lbi v distdir $$+      \c clbi bi -> let+           outdir = componentOutDir lbi c+           (clbi', adopts) = case flags of+                               ["--with-inplace"] -> (clbi, mempty)+                               [] -> removeInplaceDeps pd clbi+           opts = componentGhcOptions v lbi bi clbi' outdir+           comp = compiler lbi++           opts' = mempty {+               -- Not really needed but "unexpected package db stack: []"+               ghcOptPackageDBs      = [GlobalPackageDB],+               ghcOptCppOptions      = ghcOptCppOptions opts,+               ghcOptCppIncludePath  = ghcOptCppIncludePath opts,+               ghcOptCppIncludes     = ghcOptCppIncludes opts,+               ghcOptFfiIncludes     = ghcOptFfiIncludes opts,+               ghcOptSourcePathClear = ghcOptSourcePathClear opts,+               ghcOptSourcePath      = ghcOptSourcePath opts+              }+            in+              renderGhcOptions' lbi v $ opts `mappend` adopts++    "ghc-pkg-options":flags ->+      Just . GmCabalHelperStrings <$$> componentsMap lbi v distdir $$+      \c clbi bi -> let+           comp = compiler lbi+           outdir = componentOutDir lbi c+           (clbi', adopts) = case flags of+                               ["--with-inplace"] -> (clbi, mempty)+                               [] -> removeInplaceDeps pd clbi+           opts = componentGhcOptions v lbi bi clbi' outdir++           opts' = mempty {+                       ghcOptPackageDBs = ghcOptPackageDBs opts,+                       ghcOptPackages   = ghcOptPackages opts,+                       ghcOptHideAllPackages = ghcOptHideAllPackages opts+                   }+           in+             renderGhcOptions' lbi v $ opts' `mappend` adopts++    "entrypoints":[] -> do+      eps <- componentsMap lbi v distdir $ \c clbi bi ->+               return $ componentEntrypoints c+      -- MUST append Setup component at the end otherwise CabalHelper gets+      -- confused+      let eps' = eps ++ [(GmSetupHsName, Right [GmModuleName "Setup"])]+      return $ Just $ GmCabalHelperEntrypoints eps'++    "source-dirs":[] ->+      Just . GmCabalHelperStrings <$$> componentsMap lbi v distdir $$+      \c clbi bi -> return $ hsSourceDirs bi++    "print-lbi":[] ->+      return $ Just $ GmCabalHelperLbi $ show lbi++    cmd:_ | not (cmd `elem` commands) ->+            errMsg ("Unknown command: " ++ cmd) >> usage >> exitFailure+    _ ->+            errMsg "Invalid usage!" >> usage >> exitFailure+++getLibrary :: PackageDescription -> Library+getLibrary pd = unsafePerformIO $ do+  lr <- newIORef (error "libraryMap: empty IORef")+  withLib pd (writeIORef lr)+  readIORef lr++componentsMap :: LocalBuildInfo+              -> Verbosity+              -> FilePath+              -> (   Component+                  -> ComponentLocalBuildInfo+                  -> BuildInfo+                  -> IO a)+              -> IO [(GmComponentName, a)]+componentsMap lbi v distdir f = do+    let pd = localPkgDescr lbi++    lr <- newIORef []++    withComponentsLBI pd lbi $ \c clbi -> do+        let bi = componentBuildInfo c+            name = componentNameFromComponent c++        l' <- readIORef lr+        r <- f c clbi bi+        writeIORef lr $ (componentNameToGm name, r):l'+    reverse <$> readIORef lr++componentNameToGm CLibName = GmLibName+componentNameToGm (CExeName n) = GmExeName n+componentNameToGm (CTestName n) = GmTestName n+componentNameToGm (CBenchName n) = GmBenchName n++componentNameFromComponent (CLib Library {}) = CLibName+componentNameFromComponent (CExe Executable {..}) = CExeName exeName+componentNameFromComponent (CTest TestSuite {..}) = CTestName testName+componentNameFromComponent (CBench Benchmark {..}) = CBenchName benchmarkName++componentOutDir lbi (CLib Library {..})= buildDir lbi+componentOutDir lbi (CExe Executable {..})= exeOutDir lbi exeName+componentOutDir lbi (CTest TestSuite { testInterface = TestSuiteExeV10 _ _, ..}) =+    exeOutDir lbi testName+componentOutDir lbi (CTest TestSuite { testInterface = TestSuiteLibV09 _ _, ..}) =+    exeOutDir lbi (testName ++ "Stub")+componentOutDir lbi (CBench Benchmark { benchmarkInterface = BenchmarkExeV10 _ _, ..})=+    exeOutDir lbi benchmarkName++gmModuleName :: C.ModuleName -> GmModuleName+gmModuleName = GmModuleName . intercalate "." . components++componentEntrypoints :: Component -> Either FilePath [GmModuleName]+componentEntrypoints (CLib Library {..})+    = Right $ map gmModuleName $ exposedModules ++ (otherModules libBuildInfo)+componentEntrypoints (CExe Executable {..})+    = Left modulePath+componentEntrypoints (CTest TestSuite { testInterface = TestSuiteExeV10 _ fp })+    = Left fp+componentEntrypoints (CTest TestSuite { testInterface = TestSuiteLibV09 _ mn })+    = Right [gmModuleName mn]+componentEntrypoints (CTest TestSuite {})+    = Right []+componentEntrypoints (CBench Benchmark { benchmarkInterface = BenchmarkExeV10 _  fp})+    = Left fp+componentEntrypoints (CBench Benchmark {})+    = Left []++exeOutDir :: LocalBuildInfo -> String -> FilePath+exeOutDir lbi exeName =+  ----- Copied from Distribution/Simple/GHC.hs:buildOrReplExe+  -- exeNameReal, the name that GHC really uses (with .exe on Windows)+  let exeNameReal = exeName <.>+                    (if takeExtension exeName /= ('.':exeExtension)+                       then exeExtension+                       else "")++      targetDir = (buildDir lbi) </> exeName+  in targetDir+++removeInplaceDeps :: PackageDescription+                  -> ComponentLocalBuildInfo+                  -> (ComponentLocalBuildInfo, GhcOptions)+removeInplaceDeps pd clbi = let+    (ideps, deps) = partition isInplaceDep (componentPackageDeps clbi)+    hasIdeps = not $ null ideps+    clbi' = clbi { componentPackageDeps = deps }+    lib = getLibrary pd+    src_dirs = hsSourceDirs (libBuildInfo lib)+    adopts = mempty {+               ghcOptSourcePath      =+#if CABAL_MAJOR == 1 && CABAL_MINOR >= 22+                   toNubListR src_dirs+#else+                   src_dirs+#endif++             }++  in (clbi', if hasIdeps then adopts else mempty)++ where+   isInplaceDep :: (InstalledPackageId, PackageId) -> Bool+   isInplaceDep (ipid, pid) = inplacePackageId pid == ipid++renderGhcOptions' lbi v opts = do+#if CABAL_MAJOR == 1 && CABAL_MINOR < 20+  (ghcProg, _) <- requireProgram v ghcProgram (withPrograms lbi)+  let Just ghcVer = programVersion ghcProg+  return $ renderGhcOptions ghcVer opts+#else+  return $ renderGhcOptions (compiler lbi) opts+#endif
+ CabalHelper/Types.hs view
@@ -0,0 +1,40 @@+-- cabal-helper: Simple interface to Cabal's configuration state+-- Copyright (C) 2015  Daniel Gröber <dxld ÄT darkboxed DOT org>+--+-- This program is free software: you can redistribute it and/or modify+-- it under the terms of the GNU Affero General Public License as published by+-- the Free Software Foundation, either version 3 of the License, or+-- (at your option) any later version.+--+-- This program is distributed in the hope that it will be useful,+-- but WITHOUT ANY WARRANTY; without even the implied warranty of+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+-- GNU Affero General Public License for more details.+--+-- You should have received a copy of the GNU Affero General Public License+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.++module CabalHelper.Types where++newtype ChModuleName = ChModuleName String+    deriving (Eq, Ord, Read, Show)++data ChComponentName = ChSetupHsName+                     | ChLibName+                     | ChExeName String+                     | ChTestName String+                     | ChBenchName String+  deriving (Eq, Ord, Read, Show)++data Response+    = ResponseStrings    [(ChComponentName, [String])]+    | ResponseEntrypoints [(ChComponentName, ChEntrypoint)]+    | ResponseLbi String+  deriving (Eq, Ord, Read, Show)++data ChEntrypoint = ChExeEntrypoint { chMainIs         :: FilePath+                                    , chOtherModules   :: [ChModuleName]+                                    }+                  | ChLibentrypoint { chExposedModules :: [ChModuleName]+                                    , chOtherModules   :: [ChModuleName]+                                    } deriving (Eq, Ord, Read, Show)
cabal-helper.cabal view
@@ -1,5 +1,5 @@ name:                cabal-helper-version:             0.1.0.0+version:             0.1.0.1 synopsis:            Simple interface to Cabal's configuration state used by ghc-mod description:     @cabal-helper@ provides a library which wraps the internal use of executables@@ -31,6 +31,7 @@ category:            Distribution build-type:          Simple cabal-version:       >=1.10+extra-source-files:  CabalHelper/Main.hs  source-repository head   type:     git@@ -48,12 +49,15 @@                      , mtl                      , process - Executable cabal-helper-wrapper   Default-Language:    Haskell2010   Other-Extensions:    TemplateHaskell   Main-Is:             CabalHelper/Wrapper.hs   Other-Modules:       Paths_cabal_helper+                       CabalHelper.Types+                       CabalHelper.Common+                       CabalHelper.GuessGhc+                       CabalHelper.Data   GHC-Options:         -Wall   X-Install-Target:    $libexecdir   Build-Depends:       base >= 4.5 && < 5