@@ -1,15 +1,24 @@
1module Main ( main ) where
1module Main ( main ) where
3import Data.List
4import Data.List
5import Data.Version
5import Data.Version
6import Distribution.Text
6import Distribution.Text
7import System.Process
7import System.Process
8import Text.Regex.Posix
8import Text.Regex.Posix
9+import Control.Exception ( assert )
10type Pkg = (String,Version,String) -- (Name, Version, Attribute)
11type Pkg = (String,Version,String) -- (Name, Version, Attribute)
11type Pkgset = [Pkg]
12type Pkgset = [Pkg]
14+comparePkgByVersion :: Pkg -> Pkg -> Ordering -- prefers the latest version
15+comparePkgByVersion (n1,v1,a1) (n2,v2,a2)
16+ | a1 == a2 = assert (n1 == n2) (compare v2 v1)
17+ | otherwise = compare a2 a1
19+comparePkgByName :: Pkg -> Pkg-> Ordering
20+comparePkgByName (n1,_,_) (n2,_,_) = compare (map toLower n1) (map toLower n2)
13parseHaskellPackageName :: String -> Maybe Pkg
22parseHaskellPackageName :: String -> Maybe Pkg
14parseHaskellPackageName name =
23parseHaskellPackageName name =
15 case name `regsubmatch` "^(haskellPackages[^ \t]+)[ \t]+haskell-(.*)-ghc[0-9.]+-(.*)$" of
24 case name `regsubmatch` "^(haskellPackages[^ \t]+)[ \t]+haskell-(.*)-ghc[0-9.]+-(.*)$" of
@@ -21,19 +30,13 @@ parseHaskellPackageName name =
21getHaskellPackageList :: IO Pkgset
30getHaskellPackageList :: IO Pkgset
22getHaskellPackageList = do
31getHaskellPackageList = do
23 allPkgs <- fmap lines (readProcess "bash" ["-c", "exec nix-env -qaP \\* 2>/dev/tty"] "")
32 allPkgs <- fmap lines (readProcess "bash" ["-c", "exec nix-env -qaP \\* 2>/dev/tty"] "")
24− let pkgset = map parseHaskellPackageName allPkgs
33+ return [ p | Just p <- map parseHaskellPackageName allPkgs ]
25− return (sort (nub (catMaybes pkgset)))
27stripProfilingVersions :: Pkgset -> Pkgset
35stripProfilingVersions :: Pkgset -> Pkgset
28−stripProfilingVersions pkgs = [ p | p@(_,_,attr) <- pkgs , not ("ghc[0-9.]+_profiling" =~ attr) ]
36+stripProfilingVersions pkgs = [ p | p@(_,_,attr) <- pkgs , not (attr =~ "ghc[0-9.]+_profiling") ]
30selectLatestVersions :: Pkgset -> Pkgset
38selectLatestVersions :: Pkgset -> Pkgset
31−selectLatestVersions = nubBy f2 . sortBy f1
39+selectLatestVersions = nubBy (\x y -> comparePkgByName x y == EQ) . sortBy comparePkgByVersion
33− f1 (n1,v1,a1) (n2,v2,a2)
34− | n1 == n2 = compare v2 v1
35− | otherwise = compare n1 n2
36− f2 (n1,_,_) (n2,_,_) = n1 == n2
38formatPackageLine :: Pkg -> String
41formatPackageLine :: Pkg -> String
39formatPackageLine (name,version,attr) = show (name, showVersion version, Just url)
42formatPackageLine (name,version,attr) = show (name, showVersion version, Just url)
@@ -47,5 +50,5 @@ regsubmatch buf patt = let (_,_,_,x) = f in x
48main :: IO ()
51main :: IO ()
50− pkgs <- fmap (selectLatestVersions . stripProfilingVersions) getHaskellPackageList
53+ pkgset <- fmap (selectLatestVersions . stripProfilingVersions) getHaskellPackageList
51− mapM_ (putStrLn . formatPackageLine) pkgs
54+ mapM_ (putStrLn . formatPackageLine) (sortBy comparePkgByName pkgset)