Skip to content
Newer
Older
100644 241 lines (206 sloc) 9.15 KB
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
1 module Status
2 ( FileStatus(..)
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
3 , StatusDirection(..)
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
4 , fromStatus
5 , status
a1730ad @kolmodin Switch to using Cabal's CLI API
kolmodin authored Aug 31, 2008
6 , runStatus
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
7 ) where
9448bb7 @kolmodin Rewritten overlayonly functionality
kolmodin authored Aug 13, 2007
8
9 import AnsiColor
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
10
a46eb46 @trofi Portage.Version: add 'is_live' helper to distinct live ebuilds
trofi authored Mar 12, 2012
11 import qualified Portage.Version as V (is_live)
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
12
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
13 import Portage.Overlay
14 import Portage.PackageId
599de8c @trofi status: hackage packages are now mapped properly to overlay categories
trofi authored Feb 28, 2012
15 import Portage.Resolve
ac9dddd @dcoutts Eliminate redundant Utils module
dcoutts authored Sep 1, 2008
16
9448bb7 @kolmodin Rewritten overlayonly functionality
kolmodin authored Aug 13, 2007
17 import Control.Monad.State
18
19 import qualified Data.List as List
20
21 import qualified Data.ByteString.Lazy.Char8 as L
22
23 import Data.Char
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
24 import Data.Function (on)
9448bb7 @kolmodin Rewritten overlayonly functionality
kolmodin authored Aug 13, 2007
25 import qualified Data.Map as Map
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
26 import Data.Map as Map (Map)
9448bb7 @kolmodin Rewritten overlayonly functionality
kolmodin authored Aug 13, 2007
27
2ee9bd4 @kolmodin A bit prettier... thanks to sjanssen
kolmodin authored Aug 14, 2007
28 import qualified Data.Traversable as T
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
29 import Control.Applicative
2ee9bd4 @kolmodin A bit prettier... thanks to sjanssen
kolmodin authored Aug 14, 2007
30
a1730ad @kolmodin Switch to using Cabal's CLI API
kolmodin authored Aug 31, 2008
31 -- cabal
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
32 import Distribution.Client.Types ( Repo, SourcePackageDb(..), SourcePackage(..) )
a1730ad @kolmodin Switch to using Cabal's CLI API
kolmodin authored Aug 31, 2008
33 import Distribution.Verbosity
599de8c @trofi status: hackage packages are now mapped properly to overlay categories
trofi authored Feb 28, 2012
34 import Distribution.Package (pkgName)
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
35 import Distribution.Simple.Utils (comparing, die, equating)
85f4f4e @kolmodin Die earlier if we can't parse the package name in 'hackport status'
kolmodin authored Aug 3, 2010
36 import Distribution.Text ( display, simpleParse )
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
37
38 import qualified Distribution.Client.PackageIndex as CabalInstall
39 import qualified Distribution.Client.IndexUtils as CabalInstall
40
41 import Hackage (defaultRepo)
42
43 data StatusDirection
44 = PortagePlusOverlay
45 | OverlayToPortage
46 | HackageToOverlay
47 deriving Eq
a1730ad @kolmodin Switch to using Cabal's CLI API
kolmodin authored Aug 31, 2008
48
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
49 data FileStatus a
50 = Same a
132b9d4 @kolmodin Keep both ebuilds if they differ
kolmodin authored May 25, 2008
51 | Differs a a
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
52 | OverlayOnly a
53 | PortageOnly a
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
54 | HackageOnly a
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
55 deriving (Show,Eq)
56
57 instance Ord a => Ord (FileStatus a) where
ac9dddd @dcoutts Eliminate redundant Utils module
dcoutts authored Sep 1, 2008
58 compare = comparing fromStatus
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
59
60 instance Functor FileStatus where
61 fmap f st =
62 case st of
63 Same a -> Same (f a)
132b9d4 @kolmodin Keep both ebuilds if they differ
kolmodin authored May 25, 2008
64 Differs a b -> Differs (f a) (f b)
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
65 OverlayOnly a -> OverlayOnly (f a)
66 PortageOnly a -> PortageOnly (f a)
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
67 HackageOnly a -> HackageOnly (f a)
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
68
69 fromStatus :: FileStatus a -> a
70 fromStatus fs =
71 case fs of
72 Same a -> a
132b9d4 @kolmodin Keep both ebuilds if they differ
kolmodin authored May 25, 2008
73 Differs a _ -> a -- second status is lost
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
74 OverlayOnly a -> a
75 PortageOnly a -> a
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
76 HackageOnly a -> a
77
78
79
599de8c @trofi status: hackage packages are now mapped properly to overlay categories
trofi authored Feb 28, 2012
80 loadHackage :: Verbosity -> Distribution.Client.Types.Repo -> Overlay -> IO [[PackageId]]
81 loadHackage verbosity repo overlay = do
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
82 SourcePackageDb { packageIndex = pindex } <- CabalInstall.getSourcePackages verbosity [repo]
599de8c @trofi status: hackage packages are now mapped properly to overlay categories
trofi authored Feb 28, 2012
83 let get_cat cabal_pkg = case resolveCategories overlay (pkgName cabal_pkg) of
84 [cat] -> cat
85 _ -> {- ambig -} Category "dev-haskell"
86 pkg_infos = map ( reverse . take 3 . reverse -- hackage usually has a ton of older versions
87 . map ((\p -> fromCabalPackageId (get_cat p) p)
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
88 . packageInfoId))
89 (CabalInstall.allPackagesByName pindex)
90 return pkg_infos
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
91
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
92 status :: Verbosity -> FilePath -> FilePath -> IO (Map PackageName [FileStatus ExistingEbuild])
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
93 status verbosity portdir overlaydir = do
94 let repo = defaultRepo overlaydir
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
95 overlay <- loadLazy overlaydir
599de8c @trofi status: hackage packages are now mapped properly to overlay categories
trofi authored Feb 28, 2012
96 hackage <- loadHackage verbosity repo overlay
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
97 portage <- filterByHerd ("haskell" `elem`) <$> loadLazy portdir
98 let (over, both, port) = portageDiff (overlayMap overlay) (overlayMap portage)
9448bb7 @kolmodin Rewritten overlayonly functionality
kolmodin authored Aug 13, 2007
99
2ee9bd4 @kolmodin A bit prettier... thanks to sjanssen
kolmodin authored Aug 14, 2007
100 both' <- T.forM both $ mapM $ \e -> liftIO $ do
9448bb7 @kolmodin Rewritten overlayonly functionality
kolmodin authored Aug 13, 2007
101 -- can't fail, we know the ebuild exists in both portagedirs
fe0c291 @kolmodin Fix diff bug
kolmodin authored Aug 14, 2007
102 -- also, one of them is already bound to 'e'
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
103 let (Just e1) = lookupEbuildWith (overlayMap portage) (ebuildId e)
104 (Just e2) = lookupEbuildWith (overlayMap overlay) (ebuildId e)
105 eq <- equals (ebuildPath e1) (ebuildPath e2)
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
106 return $ if eq
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
107 then Same e1
132b9d4 @kolmodin Keep both ebuilds if they differ
kolmodin authored May 25, 2008
108 else Differs e1 e2
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
109
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
110 let p_to_ee :: PackageId -> ExistingEbuild
111 p_to_ee p = ExistingEbuild p cabal_p ebuild_path
112 where Just cabal_p = toCabalPackageId p -- lame doubleconv
113 ebuild_path = packageIdToFilePath p
114 mk_fake_ee :: [PackageId] -> (PackageName, [ExistingEbuild])
115 mk_fake_ee ~pkgs@(p:_) = (packageId p, map p_to_ee pkgs)
116
117 map_diff = Map.differenceWith (\le re -> Just $ foldr (List.deleteBy (equating ebuildId)) le re)
118 hack = ((Map.fromList $ map mk_fake_ee hackage) `map_diff` overlayMap overlay) `map_diff` overlayMap portage
119
120 meld = Map.unionsWith (\a b -> List.sort (a++b))
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
121 [ Map.map (map PortageOnly) port
122 , both'
123 , Map.map (map OverlayOnly) over
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
124 , Map.map (map HackageOnly) hack
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
125 ]
126 return meld
127
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
128 type EMap = Map PackageName [ExistingEbuild]
129
130 lookupEbuildWith :: EMap -> PackageId -> Maybe ExistingEbuild
131 lookupEbuildWith overlay pkgid = do
132 ebuilds <- Map.lookup (packageId pkgid) overlay
133 List.find (\e -> ebuildId e == pkgid) ebuilds
134
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
135 runStatus :: Verbosity -> FilePath -> FilePath -> StatusDirection -> [String] -> IO ()
136 runStatus verbosity portdir overlaydir direction pkgs = do
137 let pkgFilter = case direction of
138 OverlayToPortage -> toPortageFilter
139 PortagePlusOverlay -> id
140 HackageToOverlay -> fromHackageFilter
85f4f4e @kolmodin Die earlier if we can't parse the package name in 'hackport status'
kolmodin authored Aug 3, 2010
141 pkgs' <- forM pkgs $ \p ->
142 case simpleParse p of
143 Nothing -> die ("Could not parse package name: " ++ p ++ ". Format cat/pkg")
144 Just pn -> return pn
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
145 tree0 <- status verbosity portdir overlaydir
fe415df @kolmodin Allow to 'hackport status' by package name
kolmodin authored Oct 4, 2008
146 let tree = pkgFilter tree0
85f4f4e @kolmodin Die earlier if we can't parse the package name in 'hackport status'
kolmodin authored Aug 3, 2010
147 if (null pkgs')
fe415df @kolmodin Allow to 'hackport status' by package name
kolmodin authored Oct 4, 2008
148 then statusPrinter tree
85f4f4e @kolmodin Die earlier if we can't parse the package name in 'hackport status'
kolmodin authored Aug 3, 2010
149 else forM_ pkgs' $ \pkg -> statusPrinter (Map.filterWithKey (\k _ -> k == pkg) tree)
b701c1f @kolmodin Add feature 'status toportage'
kolmodin authored May 25, 2008
150
151 -- |Only return packages that seems interesting to sync to portage;
152 --
153 -- * Ebuild differs, or
154 -- * Newer version in overlay than in portage
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
155 toPortageFilter :: Map PackageName [FileStatus ExistingEbuild] -> Map PackageName [FileStatus ExistingEbuild]
b701c1f @kolmodin Add feature 'status toportage'
kolmodin authored May 25, 2008
156 toPortageFilter = Map.mapMaybe $ \ sts ->
157 let inPortage = flip filter sts $ \st ->
158 case st of
159 OverlayOnly _ -> False
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
160 HackageOnly _ -> False
b701c1f @kolmodin Add feature 'status toportage'
kolmodin authored May 25, 2008
161 _ -> True
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
162 latestPortageVersion = List.maximum $ map (pkgVersion . ebuildId . fromStatus) inPortage
b701c1f @kolmodin Add feature 'status toportage'
kolmodin authored May 25, 2008
163 interestingPackages = flip filter sts $ \st ->
164 case st of
165 Differs _ _ -> True
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
166 _ | pkgVersion (ebuildId (fromStatus st)) > latestPortageVersion -> True
b701c1f @kolmodin Add feature 'status toportage'
kolmodin authored May 25, 2008
167 | otherwise -> False
168 in if not (null inPortage) && not (null interestingPackages)
18d74c7 @kolmodin More interesting to not filter out older/same packages
kolmodin authored May 25, 2008
169 then Just sts
b701c1f @kolmodin Add feature 'status toportage'
kolmodin authored May 25, 2008
170 else Nothing
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
171
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
172 -- |Only return packages that exist in overlay or portage but look outdated
173 fromHackageFilter :: Map PackageName [FileStatus ExistingEbuild] -> Map PackageName [FileStatus ExistingEbuild]
174 fromHackageFilter = Map.mapMaybe $ \ sts ->
175 let inEbuilds = flip filter sts $ \st ->
176 case st of
177 HackageOnly _ -> False
178 _ -> True
a46eb46 @trofi Portage.Version: add 'is_live' helper to distinct live ebuilds
trofi authored Mar 12, 2012
179 -- treat live as oldest version not avoid masking hackage releases
180 mangle_live_versions v
181 | V.is_live v = v {versionNumber=[-1]}
182 | otherwise = v
d058ee8 @trofi status: don't treat live (9999) ebuilds as newer, than hackage's
trofi authored Feb 28, 2012
183 latestVersion = List.maximumBy (compare `on` mangle_live_versions . pkgVersion . ebuildId . fromStatus) sts
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
184 in case latestVersion of
185 HackageOnly _ | not (null inEbuilds) -> Just sts
186 _ -> Nothing
187
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
188 statusPrinter :: Map PackageName [FileStatus ExistingEbuild] -> IO ()
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
189 statusPrinter packages = do
a1730ad @kolmodin Switch to using Cabal's CLI API
kolmodin authored Aug 31, 2008
190 putStrLn $ toColor (Same "Green") ++ ": package in portage and overlay are the same"
191 putStrLn $ toColor (Differs "Yellow" "") ++ ": package in portage and overlay differs"
192 putStrLn $ toColor (OverlayOnly "Red") ++ ": package only exist in the overlay"
193 putStrLn $ toColor (PortageOnly "Magenta") ++ ": package only exist in the portage tree"
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
194 putStrLn $ toColor (HackageOnly "Cyan") ++ ": package only exist on hackage"
a1730ad @kolmodin Switch to using Cabal's CLI API
kolmodin authored Aug 31, 2008
195 forM_ (Map.toAscList packages) $ \(pkg, ebuilds) -> do
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
196 let (PackageName c p) = pkg
197 putStr $ display c ++ '/' : bold (display p)
53f5342 @kolmodin Somewhat better output
kolmodin authored Aug 15, 2007
198 putStr " "
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
199 forM_ ebuilds $ \e -> do
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
200 putStr $ toColor (fmap (display . pkgVersion . ebuildId) e)
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
201 putChar ' '
53f5342 @kolmodin Somewhat better output
kolmodin authored Aug 15, 2007
202 putStrLn ""
2ee9bd4 @kolmodin A bit prettier... thanks to sjanssen
kolmodin authored Aug 14, 2007
203
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
204 toColor :: FileStatus String -> String
205 toColor st = inColor c False Default (fromStatus st)
206 where
207 c = case st of
208 (Same _) -> Green
132b9d4 @kolmodin Keep both ebuilds if they differ
kolmodin authored May 25, 2008
209 (Differs _ _) -> Yellow
f10e33d @kolmodin Clean up Status, separating building status structure from printing
kolmodin authored May 16, 2008
210 (OverlayOnly _) -> Red
211 (PortageOnly _) -> Magenta
dd1447b @trofi hackport status: now it works with hackage!
trofi authored Feb 21, 2012
212 (HackageOnly _) -> Cyan
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
213
214 portageDiff :: EMap -> EMap -> (EMap, EMap, EMap)
53f5342 @kolmodin Somewhat better output
kolmodin authored Aug 15, 2007
215 portageDiff p1 p2 = (in1, ins, in2)
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
216 where ins = Map.filter (not . null) $ Map.intersectionWith (List.intersectBy $ equating ebuildId) p1 p2
87d875b @kolmodin Wall police
kolmodin authored Mar 15, 2008
217 in1 = difference p1 p2
218 in2 = difference p2 p1
219 difference x y = Map.filter (not . null) $
53f5342 @kolmodin Somewhat better output
kolmodin authored Aug 15, 2007
220 Map.differenceWith (\xs ys ->
726e985 @kolmodin Port 'hackport status' to use Portage.Overlay/PackageId instead of P2
kolmodin authored Aug 3, 2010
221 let lst = foldr (List.deleteBy (equating ebuildId)) xs ys in
9448bb7 @kolmodin Rewritten overlayonly functionality
kolmodin authored Aug 13, 2007
222 if null lst
223 then Nothing
224 else Just lst
53f5342 @kolmodin Somewhat better output
kolmodin authored Aug 15, 2007
225 ) x y
9448bb7 @kolmodin Rewritten overlayonly functionality
kolmodin authored Aug 13, 2007
226
227 -- | Compares two ebuilds, returns True if they are equal.
228 -- Disregards comments.
229 equals :: FilePath -> FilePath -> IO Bool
230 equals fp1 fp2 = do
231 f1 <- L.readFile fp1
232 f2 <- L.readFile fp2
233 return (equal' f1 f2)
234
235 equal' :: L.ByteString -> L.ByteString -> Bool
ac9dddd @dcoutts Eliminate redundant Utils module
dcoutts authored Sep 1, 2008
236 equal' = equating essence
9448bb7 @kolmodin Rewritten overlayonly functionality
kolmodin authored Aug 13, 2007
237 where
238 essence = filter (not . isEmpty) . filter (not . isComment) . L.lines
239 isComment = L.isPrefixOf (L.pack "#") . L.dropWhile isSpace
240 isEmpty = L.null . L.dropWhile isSpace
Something went wrong with that request. Please try again.