packages feed

cabal-helper 0.5.3.0 → 0.6.0.0

raw patch · 9 files changed

+274/−132 lines, 9 filesdep −data-defaultPVP ok

version bump matches the API change (PVP)

Dependencies removed: data-default

API changes (from Hackage documentation)

- Distribution.Helper: instance Default Programs
- Distribution.Helper: runQuery' :: Monad m => Programs -> FilePath -> FilePath -> Query m a -> m a
- Distribution.Helper: runQuery'' :: Monad m => (FilePath -> [String] -> String -> IO String) -> Programs -> FilePath -> FilePath -> Query m a -> m a
+ Distribution.Helper: data QueryEnv
+ Distribution.Helper: defaultPrograms :: Programs
+ Distribution.Helper: defaultQueryEnv :: FilePath -> FilePath -> QueryEnv
+ Distribution.Helper: pkgLicenses :: MonadIO m => Query m [(String, [(String, Version)])]
+ Distribution.Helper: qeCabalPkgDb :: QueryEnv -> Maybe FilePath
+ Distribution.Helper: qeCabalVer :: QueryEnv -> Maybe Version
+ Distribution.Helper: qeDistDir :: QueryEnv -> FilePath
+ Distribution.Helper: qePrograms :: QueryEnv -> Programs
+ Distribution.Helper: qeProjectDir :: QueryEnv -> FilePath
+ Distribution.Helper: qeReadProcess :: QueryEnv -> FilePath -> [String] -> String -> IO String
- Distribution.Helper: runQuery :: Monad m => FilePath -> FilePath -> Query m a -> m a
+ Distribution.Helper: runQuery :: Monad m => QueryEnv -> Query m a -> m a

Files

