summaryrefslogtreecommitdiff
path: root/Merge.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Merge.hs')
-rw-r--r--Merge.hs70
1 files changed, 60 insertions, 10 deletions
diff --git a/Merge.hs b/Merge.hs
index 487857c..0944c64 100644
--- a/Merge.hs
+++ b/Merge.hs
@@ -6,6 +6,7 @@ module Merge
import Control.Monad
import Control.Exception
import qualified Data.ByteString.Lazy.Char8 as BL
+import qualified Data.ByteString.Builder as BL (stringUtf8, toLazyByteString)
import Data.Function (on)
import Data.Maybe
import qualified Data.List as L
@@ -35,9 +36,10 @@ import System.Directory ( getCurrentDirectory
, setCurrentDirectory
, createDirectoryIfMissing
, doesFileExist
+ , listDirectory
)
import System.Process (system)
-import System.FilePath ((</>))
+import System.FilePath ((</>), isExtensionOf)
import System.Exit
import qualified Cabal2Ebuild as C2E
@@ -64,7 +66,6 @@ a <.> b = a ++ '.':b
{-
Requested features:
* Add files to git?
- * Print diff with the next latest version?
-}
readPackageString :: [String]
@@ -153,9 +154,59 @@ merge verbosity repoContext args overlayPath users_cabal_flags = do
cat <- maybe (Portage.resolveCategory verbosity overlay norm_pkgName) return m_category
mergeGenericPackageDescription verbosity overlayPath cat (CabalInstall.packageDescription selectedPkg) True users_cabal_flags
+ -- Maybe generate a diff
+ let pkgPath = overlayPath </> (Portage.unCategory cat) </> (Cabal.unPackageName norm_pkgName)
+ newPkgId = Portage.fromCabalPackageId cat cabal_pkgId
+ pkgDir <- listDirectory pkgPath
+ case getPreviousPackageId pkgDir newPkgId of
+ Just validPkg -> do info verbosity "Generating a diff..."
+ diffEbuilds overlayPath validPkg newPkgId
+ _ -> info verbosity "Nothing to diff!"
+
+-- | 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
+
+-- | Maybe return a PackageId of the next highest version for a given
+-- package, relative to the provided PackageId of the new version.
+-- We achieve this by mapping Portage.filePathToPackageId over the
+-- provided package directory, whose contents are filtered for files
+-- with the '.ebuild' file extension
+getPreviousPackageId :: [FilePath] -- ^ list of ebuilds for given package
+ -> Portage.PackageId -- ^ new PackageId
+ -> Maybe Portage.PackageId -- ^ maybe PackageId of previous version
+getPreviousPackageId pkgDir newPkgId = do
+ let pkgIds = reverse
+ . L.sortOn (Portage.pkgVersion)
+ . filter (<newPkgId)
+ $ Portage.filePathToPackageId newPkgId
+ <$> filter (\fp -> ".ebuild" `isExtensionOf` fp) pkgDir
+ case pkgIds of
+ x:_ -> Just x
+ _ -> Nothing
+
first_just_of :: [Maybe a] -> Maybe a
first_just_of = msum
+-- Gentoo allows underscore ('_') names in IUSE only for
+-- USE_EXPAND values. If it's not a user-specified rename mangle
+-- it into a hyphen ('-').
+mangle_iuse :: String -> String
+mangle_iuse = map f
+ where f '_' = '-'
+ f c = c
+
+-- | Remove "with_" or "with-" from beginning of flag names.
+drop_with :: String -> String
+drop_with = \x ->
+ case splitAt 5 x of
+ ("with_", b) -> b
+ ("with-", b) -> b
+ _ -> x
+
-- used to be FlagAssignment in Cabal but now it's an opaque type
type CabalFlags = [(Cabal.FlagName, Bool)]
@@ -232,11 +283,10 @@ mergeGenericPackageDescription verbosity overlayPath cat pkgGenericDesc fetch us
, let f = Cabal.unFlagName cabal_f
]
-
cfn_to_iuse :: String -> String
cfn_to_iuse cfn =
case lookup cfn cf_to_iuse_rename of
- Nothing -> cfn
+ Nothing -> mangle_iuse . drop_with $ cfn
Just ein -> ein
-- key idea is to generate all possible list of flags
@@ -383,13 +433,11 @@ mergeGenericPackageDescription verbosity overlayPath cat pkgGenericDesc fetch us
Just ucf -> (\e -> e { E.used_options = E.used_options e ++ [("flags", ucf)] }))
$ C2E.cabal2ebuild cat pkgDesc
- mergeEbuild verbosity existing_meta pkgdir ebuild cabal_flag_descs
+ mergeEbuild verbosity existing_meta pkgdir ebuild active_flag_descs
when fetch $ do
let cabal_pkgId = Cabal.packageId pkgDesc
norm_pkgName = Cabal.packageName (Portage.normalizeCabalPackageId cabal_pkgId)
- fetchDigestAndCheck
- verbosity
- (overlayPath </> display cat </> display norm_pkgName)
+ fetchDigestAndCheck verbosity (overlayPath </> display cat </> display norm_pkgName)
fetchDigestAndCheck :: Verbosity
-> FilePath -- ^ directory of ebuild
@@ -423,7 +471,7 @@ to_unstable kw =
-- | Generate a list of tuples containing Cabal flag names and descriptions
metaFlags :: [Cabal.Flag] -> [(String, String)]
-metaFlags flags = zip (Cabal.unFlagName . Cabal.flagName <$> flags) (Cabal.flagDescription <$> flags)
+metaFlags flags = zip (mangle_iuse . drop_with . Cabal.unFlagName . Cabal.flagName <$> flags) (Cabal.flagDescription <$> flags)
mergeEbuild :: Verbosity -> EM.EMeta -> FilePath -> E.EBuild -> [Cabal.Flag] -> IO ()
mergeEbuild verbosity existing_meta pkgdir ebuild flags = do
@@ -432,7 +480,9 @@ mergeEbuild verbosity existing_meta pkgdir ebuild flags = do
epath = edir </> elocal
emeta = "metadata.xml"
mpath = edir </> emeta
- default_meta = BL.pack $ Portage.makeDefaultMetadata (E.long_desc ebuild) (metaFlags flags)
+ default_meta = BL.toLazyByteString . BL.stringUtf8
+ $ Portage.makeDefaultMetadata (E.long_desc ebuild)
+ $ metaFlags flags
createDirectoryIfMissing True edir
now <- TC.getCurrentTime