packages feed

cabal-helper 0.3.7.0 → 0.3.8.0

raw patch · 7 files changed

+143/−44 lines, 7 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Distribution.Helper: ChPkgGlobal :: ChPkgDb
+ Distribution.Helper: ChPkgSpecific :: FilePath -> ChPkgDb
+ Distribution.Helper: ChPkgUser :: ChPkgDb
+ Distribution.Helper: data ChPkgDb
+ Distribution.Helper: packageDbStack :: MonadIO m => Query m [ChPkgDb]

Files

CabalHelper/Common.hs view
@@ -31,6 +31,7 @@ import System.IO import System.Exit import Text.ParserCombinators.ReadP+import Prelude  data Panic = Panic String deriving (Typeable, Show) instance Exception Panic
CabalHelper/Data.hs view
@@ -32,7 +32,8 @@ withHelperSources action = withSystemTempDirectory "cabal-helper" $ \dir -> do     let chdir = dir </> "CabalHelper"     createDirectory chdir-    forM_ sourceFiles $ \(fn, src) -> writeFile (chdir </> fn) src+    forM_ sourceFiles $ \(fn, src) ->+        BS.writeFile (chdir </> fn) $ UTF8.fromString src     action dir  sourceFiles :: [(FilePath, String)]
CabalHelper/Main.hs view
@@ -96,6 +96,7 @@      ++"         | ghc-pkg-options [--with-inplace]\n"      ++"         | ghc-merged-pkg-options [--with-inplace]\n"      ++"         | ghc-lang-options [--with-inplace]\n"+     ++"         | package-db-stack\n"      ++"         | entrypoints\n"      ++"         | source-dirs\n"      ++"         ) ...\n"@@ -108,6 +109,7 @@            , "ghc-src-options"            , "ghc-pkg-options"            , "ghc-lang-options"+           , "package-db-stack"            , "entrypoints"            , "source-dirs"] @@ -220,6 +222,15 @@                        ghcOptExtensionMap = ghcOptExtensionMap opts                    }       return $ Just $ ChResponseCompList (res ++ [(ChSetupHsName, [])])++    "package-db-stack":[] -> do+      let+          pkgDb GlobalPackageDB = ChPkgGlobal+          pkgDb UserPackageDB   = ChPkgUser+          pkgDb (SpecificPackageDB s) = ChPkgSpecific s++      -- TODO: Setup.hs has access to the sandbox as well: ghc-mod#478+      return $ Just $ ChResponsePkgDbs $ map pkgDb $ withPackageDB lbi      "entrypoints":[] -> do       eps <- componentsMap lbi v distdir $ \c clbi bi ->
CabalHelper/Types.hs view
@@ -34,6 +34,7 @@     = ChResponseCompList    [(ChComponentName, [String])]     | ChResponseEntrypoints [(ChComponentName, ChEntrypoint)]     | ChResponseList        [String]+    | ChResponsePkgDbs      [ChPkgDb]     | ChResponseLbi String     | ChResponseVersion String Version   deriving (Eq, Ord, Read, Show, Generic)@@ -49,3 +50,8 @@                   | ChExeEntrypoint { chMainIs         :: FilePath                                     , chOtherModules   :: [ChModuleName]                                     } deriving (Eq, Ord, Read, Show, Generic)++data ChPkgDb = ChPkgGlobal+             | ChPkgUser+             | ChPkgSpecific FilePath+               deriving (Eq, Ord, Read, Show, Generic)
CabalHelper/Wrapper.hs view
@@ -23,6 +23,7 @@ import Control.Monad import Control.Monad.Trans.Maybe import Control.Monad.IO.Class+import Data.Traversable import Data.Char import Data.List import Data.Maybe@@ -36,6 +37,7 @@ import System.Process import System.Exit import System.IO+import Prelude  import Distribution.System (buildPlatform) import Distribution.Text (display)@@ -53,20 +55,28 @@    usageMsg = "\ \( print-appdatadir\n\ \| print-build-platform\n\-\| DIST_DIR ( print-exe | [CABAL_HELPER_ARGS...] ) )\n"+\| [--verbose]\n\+\  [--with-ghc=GHC_PATH]\n\+\  [--with-ghc-pkg=GHC_PKG_PATH]\n\+\  [--with-cabal=CABAL_PATH]\n\+\  DIST_DIR ( print-exe | [CABAL_HELPER_ARGS...] ) )\n"  data Options = Options {-          ghcProgram    :: FilePath+          verbose       :: Bool+        , ghcProgram    :: FilePath         , ghcPkgProgram :: FilePath         , cabalProgram  :: FilePath }  defaultOptions :: Options-defaultOptions = Options "ghc" "ghc-pkg" "cabal"+defaultOptions = Options False "ghc" "ghc-pkg" "cabal"  globalArgSpec :: [OptDescr (Options -> Options)] globalArgSpec =-      [ option "" ["with-ghc"] "GHC executable to use" $+      [ option "" ["verbose"] "Be more verbose" $+              NoArg $ \o -> o { verbose = True }++      , option "" ["with-ghc"] "GHC executable to use" $               reqArg "PROG" $ \p o -> o { ghcProgram = p }        , option "" ["with-ghc-pkg"] "ghc-pkg executable to use (only needed when guessing from GHC path fails)" $@@ -84,10 +94,10 @@  parseCommandArgs :: Options -> [String] -> (Options, [String]) parseCommandArgs opts argv-    = case getOpt Permute globalArgSpec argv of+    = case getOpt RequireOrder globalArgSpec argv of         (o,r,[])   -> (foldr id opts o, r)         (_,_,errs) ->-            panic $ "Parsing command options failed: " ++ concat errs+            panic $ "Parsing command options failed:\n" ++ concat errs  guessProgramPaths :: Options -> IO Options guessProgramPaths opts = do@@ -108,7 +118,8 @@   opts <- guessProgramPaths opts'   case args of     [] -> usage-    "--help":[] -> usage+    "help":[] -> usage+    "version":[] -> putStrLn $ showVersion version     "print-appdatadir":[] -> putStrLn =<< appDataDir     "print-build-platform":[] -> putStrLn $ display buildPlatform     distdir:args' -> do@@ -135,24 +146,35 @@  compileHelper :: Options -> Version -> FilePath -> IO (Either ExitCode FilePath) compileHelper opts cabalVer distdir = withHelperSources $ \chdir -> do-  run [ Right <$> MaybeT (cachedExe cabalVer)+  run [ compileCabalSource chdir -- TODO: here ghc's caching fails and it always+                                 -- recompiles, probably because we write the+                                 -- sources to a tempdir and they always look+                                 -- newer than the Cabal sources, not sure if we+                                 -- can fix this+      , Right <$> MaybeT (cachedExe cabalVer)       , compileGlobal chdir       , cachedCabalPkg chdir-      , compileCabalSource chdir       , MaybeT (Just <$> compileSandbox chdir)       ]   where    run actions = fromJust <$> runMaybeT (msum actions) +   logMsg = "compiling helper with Cabal from "+++-- for relaxed deps: find (sameMajorVersionAs cabalVer) . reverse . sort+    -- | Check if this version is globally available    compileGlobal :: FilePath -> MaybeT IO (Either ExitCode FilePath)    compileGlobal chdir = do       -- TODO: add option to let user specify custom package-db, relevant when       -- using a Cabal compiled from git!-       _ <- MaybeT $ find (== cabalVer) <$> listCabalVersions opts-       liftIO $ compileWithPkg chdir Nothing +       ver <- MaybeT $ find (== cabalVer) <$> listCabalVersions opts+       vLog opts $ logMsg ++ "user/global package-db"+       liftIO $ compileWithPkg chdir Nothing ver+    -- | Check if we already compiled this version of cabal into a private    -- package-db    cachedCabalPkg :: FilePath -> MaybeT IO (Either ExitCode FilePath)@@ -160,20 +182,30 @@        db_exists <- liftIO $ cabalPkgDbExists opts cabalVer        case db_exists of          False -> mzero-         True -> liftIO $ do-             db <- cabalPkgDb opts cabalVer-             compileWithPkg chdir (Just db)+         True -> do+             db <- liftIO $ cabalPkgDb opts cabalVer+             vLog opts $ logMsg ++ "private package-db in " ++ db+             liftIO $ compileWithPkg chdir (Just db) cabalVer     -- | See if we're in a cabal source tree    compileCabalSource :: FilePath -> MaybeT IO (Either ExitCode FilePath)    compileCabalSource chdir = do        let couldBeSrcDir = takeDirectory distdir            cabalFile = couldBeSrcDir </> "Cabal.cabal"-       cabal <- liftIO $ doesFileExist cabalFile-       case cabal of+           isCabalMagicVer = cabalVer == Version [1,9999] []+       cabalSrc <- liftIO $ doesFileExist cabalFile++       when isCabalMagicVer $+         vLog opts $ "cabal magic version (1.9999) found"++       when cabalSrc $+         vLog opts $ "directory above distdir looks like cabal source tree (Cabal.cabal exists)"++       case isCabalMagicVer || cabalSrc of          False -> mzero          True -> liftIO $ do            ver <- cabalFileVersion <$> readFile cabalFile+           vLog opts $ "compiling helper with local Cabal source tree"            compileWithCabalTree chdir ver couldBeSrcDir     -- | Compile the requested cabal version into an isolated package-db@@ -181,13 +213,13 @@    compileSandbox chdir = do        db <- installCabal opts cabalVer `E.catch`              \(SomeException _) -> errorInstallCabal cabalVer distdir-       compileWithPkg chdir (Just db)+       compileWithPkg chdir (Just db) cabalVer     compileWithCabalTree chdir ver srcDir =-       compile opts $ Compile chdir (Just srcDir) Nothing ver []+       compile distdir opts $ Compile chdir (Just srcDir) Nothing ver [] -   compileWithPkg chdir mdb =-       compile opts $ Compile chdir Nothing mdb cabalVer [cabalPkgId cabalVer]+   compileWithPkg chdir mdb ver =+       compile distdir opts $ Compile chdir Nothing mdb ver [cabalPkgId ver]     cabalPkgId v = "Cabal-" ++ showVersion v @@ -211,7 +243,8 @@ \    having it linked to a version of Cabal that's available in you\n\ \    package-dbs or can be built automatically:\n\ \        $ ghc-pkg list | grep Cabal  # find an available Cabal version\n\-\        $ cabal install cabal-install --constraint 'Cabal == $the_found_version'\n\+\            Cabal-W.X.Y.Z\n\+\        $ cabal install cabal-install --constraint 'Cabal == W.X.*'\n\ \    Afterwards you'll have to reconfigure your project:\n\ \        $ cabal clean && cabal configure\n\ \\n\@@ -225,6 +258,7 @@  where    sver = showVersion cabalVer + data Compile = Compile {       cabalHelperSourceDir :: FilePath,       cabalSourceDir :: Maybe FilePath,@@ -233,12 +267,23 @@       packageDeps    :: [String]     } -compile :: Options -> Compile -> IO (Either ExitCode FilePath)-compile Options {..} Compile {..} = do-    outdir <- appDataDir-    createDirectoryIfMissing True outdir-    exe <- exePath cabalVersion+compile :: FilePath -> Options -> Compile -> IO (Either ExitCode FilePath)+compile distdir opts@Options {..} Compile {..} = do+    cCabalSourceDir <- canonicalizePath `traverse` cabalSourceDir+    appdir <- appDataDir +    let outdir' = maybe appdir (const $ distdir </> "cabal-helper") cCabalSourceDir+    createDirectoryIfMissing True outdir'+    outdir <- canonicalizePath outdir'++    let exedir' = maybe outdir (const distdir) cCabalSourceDir+    createDirectoryIfMissing True exedir'+    exedir <- canonicalizePath exedir'+    exe <- exePath' cabalVersion <$> canonicalizePath exedir++    vLog opts $ "outdir: " ++ outdir+    vLog opts $ "exedir: " ++ exedir+     let Version (mj:mi:_) _ = cabalVersion     let ghc_opts =              concat [@@ -249,11 +294,25 @@           , "-optP-DCABAL_MINOR=" ++ show mi           ],           maybeToList $ ("-package-conf="++) <$> packageDb,-          map ("-i"++) $ ".":maybeToList cabalSourceDir,+          map ("-i"++) $ nub $ ".":maybeToList cCabalSourceDir,++          if isNothing cCabalSourceDir+             then [ "-hide-all-packages"+                  , "-package", "base"+                  , "-package", "directory"+                  , "-package", "filepath"+                  , "-package", "process"+                  , "-package", "bytestring"+                  , "-package", "ghc-prim"+                  ]+             else [],+           concatMap (\p -> ["-package", p]) packageDeps,           [ "--make",  "CabalHelper/Main.hs" ]          ] +    vLog opts $ intercalate " " $ map (("\""++) . (++"\"")) $ ghcProgram:ghc_opts+     -- TODO: touch exe after, ghc doesn't do that if the input files didn't     -- actually change     rv <- callProcessStderr' (Just cabalHelperSourceDir) ghcProgram ghc_opts@@ -263,10 +322,13 @@  exePath :: Version -> IO FilePath exePath cabalVersion = do-    outdir <- appDataDir-    return $ outdir </> "cabal-helper-" ++ showVersion version -- our ver-                     ++ "-Cabal-" ++ showVersion cabalVersion+    exePath' cabalVersion <$> appDataDir +exePath' :: Version-> FilePath -> FilePath+exePath' cabalVersion outdir =+    outdir </> "cabal-helper-" ++ showVersion version -- our ver+            ++ "-Cabal-" ++ showVersion cabalVersion+ cachedExe :: Version -> IO (Maybe FilePath) cachedExe cabalVersion = do    exe <- exePath cabalVersion@@ -306,25 +368,29 @@ \\n\ \If you want to avoid this automatic installation altogether install\n\ \version %s of Cabal manually (into your user or global package-db):\n\-\    $ cabal install Cabal-%s\n\+\    $ cabal install Cabal --constraint \"Cabal == %s\"\n\ \\n\-\Building Cabal-%s..." appdir sver sver sver+\Building Cabal %s ...\n" appdir sver sver sver    db <- createPkgDb opts ver-  callProcessStderr (Just "/") (cabalProgram opts) $ concat+  cabal_opts <- return $ concat       [         [ "--package-db=clear"         , "--package-db=global"         , "--package-db=" ++ db         , "--prefix=" ++ db </> "prefix"-        , "-v0"         , "--with-ghc=" ++ ghcProgram opts         ]         , if ghcPkgProgram opts /= ghcPkgProgram defaultOptions             then [ "--with-ghc-pkg=" ++ ghcPkgProgram opts ]             else []-        , [ "install", "Cabal-"++showVersion ver ]+        , [ "install", "Cabal", "--constraint"+          , "Cabal == " ++ showVersion ver ]       ]++  vLog opts $ intercalate " " $ map (("\""++) . (++"\"")) $ cabalProgram opts:cabal_opts++  callProcessStderr (Just "/") (cabalProgram opts) cabal_opts   hPutStrLn stderr "done"   return db @@ -334,7 +400,7 @@  ghcPkgVersion :: Options -> IO Version ghcPkgVersion Options {..} = do-    parseVer . trim <$> readProcess ghcPkgProgram ["--numeric-version"] ""+    parseVer . trim . dropWhile (not . isDigit) <$> readProcess ghcPkgProgram ["--version"] ""  trim :: String -> String trim = dropWhileEnd isSpace@@ -376,8 +442,13 @@  -- | Find @version: XXX@ delcaration in a cabal file cabalFileVersion :: String -> Version-cabalFileVersion cabalFile = do-  fromJust $ parseVer . extract <$> find ("version" `isPrefixOf`) ls+cabalFileVersion cabalFile =+  fromJust $ parseVer . extract <$> find ("version:" `isPrefixOf`) ls  where   ls = map (map toLower) $ lines cabalFile-  extract = dropWhile (/=':') >>> dropWhile isSpace >>> takeWhile (not . isSpace)+  extract = dropWhile (/=':') >>> drop 1 >>> dropWhile isSpace >>> takeWhile (not . isSpace)++vLog :: MonadIO m => Options -> String -> m ()+vLog Options { verbose = True } msg =+    liftIO $ hPutStrLn stderr msg+vLog _ _ = return ()
Distribution/Helper.hs view
@@ -27,6 +27,7 @@    -- * Queries against Cabal\'s on disk state +  , packageDbStack   , entrypoints   , sourceDirs   , ghcOptions@@ -38,6 +39,7 @@   -- * Result types   , ChModuleName(..)   , ChComponentName(..)+  , ChPkgDb(..)   , ChEntrypoint(..)    -- * General information@@ -86,6 +88,7 @@     def = Programs "cabal" "ghc" "ghc-pkg"  data SomeLocalBuildInfo = SomeLocalBuildInfo {+      slbiPackageDbStack      :: [ChPkgDb],       slbiEntrypoints         :: [(ChComponentName, ChEntrypoint)],       slbiSourceDirs          :: [(ChComponentName, [String])],       slbiGhcOptions          :: [(ChComponentName, [String])],@@ -133,6 +136,9 @@             return slbi     Just slbi -> return slbi +-- | List of package databases to use.+packageDbStack :: MonadIO m => Query m [ChPkgDb]+ -- | Modules or files Cabal would have the compiler build directly. Can be used -- to compute the home module closure for a component. entrypoints   :: MonadIO m => Query m [(ChComponentName, ChEntrypoint)]@@ -157,6 +163,7 @@ -- | Only language related options, i.e. @-XSomeExtension@ ghcLangOptions :: MonadIO m => Query m [(ChComponentName, [String])] +packageDbStack      = Query $ slbiPackageDbStack      `liftM` getSlbi entrypoints         = Query $ slbiEntrypoints         `liftM` getSlbi sourceDirs          = Query $ slbiSourceDirs          `liftM` getSlbi ghcOptions          = Query $ slbiGhcOptions          `liftM` getSlbi@@ -189,7 +196,8 @@                  , "--with-cabal="   ++ cabalProgram progs                  ] -  let args = [ "entrypoints"+  let args = [ "package-db-stack"+             , "entrypoints"              , "source-dirs"              , "ghc-options"              , "ghc-src-options"@@ -206,7 +214,8 @@                      , intercalate " " (map show $ distdir:args)                      , " (read failed)"] -  let [ Just (ChResponseEntrypoints eps),+  let [ Just (ChResponsePkgDbs pkgDbs),+        Just (ChResponseEntrypoints eps),         Just (ChResponseCompList srcDirs),         Just (ChResponseCompList ghcOpts),         Just (ChResponseCompList ghcSrcOpts),@@ -215,7 +224,7 @@         Just (ChResponseCompList ghcLangOpts) ] = res    return $ SomeLocalBuildInfo-    eps srcDirs ghcOpts ghcSrcOpts ghcPkgOpts ghcMergedPkgOpts ghcLangOpts+    pkgDbs eps srcDirs ghcOpts ghcSrcOpts ghcPkgOpts ghcMergedPkgOpts ghcLangOpts  -- | Create @cabal_macros.h@ and @Paths_\<pkg\>@ possibly other generated files -- in the usual place.
cabal-helper.cabal view
@@ -1,5 +1,5 @@ name:                cabal-helper-version:             0.3.7.0+version:             0.3.8.0 synopsis:            Simple interface to some of Cabal's configuration state used by ghc-mod description:     @cabal-helper@ provides a library which wraps the internal use of executables