CabalHelper/Common.hs view
@@ -50,20 +50,6 @@   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, (ByteString, Version)))
CabalHelper/Compile.hs view
@@ -46,19 +46,33 @@ import CabalHelper.Types import CabalHelper.Log +data Compile = Compile {+      compCabalHelperSourceDir :: FilePath,+      compCabalSourceDir :: Maybe FilePath,+      compPackageDb      :: Maybe FilePath,+      compCabalVersion   :: Version,+      compPackageDeps    :: [String]+    }+ compileHelper :: Options -> Version -> FilePath -> FilePath -> IO (Either ExitCode FilePath) compileHelper opts cabalVer projdir distdir = withHelperSources $ \chdir -> do-  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)-      , compileSandbox chdir-      , compileGlobal chdir-      , cachedCabalPkg chdir-      , MaybeT (Just <$> compilePrivatePkgDb chdir)-      ]+  case cabalPkgDb opts of+    Nothing ->+      run [+            -- 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+            compileCabalSource chdir+          , Right <$> MaybeT (cachedExe cabalVer)+          , compileSandbox chdir+          , compileGlobal chdir+          , cachedCabalPkg chdir+          , MaybeT (Just <$> compilePrivatePkgDb chdir)+          ]+    mdb ->+      run [ Right <$> MaybeT (cachedExe cabalVer)+          , liftIO $ compileWithPkg chdir mdb cabalVer+          ]   where    run actions = fromJust <$> runMaybeT (msum actions)@@ -95,7 +109,7 @@        case db_exists of          False -> mzero          True -> do-             db <- liftIO $ cabalPkgDb opts cabalVer+             db <- liftIO $ getPrivateCabalPkgDb opts cabalVer              vLog opts $ logMsg ++ "private package-db in " ++ db              liftIO $ compileWithPkg chdir (Just db) cabalVer @@ -134,17 +148,9 @@     cabalPkgId v = "Cabal-" ++ showVersion v -data Compile = Compile {-      cabalHelperSourceDir :: FilePath,-      cabalSourceDir :: Maybe FilePath,-      packageDb      :: Maybe FilePath,-      cabalVersion   :: Version,-      packageDeps    :: [String]-    }- compile :: FilePath -> Options -> Compile -> IO (Either ExitCode FilePath) compile distdir opts@Options {..} Compile {..} = do-    cCabalSourceDir <- canonicalizePath `traverse` cabalSourceDir+    cCabalSourceDir <- canonicalizePath `traverse` compCabalSourceDir     appdir <- appDataDir      let outdir' = maybe appdir (const $ distdir </> "cabal-helper") cCabalSourceDir@@ -154,12 +160,12 @@     let exedir' = maybe outdir (const distdir) cCabalSourceDir     createDirectoryIfMissing True exedir'     exedir <- canonicalizePath exedir'-    exe <- exePath' cabalVersion <$> canonicalizePath exedir+    exe <- exePath' compCabalVersion <$> canonicalizePath exedir      vLog opts $ "outdir: " ++ outdir     vLog opts $ "exedir: " ++ exedir -    let Version (mj:mi:_) _ = cabalVersion+    let Version (mj:mi:_) _ = compCabalVersion     let ghc_opts =              concat [           [ "-outputdir", outdir@@ -168,12 +174,13 @@           , "-optP-DCABAL_MAJOR=" ++ show mj           , "-optP-DCABAL_MINOR=" ++ show mi           ],-          maybeToList $ ("-package-conf="++) <$> packageDb,+          maybeToList $ ("-package-conf="++) <$> compPackageDb,           map ("-i"++) $ nub $ ".":maybeToList cCabalSourceDir,            if isNothing cCabalSourceDir              then [ "-hide-all-packages"                   , "-package", "base"+                  , "-package", "containers"                   , "-package", "directory"                   , "-package", "filepath"                   , "-package", "process"@@ -182,7 +189,7 @@                   ]              else [], -          concatMap (\p -> ["-package", p]) packageDeps,+          concatMap (\p -> ["-package", p]) compPackageDeps,           [ "--make",  "CabalHelper/Main.hs" ]          ] @@ -190,19 +197,19 @@      -- TODO: touch exe after, ghc doesn't do that if the input files didn't     -- actually change-    rv <- callProcessStderr' (Just cabalHelperSourceDir) ghcProgram ghc_opts+    rv <- callProcessStderr' (Just compCabalHelperSourceDir) ghcProgram ghc_opts     return $ case rv of                ExitSuccess -> Right exe                e@(ExitFailure _) -> Left e  exePath :: Version -> IO FilePath-exePath cabalVersion = do-    exePath' cabalVersion <$> appDataDir+exePath compCabalVersion = do+    exePath' compCabalVersion <$> appDataDir  exePath' :: Version-> FilePath -> FilePath-exePath' cabalVersion outdir =+exePath' compCabalVersion outdir =     outdir </> "cabal-helper-" ++ showVersion version -- our ver-            ++ "-Cabal-" ++ showVersion cabalVersion+            ++ "-Cabal-" ++ showVersion compCabalVersion  callProcessStderr' :: Maybe FilePath -> FilePath -> [String] -> IO ExitCode callProcessStderr' mwd exe args = do@@ -303,8 +310,8 @@    sver = showVersion cabalVer  cachedExe :: Version -> IO (Maybe FilePath)-cachedExe cabalVersion = do-   exe <- exePath cabalVersion+cachedExe compCabalVersion = do+   exe <- exePath compCabalVersion    exists <- doesFileExist exe    return $ if exists then Just exe else Nothing @@ -322,7 +329,7 @@  cabalPkgDbExists :: Options -> Version -> IO Bool cabalPkgDbExists opts ver = do-  db <- cabalPkgDb opts ver+  db <- getPrivateCabalPkgDb opts ver   dexists <- doesDirectoryExist db   case dexists of     False -> return False@@ -348,13 +355,13 @@  createPkgDb :: Options -> Version -> IO FilePath createPkgDb opts@Options {..} ver = do-  db <- cabalPkgDb opts ver+  db <- getPrivateCabalPkgDb opts ver   exists <- doesDirectoryExist db   when (not exists) $ callProcessStderr Nothing ghcPkgProgram ["init", db]   return db -cabalPkgDb :: Options -> Version -> IO FilePath-cabalPkgDb opts ver = do+getPrivateCabalPkgDb :: Options -> Version -> IO FilePath+getPrivateCabalPkgDb opts ver = do   appdir <- appDataDir   ghcVer <- ghcVersion opts   return $ appdir </> "Cabal-" ++ showVersion ver ++ "-db-" ++ showVersion ghcVer
CabalHelper/Data.hs view
@@ -41,5 +41,6 @@   [ ("Main.hs",   $(LitE . StringL <$> runIO (UTF8.toString <$> BS.readFile "CabalHelper/Main.hs")))   , ("Common.hs", $(LitE . StringL <$> runIO (UTF8.toString <$> BS.readFile "CabalHelper/Common.hs")))   , ("Sandbox.hs",  $(LitE . StringL <$> runIO (UTF8.toString <$> BS.readFile "CabalHelper/Sandbox.hs")))+  , ("Licenses.hs",  $(LitE . StringL <$> runIO (UTF8.toString <$> BS.readFile "CabalHelper/Licenses.hs")))   , ("Types.hs",  $(LitE . StringL <$> runIO (UTF8.toString <$> BS.readFile "CabalHelper/Types.hs")))   ]
+ CabalHelper/Licenses.hs view
@@ -0,0 +1,102 @@+{-# LANGUAGE CPP #-}+module CabalHelper.Licenses where++-- Copyright (c) 2014, Jasper Van der Jeugt <m@jaspervdj.be>++--------------------------------------------------------------------------------+import           Control.Arrow                      ((***), (&&&))+import           Control.Monad                      (forM_, unless)+import           Data.List                          (foldl', sort)+import           Data.Maybe                         (catMaybes)+import           Data.Version                       (Version)+import           Data.Set                           (Set)+import qualified Data.Set                           as Set+import           Distribution.InstalledPackageInfo  (InstalledPackageInfo)+import qualified Distribution.InstalledPackageInfo  as InstalledPackageInfo+import qualified Distribution.License               as Cabal+import qualified Distribution.Package               as Cabal+import qualified Distribution.Simple.Configure      as Cabal+import qualified Distribution.Simple.LocalBuildInfo as Cabal+import qualified Distribution.Simple.PackageIndex   as Cabal+import qualified Distribution.Text                  as Cabal+import           System.Directory                   (getDirectoryContents)+import           System.Exit                        (exitFailure)+import           System.FilePath                    (takeExtension)+import           System.IO                          (hPutStrLn, stderr)++--------------------------------------------------------------------------------++#if CABAL_MAJOR == 1 && CABAL_MINOR >  22+type PackageIndex a = Cabal.PackageIndex (InstalledPackageInfo.InstalledPackageInfo)+#elif CABAL_MAJOR == 1 && CABAL_MINOR >= 22+type PackageIndex a = Cabal.PackageIndex (InstalledPackageInfo.InstalledPackageInfo_ a)+#else+type PackageIndex a = Cabal.PackageIndex+#endif++findTransitiveDependencies+    :: PackageIndex a+    -> Set Cabal.InstalledPackageId+    -> Set Cabal.InstalledPackageId+findTransitiveDependencies pkgIdx set0 = go Set.empty (Set.toList set0)+  where+    go set []  = set+    go set (q : queue)+        | q `Set.member` set = go set queue+        | otherwise          =+            case Cabal.lookupInstalledPackageId pkgIdx q of+                Nothing  ->+                    -- Not found can mean that the package still needs to be+                    -- installed (e.g. a component of the target cabal package).+                    -- We can ignore those.+                    go set queue+                Just ipi ->+                    go (Set.insert q set)+                        (InstalledPackageInfo.depends ipi ++ queue)+++--------------------------------------------------------------------------------+getDependencyInstalledPackageIds+    :: Cabal.LocalBuildInfo -> Set Cabal.InstalledPackageId+getDependencyInstalledPackageIds lbi =+    findTransitiveDependencies (Cabal.installedPkgs lbi) $+      Set.fromList $ map fst $ Cabal.externalPackageDeps lbi++--------------------------------------------------------------------------------+getDependencyInstalledPackageInfos+    :: Cabal.LocalBuildInfo -> [InstalledPackageInfo]+getDependencyInstalledPackageInfos lbi = catMaybes $+    map (Cabal.lookupInstalledPackageId pkgIdx) $+    Set.toList (getDependencyInstalledPackageIds lbi)+  where+    pkgIdx = Cabal.installedPkgs lbi+++--------------------------------------------------------------------------------+groupByLicense+    :: [InstalledPackageInfo]+    -> [(Cabal.License, [InstalledPackageInfo])]+groupByLicense = foldl'+    (\assoc ipi -> insert (InstalledPackageInfo.license ipi) ipi assoc) []+  where+    -- 'Cabal.License' doesn't have an 'Ord' instance so we need to use an+    -- association list instead of 'Map'. The number of licenses probably won't+    -- exceed 100 so I think we're alright.+    insert :: Eq k => k -> v -> [(k, [v])] -> [(k, [v])]+    insert k v []   = [(k, [v])]+    insert k v ((k', vs) : kvs)+        | k == k'   = (k, v : vs) : kvs+        | otherwise = (k', vs) : insert k v kvs+++--------------------------------------------------------------------------------+displayDependencyLicenseList+    :: [(Cabal.License, [InstalledPackageInfo])]+    -> [(String, [(String, Version)])]+displayDependencyLicenseList =+    map (Cabal.display *** map (getName &&& getVersion))+  where+    getName =+        Cabal.display . Cabal.pkgName . InstalledPackageInfo.sourcePackageId+    getVersion =+        Cabal.pkgVersion . InstalledPackageInfo.sourcePackageId
CabalHelper/Main.hs view
@@ -79,28 +79,31 @@ import System.IO.Unsafe (unsafeInterleaveIO, unsafePerformIO) import Text.Printf +import CabalHelper.Licenses import CabalHelper.Sandbox import CabalHelper.Common import CabalHelper.Types hiding (Options(..))  usage = do   prog <- getProgName-  hPutStr stderr $ align "(" "|" ("Usage: " ++ prog ++ " " ++ usageMsg)+  hPutStr stderr $ "Usage: " ++ prog ++ " " ++ usageMsg  where    usageMsg = ""-     ++"DIST_DIR ( version\n"-     ++"         | print-lbi [--human]\n"-     ++"         | write-autogen-files\n"-     ++"         | compiler-version\n"-     ++"         | ghc-options     [--with-inplace]\n"-     ++"         | ghc-src-options [--with-inplace]\n"-     ++"         | 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"+     ++"PROJ_DIR DIST_DIR [--with-* ...] (\n"+     ++"    version\n"+     ++"  | print-lbi [--human]\n"+     ++"  | write-autogen-files\n"+     ++"  | compiler-version\n"+     ++"  | ghc-options     [--with-inplace]\n"+     ++"  | ghc-src-options [--with-inplace]\n"+     ++"  | 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"+     ++"  | licenses\n"+     ++"  ) ...\n"  commands :: [String] commands = [ "print-bli"@@ -112,7 +115,8 @@            , "ghc-lang-options"            , "package-db-stack"            , "entrypoints"-           , "source-dirs"]+           , "source-dirs"+           , "licenses"]  main :: IO () main = do@@ -237,6 +241,10 @@     "source-dirs":[] -> do       res <- componentsMap lbi v distdir $$ \_ _ bi -> return $ hsSourceDirs bi       return $ Just $ ChResponseCompList (res ++ [(ChSetupHsName, [])])++    "licenses":[] -> do+      return $ Just $ ChResponseLicenses $+        displayDependencyLicenseList $ groupByLicense $ getDependencyInstalledPackageInfos lbi      "print-lbi":flags ->       case flags of
CabalHelper/Types.hs view
@@ -37,6 +37,7 @@     | ChResponsePkgDbs      [ChPkgDb]     | ChResponseLbi String     | ChResponseVersion String Version+    | ChResponseLicenses    [(String, [(String, Version)])]   deriving (Eq, Ord, Read, Show, Generic)  data ChEntrypoint = ChSetupEntrypoint -- ^ Almost like 'ChExeEntrypoint' but@@ -61,7 +62,9 @@         , ghcProgram    :: FilePath         , ghcPkgProgram :: FilePath         , cabalProgram  :: FilePath+        , cabalVersion  :: Maybe Version+        , cabalPkgDb    :: Maybe FilePath }  defaultOptions :: Options-defaultOptions = Options False "ghc" "ghc-pkg" "cabal"+defaultOptions = Options False "ghc" "ghc-pkg" "cabal" Nothing Nothing
CabalHelper/Wrapper.hs view
@@ -45,7 +45,7 @@ usage :: IO () usage = do   prog <- getProgName-  hPutStr stderr $ align "(" "|" ("Usage: " ++ prog ++ " " ++ usageMsg)+  hPutStr stderr $ "Usage: " ++ prog ++ " " ++ usageMsg  where    usageMsg = "\ \( print-appdatadir\n\@@ -54,6 +54,8 @@ \  [--with-ghc=GHC_PATH]\n\ \  [--with-ghc-pkg=GHC_PKG_PATH]\n\ \  [--with-cabal=CABAL_PATH]\n\+\  [--with-cabal-version=VERSION]\n\+\  [--with-cabal-pkg-db=PKG_DB]\n\ \  PROJ_DIR DIST_DIR ( print-exe | [CABAL_HELPER_ARGS...] ) )\n"  globalArgSpec :: [OptDescr (Options -> Options)]@@ -69,6 +71,13 @@        , option "" ["with-cabal"] "cabal-install executable to use" $                reqArg "PROG" $ \p o -> o { cabalProgram = p }++      , option "" ["with-cabal-version"] "Cabal library version to use" $+               reqArg "VERSION" $ \p o -> o { cabalVersion = Just $ parseVer p }++      , option "" ["with-cabal-pkg-db"] "package database to look for Cabal library in" $+               reqArg "PKG_DB" $ \p o -> o { cabalPkgDb = Just p }+       ]  where    option :: [Char] -> [String] -> String -> ArgDescr a -> OptDescr a@@ -116,13 +125,18 @@ \- Check first line of: %s\n\ \- Maybe try: $ cabal configure" cfgf         Just (hdrCabalVersion, _) -> do-          eexe <- compileHelper opts hdrCabalVersion projdir distdir-          case eexe of-              Left e -> exitWith e-              Right exe ->-                case args' of-                  "print-exe":_ -> putStrLn exe-                  _ -> do-                    (_,_,_,h) <- createProcess $ proc exe args-                    exitWith =<< waitForProcess h+          case cabalVersion opts of+            Just ver | hdrCabalVersion /= ver -> panic $ printf "\+\Cabal version %s was requested setup configuration was\n\+\written by version %s" (showVersion ver) (showVersion hdrCabalVersion)+            _ -> do+              eexe <- compileHelper opts hdrCabalVersion projdir distdir+              case eexe of+                  Left e -> exitWith e+                  Right exe ->+                    case args' of+                      "print-exe":_ -> putStrLn exe+                      _ -> do+                        (_,_,_,h) <- createProcess $ proc exe args+                        exitWith =<< waitForProcess h     _ -> error "invalid command line"
Distribution/Helper.hs view
@@ -14,17 +14,24 @@ -- 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, FlexibleContexts, ConstraintKinds #-}+{-# LANGUAGE CPP, RecordWildCards, FlexibleContexts, ConstraintKinds #-} {-# LANGUAGE GeneralizedNewtypeDeriving, DeriveDataTypeable, DeriveGeneric #-}  module Distribution.Helper (     Programs(..)+  , defaultPrograms+  , QueryEnv+  , qeReadProcess+  , qePrograms+  , qeProjectDir+  , qeDistDir+  , qeCabalPkgDb+  , qeCabalVer+  , defaultQueryEnv    -- * Running Queries   , Query   , runQuery-  , runQuery'-  , runQuery''    -- * Queries against Cabal\'s on disk state @@ -36,6 +43,7 @@   , ghcPkgOptions   , ghcMergedPkgOptions   , ghcLangOptions+  , pkgLicenses    -- * Result types   , ChModuleName(..)@@ -67,7 +75,6 @@ import Control.Exception as E import Data.Char import Data.List-import Data.Default import Data.Version import Data.Typeable import Distribution.Simple.BuildPaths (exeExtension)@@ -91,9 +98,46 @@       ghcPkgProgram :: FilePath     } deriving (Eq, Ord, Show, Read, Generic, Typeable) -instance Default Programs where-    def = Programs "cabal" "ghc" "ghc-pkg"+defaultPrograms :: Programs+defaultPrograms = Programs "cabal" "ghc" "ghc-pkg" +data QueryEnv = QueryEnv {+      -- | How to start the cabal-helper process. Useful if you need to+      -- capture stderr output from the helper.+      qeReadProcess :: FilePath -> [String] -> String -> IO String,++      qePrograms    :: Programs,++      -- | Path to project directory, i.e. the one containing the+      -- @project.cabal@ file+      qeProjectDir  :: FilePath,++      -- | Path to the @dist/@ directory+      qeDistDir     :: FilePath,++      -- | Where to look for the Cabal library when linking the helper+      qeCabalPkgDb  :: Maybe FilePath,++      -- | If @dist/setup-config@ wasn\'t written by this version of Cabal throw+      -- an error+      qeCabalVer    :: Maybe Version+    }++defaultQueryEnv :: FilePath+                -- ^ Path to project directory, i.e. the one containing the+                -- @project.cabal@ file+                -> FilePath+                -- ^ Path to the @dist/@ directory+                -> QueryEnv+defaultQueryEnv projdir distdir = QueryEnv {+    qeReadProcess = readProcess+  , qePrograms    = defaultPrograms+  , qeProjectDir  = projdir+  , qeDistDir     = distdir+  , qeCabalPkgDb  = Nothing+  , qeCabalVer    = Nothing+  }+ data SomeLocalBuildInfo = SomeLocalBuildInfo {       slbiPackageDbStack      :: [ChPkgDb],       slbiEntrypoints         :: [(ChComponentName, ChEntrypoint)],@@ -102,7 +146,8 @@       slbiGhcSrcOptions       :: [(ChComponentName, [String])],       slbiGhcPkgOptions       :: [(ChComponentName, [String])],       slbiGhcMergedPkgOptions :: [String],-      slbiGhcLangOptions      :: [(ChComponentName, [String])]+      slbiGhcLangOptions      :: [(ChComponentName, [String])],+      slbiPkgLicenses         :: [(String, [(String, Version)])]     } deriving (Eq, Ord, Read, Show)  -- | Caches helper executable result so it doesn't have to be run more than once@@ -112,54 +157,20 @@                                          (ReaderT QueryEnv m) a }     deriving (Functor, Applicative, Monad, MonadIO) -data QueryEnv = QueryEnv {-      _qeReadProcess :: FilePath -> [String] -> String -> IO String,-      _qeProgs       :: Programs,-      _qeProjectDir  :: FilePath,-      _qeDistDir     :: FilePath-    }- type MonadQuery m = ( MonadIO m                     , MonadState (Maybe SomeLocalBuildInfo) m                     , MonadReader QueryEnv m) -run :: Monad m-  => QueryEnv -> Maybe SomeLocalBuildInfo -> Query m a -> m a+run :: Monad m => QueryEnv -> Maybe SomeLocalBuildInfo -> Query m a -> m a run e s action = flip runReaderT e (flip evalStateT s (unQuery action))  -- | @runQuery query distdir@. Run a 'Query'. @distdir@ is where Cabal's -- @setup-config@ file is located. runQuery :: Monad m-         => FilePath -- ^ Path to project directory, i.e. the one containing the-                     -- @project.cabal@ file-         -> FilePath -- ^ Path to @dist/@-         -> Query m a-         -> m a-runQuery pd dd action = run (QueryEnv readProcess def pd dd) Nothing action--runQuery' :: Monad m-         => Programs-         -> FilePath -- ^ Path to project directory, i.e. the one containing the-                     -- @project.cabal@ file-         -> FilePath -- ^ Path to @dist/@-         -> Query m a-         -> m a-runQuery' progs pd dd action =-    run (QueryEnv readProcess progs pd dd) Nothing action--runQuery'' :: Monad m-         => (FilePath -> [String] -> String -> IO String)-         -- ^ How to start the cabal-helper process. Useful if you need to-         -- capture stderr output from the helper.-         -> Programs-         -> FilePath -- ^ Path to project directory, i.e. the one containing the-                     -- @project.cabal@ file-         -> FilePath -- ^ Path to @dist/@+         => QueryEnv          -> Query m a          -> m a-runQuery'' readProc progs pd dd action =-    run (QueryEnv readProc progs pd dd) Nothing action-+runQuery qe action = run qe Nothing action  getSlbi :: MonadQuery m => m SomeLocalBuildInfo getSlbi = do@@ -198,6 +209,9 @@ -- | Only language related options, i.e. @-XSomeExtension@ ghcLangOptions :: MonadIO m => Query m [(ChComponentName, [String])] +-- | Get the licenses of the packages the current project is linking against.+pkgLicenses :: MonadIO m => Query m [(String, [(String, Version)])]+ packageDbStack      = Query $ slbiPackageDbStack      `liftM` getSlbi entrypoints         = Query $ slbiEntrypoints         `liftM` getSlbi sourceDirs          = Query $ slbiSourceDirs          `liftM` getSlbi@@ -206,6 +220,7 @@ ghcPkgOptions       = Query $ slbiGhcPkgOptions       `liftM` getSlbi ghcMergedPkgOptions = Query $ slbiGhcMergedPkgOptions `liftM` getSlbi ghcLangOptions      = Query $ slbiGhcLangOptions      `liftM` getSlbi+pkgLicenses         = Query $ slbiPkgLicenses         `liftM` getSlbi  -- | Run @cabal configure@ reconfigure :: MonadIO m@@ -218,7 +233,7 @@             [ "--with-ghc=" ++ ghcProgram progs ]             -- Only pass ghc-pkg if it was actually set otherwise we             -- might break cabal's guessing logic-            ++ if ghcPkgProgram progs /= ghcPkgProgram def+            ++ if ghcPkgProgram progs /= "ghc-pkg"                  then [ "--with-ghc-pkg=" ++ ghcPkgProgram progs ]                  else []             ++ cabalOpts@@ -226,13 +241,17 @@     return ()  getSomeConfigState :: MonadQuery m => m SomeLocalBuildInfo-getSomeConfigState = ask >>= \(QueryEnv readProc progs projdir distdir) -> do-  let progArgs = [ "--with-ghc="     ++ ghcProgram progs+getSomeConfigState = ask >>= \QueryEnv {..} -> do+  let progs = qePrograms+      projdir = qeProjectDir+      distdir = qeDistDir++      progArgs = [ "--with-ghc="     ++ ghcProgram progs                  , "--with-ghc-pkg=" ++ ghcPkgProgram progs                  , "--with-cabal="   ++ cabalProgram progs                  ] -  let args = [ "package-db-stack"+      args = [ "package-db-stack"              , "entrypoints"              , "source-dirs"              , "ghc-options"@@ -240,14 +259,15 @@              , "ghc-pkg-options"              , "ghc-merged-pkg-options"              , "ghc-lang-options"-             ] ++ progArgs+             , "licenses"+             ]    res <- liftIO $ do     exe  <- findLibexecExe "cabal-helper-wrapper"-    out <- readProc exe (projdir:distdir:args) ""+    out <- qeReadProcess exe (progArgs ++ projdir:distdir:args) ""     evaluate (read out) `E.catch` \(SomeException _) ->       error $ concat ["getSomeConfigState", ": ", exe, " "-                     , intercalate " " (map show $ distdir:args)+                     , intercalate " " (map show $ progArgs ++ projdir:distdir:args)                      , " (read failed)"]    let [ Just (ChResponsePkgDbs pkgDbs),@@ -257,10 +277,12 @@         Just (ChResponseCompList ghcSrcOpts),         Just (ChResponseCompList ghcPkgOpts),         Just (ChResponseList     ghcMergedPkgOpts),-        Just (ChResponseCompList ghcLangOpts) ] = res+        Just (ChResponseCompList ghcLangOpts),+        Just (ChResponseLicenses pkgLics)+        ] = res    return $ SomeLocalBuildInfo-    pkgDbs eps srcDirs ghcOpts ghcSrcOpts ghcPkgOpts ghcMergedPkgOpts ghcLangOpts+    pkgDbs eps srcDirs ghcOpts ghcSrcOpts ghcPkgOpts ghcMergedPkgOpts ghcLangOpts pkgLics  -- | Make sure the appropriate helper executable for the given project is -- installed and ready to run queries.
cabal-helper.cabal view
@@ -1,5 +1,5 @@ name:                cabal-helper-version:             0.5.3.0+version:             0.6.0.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@@ -35,6 +35,7 @@ build-type:          Custom cabal-version:       >=1.10 extra-source-files:  CabalHelper/Main.hs+                     CabalHelper/Licenses.hs  source-repository head   type:     git@@ -49,7 +50,6 @@   GHC-Options:         -Wall   Build-Depends:       base >= 4.5 && < 5                      , Cabal >= 1.14 && < 1.23-                     , data-default                      , directory                      , filepath                      , transformers@@ -93,7 +93,6 @@                      , extra                      , unix                      , Cabal >= 1.14 && < 1.23-                     , data-default                      , directory                      , filepath                      , transformers