packages feed

hackport 0.8.5.1 → 0.8.5.2

raw patch · 26 files changed

+766/−355 lines, 26 filesdep ~base

Dependency ranges changed: base

Files

.github/workflows/haskell.yml view
@@ -21,6 +21,7 @@           , "9.2"           , "9.4"           , "9.6"+          , "9.8"           ]      steps:@@ -42,7 +43,8 @@        - name: Configure the build         run: |-          cabal configure --enable-tests --enable-benchmarks --disable-documentation --flag=pedantic+          # (2024-10-11) doctests are failing only with ghc-9.2 on github CI+          cabal configure --enable-tests --enable-benchmarks --disable-documentation --flag=pedantic --flag=-doctests           cabal build --dry-run         # The last step generates dist-newstyle/cache/plan.json for the cache key. @@ -73,9 +75,6 @@        - name: Run tests         run: cabal test all --test-option=--color --test-show-details=streaming --jobs=1--      - name: Check cabal file-        run: cabal check        - name: Build documentation         run: cabal haddock all
CHANGELOG.md view
@@ -1,3 +1,17 @@+## v0.8.5.2 (2024-12-01)++Release v0.8.5.2++- No longer display warning notification when there are no warnings++- Add detection for new GHC versions++    - 9.6.6, 9.8.2, 9.8.3, 9.8.4, 9.10.1++- More entries for resolving pkg-config strings to gentoo packages++- Remove autogenerated `Paths_Cabal` and `Paths_cabal_install` modules+ ## v0.8.5.1 (2023-02-14)  Release v0.8.5.1
cabal/Cabal/src/Distribution/Simple/Utils.hs view
@@ -193,9 +193,7 @@ import Distribution.Verbosity import Distribution.Types.PackageId -#ifdef CURRENT_PACKAGE_KEY-#define BOOTSTRAPPED_CABAL 1-#endif+#define CABAL_VERSION 3,8,1,0  #ifdef BOOTSTRAPPED_CABAL import qualified Paths_Cabal (version)
− cabal/Paths_Cabal.hs
@@ -1,9 +0,0 @@-module Paths_Cabal (-    version,-  ) where--import Data.Version (Version(..))--version :: Version-version = Version [3,8,1,0] []-
− cabal/Paths_cabal_install.hs
@@ -1,8 +0,0 @@-module Paths_cabal_install (-    version,-  ) where--import Data.Version (Version(..))--version :: Version-version = Version [3,8,1,0] []
cabal/cabal-dev-scripts/cabal-dev-scripts.cabal view
@@ -18,7 +18,7 @@   ghc-options:      -Wall   build-depends:     , aeson                 ^>=1.4.1.0 || ^>=1.5.2.0 || ^>=2.1.1.0-    , base                  >=4.10     && <4.17+    , base                  >=4.10     && <4.18     , bytestring     , containers     , Diff                  ^>=0.4@@ -35,7 +35,7 @@   ghc-options:      -Wall   build-depends:     , aeson                 ^>=1.4.1.0 || ^>=1.5.2.0 || ^>=2.1.1.0-    , base                  >=4.10     && <4.17+    , base                  >=4.10     && <4.18     , bytestring     , containers     , Diff                  ^>=0.4
cabal/cabal-install-solver/cabal-install-solver.cabal view
@@ -105,7 +105,7 @@    build-depends:     , array         >=0.4      && <0.6-    , base          >=4.10     && <4.17+    , base          >=4.10     && <4.18     , bytestring    >=0.10.6.0 && <0.12     , Cabal         ^>=3.8     , Cabal-syntax  ^>=3.8@@ -138,7 +138,7 @@      UnitTests.Distribution.Solver.Modular.MessageUtils     build-depends:-     , base        >= 4.10  && <4.17+     , base        >= 4.10  && <4.18      , Cabal      , Cabal-syntax      , cabal-install-solver
cabal/cabal-install/cabal-install.cabal view
@@ -48,7 +48,7 @@       ghc-options: -Wunused-packages  common base-dep-    build-depends: base >=4.10 && <4.17+    build-depends: base >=4.10 && <4.18  common cabal-dep     build-depends: Cabal ^>=3.8
cabal/cabal-install/tests/UnitTests/Distribution/Client/ArbitraryInstances.hs view
@@ -43,7 +43,7 @@  import Data.Coerce                      (Coercible, coerce) import Network.URI                      (URI (..), URIAuth (..), isUnreserved)-import Test.QuickCheck+import Test.QuickCheck hiding (shrinkBoundedEnum) import Test.QuickCheck.GenericArbitrary import Test.QuickCheck.Instances.Cabal () 
cabal/cabal-testsuite/cabal-testsuite.cabal view
@@ -26,7 +26,7 @@   default-language: Haskell2010    build-depends:-    , base >= 4.6 && <4.17+    , base >= 4.6 && <4.18     -- this needs to match the in-tree lib:Cabal version     , Cabal ^>=3.8.0.0     , Cabal-syntax ^>=3.8.0.0@@ -113,6 +113,6 @@   -- we only depend on even stable releases of lib:Cabal   -- and due to Custom complexity and ConstraintSetupCabalMaxVersion   -- it can't be the current version-  setup-depends: Cabal == 3.6.*,-                 Cabal-syntax == 3.6.*,+  setup-depends: Cabal == 3.8.*,+                 Cabal-syntax == 3.8.*,                  base, filepath, directory
exe/Main.hs view
@@ -25,11 +25,12 @@ import Hackport.Command.Merge import Hackport.Completion -import Data.Version (showVersion) import Distribution.Pretty (prettyShow) import Distribution.Simple.Utils (cabalVersion) -import qualified Paths_cabal_install+import Data.Version (showVersion, makeVersion)+import Distribution.Version (versionNumbers)+import Distribution.Client.Version (cabalInstallVersion) import qualified Paths_hackport  main :: IO ()@@ -69,7 +70,7 @@               $  "hackport version "               ++ showVersion Paths_hackport.version               ++ "\nusing cabal-install "-              ++ showVersion Paths_cabal_install.version+              ++ showVersion (makeVersion (versionNumbers cabalInstallVersion))               ++ " and the Cabal library version "               ++ prettyShow cabalVersion 
hackport.cabal view
@@ -1,11 +1,11 @@ cabal-version: 3.0 name:          hackport-version:       0.8.5.1+version:       0.8.5.2 license:       GPL-3.0-or-later license-file:  LICENSE author:        Henning Günther, Duncan Coutts, Lennart Kolmodin maintainer:    Gentoo Haskell team <haskell@gentoo.org>-copyright:     Copyright 1999-2023 Gentoo Authors+copyright:     Copyright 1999-2024 Gentoo Authors category:      Distribution synopsis:      Hackage and Portage integration tool homepage:      https://github.com/gentoo-haskell/hackport#readme@@ -13,11 +13,18 @@   A command line tool to manage an overlay of Gentoo ebuilds   that are generated from a hackage repo of Cabal packages. +extra-doc-files:+  , ./CHANGELOG.md+  , ./README.rst++-- Tested with github CI using specific versions chosen by+-- <https://github.com/haskell-actions/setup> tested-with:   , GHC == 9.0.2   , GHC == 9.2.8   , GHC == 9.4.8-  , GHC == 9.6.4+  , GHC == 9.6.6+  , GHC == 9.8.2  source-repository head   type:     git@@ -398,7 +405,6 @@     Distribution.Simple.GHC.ImplInfo     Distribution.Utils.UnionFind     Distribution.ZinzaPrelude-    Paths_Cabal    other-extensions:     BangPatterns@@ -435,7 +441,7 @@   hs-source-dirs:     hackage-security/hackage-security/src   build-depends:     , hackport-external-libs-Cabal-syntax-    , base                          >=4.9+    , base                          >=4.9 && <5     , base16-bytestring             >=0.1.1     , base64-bytestring             >=1.0     , bytestring                    >=0.9@@ -547,7 +553,7 @@     , hackport-external-libs-Cabal     , hackport-external-libs-Cabal-syntax     , array         >=0.4-    , base          >=4.10+    , base          >=4.10 && <5     , bytestring    >=0.10.6.0     , containers    >=0.5.6.2     , edit-distance >=0.2.2@@ -617,7 +623,7 @@     , hackport-external-libs-Cabal-syntax     , hackport-external-libs-hackage-security     , hackport-external-libs-cabal-install-solver-    , base                                     >=4.10+    , base                                     >=4.10 && <5     , array                                    >=0.4     , async                                    >=2.0     , base16-bytestring                        >=0.1.1@@ -783,7 +789,6 @@     Distribution.Deprecated.ParseUtils     Distribution.Deprecated.ReadP     Distribution.Deprecated.ViewAsFieldDescr-    Paths_cabal_install  library hackport-internal   import:             warnings@@ -794,7 +799,7 @@     , hackport-external-libs-Cabal     , hackport-external-libs-cabal-install-solver     , hackport-external-libs-cabal-install-    , base+    , base <5     , async     , binary     , bytestring@@ -845,6 +850,7 @@     Hackport.Command.Status     Hackport.Command.Update     Hackport.Completion+    Hackport.Dirs     Hackport.Env     Hackport.Util     Merge@@ -892,7 +898,7 @@     , hackport-external-libs-Cabal     , hackport-external-libs-cabal-install     , hackport-internal-    , base+    , base <5     , directory     , filepath     , optparse-applicative@@ -905,6 +911,8 @@     ApplicativeDo     CPP +  autogen-modules:  Paths_hackport+ test-suite test-resolve-category   import:             warnings @@ -920,7 +928,7 @@     , hackport-external-libs-Cabal-syntax     , hackport-external-libs-Cabal     , hackport-internal-    , base+    , base <5     , array     , binary     , bytestring@@ -956,7 +964,7 @@   hs-source-dirs:     tests/print_deps   build-depends:     , array-    , base+    , base <5     , binary     , bytestring     , containers@@ -991,7 +999,7 @@   hs-source-dirs:     tests/normalize_deps   build-depends:     , array-    , base+    , base <5     , binary     , bytestring     , containers@@ -1023,7 +1031,7 @@   default-language:     Haskell98   main-is:              Main.hs   build-depends:-    , base+    , base <5     , base-compat     , cabal-doctest     , directory@@ -1035,6 +1043,8 @@    other-modules:        Paths_hackport +  autogen-modules:      Paths_hackport+   if !flag(doctests) || !flag(cabal-v1)     buildable: False @@ -1045,7 +1055,7 @@   hs-source-dirs:     tests/doctests-v2   main-is:            Main.hs   build-depends:-    , base+    , base <5     , process    build-tool-depends:@@ -1078,7 +1088,7 @@     , hackport-external-libs-Cabal     , hackport-external-libs-cabal-install     , hackport-internal-    , base+    , base <5     , async     , bytestring     , containers
src/Hackport/Completion.hs view
@@ -22,8 +22,9 @@  import qualified Data.Trie as Trie import Data.Trie (Trie)+import Hackport.Dirs (hackportDir) import Hackport.Env-import Hackport.Util (withHackportContext, hackportDir)+import Hackport.Util (withHackportContext) import Util  import Distribution.Client.GlobalFlags (RepoContext(..))
+ src/Hackport/Dirs.hs view
@@ -0,0 +1,18 @@+module Hackport.Dirs+  ( hackportDir+  ) where++import Control.Monad.IO.Class+import System.Directory+    ( getHomeDirectory+    , createDirectoryIfMissing+    )+import System.FilePath ( (</>) )++-- | Return the path to @~/.hackport/@ and create it if it doesn't exist.+hackportDir :: MonadIO m => m FilePath+hackportDir = do+    h <- liftIO $ getHomeDirectory+    let d = h </> ".hackport"+    liftIO $ createDirectoryIfMissing True d+    pure d
src/Hackport/Env.hs view
@@ -1,15 +1,18 @@-{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DerivingVia #-} {-# LANGUAGE FlexibleInstances #-}  module Hackport.Env   (     -- * Env monad-    MonadEnv-  , HasEnv (..)-  , HasGlobalEnv (..)-  , Env+    Env   , runEnv+  , HasGlobalEnv(..)+  , HasEnv (..)+    -- ** Warning buffer+  , WarningBuffer+  , getWarningBuffer+  , modifyWarningBuffer+  , displayWarnings     -- * Global env   , GlobalEnv (..)     -- * Subcommand env@@ -25,58 +28,95 @@   , WritesMetadata (..)   , UseHackageRemote     -- * Re-exports+  , module Control.Monad   , module Control.Monad.Reader   ) where +import Control.Monad import Control.Monad.Reader+import Control.Monad.State.Strict (StateT, MonadState, runStateT, get, modify)+import qualified Data.DList as DL+import qualified Data.List as L import Data.List.NonEmpty (NonEmpty (..)) import Data.Semigroup (Last(..))+import qualified Distribution.Simple.Utils as Cabal import qualified Distribution.Verbosity as V  import Status.Types (StatusDirection) -type MonadEnv env m = (HasGlobalEnv m, HasEnv env m, MonadIO m)-type Env env = ReaderT (GlobalEnv, env) IO+-- | @hackport@ is noisy. Hold off on displaying any warnings until the bulk+--   of the output has been printed. We use a 'DL.DList' to hold the pending+--   warnings.+type WarningBuffer = DL.DList String +-- | Monad that carries command line information and 'WarningBuffer' state+type Env env = ReaderT (GlobalEnv, env) (StateT WarningBuffer IO)+ class HasGlobalEnv m where+  -- | Convenient way to grab the 'GlobalEnv'   askGlobalEnv :: m GlobalEnv  instance Monad m => HasGlobalEnv (ReaderT (GlobalEnv,env) m) where   askGlobalEnv = asks fst  class HasEnv env m where+  -- | Convenient way to grab the custom @env@ data   askEnv :: m env  instance Monad m => HasEnv env (ReaderT (a,env) m) where   askEnv = asks snd +-- | Convenient way to get the current 'WarningBuffer' state+getWarningBuffer :: MonadState WarningBuffer m => m WarningBuffer+getWarningBuffer = get++-- | Convenient way to modify the current 'WarningBuffer' state+modifyWarningBuffer :: MonadState WarningBuffer m+  => (WarningBuffer -> WarningBuffer) -> m ()+modifyWarningBuffer = modify++-- | Read the warning buffer and output using 'Cabal.warn'.+displayWarnings :: MonadIO m => V.Verbosity -> WarningBuffer -> m ()+displayWarnings v dl = unless (null dl) $ liftIO . Cabal.warn v+  $ unlines+    -- insert an empty line between each paragraph+    $ L.intercalate [""]+      -- A list of strings forms a paragraph+      $ ["hackport emitted the following warnings:"]+        -- Add indentation to each string in the warning buffer+        -- This forms a list of paragraphs (one for each warning)+        : (indent <$> DL.toList dl)+  where+    indent :: String -> [String]+    indent = map ("  " ++) . lines++-- | Environment info that every @hackport@ subcommand needs data GlobalEnv = GlobalEnv   { globalVerbosity :: V.Verbosity   , globalPathToOverlay :: Maybe FilePath   , globalPathToPortage :: Maybe FilePath   }   deriving (Show, Eq, Ord)--instance Semigroup GlobalEnv where-  GlobalEnv v1 po1 pp1 <> GlobalEnv v2 po2 pp2 =-    GlobalEnv-      (getLast (Last v1 <> Last v2))-      (getLast <$> ((Last <$> po1) <> (Last <$> po2)))-      (getLast <$> ((Last <$> pp1) <> (Last <$> pp2)))+  deriving Semigroup via Last GlobalEnv  instance Monoid GlobalEnv where   mempty = GlobalEnv V.normal Nothing Nothing +-- | Environment info specific to the @list@ subcommand newtype ListEnv = ListEnv   { listPackages :: [String]   }   deriving (Show, Eq, Ord) +-- | Class for the @make-ebuild@ and @merge@ subcommands, which write to+--   @metadata.xml@ class WritesMetadata a where+  -- | Should @hackport@ write @hackage@ remote info to @metadata.xml@?   useHackageRemote :: a -> UseHackageRemote  type UseHackageRemote = Bool +-- | Environment info specific to the @make-ebuild@ subcommand data MakeEbuildEnv = MakeEbuildEnv   { makeEbuildCategory :: String   , makeEbuildCabalFiles :: NonEmpty FilePath@@ -88,12 +128,14 @@ instance WritesMetadata MakeEbuildEnv where   useHackageRemote = makeEbuildUseHackageRemote +-- | Environment info specific to the @status@ subcommand data StatusEnv = StatusEnv   { statusDirection :: StatusDirection   , statusPackages :: [String]   }   deriving (Eq) +-- | Environment info specific to the @merge@ subcommand data MergeEnv = MergeEnv   { mergeCabalFlags :: Maybe String   , mergePackage :: String@@ -102,9 +144,14 @@ instance WritesMetadata MergeEnv where   useHackageRemote _ = True +-- | Run with environment information. This calls 'displayWarnings' at the+--   end of the execution. runEnv   :: Env env a   -> env   -> GlobalEnv   -> IO a-runEnv env e global = runReaderT env (global, e)+runEnv env e global = do+    (a, dl) <- runStateT (runReaderT env (global, e)) DL.empty+    displayWarnings (V.verboseNoWrap (globalVerbosity global)) dl+    pure a
src/Hackport/Util.hs view
@@ -4,7 +4,6 @@   ( getPortageDir   , withHackportContext   , defaultRemoteRepo-  , hackportDir   ) where  #if MIN_VERSION_mtl(2,3,0)@@ -13,11 +12,7 @@ import Control.Monad.Trans.Control import Data.Maybe (fromJust) import qualified Network.URI as NU-import System.Directory-    ( doesDirectoryExist-    , getHomeDirectory-    , createDirectoryIfMissing-    )+import System.Directory (doesDirectoryExist) import System.FilePath ( (</>) )  import Distribution.Simple.Utils (warn)@@ -36,7 +31,7 @@ getPortageDir = do   (GlobalEnv verbosity _ portagePathM, _) <- ask   portagePath <- case portagePathM of-                   Nothing -> liftIO $ Host.portage_dir <$> Host.getInfo+                   Nothing -> Host.portage_dir <$> Host.getInfo                    Just path -> return path   exists <- liftIO $ doesDirectoryExist $ portagePath </> "dev-haskell"   unless exists $ liftIO $@@ -48,14 +43,15 @@ withHackportContext :: (DCG.GlobalFlags -> DCG.RepoContext -> Env env a) -> Env env a withHackportContext callback = do     (GlobalEnv verbosity _ _, _) <- ask+    warnBuffer <- getWarningBuffer     overlayPath <- getOverlayPath     let flags = DCG.defaultGlobalFlags {                     DCG.globalRemoteRepos = DUN.toNubList [defaultRemoteRepo]                   , DCG.globalCacheDir    = DSS.Flag $ overlayPath </> ".hackport"                 }     control-      $ \runInIO -> DCG.withRepoContext verbosity flags-      $ runInIO . (callback flags <=< restoreM)+        $ \runInIO -> DCG.withRepoContext verbosity flags+        $ \ctx -> runInIO $ restoreM (ctx, warnBuffer) >>= callback flags  -- | Default remote repository. Defaults to [hackage](hackage.haskell.org). defaultRemoteRepo :: DCT.RemoteRepo@@ -64,11 +60,3 @@    where     uri  = fromJust $ NU.parseURI "https://hackage.haskell.org/"     name = "hackage.haskell.org"---- | Return the path to @~/.hackport/@ and create it if it doesn't exist.-hackportDir :: MonadIO m => m FilePath-hackportDir = do-    h <- liftIO $ getHomeDirectory-    let d = h </> ".hackport"-    liftIO $ createDirectoryIfMissing True d-    pure d
src/Merge.hs view
@@ -24,6 +24,7 @@ import qualified Data.Map.Strict as Map import           Data.Maybe import qualified Data.List as L+import qualified Data.List.NonEmpty as NE import qualified Data.Set as S import qualified Data.Time.Clock as TC @@ -54,7 +55,7 @@                         ) import           System.Process import           System.FilePath ((</>),(<.>))-import           System.Exit (ExitCode(ExitSuccess), exitSuccess)+import           System.Exit (ExitCode(ExitSuccess))  -- hackport import qualified AnsiColor as A@@ -88,11 +89,10 @@ -}  -- | Call @diff@ between two ebuilds.-diffEbuilds :: FilePath -> Portage.PackageId -> Portage.PackageId -> IO ()-diffEbuilds fp a b = do _ <- system $ "diff -u --color=auto "-                             ++ fp </> Portage.packageIdToFilePath a ++ " "-                             ++ fp </> Portage.packageIdToFilePath b-                        exitSuccess+diffEbuilds :: FilePath -> Portage.PackageId -> Portage.PackageId -> IO ExitCode+diffEbuilds fp a b = system $ "diff -u --color=auto "+    ++ fp </> Portage.packageIdToFilePath a ++ " "+    ++ fp </> Portage.packageIdToFilePath b  -- | Given a list of available packages, and maybe a preferred version, -- return the available package with that version. Latest version is chosen@@ -144,17 +144,21 @@   index <- fmap packageIndex $ liftIO $ getSourcePackages verbosity repoContext    -- find all packages that maches the user specified package name+  let searchResults = CabalInstall.searchByName index user_pname_str   availablePkgs <--    case map snd (CabalInstall.searchByName index user_pname_str) of+    case mapMaybe (NE.nonEmpty . snd) searchResults of       [] -> throw (PackageNotFound user_pname_str)-      [pkg] -> return pkg-      pkgs  -> do let cabal_pkg_to_pn pkg = Cabal.unPackageName $ Cabal.pkgName (CabalInstall.srcpkgPackageId pkg)-                      names      = map (cabal_pkg_to_pn . L.head) pkgs-                  notice $ "Ambiguous names: " ++ L.intercalate ", " names-                  forM_ pkgs $ \ps ->-                      do let p_name = (cabal_pkg_to_pn . L.head) ps-                         notice $ p_name ++ ": " ++ (L.intercalate ", " $ map (prettyShow . Cabal.pkgVersion . CabalInstall.srcpkgPackageId) ps)-                  return $ concat pkgs+      [pkg] -> return (NE.toList pkg)+      pkgs -> do+          let cabal_pkg_to_pn pkg = Cabal.unPackageName $+                  Cabal.pkgName (CabalInstall.srcpkgPackageId pkg)+              names      = map (cabal_pkg_to_pn . NE.head) pkgs+          notice $ "Ambiguous names: " ++ L.intercalate ", " names+          forM_ pkgs $ \ps -> do+              let p_name = (cabal_pkg_to_pn . NE.head) ps+                  showPkg = prettyShow . Cabal.pkgVersion . CabalInstall.srcpkgPackageId+              notice $ p_name ++ ": " ++ L.intercalate ", " (map showPkg (NE.toList ps))+          return $ pkgs >>= NE.toList     -- select a single package taking into account the user specified version@@ -191,8 +195,11 @@       newPkgId = Portage.fromCabalPackageId cat cabal_pkgId   pkgDir <- liftIO $ listDirectory pkgPath   case Merge.getPreviousPackageId pkgDir newPkgId of-    Just validPkg -> do info "Generating a diff..."-                        liftIO $ diffEbuilds overlayPath validPkg newPkgId+    Just validPkg -> do+      info "Generating a diff..."+      -- Ignore the ExitCode generated by diff+      _ <- liftIO $ diffEbuilds overlayPath validPkg newPkgId+      pure ()     _ -> info "Nothing to diff!"  -- used to be FlagAssignment in Cabal but now it's an opaque type@@ -394,7 +401,7 @@   debug $ "buildDepends pkgDesc:  " ++ show (map prettyShow (Merge.buildDepends pkgDesc))    -- <https://github.com/gentoo-haskell/hackport/issues/116>-  warnings <- errorWarnOnUnbuildable+  errorWarnOnUnbuildable     (prettyShow cat)     (prettyShow merged_cabal_pkg_name)     pkgDesc0@@ -411,10 +418,12 @@       \name -> info $ "Excluded packages (comes with ghc): " ++ Cabal.unPackageName name    -- We only add the current arch to KEYWORDS-  thisArch <- run_cmd "portageq envvar ARCH" >>=-      maybe-          (die "Error running 'portageq envvar ARCH'")-          (pure . head . lines)+  thisArch <- do+      result <- run_cmd "portageq envvar ARCH"+      case fmap lines result of+          Nothing -> die "Error running 'portageq envvar ARCH'"+          Just [] -> die "No output from 'portageq envvar ARCH'"+          Just (l:_) -> pure l    let pp_fn (cabal_fn, yesno) = b yesno ++ Cabal.unFlagName cabal_fn           where b True  = ""@@ -470,8 +479,6 @@     fetchDigestAndCheck (overlayPath </> prettyShow cat </> prettyShow norm_pkgName)       $ Portage.fromCabalPackageId cat cabal_pkgId -  forM_ warnings $ notice . ("\n" ++)- -- | Run @ebuild@ and @pkgcheck@ commands in the directory of the -- newly-generated ebuild. --@@ -594,50 +601,63 @@     notice $ "Writing " ++ emeta     liftIO $ T.writeFile mpath updatedMetaText +---+ -- <https://github.com/gentoo-haskell/hackport/issues/116> -- TODO: Make it so this is automatically fixed instead of requiring manual -- intervention++-- | Check for unbuildable components. Unbuildable libraries are considered+--   a fatal error, whereas any other unbuildable components only require a+--   warning. This may produce false negatives when components are toggled by+--   flags, but it also helps catch .cabal files that hackport has a hard time+--   processing. errorWarnOnUnbuildable     :: String -- Category name     -> String -- Package name     -> Cabal.PackageDescription-    -> Env env [String]-errorWarnOnUnbuildable cn pn pkgdesc = execWriterT $ do-  let lib = Cabal.library pkgdesc            -- Main library-      subLibs = Cabal.subLibraries pkgdesc   -- sub-libraries-      exes = Cabal.executables pkgdesc       -- executables-      tests = Cabal.testSuites pkgdesc       -- test-suites-      ubLib = findUnbuildable Cabal.libName Cabal.libBuildInfo lib-      ubSubLibs = findUnbuildable Cabal.libName Cabal.libBuildInfo subLibs-      ubExes = findUnbuildable Cabal.exeName Cabal.buildInfo exes-      ubTests = findUnbuildable Cabal.testName Cabal.testBuildInfo tests-      ubErrs = execWriter $ do-        forM_ ubLib $ \_ ->-          tell ["main library"]-        forM_ ubSubLibs $ \l ->-          tell ["sub-library: " ++ Cabal.showLibraryName l]-      ubWarns = execWriter $ do+    -> Env env ()+errorWarnOnUnbuildable cn pn pkgdesc = do+    unless (null ubWarns) $ warn $ unlines $+        [ "The following components are unbuildable!" ]+        ++ map ("  - " ++) ubWarns+    unless (null ubErrs) $ die ubErrMsg+  where+    findUnbuildable toName toBuildable+        = fmap toName . mfilter (not . Cabal.buildable . toBuildable)++    lib = Cabal.library pkgdesc            -- Main library+    subLibs = Cabal.subLibraries pkgdesc   -- sub-libraries+    exes = Cabal.executables pkgdesc       -- executables+    tests = Cabal.testSuites pkgdesc       -- test-suites+    ubLib = findUnbuildable Cabal.libName Cabal.libBuildInfo lib+    ubSubLibs = findUnbuildable Cabal.libName Cabal.libBuildInfo subLibs+    ubExes = findUnbuildable Cabal.exeName Cabal.buildInfo exes+    ubTests = findUnbuildable Cabal.testName Cabal.testBuildInfo tests++    ubWarns :: [String]+    ubWarns = execWriter $ do         forM_ ubExes $ \e ->-          tell ["executable: " ++ Cabal.unUnqualComponentName e]+            tell ["executable: " ++ Cabal.unUnqualComponentName e]         forM_ ubTests $ \t ->-          tell ["test-suite: " ++ Cabal.unUnqualComponentName t]--  unless (null ubWarns) $ tell $ pure $ unlines-    $  [ "WARNING: The following components are unbuildable!" ]-    ++ map ("  - " ++) ubWarns+            tell ["test-suite: " ++ Cabal.unUnqualComponentName t] -  unless (null ubErrs) $ error $ unlines-    $  [ "FATAL: The following library components are unbuildable!" ]-    ++ map ("  - " ++) ubErrs-    ++ [ ""-       , "You can edit the .cabal file to make the needed components buildable,"-       , "then merge the package manually:"-       , "  $ cabal get " ++ pn-       , "  $ cd " ++ pn ++ "*/"-       , "  # fix " ++ pn ++ ".cabal"-       , "  $ hackport make-ebuild " ++ cn ++ " " ++ pn ++ ".cabal"-       ]+    ubErrs :: [String]+    ubErrs = execWriter $ do+        forM_ ubLib $ \_ ->+            tell ["main library"]+        forM_ ubSubLibs $ \l ->+            tell ["sub-library: " ++ Cabal.showLibraryName l] -  where-    findUnbuildable toName toBuildable-        = fmap toName . mfilter (not . Cabal.buildable . toBuildable)+    ubErrMsg :: String+    ubErrMsg = unlines+        $  [ "FATAL: The following library components are unbuildable!" ]+        ++ map ("  - " ++) ubErrs+        ++ [ ""+           , "You can edit the .cabal file to make the needed components buildable,"+           , "then merge the package manually:"+           , "  $ cabal get " ++ pn+           , "  $ cd " ++ pn ++ "*/"+           , "  # fix " ++ pn ++ ".cabal"+           , "  $ hackport make-ebuild " ++ cn ++ " " ++ pn ++ ".cabal"+           ]
src/Merge/Dependencies.hs view
@@ -394,6 +394,7 @@       , ("libbrotlidec", any_c_p "app-arch" "brotli")       , ("libbrotlienc", any_c_p "app-arch" "brotli")       , ("libarchive", at_least_c_p_v "app-arch" "libarchive" [3,5,2])+      , ("double-conversion", any_c_p "dev-libs" "double-conversion")       ]  ---------------------------------------------------------------@@ -538,7 +539,11 @@   ,("gtksourceview-3.0", ("x11-libs", "gtksourceview", Portage.DAttr (Portage.GivenSlot "3.0") []))    ,("gstreamer-0.10",              ("media-libs", "gstreamer", def))+  ,("gstreamer-1.0",               ("media-libs", "gstreamer",+      Portage.DAttr (Portage.GivenSlot "1.0") [Portage.mkUse (Portage.Use "introspection")]))   ,("gstreamer-base-0.10",         ("media-libs", "gstreamer", def))+  ,("gstreamer-base-1.0",          ("media-libs", "gstreamer",+      Portage.DAttr (Portage.GivenSlot "1.0") [Portage.mkUse (Portage.Use "introspection")]))   ,("gstreamer-check-0.10",        ("media-libs", "gstreamer", def))   ,("gstreamer-controller-0.10",   ("media-libs", "gstreamer", def))   ,("gstreamer-dataprotocol-0.10", ("media-libs", "gstreamer", def))@@ -547,6 +552,8 @@   ,("gstreamer-app-0.10",          ("media-libs", "gst-plugins-base", def))   ,("gstreamer-audio-0.10",        ("media-libs", "gst-plugins-base", def))   ,("gstreamer-video-0.10",        ("media-libs", "gst-plugins-base", def))+  ,("gstreamer-video-1.0",         ("media-libs", "gst-plugins-base",+      Portage.DAttr (Portage.GivenSlot "1.0") [Portage.mkUse (Portage.Use "introspection")]))   ,("gstreamer-plugins-base-0.10", ("media-libs", "gst-plugins-base", def))    ,("gtksourceview-2.0",           ("x11-libs", "gtksourceview", Portage.DAttr (Portage.GivenSlot "2.0") []))@@ -599,4 +606,15 @@   ,("harfbuzz",                    ("media-libs", "harfbuzz", def))   ,("harfbuzz-gobject",            ("media-libs", "harfbuzz", Portage.DAttr (Portage.AnySlot) [Portage.mkUse $ Portage.Use "introspection"]))   ,("x11",                         ("x11-libs", "libX11", def))+  ,("icu-i18n",                    ("dev-libs", "icu", def))+  ,("libtelnet",                   ("net-libs", "libtelnet", def))+  ,("zstd",                        ("app-arch", "zstd", def))+  ,("libarchive",                  ("app-arch", "libarchive", def))+  ,("libbrotlidec",                ("app-arch", "brotli", def))+  ,("libbrotlienc",                ("app-arch", "brotli", def))+  ,("gdk-x11-3.0",                 ("x11-libs", "gtk+", Portage.DAttr (Portage.GivenSlot "3")+    (Portage.mkUse <$> [Portage.Use "X", Portage.Use "introspection"])))+  ,("dbusmenu-glib-0.4",           ("dev-libs", "libdbusmenu", Portage.DAttr Portage.AnySlot [Portage.mkUse $ Portage.Use "introspection"]))+  ,("dbusmenu-gtk3-0.4",           ("dev-libs", "libdbusmenu", Portage.DAttr Portage.AnySlot+    (Portage.mkUse <$> [Portage.Use "gtk3", Portage.Use "introspection"])))   ]
src/Overlays.hs view
@@ -5,6 +5,7 @@     ) where  import Control.Monad+import Control.Monad.State.Strict (MonadState) import Data.List (nub, inits) import Data.Maybe (maybeToList, listToMaybe, isJust, fromJust) import qualified System.Directory as SD@@ -48,10 +49,11 @@     info "Override my decision with hackport --overlay /my/overlay"     return overlay -getOverlays :: MonadIO m => m [String]+getOverlays :: (HasGlobalEnv m, MonadIO m, MonadState WarningBuffer m)+    => m [String] getOverlays = do   local    <- getLocalOverlay-  overlays <- liftIO $ overlay_list `fmap` getInfo+  overlays <- overlay_list <$> getInfo   return $ nub $ map clean $                  maybeToList local               ++ overlays
src/Portage/Dependency/Normalize.hs view
@@ -10,6 +10,8 @@ import qualified Control.Arrow as A import           Control.Monad import qualified Data.List as L+import           Data.List.NonEmpty (NonEmpty(..))+import qualified Data.List.NonEmpty as NE import qualified Data.Set as S import           Data.Maybe @@ -169,19 +171,24 @@     where go = combine_use_guards  find_use_intersections :: [Dependency] -> [Dependency]-find_use_intersections = map merge_use_intersections . L.groupBy is_use_mergeable+find_use_intersections = map merge_use_intersections . NE.groupBy is_use_mergeable     where         is_use_mergeable :: Dependency -> Dependency -> Bool         is_use_mergeable (DependIfUse lu _ltd _lfd) (DependIfUse ru _rtd _rfd)             | lu == ru       = True         is_use_mergeable _ _ = False -        merge_use_intersections :: [Dependency] -> Dependency-        merge_use_intersections [x] = x-        merge_use_intersections ds = pop_common $ DependIfUse u (DependAllOf tds) (DependAllOf fds)-            where DependIfUse u _tf _fd = head ds+        merge_use_intersections :: NonEmpty Dependency -> Dependency+        -- Dependency was not grouped by is_use_mergable; no optimization is+        -- possible.+        merge_use_intersections (x :| []) = x+        -- When two or more dependencies are grouped together by+        -- is_use_mergable, they can be optimized.+        merge_use_intersections ds = pop_common $+            DependIfUse u (DependAllOf tds) (DependAllOf fds)+            where DependIfUse u _tf _fd = NE.head ds                   tfdeps ~(DependIfUse _u td fd) = (td, fd)-                  (tds, fds) = unzip $ map tfdeps ds+                  (tds, fds) = unzip $ map tfdeps (NE.toList ds)  pop_common :: Dependency -> Dependency -- depend
src/Portage/EBuild.hs view
@@ -177,7 +177,6 @@     -- add to this list with any non https-aware websites     httpOnlyHomepages = Just <$> [ "leksah.org"                                  , "darcs.net"-                                 , "khumba.net"                                  ]  -- | Sort IUSE alphabetically@@ -271,11 +270,12 @@ subStr :: String                -- ^ the search string        -> String                -- ^ the string to be searched        -> Maybe (String,String) -- ^ Just (pre,post) if string is found-subStr sstr str = case getRestIfPrefix sstr str of-    Nothing -> if null str then Nothing else case subStr sstr (tail str) of-        Nothing -> Nothing-        Just (pre,post) -> Just (head str:pre,post)-    Just rest -> Just ([],rest)+subStr sstr str = case (getRestIfPrefix sstr str, str) of+    (Just rest, _) -> Just ("",rest)+    (Nothing, "") -> Nothing+    (Nothing, strHead:strTail) -> do+        (pre, post) <- subStr sstr strTail+        Just (strHead:pre, post)  replaceMultiVars ::     [(String,String)] -- ^ pairs of variable name and content
src/Portage/GHCCore.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE OverloadedStrings #-} -- For Cabal.PackageName+ {-| Module      : Portage.GHCCore License     : GPL-3+@@ -40,8 +42,12 @@ -- The first @GHC@ version in this list is a minimum default. ghcs :: [(DC.CompilerInfo, InstalledPackageIndex)] ghcs =-    [ ghc902, ghc924, ghc925, ghc926, ghc927, ghc928, ghc945, ghc946, ghc947-    , ghc948, ghc962, ghc963, ghc964+    [ ghc902+    , ghc924, ghc925, ghc926, ghc927, ghc928+    , ghc945, ghc946, ghc947, ghc948+    , ghc962, ghc963, ghc964, ghc965, ghc966+    , ghc982, ghc983, ghc984+    , ghc9101     ]  -- | Maybe determine the appropriate 'Cabal.Version' of the @Cabal@ package@@ -66,6 +72,12 @@           , ([9,6,2], Cabal.mkVersion [3,10,1,0])           , ([9,6,3], Cabal.mkVersion [3,10,1,0])           , ([9,6,4], Cabal.mkVersion [3,10,1,0])+          , ([9,6,5], Cabal.mkVersion [3,10,3,0])+          , ([9,6,6], Cabal.mkVersion [3,10,3,0])+          , ([9,8,2], Cabal.mkVersion [3,10,3,0]) -- bumped via BUMP_LIBRARIES+          , ([9,8,3], Cabal.mkVersion [3,10,3,0])+          , ([9,8,4], Cabal.mkVersion [3,10,3,0])+          , ([9,10,1], Cabal.mkVersion [3,12,0,0])           ]  platform :: Platform@@ -152,8 +164,37 @@       : p "ghc-boot-th" ghcVer       : p "ghc-heap" ghcVer       : p "ghci" ghcVer-      : pids+      : filter filtUpgradeable pids +    -- | only include 'Cabal.PackageIdentifier's whose 'Cabal.packageName' does+    --   not match anything from 'upgradeablePkgs'+    filtUpgradeable :: Cabal.PackageIdentifier -> Bool+    filtUpgradeable pid =+        all (Cabal.packageName pid /=) (upgradeablePkgs ghcVer)++-- | These bundled packages are "upgradeable" and should not be present in the+--   generated 'InstalledPackageIndex'. If they are, they will /not/ show up+--   in the generated list of dependencies (@RDEPEND@ and/or @DEPEND@), which+--   is undesireable (since this is where required version ranges are found).+--+--   Takes the '[Int]' representation of the GHC version as an argument to+--   determine if any extra upgradeable packages are bundled.+--+--   See: <https://github.com/gentoo-haskell/gentoo-haskell/issues/1386>+upgradeablePkgs :: [Int] -> [Cabal.PackageName]+upgradeablePkgs ghcVer+    -- Upgradeable package @Cabal-syntax@ gets bundled with >=ghc-9.4+    | ghcVer >= [9,4] = "Cabal-syntax" : upgradeablePkgs [9,0]+    -- These have been bundled since at least ghc-9.0+    | otherwise =+        [ "Cabal"+        , "haskeline"+        , "parsec"+        , "text"+        , "xhtml"+        ]++ packageNamesFromPackageIndex :: InstalledPackageIndex -> [Cabal.PackageName] packageNamesFromPackageIndex pix = nub $ map fst $ allPackagesByName pix @@ -168,6 +209,24 @@   -> (DC.CompilerInfo, InstalledPackageIndex) mkInfoIndex ghcVer pids = (ghc ghcVer, mkIndex ghcVer pids) +ghc9101 :: (DC.CompilerInfo, InstalledPackageIndex)+ghc9101 = mkInfoIndex [9,10,1] ghc9101_pkgs++ghc984 :: (DC.CompilerInfo, InstalledPackageIndex)+ghc984 = mkInfoIndex [9,8,4] ghc984_pkgs++ghc983 :: (DC.CompilerInfo, InstalledPackageIndex)+ghc983 = mkInfoIndex [9,8,3] ghc983_pkgs++ghc982 :: (DC.CompilerInfo, InstalledPackageIndex)+ghc982 = mkInfoIndex [9,8,2] ghc982_pkgs++ghc966 :: (DC.CompilerInfo, InstalledPackageIndex)+ghc966 = mkInfoIndex [9,6,6] ghc966_pkgs++ghc965 :: (DC.CompilerInfo, InstalledPackageIndex)+ghc965 = mkInfoIndex [9,6,5] ghc965_pkgs+ ghc964 :: (DC.CompilerInfo, InstalledPackageIndex) ghc964 = mkInfoIndex [9,6,4] ghc964_pkgs @@ -207,8 +266,7 @@ ghc902 :: (DC.CompilerInfo, InstalledPackageIndex) ghc902 = mkInfoIndex [9,0,2] ghc902_pkgs --- | Non-upgradeable core packages. Some packages are not included for--- simplicity (see 'mkIndex').+-- | Core packages. Some packages are not included for simplicity (see 'mkIndex'). -- -- Sources: --  * release notes@@ -219,10 +277,215 @@ --  * https://gitlab.haskell.org/ghc/ghc/-/blob/ghc-9.0.2-release/compiler/ghc.cabal.in#L60-77 --  * https://flora.pm/packages/%40hackage/ghc/9.0.2/dependencies --  * https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/libraries/version-history---  * @./scripts/scan-ghc-library-versions.bash@ in the gentoo-haskell tree+--  * @./scripts/scan-ghc-library-versions.hs@ in the gentoo-haskell tree+ghc9101_pkgs :: [Cabal.PackageIdentifier]+ghc9101_pkgs =+  [ p "Cabal-syntax" [3,12,0,0]+  , p "Cabal" [3,12,0,0]+  , p "array" [0,5,7,0]+  , p "base" [4,20,0,0]+  , p "binary" [0,8,9,2]+  , p "bytestring" [0,12,1,0]+  , p "containers" [0,7]+  , p "deepseq" [1,5,0,0]+  , p "directory" [1,3,8,5] -- bumped via BUMP_LIBRARIES+  , p "exceptions" [0,10,7]+  , p "filepath" [1,5,2,0]+  , p "ghc-bignum" [1,3]+  , p "ghc-compact" [0,1,0,0]+  , p "ghc-prim" [0,11,0]+  , p "haskeline" [0,8,2,1]+  , p "hpc" [0,7,0,1]+  , p "integer-gmp" [1,1]+  , p "mtl" [2,3,1]+  , p "parsec" [3,1,17,0]+  , p "pretty" [1,1,3,6]+  , p "process" [1,6,19,0]+  , p "semaphore-compat" [1,0,0]+  , p "stm" [2,5,3,1]+  , p "template-haskell" [2,22,0,0]+  , p "terminfo" [0,4,1,6]+  , p "text" [2,1,1]+  , p "time" [1,12,2]+  , p "transformers" [0,6,1,1]+  , p "unix" [2,8,5,1]+  , p "xhtml" [3000,2,2,1]+  ]++ghc984_pkgs :: [Cabal.PackageIdentifier]+ghc984_pkgs =+  [ p "Cabal-syntax" [3,10,3,0]+  , p "Cabal" [3,10,3,0]+  , p "array" [0,5,8,0]+  , p "base" [4,19,2,0]+  , p "binary" [0,8,9,1]+  , p "bytestring" [0,12,1,0]+  , p "containers" [0,6,8]+  , p "deepseq" [1,5,1,0]+  , p "directory" [1,3,8,5]+  , p "exceptions" [0,10,7]+  , p "filepath" [1,4,301,0]+  , p "ghc-bignum" [1,3]+  , p "ghc-compact" [0,1,0,0]+  , p "ghc-prim" [0,11,0]+  , p "haskeline" [0,8,2,1]+  , p "hpc" [0,7,0,0]+  , p "integer-gmp" [1,1]+  , p "mtl" [2,3,1]+  , p "parsec" [3,1,17,0]+  , p "pretty" [1,1,3,6]+  , p "process" [1,6,25,0]+  , p "semaphore-compat" [1,0,0]+  , p "stm" [2,5,3,1]+  , p "template-haskell" [2,21,0,0]+  , p "terminfo" [0,4,1,6]+  , p "text" [2,1,1]+  , p "time" [1,12,2]+  , p "transformers" [0,6,1,0]+  , p "unix" [2,8,6,0]+  , p "xhtml" [3000,2,2,1]+  ]++ghc983_pkgs :: [Cabal.PackageIdentifier]+ghc983_pkgs =+  [ p "Cabal-syntax" [3,10,3,0]+  , p "Cabal" [3,10,3,0]+  , p "array" [0,5,8,0]+  , p "base" [4,19,2,0]+  , p "binary" [0,8,9,1]+  , p "bytestring" [0,12,1,0]+  , p "containers" [0,6,8]+  , p "deepseq" [1,5,1,0]+  , p "directory" [1,3,8,5]+  , p "exceptions" [0,10,7]+  , p "filepath" [1,4,200,1] -- needs to be bumped to 1.4.300.1+  , p "ghc-bignum" [1,3]+  , p "ghc-compact" [0,1,0,0]+  , p "ghc-prim" [0,11,0]+  , p "haskeline" [0,8,2,1]+  , p "hpc" [0,7,0,0]+  , p "integer-gmp" [1,1]+  , p "mtl" [2,3,1]+  , p "parsec" [3,1,17,0]+  , p "pretty" [1,1,3,6]+  , p "process" [1,6,25,0]+  , p "semaphore-compat" [1,0,0]+  , p "stm" [2,5,3,1]+  , p "template-haskell" [2,21,0,0]+  , p "terminfo" [0,4,1,6]+  , p "text" [2,1,1]+  , p "time" [1,12,2]+  , p "transformers" [0,6,1,0]+  , p "unix" [2,8,4,0]+  , p "xhtml" [3000,2,2,1]+  ]++ghc982_pkgs :: [Cabal.PackageIdentifier]+ghc982_pkgs =+  [ p "Cabal-syntax" [3,10,3,0] -- bumped via BUMP_LIBRARIES+  , p "Cabal" [3,10,3,0] -- bumped via BUMP_LIBRARIES+  , p "array" [0,5,6,0]+  , p "base" [4,19,1,0]+  , p "binary" [0,8,9,1]+  , p "bytestring" [0,12,1,0]+  , p "containers" [0,6,8]+  , p "deepseq" [1,5,0,0]+  , p "directory" [1,3,8,5] -- bumped via BUMP_LIBRARIES+  , p "exceptions" [0,10,7]+  , p "filepath" [1,4,300,1] -- bumped via BUMP_LIBRARIES+  , p "ghc-bignum" [1,3]+  , p "ghc-compact" [0,1,0,0]+  , p "ghc-prim" [0,11,0]+  , p "haskeline" [0,8,2,1]+  , p "hpc" [0,7,0,0]+  , p "integer-gmp" [1,1]+  , p "mtl" [2,3,1]+  , p "parsec" [3,1,17,0]+  , p "pretty" [1,1,3,6]+  , p "process" [1,6,19,0] -- bumped via BUMP_LIBRARIES+  , p "semaphore-compat" [1,0,0]+  , p "stm" [2,5,2,1]+  , p "template-haskell" [2,21,0,0]+  , p "terminfo" [0,4,1,6]+  , p "text" [2,1,1]+  , p "time" [1,12,2]+  , p "transformers" [0,6,1,0]+  , p "unix" [2,8,4,0]+  , p "xhtml" [3000,2,2,1]+  ]++ghc966_pkgs :: [Cabal.PackageIdentifier]+ghc966_pkgs =+  [ p "Cabal-syntax" [3,10,3,0]+  , p "Cabal" [3,10,3,0]+  , p "array" [0,5,6,0]+  , p "base" [4,18,2,1]+  , p "binary" [0,8,9,1]+  , p "bytestring" [0,11,5,3]+  , p "containers" [0,6,7]+  , p "deepseq" [1,4,8,1]+  , p "directory" [1,3,8,5]+  , p "exceptions" [0,10,7]+  , p "filepath" [1,4,300,1]+  , p "ghc-bignum" [1,3]+  , p "ghc-compact" [0,1,0,0]+  , p "ghc-prim" [0,10,0]+  , p "haskeline" [0,8,2,1]+  , p "hpc" [0,6,2,0]+  , p "integer-gmp" [1,1]+  , p "mtl" [2,3,1]+  , p "parsec" [3,1,16,1]+  , p "pretty" [1,1,3,6]+  , p "process" [1,6,19,0]+  , p "stm" [2,5,1,0]+  , p "template-haskell" [2,20,0,0]+  , p "terminfo" [0,4,1,6]+  , p "text" [2,0,2]+  , p "time" [1,12,2]+  , p "transformers" [0,6,1,0]+  , p "unix" [2,8,4,0]+  , p "xhtml" [3000,2,2,1]+  ]+++ghc965_pkgs :: [Cabal.PackageIdentifier]+ghc965_pkgs =+  [ p "Cabal-syntax" [3,10,3,0]+  , p "Cabal" [3,10,3,0]+  , p "array" [0,5,6,0]+  , p "base" [4,18,2,1]+  , p "binary" [0,8,9,1]+  , p "bytestring" [0,11,5,3]+  , p "containers" [0,6,7]+  , p "deepseq" [1,4,8,1]+  , p "directory" [1,3,8,4]+  , p "exceptions" [0,10,7]+  , p "filepath" [1,4,300,1]+  , p "ghc-bignum" [1,3]+  , p "ghc-compact" [0,1,0,0]+  , p "ghc-prim" [0,10,0]+  , p "haskeline" [0,8,2,1]+  , p "hpc" [0,6,2,0]+  , p "integer-gmp" [1,1]+  , p "mtl" [2,3,1]+  , p "parsec" [3,1,16,1]+  , p "pretty" [1,1,3,6]+  , p "process" [1,6,19,0]+  , p "stm" [2,5,1,0]+  , p "template-haskell" [2,20,0,0]+  , p "terminfo" [0,4,1,6]+  , p "text" [2,0,2]+  , p "time" [1,12,2]+  , p "transformers" [0,6,1,0]+  , p "unix" [2,8,4,0]+  , p "xhtml" [3000,2,2,1]+  ]+ ghc964_pkgs :: [Cabal.PackageIdentifier] ghc964_pkgs =-  [ p "array" [0,5,5,0]+  [ p "Cabal-syntax" [3,10,1,0]+  , p "Cabal" [3,10,1,0]+  , p "array" [0,5,6,0]   , p "base" [4,18,2,0]   , p "binary" [0,8,9,1]   , p "bytestring" [0,11,5,3]@@ -230,26 +493,32 @@   , p "deepseq" [1,4,8,1]   , p "directory" [1,3,8,1]   , p "exceptions" [0,10,7]-  , p "filepath" [1,4,200,4]+  , p "filepath" [1,4,200,1]   , p "ghc-bignum" [1,3]   , p "ghc-compact" [0,1,0,0]   , p "ghc-prim" [0,10,0]+  , p "haskeline" [0,8,2,1]   , p "hpc" [0,6,2,0]   , p "integer-gmp" [1,1]   , p "mtl" [2,3,1]+  , p "parsec" [3,1,16,1]   , p "pretty" [1,1,3,6]-  , p "process" [1,6,17,0]+  , p "process" [1,6,18,0] -- bumped via BUMP_LIBRARIES   , p "stm" [2,5,1,0]   , p "template-haskell" [2,20,0,0]   , p "terminfo" [0,4,1,6]+  , p "text" [2,0,2]   , p "time" [1,12,2]   , p "transformers" [0,6,1,0]   , p "unix" [2,8,4,0]+  , p "xhtml" [3000,2,2,1]   ]  ghc963_pkgs :: [Cabal.PackageIdentifier] ghc963_pkgs =-  [ p "array" [0,5,5,0]+  [ p "Cabal-syntax" [3,10,1,0]+  , p "Cabal" [3,10,1,0]+  , p "array" [0,5,5,0]   , p "base" [4,18,1,0]   , p "binary" [0,8,9,1]   , p "bytestring" [0,11,5,2]@@ -261,54 +530,61 @@   , p "ghc-bignum" [1,3]   , p "ghc-compact" [0,1,0,0]   , p "ghc-prim" [0,10,0]+  , p "haskeline" [0,8,2,1]   , p "hpc" [0,6,2,0]   , p "integer-gmp" [1,1]   , p "mtl" [2,3,1]+  , p "parsec" [3,1,16,1]   , p "pretty" [1,1,3,6]-  , p "process" [1,6,17,0]+  , p "process" [1,6,18,0] -- bumped via BUMP_LIBRARIES   , p "stm" [2,5,1,0]   , p "template-haskell" [2,20,0,0]   , p "terminfo" [0,4,1,6]+  , p "text" [2,0,2]   , p "time" [1,12,2]   , p "transformers" [0,6,1,0]   , p "unix" [2,8,1,0]+  , p "xhtml" [3000,2,2,1]   ]  ghc962_pkgs :: [Cabal.PackageIdentifier] ghc962_pkgs =-  [ p "array" [0,5,5,0]+  [ p "Cabal-syntax" [3,10,1,0]+  , p "Cabal" [3,10,1,0]+  , p "array" [0,5,5,0]   , p "base" [4,18,0,0]-  , p "binary" [0,8,9,1] -- used by libghc+  , p "binary" [0,8,9,1]   , p "bytestring" [0,11,5,1] -- MUST BE PATCHED on ghc-9.6.2---  , p "Cabal" [3,6,3,0]  package is upgradeable   , p "containers" [0,6,7]-  , p "deepseq" [1,4,8,1] -- used by time+  , p "deepseq" [1,4,8,1]   , p "directory" [1,3,8,1]-  , p "exceptions" [0,10,7] -- used by libghc+  , p "exceptions" [0,10,7]   , p "filepath" [1,4,100,1]   , p "ghc-bignum" [1,3]   , p "ghc-compact" [0,1,0,0]   , p "ghc-prim" [0,10,0]---  , p "haskeline" [0,8,2]  package is upgradeable-  , p "hpc" [0,6,2,0] -- used by libghc+  , p "haskeline" [0,8,2,1]+  , p "hpc" [0,6,2,0]   , p "integer-gmp" [1,1]-  , p "mtl" [2,3,1]  -- used by exceptions---   , p "parsec" [3,1,15,0]  -- package is upgradeable+  , p "mtl" [2,3,1]+  , p "parsec" [3,1,16,1]   , p "pretty" [1,1,3,6]   , p "process" [1,6,17,0]   , p "stm" [2,5,1,0]-  , p "template-haskell" [2,20,0,0] -- used by libghc-  , p "terminfo" [0,4,1,6] -- used by libghc---   , p "text" [1,2,5,0] -- package is upgradeable-  , p "time" [1,12,2] -- used by unix, directory, hpc, ghc. unsafe to upgrade-  , p "transformers" [0,6,1,0] -- used by libghc+  , p "template-haskell" [2,20,0,0]+  , p "terminfo" [0,4,1,6]+  , p "text" [2,0,2]+  , p "time" [1,12,2]+  , p "transformers" [0,6,1,0]   , p "unix" [2,8,1,0]---  , p "xhtml" [3000,2,2,1]+  , p "xhtml" [3000,2,2,1]   ]  ghc948_pkgs :: [Cabal.PackageIdentifier] ghc948_pkgs =-  [ p "array" [0,5,4,0]+  [ p "Cabal-syntax" [3,8,1,0]+  , p "Cabal" [3,8,1,0]+  , p "array" [0,5,4,0]   , p "base" [4,17,2,1]   , p "binary" [0,8,9,1]   , p "bytestring" [0,11,5,3]@@ -320,22 +596,28 @@   , p "ghc-bignum" [1,3]   , p "ghc-compact" [0,1,0,0]   , p "ghc-prim" [0,9,1]+  , p "haskeline" [0,8,2]   , p "hpc" [0,6,1,0]   , p "integer-gmp" [1,1]   , p "mtl" [2,2,2]+  , p "parsec" [3,1,16,1]   , p "pretty" [1,1,3,6]   , p "process" [1,6,18,0]   , p "stm" [2,5,1,0]   , p "template-haskell" [2,19,0,0]   , p "terminfo" [0,4,1,5]+  , p "text" [2,0,2]   , p "time" [1,12,2]   , p "transformers" [0,5,6,2]   , p "unix" [2,7,3]+  , p "xhtml" [3000,2,2,1]   ]  ghc947_pkgs :: [Cabal.PackageIdentifier] ghc947_pkgs =-  [ p "array" [0,5,4,0]+  [ p "Cabal-syntax" [3,8,1,0]+  , p "Cabal" [3,8,1,0]+  , p "array" [0,5,4,0]   , p "base" [4,17,2,0]   , p "binary" [0,8,9,1]   , p "bytestring" [0,11,5,2]@@ -347,242 +629,248 @@   , p "ghc-bignum" [1,3]   , p "ghc-compact" [0,1,0,0]   , p "ghc-prim" [0,9,1]+  , p "haskeline" [0,8,2]   , p "hpc" [0,6,1,0]   , p "integer-gmp" [1,1]   , p "mtl" [2,2,2]+  , p "parsec" [3,1,16,1]   , p "pretty" [1,1,3,6]   , p "process" [1,6,17,0]   , p "stm" [2,5,1,0]   , p "template-haskell" [2,19,0,0]   , p "terminfo" [0,4,1,5]+  , p "text" [2,0,2]   , p "time" [1,12,2]   , p "transformers" [0,5,6,2]   , p "unix" [2,7,3]+  , p "xhtml" [3000,2,2,1]   ]  ghc946_pkgs :: [Cabal.PackageIdentifier] ghc946_pkgs =-  [ p "array" [0,5,4,0]+  [ p "Cabal-syntax" [3,8,1,0]+  , p "Cabal" [3,8,1,0]+  , p "array" [0,5,4,0]   , p "base" [4,17,2,0]-  , p "binary" [0,8,9,1] -- used by libghc+  , p "binary" [0,8,9,1]   , p "bytestring" [0,11,5,1]---  , p "Cabal" [3,6,3,0]  package is upgradeable   , p "containers" [0,6,7]-  , p "deepseq" [1,4,8,0] -- used by time+  , p "deepseq" [1,4,8,0]   , p "directory" [1,3,7,1]-  , p "exceptions" [0,10,5] -- used by libghc+  , p "exceptions" [0,10,5]   , p "filepath" [1,4,2,2]   , p "ghc-bignum" [1,3]   , p "ghc-compact" [0,1,0,0]   , p "ghc-prim" [0,9,1]---  , p "haskeline" [0,8,2]  package is upgradeable-  , p "hpc" [0,6,1,0] -- used by libghc+  , p "haskeline" [0,8,2]+  , p "hpc" [0,6,1,0]   , p "integer-gmp" [1,1]-  , p "mtl" [2,2,2]  -- used by exceptions---   , p "parsec" [3,1,15,0]  -- package is upgradeable+  , p "mtl" [2,2,2]+  , p "parsec" [3,1,16,1]   , p "pretty" [1,1,3,6]   , p "process" [1,6,17,0]   , p "stm" [2,5,1,0]-  , p "template-haskell" [2,19,0,0] -- used by libghc-  , p "terminfo" [0,4,1,5] -- used by libghc---   , p "text" [1,2,5,0] -- package is upgradeable-  , p "time" [1,12,2] -- used by unix, directory, hpc, ghc. unsafe to upgrade-  , p "transformers" [0,5,6,2] -- used by libghc+  , p "template-haskell" [2,19,0,0]+  , p "terminfo" [0,4,1,5]+  , p "text" [2,0,2]+  , p "time" [1,12,2]+  , p "transformers" [0,5,6,2]   , p "unix" [2,7,3]---  , p "xhtml" [3000,2,2,1]+  , p "xhtml" [3000,2,2,1]   ] - ghc945_pkgs :: [Cabal.PackageIdentifier] ghc945_pkgs =-  [ p "array" [0,5,4,0]+  [ p "Cabal-syntax" [3,8,1,0]+  , p "Cabal" [3,8,1,0]+  , p "array" [0,5,4,0]   , p "base" [4,17,1,0]-  , p "binary" [0,8,9,1] -- used by libghc+  , p "binary" [0,8,9,1]   , p "bytestring" [0,11,4,0]---  , p "Cabal" [3,6,3,0]  package is upgradeable   , p "containers" [0,6,7]-  , p "deepseq" [1,4,8,0] -- used by time+  , p "deepseq" [1,4,8,0]   , p "directory" [1,3,7,1]-  , p "exceptions" [0,10,5] -- used by libghc+  , p "exceptions" [0,10,5]   , p "filepath" [1,4,2,2]   , p "ghc-bignum" [1,3]   , p "ghc-compact" [0,1,0,0]   , p "ghc-prim" [0,9,0]---  , p "haskeline" [0,8,2]  package is upgradeable-  , p "hpc" [0,6,1,0] -- used by libghc+  , p "haskeline" [0,8,2]+  , p "hpc" [0,6,1,0]   , p "integer-gmp" [1,1]-  , p "mtl" [2,2,2]  -- used by exceptions---   , p "parsec" [3,1,15,0]  -- package is upgradeable+  , p "mtl" [2,2,2]+  , p "parsec" [3,1,16,1]   , p "pretty" [1,1,3,6]   , p "process" [1,6,16,0]   , p "stm" [2,5,1,0]-  , p "template-haskell" [2,19,0,0] -- used by libghc-  , p "terminfo" [0,4,1,5] -- used by libghc---   , p "text" [1,2,5,0] -- package is upgradeable-  , p "time" [1,12,2] -- used by unix, directory, hpc, ghc. unsafe to upgrade-  , p "transformers" [0,5,6,2] -- used by libghc+  , p "template-haskell" [2,19,0,0]+  , p "terminfo" [0,4,1,5]+  , p "text" [2,0,2]+  , p "time" [1,12,2]+  , p "transformers" [0,5,6,2]   , p "unix" [2,7,3]---  , p "xhtml" [3000,2,2,1]+  , p "xhtml" [3000,2,2,1]   ]  ghc927_pkgs :: [Cabal.PackageIdentifier] ghc927_pkgs =-  [ p "array" [0,5,4,0]+  [ p "Cabal" [3,6,3,0]+  , p "array" [0,5,4,0]   , p "base" [4,16,4,0]-  , p "binary" [0,8,9,0] -- used by libghc+  , p "binary" [0,8,9,0]   , p "bytestring" [0,11,4,0]---  , p "Cabal" [3,6,3,0]  package is upgradeable   , p "containers" [0,6,5,1]-  , p "deepseq" [1,4,6,1] -- used by time+  , p "deepseq" [1,4,6,1]   , p "directory" [1,3,6,2]-  , p "exceptions" [0,10,4] -- used by libghc+  , p "exceptions" [0,10,4]   , p "filepath" [1,4,2,2]   , p "ghc-bignum" [1,2]   , p "ghc-compact" [0,1,0,0]   , p "ghc-prim" [0,8,0]---  , p "haskeline" [0,8,2]  package is upgradeable-  , p "hpc" [0,6,1,0] -- used by libghc+  , p "haskeline" [0,8,2]+  , p "hpc" [0,6,1,0]   , p "integer-gmp" [1,1]-  , p "mtl" [2,2,2]  -- used by exceptions---   , p "parsec" [3,1,15,0]  -- package is upgradeable+  , p "mtl" [2,2,2]+  , p "parsec" [3,1,15,0]   , p "pretty" [1,1,3,6]   , p "process" [1,6,16,0]   , p "stm" [2,5,0,2]-  , p "template-haskell" [2,18,0,0] -- used by libghc-  , p "terminfo" [0,4,1,5] -- used by libghc---   , p "text" [1,2,5,0] -- package is upgradeable-  , p "time" [1,11,1,1] -- used by unix, directory, hpc, ghc. unsafe to upgrade-  , p "transformers" [0,5,6,2] -- used by libghc+  , p "template-haskell" [2,18,0,0]+  , p "terminfo" [0,4,1,5]+  , p "text" [1,2,5,0]+  , p "time" [1,11,1,1]+  , p "transformers" [0,5,6,2]   , p "unix" [2,7,2,2]---  , p "xhtml" [3000,2,2,1]+  , p "xhtml" [3000,2,2,1]   ]  ghc926_pkgs :: [Cabal.PackageIdentifier] ghc926_pkgs =-  [ p "array" [0,5,4,0]+  [ p "Cabal" [3,6,3,0]+  , p "array" [0,5,4,0]   , p "base" [4,16,4,0]-  , p "binary" [0,8,9,0] -- used by libghc+  , p "binary" [0,8,9,0]   , p "bytestring" [0,11,4,0]---  , p "Cabal" [3,6,3,0]  package is upgradeable   , p "containers" [0,6,5,1]-  , p "deepseq" [1,4,6,1] -- used by time+  , p "deepseq" [1,4,6,1]   , p "directory" [1,3,6,2]-  , p "exceptions" [0,10,4] -- used by libghc-  , p "filepath" [1,4,2,1]+  , p "exceptions" [0,10,4]+  , p "filepath" [1,4,2,2]   , p "ghc-bignum" [1,2]   , p "ghc-compact" [0,1,0,0]   , p "ghc-prim" [0,8,0]---  , p "haskeline" [0,8,2]  package is upgradeable-  , p "hpc" [0,6,1,0] -- used by libghc+  , p "haskeline" [0,8,2]+  , p "hpc" [0,6,1,0]   , p "integer-gmp" [1,1]-  , p "mtl" [2,2,2]  -- used by exceptions---   , p "parsec" [3,1,15,0]  -- package is upgradeable+  , p "mtl" [2,2,2]+  , p "parsec" [3,1,15,0]   , p "pretty" [1,1,3,6]   , p "process" [1,6,16,0]   , p "stm" [2,5,0,2]-  , p "template-haskell" [2,18,0,0] -- used by libghc-  , p "terminfo" [0,4,1,5] -- used by libghc---   , p "text" [1,2,5,0] -- package is upgradeable-  , p "time" [1,11,1,1] -- used by unix, directory, hpc, ghc. unsafe to upgrade-  , p "transformers" [0,5,6,2] -- used by libghc+  , p "template-haskell" [2,18,0,0]+  , p "terminfo" [0,4,1,5]+  , p "text" [1,2,5,0]+  , p "time" [1,11,1,1]+  , p "transformers" [0,5,6,2]   , p "unix" [2,7,2,2]---  , p "xhtml" [3000,2,2,1]+  , p "xhtml" [3000,2,2,1]   ]  ghc925_pkgs :: [Cabal.PackageIdentifier] ghc925_pkgs =-  [ p "array" [0,5,4,0]+  [ p "Cabal" [3,6,3,0]+  , p "array" [0,5,4,0]   , p "base" [4,16,4,0]-  , p "binary" [0,8,9,0] -- used by libghc+  , p "binary" [0,8,9,0]   , p "bytestring" [0,11,3,1]---  , p "Cabal" [3,6,3,0]  package is upgradeable   , p "containers" [0,6,5,1]-  , p "deepseq" [1,4,6,1] -- used by time+  , p "deepseq" [1,4,6,1]   , p "directory" [1,3,6,2]-  , p "exceptions" [0,10,4] -- used by libghc-  , p "filepath" [1,4,2,1]+  , p "exceptions" [0,10,4]+  , p "filepath" [1,4,2,2]   , p "ghc-bignum" [1,2]   , p "ghc-compact" [0,1,0,0]   , p "ghc-prim" [0,8,0]---  , p "haskeline" [0,8,2]  package is upgradeable-  , p "hpc" [0,6,1,0] -- used by libghc+  , p "haskeline" [0,8,2]+  , p "hpc" [0,6,1,0]   , p "integer-gmp" [1,1]-  , p "mtl" [2,2,2]  -- used by exceptions---   , p "parsec" [3,1,15,0]  -- package is upgradeable+  , p "mtl" [2,2,2]+  , p "parsec" [3,1,15,0]   , p "pretty" [1,1,3,6]   , p "process" [1,6,16,0]   , p "stm" [2,5,0,2]-  , p "template-haskell" [2,18,0,0] -- used by libghc-  , p "terminfo" [0,4,1,5] -- used by libghc---   , p "text" [1,2,5,0] -- package is upgradeable-  , p "time" [1,11,1,1] -- used by unix, directory, hpc, ghc. unsafe to upgrade-  , p "transformers" [0,5,6,2] -- used by libghc+  , p "template-haskell" [2,18,0,0]+  , p "terminfo" [0,4,1,5]+  , p "text" [1,2,5,0]+  , p "time" [1,11,1,1]+  , p "transformers" [0,5,6,2]   , p "unix" [2,7,2,2]---  , p "xhtml" [3000,2,2,1]+  , p "xhtml" [3000,2,2,1]   ] + ghc924_pkgs :: [Cabal.PackageIdentifier] ghc924_pkgs =-  [ p "array" [0,5,4,0]+  [ p "Cabal" [3,6,3,0]+  , p "array" [0,5,4,0]   , p "base" [4,16,3,0]-  , p "binary" [0,8,9,0] -- used by libghc+  , p "binary" [0,8,9,0]   , p "bytestring" [0,11,3,1]---  , p "Cabal" [3,6,3,0]  package is upgradeable   , p "containers" [0,6,5,1]-  , p "deepseq" [1,4,6,1] -- used by time+  , p "deepseq" [1,4,6,1]   , p "directory" [1,3,6,2]-  , p "exceptions" [0,10,4] -- used by libghc-  , p "filepath" [1,4,2,1]+  , p "exceptions" [0,10,4]+  , p "filepath" [1,4,2,2]   , p "ghc-bignum" [1,2]   , p "ghc-compact" [0,1,0,0]   , p "ghc-prim" [0,8,0]---  , p "haskeline" [0,8,2]  package is upgradeable-  , p "hpc" [0,6,1,0] -- used by libghc+  , p "haskeline" [0,8,2]+  , p "hpc" [0,6,1,0]   , p "integer-gmp" [1,1]-  , p "mtl" [2,2,2]  -- used by exceptions---   , p "parsec" [3,1,15,0]  -- package is upgradeable+  , p "mtl" [2,2,2]+  , p "parsec" [3,1,15,0]   , p "pretty" [1,1,3,6]-  , p "process" [1,6,16,0]+  , p "process" [1,6,13,2]   , p "stm" [2,5,0,2]-  , p "template-haskell" [2,18,0,0] -- used by libghc-  , p "terminfo" [0,4,1,5] -- used by libghc---   , p "text" [1,2,5,0] -- package is upgradeable-  , p "time" [1,11,1,1] -- used by unix, directory, hpc, ghc. unsafe to upgrade-  , p "transformers" [0,5,6,2] -- used by libghc+  , p "template-haskell" [2,18,0,0]+  , p "terminfo" [0,4,1,5]+  , p "text" [1,2,5,0]+  , p "time" [1,11,1,1]+  , p "transformers" [0,5,6,2]   , p "unix" [2,7,2,2]---  , p "xhtml" [3000,2,2,1]+  , p "xhtml" [3000,2,2,1]   ]  ghc902_pkgs :: [Cabal.PackageIdentifier] ghc902_pkgs =-  [ p "array" [0,5,4,0]+  [ p "Cabal" [3,4,1,0]+  , p "array" [0,5,4,0]   , p "base" [4,15,1,0]-  , p "binary" [0,8,8,0] -- used by libghc+  , p "binary" [0,8,8,0]   , p "bytestring" [0,10,12,1]---  , p "Cabal" [3,4,1,0]  package is upgradeable   , p "containers" [0,6,4,1]-  , p "deepseq" [1,4,5,0] -- used by time+  , p "deepseq" [1,4,5,0]   , p "directory" [1,3,6,2]+  , p "exceptions" [0,10,4]   , p "filepath" [1,4,2,1]-  , p "exceptions" [0,10,4] -- used by libghc   , p "ghc-bignum" [1,1]   , p "ghc-compact" [0,1,0,0]   , p "ghc-prim" [0,7,0]---  , p "haskeline" [0,8,2]  package is upgradeable-  , p "hpc" [0,6,1,0] -- used by libghc+  , p "haskeline" [0,8,2]+  , p "hpc" [0,6,1,0]   , p "integer-gmp" [1,1]-  , p "mtl" [2,2,2]  -- used by exceptions---   , p "parsec" [3,1,14,0]  -- package is upgradeable+  , p "mtl" [2,2,2]+  , p "parsec" [3,1,14,0]   , p "pretty" [1,1,3,6]-  , p "process" [1,6,16,0]+  , p "process" [1,6,13,2]   , p "stm" [2,5,0,0]-  , p "template-haskell" [2,17,0,0] -- used by libghc-  , p "terminfo" [0,4,1,5] -- used by libghc---   , p "text" [1,2,5,0] -- package is upgradeable-  , p "time" [1,9,3,0] -- used by unix, directory, hpc, ghc. unsafe to upgrade-  , p "transformers" [0,5,6,2] -- used by libghc+  , p "template-haskell" [2,17,0,0]+  , p "terminfo" [0,4,1,5]+  , p "text" [1,2,5,0]+  , p "time" [1,9,3]+  , p "transformers" [0,5,6,2]   , p "unix" [2,7,2,2]---  , p "xhtml" [3000,2,2,1]+  , p "xhtml" [3000,2,2,1]   ]  p :: String -> [Int] -> Cabal.PackageIdentifier
src/Portage/Host.hs view
@@ -5,12 +5,19 @@  import Util (run_cmd) import qualified Data.List.Split as DLS-import Data.Maybe (fromJust, isJust, mapMaybe)+import Data.Maybe (fromJust, isJust, mapMaybe, fromMaybe)  import qualified System.Directory as D import           System.FilePath ((</>))+import           Hackport.Dirs (hackportDir) -import System.IO+import Control.Applicative ((<|>))+import Control.Monad (guard)+import Control.Monad.IO.Class (MonadIO, liftIO)+import Control.Monad.State.Strict (MonadState)+import Control.Monad.Trans.Maybe (MaybeT(..))+import Hackport.Env (HasGlobalEnv, WarningBuffer)+import Util (warn)  data LocalInfo =     LocalInfo { distfiles_dir :: String@@ -25,49 +32,41 @@                         }  -- query paludis and then emerge-getInfo :: IO LocalInfo-getInfo = fromJust `fmap`-    performMaybes [ readConfig-                  , performMaybes [ getPaludisInfo-                                  , askPortageq-                                  , return (Just defaultInfo)-                                  ] >>= showAnnoyingWarning-                  ]-    where performMaybes [] = return Nothing-          performMaybes (act:acts) =-              do r <- act-                 if isJust r-                     then return r-                     else performMaybes acts+getInfo :: (HasGlobalEnv m, MonadIO m, MonadState WarningBuffer m)+    => m LocalInfo+getInfo = fromMaybe defaultInfo <$> runMaybeT (readConfig <|> getInfoWithWarning)+  where+    getInfoWithWarning = MaybeT $ do+        configPath <- hackportConfig+        info <- runMaybeT $ getPaludisInfo <|> askPortageq+        warn $ configWarning configPath info+        pure info -showAnnoyingWarning :: Maybe LocalInfo -> IO (Maybe LocalInfo)-showAnnoyingWarning info = do-    hPutStr stderr $ unlines [ "-- Consider creating ~/" ++ hackport_config ++ " file with contents:"-                             , show info-                             , "-- It will speed hackport startup time a bit."-                             ]-    return info+    configWarning configPath info = unlines+        [ "-- Consider creating " ++ configPath ++ " file with contents:"+        , show info+        , "-- It will speed hackport startup time a bit."+        ] --- relative to home dir-hackport_config :: FilePath-hackport_config = ".hackport" </> "repositories"+-- | Where @repositories@ config file is located+hackportConfig :: MonadIO m => m FilePath+hackportConfig = (</> "repositories") <$> hackportDir  -------------------------- -- fastest: config reading ---------------------------readConfig :: IO (Maybe LocalInfo)-readConfig =-    do home_dir <- D.getHomeDirectory-       let config_path  = home_dir </> hackport_config-       exists <- D.doesFileExist config_path-       if exists then read <$> readFile config_path else return Nothing+readConfig :: MonadIO m => MaybeT m LocalInfo+readConfig = do+    configPath <- hackportConfig+    liftIO (D.doesFileExist configPath) >>= guard+    MaybeT $ liftIO $ read <$> readFile configPath  ---------- -- Paludis ---------- -getPaludisInfo :: IO (Maybe LocalInfo)-getPaludisInfo = fmap parsePaludisInfo <$> run_cmd "cave info"+getPaludisInfo :: MonadIO m => MaybeT m LocalInfo+getPaludisInfo = MaybeT $ fmap parsePaludisInfo <$> run_cmd "cave info"  parsePaludisInfo :: String -> LocalInfo parsePaludisInfo text =@@ -81,7 +80,7 @@     name <- case words firstLine of                 ["Repository", nm] -> return (init nm)                 _ -> fail "not a repository chunk"-    let dict = [ (head ln, unwords (tail ln)) | ln <- map words lns ]+    let dict = [ (lnHead, unwords lnTail) | (lnHead:lnTail) <- map words lns ]     location <- lookup "location" dict     distfiles <- lookup "distdir" dict     return (name, (location, distfiles))@@ -100,22 +99,21 @@ -- Emerge --------- -askPortageq :: IO (Maybe LocalInfo)+askPortageq :: MonadIO m => MaybeT m LocalInfo askPortageq = do     distdir <- run_cmd "portageq distdir"     portdir <- run_cmd "portageq get_repo_path / gentoo"     hsRepo  <- run_cmd "portageq get_repo_path / haskell"     --There really ought to be both distdir and portdir,     --but maybe no hsRepo defined yet.-    let info = if Nothing `elem` [distdir,portdir]-               then Nothing-               else Just LocalInfo-                      { distfiles_dir = grab distdir-                      , portage_dir = grab portdir-                      , overlay_list = iffy hsRepo-                      }-                 --init: kill newline char-                 where grab = init . fromJust-                       iffy Nothing     = []-                       iffy (Just repo) = [init repo]-    return info+    guard $ all isJust [distdir,portdir]+    pure LocalInfo+        { distfiles_dir = grab distdir+        , portage_dir = grab portdir+        , overlay_list = iffy hsRepo+        }+  where+    --init: kill newline char+    grab = init . fromJust+    iffy Nothing     = []+    iffy (Just repo) = [init repo]
src/Util.hs view
@@ -11,14 +11,19 @@     , debug     , notice     , info+    , warn+    , displayWarnings     , die     ) where  import Control.Monad.IO.Class+import Control.Monad.State.Strict+import qualified Data.DList as DL import System.IO import System.Process import System.Exit (ExitCode(..)) import qualified Distribution.Simple.Utils as Cabal+import qualified Distribution.Verbosity as Cabal import Hackport.Env  -- | 'run_cmd' executes command and returns it's standard output@@ -38,14 +43,28 @@         else Just output  debug :: (HasGlobalEnv m, MonadIO m) => String -> m ()-debug s = askGlobalEnv >>= \(GlobalEnv v _ _) -> liftIO $ Cabal.debug v s+debug s = withVerbosity $ \v -> liftIO $ Cabal.debug v s  notice :: (HasGlobalEnv m, MonadIO m) => String -> m ()-notice s = askGlobalEnv >>= \(GlobalEnv v _ _) -> liftIO $ Cabal.notice v s+notice s = withVerbosity $ \v -> liftIO $ Cabal.notice v s  info :: (HasGlobalEnv m, MonadIO m) => String -> m ()-info s = askGlobalEnv >>= \(GlobalEnv v _ _) -> liftIO $ Cabal.info v s+info s = withVerbosity $ \v -> liftIO $ Cabal.info v s --- | Terminate with an error message-die :: (HasGlobalEnv m, MonadIO m) => String -> m a-die s = askGlobalEnv >>= \(GlobalEnv v _ _) -> liftIO $ Cabal.die' v s+-- | Display a warning, then add a it to the global 'WarningBuffer', so that+--   it will be displayed at the end of hackport's output.+warn :: (HasGlobalEnv m, MonadIO m, MonadState WarningBuffer m) => String -> m ()+warn s = withVerbosity $ \v -> do+    liftIO $ Cabal.warn v s+    modifyWarningBuffer (<> DL.singleton s)++-- | Display all pending warnings, then terminate with an error message+die :: (MonadState WarningBuffer m, HasGlobalEnv m, MonadIO m) => String -> m a+die s = withVerbosity $ \v -> getWarningBuffer >>= \dl -> do+    displayWarnings v dl+    liftIO $ error s++withVerbosity :: (Monad m, HasGlobalEnv m) => (Cabal.Verbosity -> m a) -> m a+withVerbosity f = do+    verbosity <- globalVerbosity <$> askGlobalEnv+    f (Cabal.verboseNoWrap verbosity)
tests/resolveCat/Main.hs view
@@ -1,5 +1,6 @@ import qualified Distribution.Package as Cabal +import Hackport.Env (runEnv) import qualified Portage.Overlay as Portage import qualified Portage.Resolve as Portage import qualified Portage.PackageId as Portage@@ -16,8 +17,8 @@  test_resolveCategory :: String -> String -> Test test_resolveCategory cat pkg = TestCase $ do-  portage_dir <- Portage.portage_dir `fmap` Portage.getInfo-  portage <- Portage.loadLazy portage_dir+  info <- runEnv Portage.getInfo () mempty+  portage <- Portage.loadLazy (Portage.portage_dir info)   let cabal = Cabal.mkPackageName pkg       hits = Portage.resolveFullPortageName portage cabal       expected = Just (Portage.PackageName (Portage.Category cat) (Portage.normalizeCabalPackageName cabal))
tests/spec/Portage/EBuildSpec.hs view
@@ -26,7 +26,6 @@     it "should not convert whitelisted http-only homepages into https homepages" $ do       toHttps "http://leksah.org" `shouldBe` "http://leksah.org"       toHttps "http://darcs.net/" `shouldBe` "http://darcs.net/"-      toHttps "http://khumba.net/" `shouldBe` "http://khumba.net/"     it "should otherwise convert all homepages into https-aware homepages" $ do       toHttps "http://pandoc.org" `shouldBe` "https://pandoc.org"       toHttps "http://www.yesodweb.com/" `shouldBe` "https://www.yesodweb.com/"