Skip to content

Commit

Permalink
Update the CLI and start using cabal-install features
Browse files Browse the repository at this point in the history
Code ported to get the CLI like cabal-install style
Use cabal-install for updating
  • Loading branch information
kolmodin committed Feb 7, 2009
1 parent f2749d2 commit 8273e68
Show file tree
Hide file tree
Showing 9 changed files with 258 additions and 145 deletions.
22 changes: 10 additions & 12 deletions Cabal2Ebuild.hs
Expand Up @@ -28,7 +28,9 @@ module Cabal2Ebuild


import qualified Distribution.PackageDescription as Cabal import qualified Distribution.PackageDescription as Cabal
(PackageDescription(..)) (PackageDescription(..))
import qualified Distribution.Package as Cabal (PackageIdentifier(..), Dependency(..)) import qualified Distribution.Package as Cabal (PackageIdentifier(..)
, Dependency(..)
, PackageName(..))
import qualified Distribution.Version as Cabal (VersionRange(..), versionBranch, Version) import qualified Distribution.Version as Cabal (VersionRange(..), versionBranch, Version)
import qualified Distribution.License as Cabal (License(..)) import qualified Distribution.License as Cabal (License(..))
import qualified Distribution.Text as Cabal (display) import qualified Distribution.Text as Cabal (display)
Expand All @@ -39,8 +41,6 @@ import Data.List (intercalate, groupBy, partition, nub, sortBy, init, l
import Data.Ord (comparing) import Data.Ord (comparing)
import Data.Maybe (catMaybes, fromJust) import Data.Maybe (catMaybes, fromJust)


import Index (pName, mkPackage)

data EBuild = EBuild { data EBuild = EBuild {
name :: String, name :: String,
version :: String, version :: String,
Expand Down Expand Up @@ -89,8 +89,6 @@ ebuildTemplate = EBuild {
my_pn = Nothing my_pn = Nothing
} }




cabal2ebuild :: Cabal.PackageDescription -> EBuild cabal2ebuild :: Cabal.PackageDescription -> EBuild
cabal2ebuild pkg = ebuildTemplate { cabal2ebuild pkg = ebuildTemplate {
name = map toLower cabalPkgName, name = map toLower cabalPkgName,
Expand All @@ -103,15 +101,15 @@ cabal2ebuild pkg = ebuildTemplate {
licenseComments = licenseComment (Cabal.license pkg), licenseComments = licenseComment (Cabal.license pkg),
depend = defaultDepGHC depend = defaultDepGHC
: (simplify_deps $ : (simplify_deps $
convertDependency (Cabal.Dependency (mkPackage "Cabal") convertDependency (Cabal.Dependency (Cabal.PackageName "Cabal")
(Cabal.descCabalVersion pkg)) (Cabal.descCabalVersion pkg))
++ convertDependencies (Cabal.buildDepends pkg)), ++ convertDependencies (Cabal.buildDepends pkg)),
my_pn = if any isUpper cabalPkgName then Just cabalPkgName else Nothing, my_pn = if any isUpper cabalPkgName then Just cabalPkgName else Nothing,
features = features ebuildTemplate features = features ebuildTemplate
++ (if null (Cabal.executables pkg) then [] else ["bin"]) ++ (if null (Cabal.executables pkg) then [] else ["bin"])
++ maybe [] (const ["lib","profile","haddock","hscolour"]) (Cabal.library pkg) ++ maybe [] (const ["lib","profile","haddock","hscolour"]) (Cabal.library pkg)
} where } where
cabalPkgName = pName $ Cabal.pkgName (Cabal.package pkg) cabalPkgName = Cabal.display $ Cabal.pkgName (Cabal.package pkg)


defaultDepGHC :: Dependency defaultDepGHC :: Dependency
defaultDepGHC = OrLaterVersionOf (Version [6,6,1]) "dev-lang/ghc" defaultDepGHC = OrLaterVersionOf (Version [6,6,1]) "dev-lang/ghc"
Expand All @@ -137,15 +135,15 @@ convertDependencies :: [Cabal.Dependency] -> [Dependency]
convertDependencies = concatMap convertDependency convertDependencies = concatMap convertDependency


convertDependency :: Cabal.Dependency -> [Dependency] convertDependency :: Cabal.Dependency -> [Dependency]
convertDependency (Cabal.Dependency pname _) convertDependency (Cabal.Dependency pname@(Cabal.PackageName name) _)
| (pName pname) `elem` coreLibs = [] -- no explicit dep on core libs | pname `elem` coreLibs = [] -- no explicit dep on core libs
convertDependency (Cabal.Dependency pname versionRange) convertDependency (Cabal.Dependency pname versionRange)
= case versionRange of = case versionRange of
(Cabal.IntersectVersionRanges v1 v2) -> [convert v1, convert v2] (Cabal.IntersectVersionRanges v1 v2) -> [convert v1, convert v2]
v -> [convert v] v -> [convert v]


where where
ebuildName = "dev-haskell/" ++ map toLower (pName pname) ebuildName = "dev-haskell/" ++ map toLower (Cabal.display pname)


convert :: Cabal.VersionRange -> Dependency convert :: Cabal.VersionRange -> Dependency
convert Cabal.AnyVersion = AnyVersionOf ebuildName convert Cabal.AnyVersion = AnyVersionOf ebuildName
Expand All @@ -166,8 +164,8 @@ cabalVtoHPv = Version . Cabal.versionBranch
instance Show Version where instance Show Version where
show (Version v) = intercalate "." $ map show v show (Version v) = intercalate "." $ map show v


coreLibs :: [String] coreLibs :: [Cabal.PackageName]
coreLibs = coreLibs = map Cabal.PackageName
["array" ["array"
,"base" ,"base"
--,"bytestring" --already has ebuild --,"bytestring" --already has ebuild
Expand Down
4 changes: 4 additions & 0 deletions Cache.hs
@@ -1,5 +1,6 @@
module Cache where module Cache where


{-
import CacheFile import CacheFile
import Error import Error
import Index import Index
Expand All @@ -26,6 +27,7 @@ import qualified Data.Map as Map
import Distribution.Verbosity import Distribution.Verbosity
import Distribution.Simple.Utils import Distribution.Simple.Utils
-- | A long time -- | A long time
alarmingLongTime :: TimeDiff alarmingLongTime :: TimeDiff
alarmingLongTime = TimeDiff alarmingLongTime = TimeDiff
Expand Down Expand Up @@ -88,3 +90,5 @@ indexToPortage index port = second nub . runWriter $ do
| otherwise = head xs | otherwise = head xs
tell ["WARNING: Category clash for package " ++ p ++ ", defaulting to " ++ c ++ ". Other categories: " ++ unwords (delete c xs)] tell ["WARNING: Category clash for package " ++ p ++ ", defaulting to " ++ c ++ ". Other categories: " ++ unwords (delete c xs)]
return c return c
-}
133 changes: 106 additions & 27 deletions Diff.hs
Expand Up @@ -3,18 +3,34 @@ module Diff
, DiffMode(..) , DiffMode(..)
) where ) where


import Control.Monad ( forM_ ) import Control.Monad ( forM_, mplus )
import Data.Char import Data.Char
import qualified Data.Map as Map import qualified Data.Map as Map
import Network.URI import Network.URI
import Control.Exception ( assert )
import Data.Maybe ( fromJust, listToMaybe )
import Data.List ( sortBy, groupBy )
import Data.Ord ( comparing )


import Cache
import P2
import qualified Portage.Version as Portage import qualified Portage.Version as Portage
import qualified Portage.Overlay as Portage
import qualified Portage.Cabal as Portage
import qualified Portage.PackageId as Portage

import qualified Data.Version as Cabal


-- cabal -- cabal
import Distribution.Verbosity import Distribution.Verbosity
import Distribution.Text(display) import Distribution.Text(display)
import qualified Distribution.Package as Cabal
import qualified Distribution.Simple.PackageIndex as Cabal
import qualified Distribution.InstalledPackageInfo as Cabal
import Distribution.Simple.Utils (equating)

-- cabal-install
import qualified Distribution.Client.IndexUtils as Index (getAvailablePackages )
import qualified Distribution.Client.Types as Cabal
import Distribution.Client.Utils (mergeBy, MergeResult(..))


data DiffMode data DiffMode
= ShowAll = ShowAll
Expand All @@ -25,40 +41,102 @@ data DiffMode
| ShowPackages [String] | ShowPackages [String]
deriving Eq deriving Eq


data DiffState a type DiffState a = MergeResult a a
= OnlyLeft a
| OnlyRight a
| Both a a


tabs :: String -> String tabs :: String -> String
tabs str = let len = length str in str++(if len < 3*8 tabs str = let len = length str in str++(if len < 3*8
then replicate (3*8-len) ' ' then replicate (3*8-len) ' '
else "") else "")


showDiffState :: Package -> DiffState Portage.Version -> String showDiffState :: Cabal.PackageName -> DiffState Portage.Version -> String
showDiffState pkg st = (tabs (show pkg)) ++ " [" ++ (case st of showDiffState pkg st = (tabs (display pkg)) ++ " [" ++ (case st of
Both x y -> display x ++ (case compare x y of InBoth x y -> display x ++ (case compare x y of
EQ -> "=" EQ -> "="
GT -> ">" GT -> ">"
LT -> "<") ++ display y LT -> "<") ++ display y
OnlyLeft x -> display x ++ ">none" OnlyInLeft x -> display x ++ ">none"
OnlyRight y -> "none<" ++ display y) ++ "]" OnlyInRight y -> "none<" ++ display y) ++ "]"


runDiff :: Verbosity -> FilePath -> URI -> DiffMode -> IO () runDiff :: Verbosity -> FilePath -> DiffMode -> Cabal.Repo -> IO ()
runDiff verbosity overlayPath serverURI dm = do runDiff verbosity overlayPath dm repo = do
cache <- readCache verbosity overlayPath serverURI -- get package list from hackage
overlayTree <- readPortageTree overlayPath pkgDB <- Index.getAvailablePackages verbosity [ repo ]
let (hackageTree, clashes) = indexToPortage cache overlayTree let (Cabal.AvailablePackageDb hackageIndex _) = pkgDB
mapM_ putStrLn clashes
case dm of -- get package list from the overlay
ShowPackages pkgs -> overlay0 <- (Portage.loadLazy overlayPath)
forM_ pkgs $ \ pkg -> do let overlayIndex = Portage.fromOverlay (Portage.reduceOverlay overlay0)
let criteria = Map.filterWithKey (\k _ -> pPackage k == pkg)
subHackage = criteria hackageTree let (subHackage, subOverlay)
subOverlay = criteria overlayTree = case dm of
diff subHackage subOverlay dm ShowPackages pkgs ->
_ -> diff hackageTree overlayTree dm (concatMap (Cabal.searchByNameSubstring hackageIndex) pkgs
,concatMap (Cabal.searchByNameSubstring overlayIndex) pkgs)
_ ->
(Cabal.allPackages hackageIndex
,Cabal.allPackages overlayIndex)
diff subHackage subOverlay dm

data PackageCompareInfo = PackageCompareInfo {
name :: Cabal.PackageName,
hackageVersions :: [ Cabal.Version ],
overlayVersions :: [ Portage.Version ]
}

diff :: [Cabal.AvailablePackage]
-> [Portage.ExistingEbuild]
-> DiffMode
-> IO ()
diff hackage overlay dm =

error "Diff.diff not implemented"

-- | We get the 'PackageCompareInfo' by combining the info for the overlay
-- and hackage versions of a package.
--
-- * We're building info about a various versions of a single named package so
-- the input package info records are all supposed to refer to the same
-- package name.
--
mergePackageInfo :: [Portage.ExistingEbuild]
-> [Cabal.AvailablePackage]
-> PackageCompareInfo
mergePackageInfo overlay hackage =
assert (length overlay + length hackage > 0) $
PackageCompareInfo {
name = combine (Cabal.pkgName . Cabal.packageId) latestHackage
(Cabal.pkgName . Cabal.packageId) latestOverlay,
hackageVersions = map (Cabal.pkgVersion . Cabal.packageId) hackage,
overlayVersions = map (Portage.pkgVersion . Portage.ebuildId) overlay
}
where
combine f x g y = fromJust (fmap f x `mplus` fmap g y)
latestHackage = latestOf hackage
latestOverlay = latestOf overlay
latestOf :: Cabal.Package pkg => [pkg] -> Maybe pkg
latestOf = listToMaybe . sortBy (comparing (Cabal.pkgVersion . Cabal.packageId))

-- | Rearrange installed and available packages into groups referring to the
-- same package by name. In the result pairs, the lists are guaranteed to not
-- both be empty.
--
mergePackages :: [Cabal.InstalledPackageInfo] -> [Cabal.AvailablePackage]
-> [([Cabal.InstalledPackageInfo], [Cabal.AvailablePackage])]
mergePackages installed available =
map collect
$ mergeBy (\i a -> fst i `compare` fst a)
(groupOn (Cabal.pkgName . Cabal.packageId) installed)
(groupOn (Cabal.pkgName . Cabal.packageId) available)
where
collect (OnlyInLeft (_,is) ) = (is, [])
collect ( InBoth (_,is) (_,as)) = (is, as)
collect (OnlyInRight (_,as)) = ([], as)


groupOn :: Ord key => (a -> key) -> [a] -> [(key,[a])]
groupOn key = map (\xs -> (key (head xs), xs))
. groupBy (equating key)
. sortBy (comparing key)
{-
diff :: Portage -> Portage -> DiffMode -> IO () diff :: Portage -> Portage -> DiffMode -> IO ()
diff pt1 pt2 mode = do diff pt1 pt2 mode = do
let pkgs1 = Map.map (OnlyLeft . eVersion . maximum) pt1 let pkgs1 = Map.map (OnlyLeft . eVersion . maximum) pt1
Expand All @@ -85,3 +163,4 @@ diff pt1 pt2 mode = do
ShowPackages _ -> True ShowPackages _ -> True
let packages = filter (showFilter . snd) (Map.assocs union) let packages = filter (showFilter . snd) (Map.assocs union)
mapM_ (putStrLn . uncurry showDiffState) packages mapM_ (putStrLn . uncurry showDiffState) packages
-}
11 changes: 4 additions & 7 deletions GenerateEbuild.hs
Expand Up @@ -8,8 +8,7 @@ import Data.Version (showVersion)
import Network.URI import Network.URI
import System.Directory import System.Directory
import System.FilePath import System.FilePath

import Distribution.Text (display)
import Index (pName)


mergeEbuild :: FilePath -> String -> EBuild -> IO () mergeEbuild :: FilePath -> String -> EBuild -> IO ()
mergeEbuild target category ebuild = do mergeEbuild target category ebuild = do
Expand All @@ -24,14 +23,12 @@ fixSrc serverURI p ebuild =
src_uri = show $ serverURI { src_uri = show $ serverURI {
uriPath = uriPath =
(uriPath serverURI) (uriPath serverURI)
</> pname </> display (pkgName p)
</> showVersion (pkgVersion p) </> display (pkgVersion p)
</> pname ++ "-" ++ showVersion (pkgVersion p) </> display (pkgName p) ++ "-" ++ display (pkgVersion p)
<.> "tar.gz" <.> "tar.gz"
} }
} }
where
pname = pName (pkgName p)


{-hackage2ebuild :: {-hackage2ebuild ::
(PackageIdentifier,String,String) -> -- ^ the package (PackageIdentifier,String,String) -> -- ^ the package
Expand Down
53 changes: 27 additions & 26 deletions Index.hs
@@ -1,44 +1,37 @@
module Index where module Index where


{-
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified Data.Map as Map import qualified Data.Map as Map
import Data.Version (Version,parseVersion) import Data.Version (Version,parseVersion)
import Data.ByteString.Lazy.Char8(ByteString,unpack) import Data.ByteString.Lazy.Char8(ByteString,unpack)
import qualified Codec.Archive.Tar as Tar import Codec.Archive.Tar
import qualified Codec.Archive.Tar.Entry as Tar
import Codec.Archive.Tar.Entry(Entry(..), EntryContent(..))
import qualified Codec.Compression.GZip as GZip
import Distribution.PackageDescription import Distribution.PackageDescription
import Distribution.PackageDescription.Parse import Distribution.PackageDescription.Parse
^ ^ ^ ^ ^ ^ ^
import Distribution.Package import Distribution.Package
import Distribution.Text
import System.FilePath.Posix import System.FilePath.Posix
import MaybeRead (readPMaybe) import MaybeRead (readPMaybe)
type Index = [(String,String,GenericPackageDescription)] type Index = [(Cabal.PackageName, Version, GenericPackageDescription)]
type IndexMap = Map.Map String (Set.Set Version) type IndexMap = Map.Map Cabal.PackageName (Set.Set Version)
readIndex :: ByteString -> Index readIndex :: ByteString -> Index
readIndex = createIndex readIndex str = do
. Tar.read . GZip.decompress let unziped = decompress str
where untared = readTarArchive unziped
createIndex = Tar.foldEntries getEntry [] (const []) entr <- archiveEntries untared

case splitDirectories (tarFileName (entryHeader entr)) of
getEntry :: Entry -> Index -> Index [".",pkgname,vers,file] -> do
getEntry ent ind = case (splitDirectories . Tar.entryPath $ ent) of let descr = case parsePackageDescription (unpack (entryData entr)) of
[".",name,vers,file] -> case (cabalIndex ent) of ParseOk _ pkg_desc -> pkg_desc
(Just desc) -> (name,vers,desc) : ind _ -> error $ "Couldn't read cabal file "++show file
_ -> error $ "Couldn't read cabal file " ++ (show file) return (pkgname,vers,descr)
_ -> ind _ -> fail "doesn't look like the proper path"

cabalIndex :: Entry -> Maybe GenericPackageDescription
cabalIndex entry = case (Tar.entryContent entry) of
(NormalFile file _) -> case (parsePackageDescription . unpack $ file) of
(ParseOk _ pkg_desc) -> Just pkg_desc
_ -> Nothing
_ -> Nothing
filterIndexByPV :: (String -> String -> Bool) -> Index -> Index filterIndexByPV :: (String -> String -> Bool) -> Index -> Index
filterIndexByPV cond index = [ x | x@(p,v,_d) <- index, cond p v] filterIndexByPV cond index = [ x | x@(p,v,_d) <- index, cond (display p) (display v)]
indexMapFromList :: [PackageIdentifier] -> IndexMap indexMapFromList :: [PackageIdentifier] -> IndexMap
indexMapFromList pids = Map.unionsWith Set.union $ indexMapFromList pids = Map.unionsWith Set.union $
Expand All @@ -53,9 +46,17 @@ mkPackage = PackageName
indexToPackageIdentifier :: Index -> [PackageIdentifier] indexToPackageIdentifier :: Index -> [PackageIdentifier]
indexToPackageIdentifier index = do indexToPackageIdentifier index = do
v v v v v v v
(name,vers,_) <- index
return $ PackageIdentifier {pkgName = name, pkgVersion = vers}
*************
(name,vers_str,_) <- index (name,vers_str,_) <- index
Just vers <- return $ readPMaybe parseVersion vers_str Just vers <- return $ readPMaybe parseVersion vers_str
return $ PackageIdentifier {pkgName = PackageName name,pkgVersion = vers} return $ PackageIdentifier {pkgName = PackageName name,pkgVersion = vers}
^ ^ ^ ^ ^ ^ ^
bestVersions :: IndexMap -> Map.Map String Version bestVersions :: IndexMap -> Map.Map Cabal.PackageName Version
bestVersions = Map.map Set.findMax bestVersions = Map.map Set.findMax
-}

0 comments on commit 8273e68

Please sign in to comment.