1-- Run: cabal build -j hackage2nix && time dist/build/hackage2nix/hackage2nix >hackage-packages.nix && mv hackage-packages.nix ~/.nix-defexpr/pkgs/development/haskell-modules/hackage-packages.nix && nix-env -qaP -A haskellngPackages | tail -1
3module Main ( main ) where
5import Cabal2Nix.Flags ( configureCabalFlags )
6import Cabal2Nix.Generate ( cabal2nix' )
7import Cabal2Nix.Hackage ( readHashedHackage, Hackage )
8import Cabal2Nix.Package
12import Control.Monad.Par.Combinator
13import Control.Monad.Par.IO
14import Control.Monad.Trans ( liftIO )
15import Data.Map.Strict ( Map )
16import qualified Data.Map.Strict as Map
19import Data.Set ( Set )
20import qualified Data.Set as Set
21import Distribution.Compiler
22import Distribution.NixOS.Derivation.Cabal
23import Distribution.NixOS.PackageMap
24import Distribution.NixOS.Util.PrettyPrinting hiding ( attr, (<>) )
25import Distribution.Package
26import Distribution.PackageDescription hiding ( buildDepends, extraLibs, buildTools )
27import Distribution.PackageDescription.Configuration
28import Distribution.System
29import Distribution.Text
30import Distribution.Version
32type Nixpkgs = PackageMap -- Map String (Set [String])
33type PackageSet = Map String Version
34type PackageMultiSet = Map String (Set Version)
36type Constraint = Dependency
38resolveConstraint :: Constraint -> Hackage -> Version
39resolveConstraint c = fromMaybe (error ("constraint " ++ display c ++ " cannot be resolved in Hackage")) .
42resolveConstraint' :: Constraint -> Hackage -> Maybe Version
43resolveConstraint' (Dependency (PackageName name) vrange) hackage | Set.null vs = Nothing
44 | otherwise = Just (Set.findMax vs)
45 where vs = Set.filter (`withinRange` vrange) (Map.keysSet (hackage Map.! name))
49 hackage <- readHashedHackage
50 nixpkgs <- readNixpkgPackageMap -- TODO: nix barfs at the generated "type" attribute for some reason.
51 runParIO (generatePackageSet (Map.delete "type" hackage) nixpkgs)
53generatePackageSet :: Hackage -> Nixpkgs -> ParIO ()
54generatePackageSet hackage nixpkgs = do
56 corePackageSet :: PackageSet
57 corePackageSet = Map.fromList [ (name, v) | PackageIdentifier (PackageName name) v <- corePackages ++ hardCorePackages ]
59 latestVersionSet :: PackageSet
60 latestVersionSet = Map.map (Set.findMax . Map.keysSet) hackage
62 defaultPackageOverridesSet :: PackageSet
63 defaultPackageOverridesSet = Map.fromList [ (name, resolveConstraint c hackage) | c@(Dependency (PackageName name) _) <- defaultPackageOverrides ]
65 generatedDefaultPackageSet :: PackageSet
66 generatedDefaultPackageSet = (defaultPackageOverridesSet `Map.union` latestVersionSet) `Map.difference` corePackageSet
68 latestCorePackageSet :: PackageSet
69 latestCorePackageSet = latestVersionSet `Map.intersection` corePackageSet
71 latestOverridePackageSet :: PackageSet
72 latestOverridePackageSet = latestVersionSet `Map.intersection` defaultPackageOverridesSet
74 extraPackageSet :: PackageMultiSet
75 extraPackageSet = Map.unionsWith Set.union
76 [ Map.singleton name (Set.singleton (resolveConstraint c hackage)) | c@(Dependency (PackageName name) _) <- extraPackages ]
79 db = Map.unionsWith Set.union [ Map.map Set.singleton generatedDefaultPackageSet
80 , Map.map Set.singleton latestCorePackageSet
81 , Map.map Set.singleton latestOverridePackageSet
85 knownAttributesSet :: Set String
86 knownAttributesSet = Set.union (Map.keysSet hackage) (Map.keysSet corePackageSet)
88 resolver :: Dependency -> Bool
89 resolver (Dependency (PackageName name) vrange)
90 | Just v <- Map.lookup name corePackageSet = v `withinRange` vrange
91 | Just v <- Map.lookup name generatedDefaultPackageSet = v `withinRange` vrange
94 liftIO $ do putStrLn "/* hackage-packages.nix is an auto-generated file -- DO NOT EDIT! */"
96 putStrLn "{ pkgs, stdenv, callPackage }:"
100 pkgs <- flip parMapM (Map.toAscList db) $ \(name, vs) -> do
101 defs <- forM (Set.toAscList vs) $ \version -> do
102 srcSpec <- liftIO $ sourceFromHackage Nothing (name ++ "-" ++ display version)
103 let Just cabalFileHash = lookup "x-cabal-file-hash" (customFieldsPD (packageDescription descr))
105 -- TODO: Include list of broken dependencies in the generated output.
106 descr = hackage Map.! name Map.! version
107 (missingDeps, _, drv') = cabal2nix resolver descr
108 drv = drv' { src = srcSpec, editedCabalFile = if revision drv == 0 then "" else cabalFileHash
109 , metaSection = (metaSection drv') { broken = not (Set.null missing) -- Missing Haskell dependencies!
110 , hydraPlatforms = if PackageName name `Set.member` brokenPackages
111 then ["stdenv.lib.platforms.none"]
112 else hydraPlatforms (metaSection drv')
114 , jailbreak = not (null missingDeps) -- Dependency constraints aren't fulfilled
117 missing :: Set String
118 missing = Set.fromList $ filter (`Set.notMember` knownAttributesSet) (buildDepends drv ++ testDepends drv)
120 buildInputs :: Map Attribute (Maybe Path)
121 buildInputs = Map.unions
122 [ Map.fromList [ (n, Nothing) | n <- Set.toList missing ]
123 , Map.fromList [ (n, resolveNixpkgsAttribute nixpkgs n) | n <- Set.toAscList (Set.fromList (extraLibs drv ++ pkgConfDeps drv)) ]
124 , Map.fromList [ (n, resolveNixpkgsOrHackageAttribute nixpkgs hackage n) | n <- Set.toAscList (Set.fromList (buildTools drv)) ]
127 systemOverrides :: Doc
128 systemOverrides = fsep (map (uncurry formatOverride) (Map.toAscList buildInputs))
130 formatOverride :: Attribute -> Maybe Path -> Doc
131 formatOverride n Nothing = space <> text n <> text " = null;" -- missing attribute
132 formatOverride n (Just []) -- Haskell package:
133 | n == name = formatOverride n Nothing -- refers to a missing system library
134 | otherwise = empty -- found by callPackage
135 formatOverride n (Just p) = (text " inherit" <+> parens (text (intercalate "." p)) <+> text n) <> semi
138 overrides = systemOverrides
140 attr | Just v <- Map.lookup name generatedDefaultPackageSet, v == version = name
141 | otherwise = name ++ '_' : [ if c == '.' then '_' else c | c <- display version ]
143 return $ nest 2 $ hang (string attr <+> equals <+> text "callPackage") 2 (parens (pPrint drv)) <+> (braces overrides <> semi)
144 return (intercalate "\n\n" (map render defs))
146 liftIO $ mapM_ (\pkg -> putStrLn pkg >> putStrLn "") pkgs
147 liftIO $ putStrLn "}"
149resolveNixpkgsOrHackageAttribute :: Nixpkgs -> Hackage -> Attribute -> Maybe Path
150resolveNixpkgsOrHackageAttribute nixpkgs hackage name
151 | p@(Just _) <- resolveNixpkgsAttribute nixpkgs name = p
152 | Just _ <- Map.lookup name hackage = Just []
153 | otherwise = Nothing
155resolveNixpkgsAttribute :: Nixpkgs -> Attribute -> Maybe Path
156resolveNixpkgsAttribute nixpkgs name
157 | Just paths <- Map.lookup name nixpkgs = getShortestPath (Set.toList (paths `Set.intersection` goodScopes))
158 | otherwise = Nothing
160 goodScopes :: Set Path
161 goodScopes = Set.fromList [[], ["xlibs"], ["gnome"], ["gnome3"], ["kde4"]]
163 getShortestPath :: [Path] -> Maybe Path
164 getShortestPath [] = Nothing
165 getShortestPath ps = Just ("pkgs" : minimumBy (on compare length) ps)
167-- These packages replace the latest respective version during dependency resolution.
168defaultPackageOverrides :: [Constraint]
169defaultPackageOverrides = map (\s -> fromMaybe (error (show s ++ " is not a valid override selector")) (simpleParse s))
170 [ "mtl == 2.1.*" -- newer versions require transformers > 4, which we cannot provide in GHC 7.8.x
171 , "HStringTemplate < 0.8" -- 0.8 depends on time >= 1.5, which we cannot provide in GHC 7.8.x
174-- These packages are added to the generated set, but the play no role during dependency resolution.
175extraPackages :: [Constraint]
177 map (\s -> fromMaybe (error (show s ++ " is not a valid extra package selector")) (simpleParse s))
178 [ "aeson < 0.8" -- newer versions don't work with GHC 6.12.3
179 , "c2hs < 0.21" -- newer versions cannot compile ncurses
180 , "Cabal == 1.18.*" -- required for cabal-install et al on old GHC versions
181 , "Cabal == 1.20.*" -- required for cabal-install et al on old GHC versions
182 , "containers < 0.5" -- required to build alex with GHC 6.12.3
183 , "deepseq == 1.3.0.1" -- required to build Cabal with GHC 6.12.3
184 , "mtl-prelude < 2" -- required for to build postgrest on mtl 2.1.x platforms
185 , "optparse-applicative == 0.10.*" -- required for elm-make 0.1.1 and elm-package 0.4
186 , "parallel == 3.2.0.3" -- newer versions don't work with GHC 6.12.3
187 , "primitive == 0.5.1.*" -- required to build alex with GHC 6.12.3
188 , "split < 0.2" -- newer versions don't work with GHC 6.12.3
189 , "vector < 0.10.10" -- newer versions don't work with GHC 6.12.3
192cabal2nix :: (Dependency -> Bool) -> GenericPackageDescription -> ([Dependency], FlagAssignment, Derivation)
193cabal2nix resolver cabal = (missingDeps, flags, drv)
195 drv = (cabal2nix' descr) -- { configureFlags = [ "-f" ++ (if b then "" else "-") ++ n | (FlagName n, b) <- flags ] }
197 Right (descr, flags) = finalize (if null missingDeps then resolver else const True) cabal
199 missingDeps :: [Dependency]
200 missingDeps = either id (const []) (finalize resolver cabal')
202 finalize :: (Dependency -> Bool) -> GenericPackageDescription -> Either [Dependency] (PackageDescription, FlagAssignment)
203 finalize resolver' = finalizePackageDescription
204 (configureCabalFlags (package (packageDescription cabal)))
206 (Platform X86_64 Linux) -- shouldn't be hardcoded
207 (CompilerId GHC (Version [7,8,4] [])) -- ditto
208 [] -- no additional constraints
210 -- A variant of the cabal file that has all test suites enabled to ensure
211 -- that their dependencies are recognized by finalizePackageDescription.
212 cabal' :: GenericPackageDescription
213 cabal' = cabal { condTestSuites = flaggedTests }
215 flaggedTests :: [(String, CondTree ConfVar [Dependency] TestSuite)]
216 flaggedTests = map (\(n, t) -> (n, mapTreeData enableTest t)) (condTestSuites cabal)
218 enableTest :: TestSuite -> TestSuite
219 enableTest t = t { testEnabled = True }
221corePackages :: [PackageIdentifier] -- Core packages found on Hackageg
222corePackages = map (\s -> fromMaybe (error (show s ++ " is not a valid core package")) (simpleParse s))
227 , "bytestring-0.10.4.0"
228 , "containers-0.5.5.1"
230 , "directory-1.2.1.0"
233 , "haskeline-0.7.1.2"
234 , "haskell2010-1.1.2.0"
235 , "haskell98-2.0.0.3"
238 , "integer-gmp-0.5.1.0"
239 , "old-locale-1.0.0.6"
243 , "template-haskell-2.9.0.0"
246 , "transformers-0.3.0.0"
251hardCorePackages :: [PackageIdentifier] -- Core packages not found on Hackage.
252hardCorePackages = map (\s -> fromMaybe (error (show s ++ " is not a valid core package")) (simpleParse s))
253 [ "bin-package-db-0.0.0.0"
258-- These packages have not succeeded a build yet, so we give them an
259-- empty meta.hydraPlatforms attribute to avoid cluttering our Hydra
260-- output with lots of broken builds.
261brokenPackages :: Set PackageName
262brokenPackages = Set.fromList $ map PackageName
266 , "abstract-par-accelerate"
268 , "accelerate-cublas"
271 , "accelerate-examples"
274 , "accelerate-fourier-benchmark"
277 , "AC-EasyRaster-GTK"
280 , "acme-numbersystem"
281 , "acme-schoenfinkel"
287 , "adaptive-containers"
292 , "adp-multi-monadiccp"
298 , "AERN-Real-Interval"
310 , "aivika-transformers"
326 , "amazonka-autoscaling"
327 , "amazonka-cloudformation"
328 , "amazonka-cloudfront"
329 , "amazonka-cloudsearch"
330 , "amazonka-cloudsearch-domains"
331 , "amazonka-cloudtrail"
332 , "amazonka-cloudwatch-logs"
333 , "amazonka-codedeploy"
334 , "amazonka-cognito-identity"
335 , "amazonka-cognito-sync"
337 , "amazonka-datapipeline"
338 , "amazonka-directconnect"
339 , "amazonka-dynamodb"
341 , "amazonka-elasticache"
342 , "amazonka-elasticbeanstalk"
343 , "amazonka-elastictranscoder"
347 , "amazonka-importexport"
350 , "amazonka-opsworks"
352 , "amazonka-redshift"
354 , "amazonka-route53-domains"
360 , "amazonka-storagegateway"
369 , "AndroidViewHierarchyImporter"
406 , "atlassian-connect-core"
407 , "atlassian-connect-descriptor"
412 , "attoparsec-iteratee"
414 , "attoparsec-text-enumerator"
427 , "aws-cloudfront-signer"
428 , "aws-elastic-transcoder"
429 , "aws-kinesis-reshard"
430 , "aws-performance-tests"
434 , "azure-service-api"
437 , "backtracking-exceptions"
440 , "bamboo-plugin-highlight"
441 , "bamboo-plugin-photo"
442 , "bamboo-theme-blueprint"
443 , "bamboo-theme-mini-html5"
457 , "bed-and-breakfast"
464 , "bidirectionalization-combined"
469 , "billeksah-services"
472 , "binary-protocol-zmq"
476 , "bindings-apr-util"
492 , "bindings-libstemmer"
494 , "bindings-linux-videodev2"
495 , "bindings-mpdecimal"
507 , "BiobaseTrainingData"
534 , "blaze-html-contrib"
535 , "blaze-html-hexpat"
536 , "blaze-textual-native"
539 , "BlogLiterately-diagrams"
546 , "boolean-normal-forms"
565 , "bytestring-arbitrary"
566 , "bytestring-builder"
570 , "bytestring-rematch"
576 , "cabal-constraints"
580 , "cabal-install-ghc72"
581 , "cabal-install-ghc74"
606 , "casadi-bindings-control"
607 , "casadi-bindings-core"
608 , "casadi-bindings-internal"
609 , "casadi-bindings-ipopt-interface"
610 , "casadi-bindings-snopt-interface"
619 , "categorical-algebra"
625 , "cctools-workqueue"
627 , "cellrenderer-cairo"
628 , "cereal-enumerator"
638 , "chalkboard-viewer"
669 , "clckwrks-plugin-bugs"
670 , "clckwrks-plugin-ircbot"
671 , "clckwrks-plugin-media"
672 , "clckwrks-plugin-page"
673 , "clckwrks-theme-bootstrap"
674 , "clckwrks-theme-clckwrks"
675 , "clckwrks-theme-geo-bootstrap"
684 , "cloudfront-signer"
697 , "cnc-spec-compiler"
699 , "Codec-Image-DevIL"
720 , "computational-algebra"
729 , "conduit-network-stream"
730 , "conduit-resumablesink"
732 , "configuration-tools"
736 , "const-math-ghc-plugin"
737 , "constructive-algebra"
744 , "control-monad-attempt"
745 , "control-monad-exception"
746 , "control-monad-exception-monadsfd"
747 , "control-monad-exception-monadstf"
748 , "control-monad-exception-mtl"
749 , "control-monad-failure"
750 , "control-monad-failure-mtl"
751 , "Control-Monad-MultiPass"
752 , "contstuff-monads-tf"
753 , "contstuff-transformers"
754 , "convertible-ascii"
764 , "coroutine-iteratee"
767 , "couchdb-enumerator"
789 , "crf-chain2-generic"
793 , "crypto-cipher-benchmarks"
794 , "crypto-pubkey-openssh"
825 , "darcs-buildpackage"
828 , "darcs-fastconvert"
866 , "definitive-filesystem"
867 , "definitive-graphics"
868 , "definitive-reactive"
888 , "diagrams-rasterific"
890 , "dice-entropy-conduit"
894 , "DifferentialEvolution"
895 , "digestive-functors-hsp"
907 , "distributed-process-async"
908 , "distributed-process-azure"
909 , "distributed-process-client-server"
910 , "distributed-process-execution"
911 , "distributed-process-extras"
912 , "distributed-process-platform"
913 , "distributed-process-registry"
914 , "distributed-process-supervisor"
915 , "distributed-process-task"
916 , "distributed-process-tests"
917 , "distribution-plot"
920 , "DnaProteinAlignment"
928 , "doctest-discover-configurator"
931 , "download-media-content"
985 , "effective-aspects"
986 , "effective-aspects-mzv"
990 , "eibd-client-simple"
1002 , "embeddock-example"
1028 , "Eternal10Seconds"
1030 , "ethereum-client-haskell"
1031 , "ethereum-merkle-patricia-db"
1036 , "every-bit-counts"
1040 , "expat-enumerator"
1042 , "explicit-sharing"
1044 , "exposed-containers"
1048 , "extended-categories"
1072 , "feldspar-compiler"
1073 , "feldspar-language"
1076 , "FermatsLastMargin"
1079 , "ffmpeg-tutorials"
1087 , "filesystem-conduit"
1088 , "Finance-Quote-Yahoo"
1089 , "Finance-Treasury"
1092 , "first-class-patterns"
1094 , "FirstOrderTheory"
1098 , "fixed-point-vector"
1099 , "fixed-point-vector-space"
1101 , "fixed-storable-array"
1102 , "fix-parser-simple"
1103 , "fix-symbols-gitit"
1105 , "flexiwrap-smallcheck"
1114 , "foldl-incremental"
1119 , "font-opengl-basic4x6"
1137 , "free-operational"
1140 , "free-theorems-counterexamples"
1141 , "free-theorems-seq"
1142 , "free-theorems-seq-webui"
1143 , "free-theorems-webui"
1153 , "full-text-search"
1154 , "functional-arrow"
1155 , "function-combine"
1168 , "gc-monitoring-wai"
1175 , "genericserialize"
1176 , "generic-storable"
1187 , "GeomPredicates-SSE"
1193 , "ghc-events-analyze"
1194 , "ghc-generic-instances"
1218 , "gladexml-accessor"
1224 , "gloss-accelerate"
1226 , "gloss-raster-accelerate"
1236 , "GoogleDirections"
1237 , "google-html5-slide"
1246 , "GPipe-TextureLoad"
1251 , "grammar-combinators"
1253 , "grapefruit-ui-gtk"
1254 , "GraphHammer-examples"
1256 , "graphics-formats-collada"
1258 , "graph-rewriting-cl"
1259 , "graph-rewriting-lambdascope"
1281 , "gtk2hs-cast-glade"
1282 , "gtk2hs-cast-gnomevfs"
1284 , "gtk2hs-cast-gtkglext"
1285 , "gtk2hs-cast-gtksourceview2"
1290 , "gtk3-mac-integration"
1295 , "gtk-largeTreeStore"
1296 , "gtk-mac-integration"
1298 , "gtk-serialized-event"
1299 , "gtk-simple-list-view"
1302 , "gtk-toggle-button-list"
1306 , "guess-combinator"
1313 , "hack2-contrib-extra"
1314 , "hack2-handler-happstack-server"
1315 , "hack2-handler-mongrel2-http"
1316 , "hack2-handler-warp"
1317 , "hack2-interface-wai"
1325 , "hack-contrib-press"
1327 , "hack-frontend-happstack"
1328 , "hack-frontend-monadcgi"
1329 , "hack-handler-epoll"
1330 , "hack-handler-evhttp"
1331 , "hack-handler-fastcgi"
1332 , "hack-handler-happstack"
1333 , "hack-handler-hyena"
1334 , "hack-handler-kibro"
1335 , "hack-handler-simpleserver"
1336 , "hack-middleware-clientsession"
1337 , "hack-middleware-jsonp"
1345 , "hakyll-blaze-templates"
1347 , "hakyll-contrib-links"
1363 , "happs-hsp-template"
1368 , "happstack-clientsession"
1369 , "happstack-contrib"
1372 , "happstack-facebook"
1373 , "happstack-fastcgi"
1375 , "happstack-fay-ajax"
1376 , "happstack-foundation"
1378 , "happstack-helpers"
1381 , "happstack-monad-peel"
1382 , "happstack-plugins"
1389 , "happybara-webkit"
1390 , "happybara-webkit-server"
1406 , "hashable-generics"
1419 , "haskell-brainfuck"
1421 , "haskelldb-dynamic"
1422 , "haskelldb-hdbc-mysql"
1424 , "haskelldb-hsql-mysql"
1425 , "haskelldb-hsql-odbc"
1426 , "haskelldb-hsql-postgresql"
1427 , "haskelldb-hsql-sqlite3"
1430 , "haskell-formatter"
1433 , "haskell-neo4j-client"
1436 , "haskell-openflow"
1437 , "haskell-pdf-presenter"
1438 , "haskell-platform-test"
1443 , "haskell-spacegoo"
1444 , "haskell-src-meta-mwotton"
1445 , "haskell-token-utils"
1447 , "haskell-type-exts"
1458 , "haskoon-httpspec"
1460 , "haskore-supercollider"
1461 , "haskore-synthesizer"
1468 , "hasql-postgres-options"
1497 , "hdaemonize-buildfix"
1523 , "her-lexer-parsec"
1533 , "hexpat-pickle-generic"
1544 , "HGamer3D-CAudio-Binding"
1545 , "HGamer3D-CEGUI-Binding"
1546 , "HGamer3D-Enet-Binding"
1547 , "HGamer3D-Graphics3D"
1549 , "HGamer3D-InputSystem"
1550 , "HGamer3D-Network"
1551 , "HGamer3D-Ogre-Binding"
1552 , "HGamer3D-OIS-Binding"
1553 , "HGamer3D-SDL2-Binding"
1554 , "HGamer3D-SFML-Binding"
1555 , "HGamer3D-WinEvent"
1567 , "hierarchical-clustering"
1568 , "hierarchical-clustering-diagrams"
1577 , "hinduce-classifier"
1578 , "hinduce-classifier-decisiontree"
1579 , "hinduce-examples"
1593 , "HLearn-approximation"
1594 , "HLearn-classification"
1595 , "HLearn-datastructures"
1596 , "HLearn-distributions"
1609 , "hmatrix-gsl-stats"
1610 , "hmatrix-quadprogpp"
1633 , "Holumbus-Distribution"
1634 , "Holumbus-MapReduce"
1635 , "Holumbus-Searchengine"
1636 , "Holumbus-Storage"
1706 , "hsc3-sf-hsndfile"
1710 , "hs-carbon-examples"
1715 , "hscurses-fish-ex"
1746 , "hsndfile-storablevector"
1755 , "hspec-expectations-pretty"
1756 , "hspec-experimental"
1759 , "hspec-test-sandbox"
1767 , "hsqml-demo-morris"
1768 , "hsqml-demo-notes"
1769 , "hsqml-demo-samples"
1780 , "hs-twitterarchiver"
1798 , "http-client-request-modifiers"
1799 , "http-conduit-browser"
1805 , "https-everywhere-rules"
1852 , "ige-mac-integration"
1856 , "ihaskell-diagrams"
1864 , "ImperativeHaskell"
1870 , "indian-language-font-converter"
1874 , "InfixApplicative"
1881 , "interleavableGen"
1884 , "interpolatedstring-qq"
1885 , "interpolatedstring-qq-mwotton"
1894 , "iptables-helpers"
1902 , "iteratee-compress"
1916 , "ivory-quickcheck"
1930 , "jmacro-rpc-happstack"
1946 , "JSON-Combinator-Examples"
1950 , "JunkDB-driver-gdbm"
1954 , "kansas-lava-cores"
1955 , "kansas-lava-papilio"
1956 , "kansas-lava-shake"
1963 , "kickass-torrents-dump-parser"
1971 , "koellner-phonetic"
1975 , "kure-your-boilerplate"
1980 , "labyrinth-server"
1986 , "lambdacube-bullet"
1987 , "lambdacube-engine"
1988 , "lambdacube-examples"
1992 , "LambdaPrettyQuote"
1999 , "language-c-comments"
2002 , "language-java-classfile"
2005 , "language-python-colour"
2007 , "language-spelling"
2011 , "latest-npm-version"
2012 , "launchpad-control"
2016 , "layout-bootstrap"
2023 , "learn-physics-examples"
2028 , "leveldb-haskell-fork"
2034 , "libarchive-conduit"
2047 , "libsystemd-daemon"
2054 , "lighttpd-conf-qq"
2057 , "linear-algebra-cblas"
2069 , "listlike-instances"
2079 , "llvm-data-interop"
2082 , "llvm-general-pure"
2083 , "llvm-general-quote"
2094 , "LogicGrowsOnTrees"
2095 , "LogicGrowsOnTrees-MPI"
2096 , "LogicGrowsOnTrees-network"
2097 , "LogicGrowsOnTrees-processes"
2122 , "mailchimp-subscribe"
2126 , "manatee-anything"
2131 , "manatee-filemanager"
2132 , "manatee-imageviewer"
2133 , "manatee-ircclient"
2135 , "manatee-pdfviewer"
2136 , "manatee-processmanager"
2138 , "manatee-template"
2139 , "manatee-terminal"
2147 , "markov-processes"
2158 , "MaybeT-monads-tf"
2172 , "meta-par-accelerate"
2200 , "modular-prelude-classy"
2201 , "module-management"
2207 , "MonadCatchIO-mtl-foreign"
2208 , "MonadCatchIO-transformers-foreign"
2211 , "monadiccp-gecode"
2212 , "monad-interleave"
2220 , "mongrel2-handler"
2243 , "multiplate-simplified"
2244 , "multirec-alt-deriver"
2248 , "musicbrainz-email"
2260 , "mysnapsession-example"
2264 , "mysql-simple-quasi"
2265 , "mysql-simple-typed"
2287 , "network-bytestring"
2288 , "network-connection"
2289 , "network-minihttp"
2293 , "network-simple-sockaddr"
2294 , "network-simple-tls"
2295 , "network-topic-models"
2296 , "network-websocket"
2314 , "not-gloss-examples"
2337 , "ois-input-manager"
2347 , "openexchangerates"
2353 , "openpgp-crypto-api"
2354 , "opensoundcontrol-ht"
2357 , "opentheory-parser"
2358 , "opentheory-prime"
2359 , "opentheory-primitive"
2386 , "parameterized-data"
2388 , "parco-attoparsec"
2389 , "parconc-examples"
2404 , "pdf-toolbox-viewer"
2417 , "persistent-hssqlppp"
2419 , "persistent-mysql"
2420 , "persistent-protobuf"
2422 , "persistent-vector"
2423 , "persistent-zookeeper"
2440 , "pipes-cereal-plus"
2442 , "pipes-network-tls"
2444 , "pipes-p2p-examples"
2461 , "pointless-lenses"
2462 , "pointless-rewrite"
2466 , "polytypeable-utils"
2467 , "pontarius-mediaserver"
2480 , "postgresql-binary"
2481 , "postgresql-simple-typed"
2482 , "postgresql-typed"
2494 , "PriorityChansConverger"
2496 , "ProbabilityMonads"
2499 , "process-progress"
2501 , "procrastinating-structure"
2502 , "procrastinating-variable"
2505 , "profunctor-extras"
2510 , "proj4-hs-bindings"
2512 , "prolog-graph-lib"
2517 , "prove-everywhere-server"
2520 , "publicsuffixlistcreate"
2535 , "push-notify-general"
2538 , "puzzle-draw-cmdline"
2544 , "querystring-pickle"
2550 , "quickcheck-regex"
2551 , "quickcheck-relaxng"
2552 , "quickcheck-rematch"
2557 , "radium-formula-parser"
2558 , "rail-compiler-editor"
2571 , "raven-haskell-scotty"
2578 , "reactive-banana-sdl"
2579 , "reactive-banana-threepenny"
2580 , "reactive-banana-wx"
2581 , "reactive-fieldtrip"
2586 , "readline-statevar"
2587 , "really-simple-xml-parser"
2589 , "recursive-line-count"
2594 , "reflection-extras"
2605 , "regional-pointers"
2607 , "regions-monadsfd"
2608 , "regions-monadstf"
2614 , "relational-postgresql8"
2615 , "relational-query"
2616 , "relational-query-HDBC"
2617 , "relational-record"
2618 , "relational-record-examples"
2619 , "relational-schemas"
2634 , "representable-functors"
2635 , "representable-profunctors"
2636 , "representable-tries"
2642 , "restricted-workers"
2643 , "rethinkdb-client-driver"
2650 , "ripple-federation"
2661 , "roguestar-engine"
2664 , "RollingDirectory"
2686 , "safe-failure-cme"
2692 , "safer-file-handles"
2693 , "safer-file-handles-bytestring"
2694 , "safer-file-handles-text"
2701 , "salvia-websocket"
2702 , "samtools-iteratee"
2705 , "satchmo-backends"
2706 , "satchmo-examples"
2712 , "scan-vector-machine"
2749 , "semigroupoid-extras"
2750 , "semigroups-actions"
2755 , "seqloc-datafiles"
2758 , "servant-postgresql"
2762 , "ses-html-snaplet"
2777 , "shakespeare-i18n"
2782 , "Shellac-compatline"
2783 , "Shellac-editline"
2784 , "Shellac-readline"
2795 , "simple-bluetooth"
2804 , "simple-log-syslog"
2806 , "simple-postgresql-orm"
2811 , "simple-templates"
2831 , "snaplet-actionlog"
2833 , "snaplet-auth-acid"
2834 , "snaplet-environments"
2839 , "snaplet-mongodb-minimalistic"
2840 , "snaplet-mysql-simple"
2842 , "snaplet-persistent"
2846 , "snaplet-ses-html"
2852 , "sndfile-enumerators"
2866 , "sonic-visualiser"
2869 , "source-code-server"
2878 , "special-functors"
2881 , "speculation-transformers"
2891 , "sqlite-simple-typed"
2893 , "sql-simple-mysql"
2895 , "sql-simple-postgresql"
2896 , "sql-simple-sqlite"
2904 , "standalone-haddock"
2907 , "statistics-dirichlet"
2908 , "statistics-fusion"
2911 , "stm-chunked-queues"
2917 , "storable-static-array"
2919 , "storablevector-carray"
2920 , "storablevector-streamfusion"
2921 , "Strafunski-Sdf2Haskell"
2922 , "StrappedTemplates"
2925 , "strict-concurrency"
2929 , "structural-induction"
2930 , "structured-haskell-mode"
2931 , "structured-mongoDB"
2934 , "sunroof-compiler"
2935 , "sunroof-examples"
2937 , "supercollider-ht"
2938 , "supercollider-midi"
2951 , "synchronous-channels"
2956 , "synthesizer-alsa"
2957 , "synthesizer-core"
2958 , "synthesizer-dimensional"
2959 , "synthesizer-llvm"
2960 , "synthesizer-midi"
2963 , "system-random-effect"
2978 , "tamarin-prover-term"
2979 , "tamarin-prover-theory"
2980 , "tamarin-prover-utils"
2995 , "test-framework-doctest"
2996 , "test-framework-quickcheck"
2997 , "test-framework-sandbox"
3003 , "test-sandbox-hunit"
3004 , "test-sandbox-quickcheck"
3012 , "text-show-instances"
3013 , "text-xml-generic"
3018 , "theoremquest-client"
3021 , "th-instance-reification"
3049 , "tokyocabinet-haskell"
3053 , "to-string-instances"
3057 , "transactional-events"
3059 , "transformers-convert"
3060 , "transformers-runnable"
3063 , "treemap-html-tools"
3070 , "tsession-happstack"
3074 , "twentefp-rosetree"
3085 , "twitter-enumerator"
3088 , "twitter-types-lens"
3097 , "type-equality-check"
3102 , "typelevel-tensor"
3104 , "type-ord-spine-cereal"
3119 , "unbounded-delays-units"
3120 , "unboxed-containers"
3122 , "unicode-normalization"
3127 , "unix-process-conduit"
3130 , "unordered-containers-rematch"
3139 , "uri-enumerator-file"
3143 , "urldisp-happstack"
3151 , "uvector-algorithms"
3163 , "vector-bytestring"
3166 , "vector-functorlazy"
3168 , "vector-read-instances"
3177 , "visual-graphrewrite"
3190 , "wai-frontend-monadcgi"
3192 , "wai-handler-devel"
3193 , "wai-handler-snap"
3194 , "wai-handler-webkit"
3198 , "wai-logger-prefork"
3199 , "wai-middleware-cache"
3200 , "wai-middleware-cache-redis"
3201 , "wai-middleware-catch"
3202 , "wai-middleware-etag"
3203 , "wai-middleware-headers"
3204 , "wai-middleware-route"
3206 , "wai-session-tokyocabinet"
3207 , "wai-static-pages"
3216 , "WebBits-multiplate"
3217 , "web-browser-in-haskell"
3223 , "webkitgtk3-javascriptcore"
3224 , "webkit-javascriptcore"
3227 , "web-routes-quasi"
3228 , "web-routes-transformers"
3240 , "Win32-dhcp-server"
3243 , "Win32-junction-point"
3246 , "Win32-services-wrapper"
3251 , "wl-pprint-terminfo"
3265 , "wumpus-microprint"
3289 , "xhaskell-library"
3302 , "xml-enumerator-combinators"
3311 , "xmms2-client-glib"
3312 , "xmonad-contrib-bluetilebranch"
3314 , "xmonad-screenshot"
3326 , "yahoo-web-search"
3335 , "yesod-auth-bcrypt"
3338 , "yesod-auth-smbclient"
3340 , "yesod-continuations"
3341 , "yesod-datatables"
3343 , "yesod-eventsource"
3349 , "yesod-pagination"
3355 , "yesod-session-redis"
3356 , "yesod-static-angular"
3373 , "Yogurt-Standalone"
3394 , "zoom-cache-sndfile"
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list