1{-# LANGUAGE PatternGuards, CPP #-}
3module Main ( main ) where
6 I use the following shell script to re-build "hackage-packages.nix":
13 | make --quiet cabal2nix.cabal
14 | cabal build -j hackage2nix
15 | time dist/build/hackage2nix/hackage2nix >hackage-packages.nix
16 | mv hackage-packages.nix ~/.nix-defexpr/pkgs/development/haskell-modules/hackage-packages.nix
17 | nix-env -qaP -A haskellngPackages | tail -1
19 Make sure that "nix-env -qaP" shows the top-level Nixpkgs attributes at the
20 top level, i.e. without any prefix like "nixos.pkgs". Otherwise, the code
21 that resolver in Distribution/Nixpkgs/PackageMap.hs will produce bogus
25-- 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
27import Cabal2Nix.Flags ( configureCabalFlags )
28import Cabal2Nix.Generate ( cabal2nix' )
29import Cabal2Nix.Hackage ( readHashedHackage, Hackage )
30import Cabal2Nix.Package
34import Control.Monad.Par.Combinator
35import Control.Monad.Par.IO
36import Control.Monad.Trans ( liftIO )
37import Data.Map.Strict ( Map )
38import qualified Data.Map.Strict as Map
41import Data.Set ( Set )
42import qualified Data.Set as Set
43import Distribution.Compiler
44import Distribution.Nixpkgs.Haskell
45import Distribution.Nixpkgs.PackageMap
46import Distribution.Nixpkgs.Util.PrettyPrinting hiding ( attr, (<>) )
47import Distribution.Package
48import Distribution.PackageDescription hiding ( buildDepends, extraLibs, buildTools )
49import Distribution.PackageDescription.Configuration
50import Distribution.System
51import Distribution.Text
52import Distribution.Version
54type Nixpkgs = PackageMap -- Map String (Set [String])
55type PackageSet = Map String Version
56type PackageMultiSet = Map String (Set Version)
58type Constraint = Dependency
60resolveConstraint :: Constraint -> Hackage -> Version
61resolveConstraint c = fromMaybe (error ("constraint " ++ display c ++ " cannot be resolved in Hackage")) .
64resolveConstraint' :: Constraint -> Hackage -> Maybe Version
65resolveConstraint' (Dependency (PackageName name) vrange) hackage | Set.null vs = Nothing
66 | otherwise = Just (Set.findMax vs)
67 where vs = Set.filter (`withinRange` vrange) (Map.keysSet (hackage Map.! name))
69data Configuration = Configuration
71 -- |Target architecture. Used by 'finalizePackageDescription' to
72 -- choose appropriate flags and dependencies.
75 -- |Target compiler. Used by 'finalizePackageDescription' to choose
76 -- appropriate flags and dependencies.
77 , compilerId :: CompilerId
79 -- |Core packages found on Hackageg
80 , corePackages :: [PackageIdentifier]
82 -- |Core packages not found on Hackage.
83 , hardCorePackages :: [PackageIdentifier]
85 -- |These packages replace the latest respective version during
86 -- dependency resolution.
87 , defaultPackageOverrides :: [Constraint]
89 -- |These packages are added to the generated set, but the play no
90 -- role during dependency resolution.
91 , extraPackages :: [Constraint]
93 -- |These packages have not succeeded a build yet, so we give them an
94 -- empty meta.hydraPlatforms attribute to avoid cluttering our Hydra
95 -- output with lots of broken builds.
96 , brokenPackages :: Set PackageName
102 hackage <- readHashedHackage
103 nixpkgs <- readNixpkgPackageMap -- TODO: nix barfs at the generated "type" attribute for some reason.
104 runParIO (generatePackageSet defaultConfiguration (Map.delete "type" hackage) nixpkgs)
106generatePackageSet :: Configuration -> Hackage -> Nixpkgs -> ParIO ()
107generatePackageSet config hackage nixpkgs = do
109 corePackageSet :: PackageSet
110 corePackageSet = Map.fromList [ (name, v) | PackageIdentifier (PackageName name) v <- corePackages config ++ hardCorePackages config ]
112 latestVersionSet :: PackageSet
113 latestVersionSet = Map.map (Set.findMax . Map.keysSet) hackage
115 defaultPackageOverridesSet :: PackageSet
116 defaultPackageOverridesSet = Map.fromList [ (name, resolveConstraint c hackage) | c@(Dependency (PackageName name) _) <- defaultPackageOverrides config ]
118 generatedDefaultPackageSet :: PackageSet
119 generatedDefaultPackageSet = (defaultPackageOverridesSet `Map.union` latestVersionSet) `Map.difference` corePackageSet
121 latestCorePackageSet :: PackageSet
122 latestCorePackageSet = latestVersionSet `Map.intersection` corePackageSet
124 latestOverridePackageSet :: PackageSet
125 latestOverridePackageSet = latestVersionSet `Map.intersection` defaultPackageOverridesSet
127 extraPackageSet :: PackageMultiSet
128 extraPackageSet = Map.unionsWith Set.union
129 [ Map.singleton name (Set.singleton (resolveConstraint c hackage)) | c@(Dependency (PackageName name) _) <- extraPackages config ]
131 db :: PackageMultiSet
132 db = Map.unionsWith Set.union [ Map.map Set.singleton generatedDefaultPackageSet
133 , Map.map Set.singleton latestCorePackageSet
134 , Map.map Set.singleton latestOverridePackageSet
138 knownAttributesSet :: Set String
139 knownAttributesSet = Set.union (Map.keysSet hackage) (Map.keysSet corePackageSet)
141 resolver :: Dependency -> Bool
142 resolver (Dependency (PackageName name) vrange)
143 | Just v <- Map.lookup name corePackageSet = v `withinRange` vrange
144 | Just v <- Map.lookup name generatedDefaultPackageSet = v `withinRange` vrange
147 liftIO $ do putStrLn "/* hackage-packages.nix is an auto-generated file -- DO NOT EDIT! */"
149 putStrLn "{ pkgs, stdenv, callPackage }:"
153 pkgs <- flip parMapM (Map.toAscList db) $ \(name, vs) -> do
154 defs <- forM (Set.toAscList vs) $ \version -> do
155 srcSpec <- liftIO $ sourceFromHackage Nothing (name ++ "-" ++ display version)
156 let Just cabalFileHash = lookup "x-cabal-file-hash" (customFieldsPD (packageDescription descr))
158 -- TODO: Include list of broken dependencies in the generated output.
159 descr = hackage Map.! name Map.! version
160 (missingDeps, _, drv') = cabal2nix resolver descr
161 drv = drv' { src = srcSpec, editedCabalFile = if revision drv == 0 then "" else cabalFileHash
162 , metaSection = (metaSection drv') { broken = not (Set.null missing) -- Missing Haskell dependencies!
163 , hydraPlatforms = if PackageName name `Set.member` brokenPackages config
164 then Set.singleton "stdenv.lib.platforms.none"
165 else hydraPlatforms (metaSection drv')
167 , jailbreak = not (null missingDeps) -- Dependency constraints aren't fulfilled
170 missing :: Set String
171 missing = Set.filter (`Set.notMember` knownAttributesSet) (buildDepends drv `Set.union` testDepends drv)
173 buildInputs :: Map Attribute (Maybe Path)
174 buildInputs = Map.unions
175 [ Map.fromList [ (n, Nothing) | n <- Set.toList missing ]
176 , Map.fromList [ (n, resolveNixpkgsAttribute nixpkgs n) | n <- Set.toAscList (extraLibs drv `Set.union` pkgConfDeps drv) ]
177 , Map.fromList [ (n, resolveNixpkgsOrHackageAttribute nixpkgs hackage n) | n <- Set.toAscList (buildTools drv) ]
180 systemOverrides :: Doc
181 systemOverrides = fsep (map (uncurry formatOverride) (Map.toAscList buildInputs))
183 formatOverride :: Attribute -> Maybe Path -> Doc
184 formatOverride n Nothing = space <> text n <> text " = null;" -- missing attribute
185 formatOverride n (Just []) -- Haskell package:
186 | n == name = formatOverride n Nothing -- refers to a missing system library
187 | otherwise = empty -- found by callPackage
188 formatOverride n (Just p) = (text " inherit" <+> parens (text (intercalate "." p)) <+> text n) <> semi
191 overrides = systemOverrides
193 attr | Just v <- Map.lookup name generatedDefaultPackageSet, v == version = name
194 | otherwise = name ++ '_' : [ if c == '.' then '_' else c | c <- display version ]
196 return $ nest 2 $ hang (string attr <+> equals <+> text "callPackage") 2 (parens (pPrint drv)) <+> (braces overrides <> semi)
197 return (intercalate "\n\n" (map render defs))
199 liftIO $ mapM_ (\pkg -> putStrLn pkg >> putStrLn "") pkgs
200 liftIO $ putStrLn "}"
202resolveNixpkgsOrHackageAttribute :: Nixpkgs -> Hackage -> Attribute -> Maybe Path
203resolveNixpkgsOrHackageAttribute nixpkgs hackage name
204 | p@(Just _) <- resolveNixpkgsAttribute nixpkgs name = p
205 | Just _ <- Map.lookup name hackage = Just []
206 | otherwise = Nothing
208resolveNixpkgsAttribute :: Nixpkgs -> Attribute -> Maybe Path
209resolveNixpkgsAttribute nixpkgs name
210 | Just paths <- Map.lookup name nixpkgs = getShortestPath (Set.toList (paths `Set.intersection` goodScopes))
211 | otherwise = Nothing
213 goodScopes :: Set Path
214 goodScopes = Set.fromList [[], ["xlibs"], ["gnome"], ["gnome3"], ["kde4"]]
216 getShortestPath :: [Path] -> Maybe Path
217 getShortestPath [] = Nothing
218 getShortestPath ps = Just ("pkgs" : minimumBy (on compare length) ps)
220cabal2nix :: (Dependency -> Bool) -> GenericPackageDescription -> ([Dependency], FlagAssignment, Derivation)
221cabal2nix resolver cabal = (missingDeps, flags, drv)
223 drv = cabal2nix' descr
225 Right (descr, flags) = finalize (if null missingDeps then resolver else const True) cabal
227 missingDeps :: [Dependency]
228 missingDeps = either id (const []) (finalize resolver cabal')
230 finalize :: (Dependency -> Bool) -> GenericPackageDescription -> Either [Dependency] (PackageDescription, FlagAssignment)
231 finalize resolver' = finalizePackageDescription
232 (configureCabalFlags (package (packageDescription cabal)))
234 (Platform X86_64 Linux) -- shouldn't be hardcoded
235#if MIN_VERSION_Cabal(1,22,0)
236 (unknownCompilerInfo (CompilerId GHC (Version [7,8,4] [])) NoAbiTag)
238 (CompilerId GHC (Version [7,8,4] []))
240 [] -- no additional constraints
242 -- A variant of the cabal file that has all test suites enabled to ensure
243 -- that their dependencies are recognized by finalizePackageDescription.
244 cabal' :: GenericPackageDescription
245 cabal' = cabal { condTestSuites = flaggedTests }
247 flaggedTests :: [(String, CondTree ConfVar [Dependency] TestSuite)]
248 flaggedTests = map (\(n, t) -> (n, mapTreeData enableTest t)) (condTestSuites cabal)
250 enableTest :: TestSuite -> TestSuite
251 enableTest t = t { testEnabled = True }
253defaultConfiguration :: Configuration
254defaultConfiguration = Configuration
255 { platform = Platform X86_64 Linux
257 , compilerId = CompilerId GHC (Version [7,8,4] [])
259 , defaultPackageOverrides = map (\s -> fromMaybe (error (show s ++ " is not a valid override selector")) (simpleParse s))
260 [ "blaze-builder < 0.4" -- the new version breaks many builds, like streaming-commons
261 , "control-monad-free < 0.6" -- newer versions don't compile with anything but GHC 7.8.x
262 , "HStringTemplate < 0.8" -- 0.8 depends on time >= 1.5, which we cannot provide in GHC 7.8.x
263 , "mtl == 2.1.*" -- newer versions require transformers > 0.4.x, which we cannot provide in GHC 7.8.x
264 , "QuickCheck < 2.8" -- 2.8 breaks chell-quickcheck-0.2.4
265 , "utf8-string < 1" -- version 1 breaks several packages right now, most notably hint
268 , corePackages = map (\s -> fromMaybe (error (show s ++ " is not a valid core package")) (simpleParse s))
273 , "bytestring-0.10.4.0"
274 , "containers-0.5.5.1"
276 , "directory-1.2.1.0"
279 , "haskeline-0.7.1.2"
280 , "haskell2010-1.1.2.0"
281 , "haskell98-2.0.0.3"
284 , "integer-gmp-0.5.1.0"
285 , "old-locale-1.0.0.6"
289 , "template-haskell-2.9.0.0"
292 , "transformers-0.3.0.0"
297 , hardCorePackages = map (\s -> fromMaybe (error (show s ++ " is not a valid core package")) (simpleParse s))
298 [ "bin-package-db-0.0.0.0"
303 , extraPackages = map (\s -> fromMaybe (error (show s ++ " is not a valid extra package selector")) (simpleParse s))
304 [ "aeson < 0.8" -- newer versions don't work with GHC 6.12.3
305 , "c2hs < 0.21" -- newer versions cannot compile ncurses
306 , "Cabal == 1.18.*" -- required for cabal-install et al on old GHC versions
307 , "Cabal == 1.20.*" -- required for cabal-install et al on old GHC versions
308 , "containers < 0.5" -- required to build alex with GHC 6.12.3
309 , "deepseq == 1.3.0.1" -- required to build Cabal with GHC 6.12.3
310 , "descriptive < 0.1" -- required for structured-haskell-mode-1.0.8
311 , "haskell-src-exts < 1.16" -- required for structured-haskell-mode-1.0.8
312 , "mtl-prelude < 2" -- required for to build postgrest on mtl 2.1.x platforms
313 , "optparse-applicative == 0.10.*" -- required for elm-make 0.1.1 and elm-package 0.4
314 , "parallel == 3.2.0.3" -- newer versions don't work with GHC 6.12.3
315 , "primitive == 0.5.1.*" -- required to build alex with GHC 6.12.3
316 , "QuickCheck < 2" -- required by test-framework-quickcheck and its users
317 , "seqid < 0.2" -- newer versions depend on transformers 0.4.x which we cannot provide in GHC 7.8.x
318 , "seqid-streams < 0.2" -- newer versions depend on transformers 0.4.x which we cannot provide in GHC 7.8.x
319 , "split < 0.2" -- newer versions don't work with GHC 6.12.3
320 , "vector < 0.10.10" -- newer versions don't work with GHC 6.12.3
323 , brokenPackages = Set.fromList $ map PackageName
327 , "abstract-par-accelerate"
329 , "accelerate-cublas"
332 , "accelerate-examples"
335 , "accelerate-fourier-benchmark"
338 , "AC-EasyRaster-GTK"
341 , "acme-numbersystem"
342 , "acme-schoenfinkel"
348 , "adaptive-containers"
353 , "adp-multi-monadiccp"
359 , "AERN-Real-Interval"
370 , "aivika-transformers"
384 , "amazonka-autoscaling"
385 , "amazonka-cloudformation"
386 , "amazonka-cloudfront"
387 , "amazonka-cloudhsm"
388 , "amazonka-cloudsearch"
389 , "amazonka-cloudsearch-domains"
390 , "amazonka-cloudtrail"
391 , "amazonka-cloudwatch-logs"
392 , "amazonka-codedeploy"
393 , "amazonka-cognito-identity"
394 , "amazonka-cognito-sync"
396 , "amazonka-datapipeline"
397 , "amazonka-directconnect"
398 , "amazonka-dynamodb"
400 , "amazonka-elasticache"
401 , "amazonka-elasticbeanstalk"
402 , "amazonka-elastictranscoder"
406 , "amazonka-importexport"
409 , "amazonka-opsworks"
411 , "amazonka-redshift"
413 , "amazonka-route53-domains"
419 , "amazonka-storagegateway"
427 , "AndroidViewHierarchyImporter"
464 , "atlassian-connect-core"
465 , "atlassian-connect-descriptor"
470 , "attoparsec-iteratee"
472 , "attoparsec-text-enumerator"
483 , "aws-cloudfront-signer"
484 , "aws-elastic-transcoder"
485 , "aws-kinesis-reshard"
489 , "azure-service-api"
491 , "backtracking-exceptions"
494 , "bamboo-plugin-highlight"
495 , "bamboo-plugin-photo"
496 , "bamboo-theme-blueprint"
497 , "bamboo-theme-mini-html5"
511 , "bed-and-breakfast"
518 , "bidirectionalization-combined"
523 , "billeksah-services"
526 , "binary-protocol-zmq"
530 , "bindings-apr-util"
546 , "bindings-libstemmer"
548 , "bindings-linux-videodev2"
549 , "bindings-mpdecimal"
560 , "BiobaseTrainingData"
587 , "blaze-html-contrib"
588 , "blaze-html-hexpat"
589 , "blaze-textual-native"
592 , "BlogLiterately-diagrams"
597 , "boolean-normal-forms"
619 , "bytestring-rematch"
625 , "cabal-constraints"
629 , "cabal-install-ghc72"
630 , "cabal-install-ghc74"
654 , "casadi-bindings-control"
655 , "casadi-bindings-core"
656 , "casadi-bindings-internal"
657 , "casadi-bindings-ipopt-interface"
658 , "casadi-bindings-snopt-interface"
667 , "categorical-algebra"
672 , "cctools-workqueue"
674 , "cereal-enumerator"
684 , "chalkboard-viewer"
713 , "clckwrks-plugin-bugs"
714 , "clckwrks-plugin-ircbot"
715 , "clckwrks-plugin-media"
716 , "clckwrks-plugin-page"
717 , "clckwrks-theme-bootstrap"
718 , "clckwrks-theme-clckwrks"
719 , "clckwrks-theme-geo-bootstrap"
728 , "cloudfront-signer"
740 , "cnc-spec-compiler"
742 , "Codec-Image-DevIL"
763 , "computational-algebra"
772 , "conduit-network-stream"
773 , "conduit-resumablesink"
778 , "const-math-ghc-plugin"
779 , "constructive-algebra"
786 , "control-monad-attempt"
787 , "control-monad-exception"
788 , "control-monad-exception-monadsfd"
789 , "control-monad-exception-monadstf"
790 , "control-monad-exception-mtl"
791 , "control-monad-failure"
792 , "control-monad-failure-mtl"
793 , "Control-Monad-MultiPass"
794 , "contstuff-monads-tf"
795 , "contstuff-transformers"
796 , "convertible-ascii"
805 , "coroutine-iteratee"
808 , "couchdb-enumerator"
828 , "crf-chain2-generic"
832 , "crypto-cipher-benchmarks"
863 , "darcs-buildpackage"
866 , "darcs-fastconvert"
904 , "definitive-filesystem"
905 , "definitive-graphics"
906 , "definitive-reactive"
925 , "dice-entropy-conduit"
929 , "DifferentialEvolution"
930 , "digestive-functors-hsp"
942 , "distributed-process-async"
943 , "distributed-process-azure"
944 , "distributed-process-client-server"
945 , "distributed-process-execution"
946 , "distributed-process-extras"
947 , "distributed-process-registry"
948 , "distributed-process-supervisor"
949 , "distributed-process-task"
950 , "distributed-process-tests"
951 , "distribution-plot"
954 , "DnaProteinAlignment"
962 , "doctest-discover-configurator"
965 , "download-media-content"
1002 , "DysFRP-Craftwerk"
1017 , "effective-aspects"
1018 , "effective-aspects-mzv"
1022 , "eibd-client-simple"
1034 , "embeddock-example"
1057 , "Eternal10Seconds"
1059 , "ethereum-client-haskell"
1060 , "ethereum-merkle-patricia-db"
1065 , "every-bit-counts"
1069 , "expat-enumerator"
1071 , "explicit-sharing"
1073 , "exposed-containers"
1077 , "extended-categories"
1100 , "feldspar-compiler"
1101 , "feldspar-language"
1104 , "FermatsLastMargin"
1107 , "ffmpeg-tutorials"
1115 , "filesystem-conduit"
1116 , "Finance-Quote-Yahoo"
1117 , "Finance-Treasury"
1120 , "first-class-patterns"
1122 , "FirstOrderTheory"
1126 , "fixed-point-vector"
1127 , "fixed-point-vector-space"
1129 , "fixed-storable-array"
1130 , "fix-parser-simple"
1131 , "fix-symbols-gitit"
1133 , "flexiwrap-smallcheck"
1142 , "foldl-incremental"
1147 , "font-opengl-basic4x6"
1165 , "free-operational"
1168 , "free-theorems-counterexamples"
1169 , "free-theorems-seq"
1170 , "free-theorems-seq-webui"
1171 , "free-theorems-webui"
1181 , "full-text-search"
1182 , "functional-arrow"
1183 , "function-combine"
1195 , "gc-monitoring-wai"
1201 , "genericserialize"
1202 , "generic-storable"
1213 , "GeomPredicates-SSE"
1219 , "ghc-events-analyze"
1220 , "ghc-generic-instances"
1242 , "gladexml-accessor"
1248 , "gloss-accelerate"
1250 , "gloss-raster-accelerate"
1260 , "GoogleDirections"
1261 , "google-html5-slide"
1270 , "GPipe-TextureLoad"
1275 , "grammar-combinators"
1277 , "GraphHammer-examples"
1279 , "graphics-formats-collada"
1281 , "graph-rewriting-cl"
1282 , "graph-rewriting-lambdascope"
1299 , "gtk2hs-cast-gnomevfs"
1301 , "gtk2hs-cast-gtkglext"
1304 , "gtk3-mac-integration"
1308 , "gtk-mac-integration"
1310 , "gtk-serialized-event"
1313 , "guess-combinator"
1318 , "hack2-contrib-extra"
1319 , "hack2-handler-happstack-server"
1320 , "hack2-handler-mongrel2-http"
1321 , "hack2-handler-warp"
1322 , "hack2-interface-wai"
1330 , "hack-contrib-press"
1332 , "hack-frontend-happstack"
1333 , "hack-frontend-monadcgi"
1334 , "hack-handler-epoll"
1335 , "hack-handler-evhttp"
1336 , "hack-handler-fastcgi"
1337 , "hack-handler-happstack"
1338 , "hack-handler-hyena"
1339 , "hack-handler-kibro"
1340 , "hack-handler-simpleserver"
1341 , "hack-middleware-clientsession"
1342 , "hack-middleware-jsonp"
1350 , "hakyll-blaze-templates"
1352 , "hakyll-contrib-links"
1368 , "happs-hsp-template"
1373 , "happstack-clientsession"
1374 , "happstack-contrib"
1377 , "happstack-facebook"
1378 , "happstack-fastcgi"
1380 , "happstack-fay-ajax"
1381 , "happstack-foundation"
1383 , "happstack-helpers"
1386 , "happstack-monad-peel"
1387 , "happstack-plugins"
1394 , "happybara-webkit"
1395 , "happybara-webkit-server"
1411 , "hashable-generics"
1423 , "haskell-brainfuck"
1425 , "haskelldb-dynamic"
1426 , "haskelldb-hdbc-mysql"
1428 , "haskelldb-hsql-mysql"
1429 , "haskelldb-hsql-odbc"
1430 , "haskelldb-hsql-postgresql"
1431 , "haskelldb-hsql-sqlite3"
1433 , "haskell-formatter"
1435 , "haskell-neo4j-client"
1438 , "haskell-openflow"
1439 , "haskell-pdf-presenter"
1440 , "haskell-platform-test"
1445 , "haskell-spacegoo"
1446 , "haskell-src-meta-mwotton"
1447 , "haskell-token-utils"
1449 , "haskell-type-exts"
1460 , "haskoon-httpspec"
1462 , "haskore-supercollider"
1463 , "haskore-synthesizer"
1493 , "hdaemonize-buildfix"
1518 , "her-lexer-parsec"
1527 , "hexpat-pickle-generic"
1538 , "HGamer3D-CAudio-Binding"
1539 , "HGamer3D-CEGUI-Binding"
1540 , "HGamer3D-Enet-Binding"
1541 , "HGamer3D-Graphics3D"
1543 , "HGamer3D-InputSystem"
1544 , "HGamer3D-Network"
1545 , "HGamer3D-Ogre-Binding"
1546 , "HGamer3D-OIS-Binding"
1547 , "HGamer3D-SDL2-Binding"
1548 , "HGamer3D-SFML-Binding"
1549 , "HGamer3D-WinEvent"
1561 , "hierarchical-clustering"
1562 , "hierarchical-clustering-diagrams"
1571 , "hinduce-classifier"
1572 , "hinduce-classifier-decisiontree"
1573 , "hinduce-examples"
1587 , "HLearn-approximation"
1588 , "HLearn-classification"
1589 , "HLearn-datastructures"
1590 , "HLearn-distributions"
1602 , "hmatrix-gsl-stats"
1603 , "hmatrix-quadprogpp"
1626 , "Holumbus-Distribution"
1627 , "Holumbus-MapReduce"
1628 , "Holumbus-Searchengine"
1629 , "Holumbus-Storage"
1692 , "hsc3-sf-hsndfile"
1696 , "hs-carbon-examples"
1701 , "hscurses-fish-ex"
1731 , "hsndfile-storablevector"
1739 , "hspec-expectations-pretty"
1740 , "hspec-experimental"
1749 , "hsqml-demo-morris"
1750 , "hsqml-demo-notes"
1751 , "hsqml-demo-samples"
1762 , "hs-twitterarchiver"
1779 , "http-client-request-modifiers"
1780 , "http-conduit-browser"
1784 , "https-everywhere-rules"
1828 , "ige-mac-integration"
1837 , "ImperativeHaskell"
1845 , "InfixApplicative"
1852 , "interleavableGen"
1855 , "interpolatedstring-qq"
1856 , "interpolatedstring-qq-mwotton"
1864 , "iptables-helpers"
1870 , "iteratee-compress"
1884 , "ivory-quickcheck"
1898 , "jmacro-rpc-happstack"
1914 , "JSON-Combinator-Examples"
1918 , "JunkDB-driver-gdbm"
1921 , "kansas-lava-cores"
1922 , "kansas-lava-papilio"
1923 , "kansas-lava-shake"
1929 , "kickass-torrents-dump-parser"
1937 , "koellner-phonetic"
1941 , "kure-your-boilerplate"
1946 , "labyrinth-server"
1952 , "lambdacube-bullet"
1953 , "lambdacube-engine"
1954 , "lambdacube-examples"
1957 , "LambdaPrettyQuote"
1964 , "language-c-comments"
1967 , "language-java-classfile"
1970 , "language-python-colour"
1972 , "language-spelling"
1976 , "latest-npm-version"
1977 , "launchpad-control"
1981 , "layout-bootstrap"
1987 , "learn-physics-examples"
1992 , "leveldb-haskell-fork"
2007 , "libsystemd-daemon"
2014 , "lighttpd-conf-qq"
2017 , "linear-algebra-cblas"
2028 , "listlike-instances"
2037 , "llvm-data-interop"
2040 , "llvm-general-pure"
2041 , "llvm-general-quote"
2051 , "LogicGrowsOnTrees"
2052 , "LogicGrowsOnTrees-MPI"
2053 , "LogicGrowsOnTrees-network"
2054 , "LogicGrowsOnTrees-processes"
2075 , "mailchimp-subscribe"
2079 , "manatee-anything"
2084 , "manatee-filemanager"
2085 , "manatee-imageviewer"
2086 , "manatee-ircclient"
2088 , "manatee-pdfviewer"
2089 , "manatee-processmanager"
2091 , "manatee-template"
2092 , "manatee-terminal"
2100 , "markov-processes"
2111 , "MaybeT-monads-tf"
2124 , "meta-par-accelerate"
2150 , "modular-prelude-classy"
2151 , "module-management"
2156 , "MonadCatchIO-mtl-foreign"
2157 , "MonadCatchIO-transformers-foreign"
2160 , "monadiccp-gecode"
2161 , "monad-interleave"
2169 , "mongrel2-handler"
2191 , "multiplate-simplified"
2192 , "multirec-alt-deriver"
2196 , "musicbrainz-email"
2208 , "mysnapsession-example"
2209 , "mysql-simple-typed"
2230 , "network-bytestring"
2231 , "network-connection"
2232 , "network-minihttp"
2236 , "network-simple-sockaddr"
2237 , "network-simple-tls"
2238 , "network-topic-models"
2239 , "network-websocket"
2256 , "not-gloss-examples"
2276 , "ois-input-manager"
2286 , "openexchangerates"
2292 , "openpgp-crypto-api"
2293 , "opensoundcontrol-ht"
2296 , "opentheory-parser"
2297 , "opentheory-prime"
2298 , "opentheory-primitive"
2324 , "parameterized-data"
2326 , "parco-attoparsec"
2327 , "parconc-examples"
2342 , "pdf-toolbox-viewer"
2355 , "persistent-hssqlppp"
2357 , "persistent-protobuf"
2359 , "persistent-vector"
2360 , "persistent-zookeeper"
2377 , "pipes-cereal-plus"
2379 , "pipes-network-tls"
2381 , "pipes-p2p-examples"
2392 , "pointless-lenses"
2393 , "pointless-rewrite"
2397 , "polytypeable-utils"
2398 , "pontarius-mediaserver"
2410 , "postgresql-simple-typed"
2411 , "postgresql-typed"
2423 , "PriorityChansConverger"
2425 , "ProbabilityMonads"
2428 , "process-progress"
2430 , "procrastinating-structure"
2431 , "procrastinating-variable"
2434 , "profunctor-extras"
2439 , "proj4-hs-bindings"
2441 , "prolog-graph-lib"
2446 , "prove-everywhere-server"
2449 , "publicsuffixlistcreate"
2464 , "push-notify-general"
2467 , "puzzle-draw-cmdline"
2473 , "querystring-pickle"
2478 , "quickcheck-regex"
2479 , "quickcheck-relaxng"
2480 , "quickcheck-rematch"
2484 , "radium-formula-parser"
2485 , "rail-compiler-editor"
2497 , "raven-haskell-scotty"
2504 , "reactive-banana-sdl"
2505 , "reactive-banana-threepenny"
2506 , "reactive-fieldtrip"
2510 , "really-simple-xml-parser"
2516 , "reflection-extras"
2527 , "regional-pointers"
2529 , "regions-monadsfd"
2530 , "regions-monadstf"
2536 , "relational-postgresql8"
2537 , "relational-query"
2538 , "relational-query-HDBC"
2539 , "relational-record"
2540 , "relational-record-examples"
2541 , "relational-schemas"
2551 , "representable-functors"
2552 , "representable-profunctors"
2553 , "representable-tries"
2559 , "restricted-workers"
2560 , "rethinkdb-client-driver"
2567 , "ripple-federation"
2578 , "roguestar-engine"
2581 , "RollingDirectory"
2602 , "safe-failure-cme"
2608 , "safer-file-handles"
2609 , "safer-file-handles-bytestring"
2610 , "safer-file-handles-text"
2617 , "salvia-websocket"
2618 , "samtools-iteratee"
2621 , "satchmo-backends"
2622 , "satchmo-examples"
2628 , "scan-vector-machine"
2662 , "semigroupoid-extras"
2663 , "semigroups-actions"
2668 , "seqloc-datafiles"
2671 , "servant-postgresql"
2688 , "shakespeare-i18n"
2693 , "Shellac-compatline"
2694 , "Shellac-editline"
2704 , "simple-bluetooth"
2712 , "simple-log-syslog"
2714 , "simple-postgresql-orm"
2719 , "simple-templates"
2737 , "snaplet-actionlog"
2738 , "snaplet-auth-acid"
2739 , "snaplet-environments"
2744 , "snaplet-mongodb-minimalistic"
2752 , "sndfile-enumerators"
2764 , "sonic-visualiser"
2767 , "source-code-server"
2776 , "special-functors"
2779 , "speculation-transformers"
2789 , "sqlite-simple-typed"
2791 , "sql-simple-mysql"
2793 , "sql-simple-postgresql"
2794 , "sql-simple-sqlite"
2802 , "standalone-haddock"
2805 , "statistics-dirichlet"
2806 , "statistics-fusion"
2809 , "stm-chunked-queues"
2814 , "storable-static-array"
2816 , "storablevector-carray"
2817 , "storablevector-streamfusion"
2818 , "Strafunski-Sdf2Haskell"
2819 , "StrappedTemplates"
2822 , "strict-concurrency"
2826 , "structural-induction"
2827 , "structured-mongoDB"
2830 , "sunroof-compiler"
2831 , "sunroof-examples"
2833 , "supercollider-ht"
2834 , "supercollider-midi"
2847 , "synchronous-channels"
2852 , "synthesizer-alsa"
2853 , "synthesizer-core"
2854 , "synthesizer-dimensional"
2855 , "synthesizer-llvm"
2856 , "synthesizer-midi"
2859 , "system-random-effect"
2871 , "tamarin-prover-term"
2872 , "tamarin-prover-theory"
2873 , "tamarin-prover-utils"
2887 , "test-framework-doctest"
2899 , "text-show-instances"
2900 , "text-xml-generic"
2905 , "theoremquest-client"
2908 , "th-instance-reification"
2935 , "tokyocabinet-haskell"
2939 , "to-string-instances"
2943 , "transactional-events"
2944 , "transformers-convert"
2945 , "transformers-runnable"
2948 , "treemap-html-tools"
2955 , "tsession-happstack"
2959 , "twentefp-rosetree"
2969 , "twitter-enumerator"
2972 , "twitter-types-lens"
2981 , "type-equality-check"
2986 , "typelevel-tensor"
2988 , "type-ord-spine-cereal"
3001 , "unbounded-delays-units"
3002 , "unboxed-containers"
3004 , "unicode-normalization"
3009 , "unix-process-conduit"
3012 , "unordered-containers-rematch"
3021 , "uri-enumerator-file"
3025 , "urldisp-happstack"
3033 , "uvector-algorithms"
3044 , "vector-bytestring"
3047 , "vector-functorlazy"
3049 , "vector-read-instances"
3058 , "visual-graphrewrite"
3068 , "wai-frontend-monadcgi"
3070 , "wai-handler-devel"
3071 , "wai-handler-snap"
3072 , "wai-handler-webkit"
3076 , "wai-logger-prefork"
3077 , "wai-middleware-cache"
3078 , "wai-middleware-cache-redis"
3079 , "wai-middleware-catch"
3080 , "wai-middleware-etag"
3081 , "wai-middleware-headers"
3082 , "wai-middleware-route"
3084 , "wai-session-tokyocabinet"
3092 , "WebBits-multiplate"
3093 , "web-browser-in-haskell"
3099 , "webkitgtk3-javascriptcore"
3100 , "webkit-javascriptcore"
3103 , "web-routes-quasi"
3104 , "web-routes-transformers"
3115 , "Win32-dhcp-server"
3118 , "Win32-junction-point"
3121 , "Win32-services-wrapper"
3126 , "wl-pprint-terminfo"
3140 , "wumpus-microprint"
3159 , "xhaskell-library"
3172 , "xml-enumerator-combinators"
3181 , "xmms2-client-glib"
3182 , "xmonad-contrib-bluetilebranch"
3194 , "yahoo-web-search"
3205 , "yesod-auth-smbclient"
3207 , "yesod-continuations"
3208 , "yesod-datatables"
3210 , "yesod-eventsource"
3216 , "yesod-pagination"
3222 , "yesod-session-redis"
3223 , "yesod-static-angular"
3234 , "Yogurt-Standalone"
3255 , "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