1{-# LANGUAGE PatternGuards #-}
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
35import Control.Monad.Par.Combinator
36import Control.Monad.Par.IO
37import Control.Monad.Trans ( liftIO )
38import Data.Map.Strict ( Map )
39import qualified Data.Map.Strict as Map
42import Data.Set ( Set )
43import qualified Data.Set as Set
44import Distribution.Compiler
45import Distribution.Nixpkgs.Fetch
46import Distribution.Nixpkgs.Haskell
47import Distribution.Nixpkgs.Meta
48import Distribution.Nixpkgs.PackageMap
49import Distribution.Nixpkgs.Util.PrettyPrinting hiding ( attr, (<>) )
50import Distribution.Package
51import Distribution.PackageDescription hiding ( buildDepends, extraLibs, buildTools )
52import Distribution.PackageDescription.Configuration
53import Distribution.System
54import Distribution.Text
55import Distribution.Version
57type Nixpkgs = PackageMap -- Map String (Set [String])
58type PackageSet = Map String Version
59type PackageMultiSet = Map String (Set Version)
61type Constraint = Dependency
63resolveConstraint :: Constraint -> Hackage -> Version
64resolveConstraint c = fromMaybe (error ("constraint " ++ display c ++ " cannot be resolved in Hackage")) .
67resolveConstraint' :: Constraint -> Hackage -> Maybe Version
68resolveConstraint' (Dependency (PackageName name) vrange) hackage | Set.null vs = Nothing
69 | otherwise = Just (Set.findMax vs)
70 where vs = Set.filter (`withinRange` vrange) (Map.keysSet (hackage Map.! name))
72data Configuration = Configuration
74 -- |Target architecture. Used by 'finalizePackageDescription' to
75 -- choose appropriate flags and dependencies.
78 -- |Target compiler. Used by 'finalizePackageDescription' to choose
79 -- appropriate flags and dependencies.
80 , compilerInfo :: CompilerInfo
82 -- |Core packages found on Hackageg
83 , corePackages :: [PackageIdentifier]
85 -- |Core packages not found on Hackage.
86 , hardCorePackages :: [PackageIdentifier]
88 -- |These packages replace the latest respective version during
89 -- dependency resolution.
90 , defaultPackageOverrides :: [Constraint]
92 -- |These packages are added to the generated set, but the play no
93 -- role during dependency resolution.
94 , extraPackages :: [Constraint]
96 -- |These packages have not succeeded a build yet, so we give them an
97 -- empty meta.hydraPlatforms attribute to avoid cluttering our Hydra
98 -- output with lots of broken builds.
99 , brokenPackages :: Set PackageName
101 deriving (Read, Show)
105 hackage <- readHashedHackage
106 nixpkgs <- readNixpkgPackageMap
107 let fixup = Map.delete "acme-everything" -- TODO: https://github.com/NixOS/cabal2nix/issues/164
108 . Map.delete "som" -- TODO: https://github.com/NixOS/cabal2nix/issues/164
109 . Map.delete "type" -- TODO: https://github.com/NixOS/cabal2nix/issues/163
110 . Map.delete "dictionary-sharing" -- TODO: https://github.com/NixOS/cabal2nix/issues/175
111 runParIO $ generatePackageSet defaultConfiguration (fixup hackage) nixpkgs
113generatePackageSet :: Configuration -> Hackage -> Nixpkgs -> ParIO ()
114generatePackageSet config hackage nixpkgs = do
116 corePackageSet :: PackageSet
117 corePackageSet = Map.fromList [ (name, v) | PackageIdentifier (PackageName name) v <- corePackages config ++ hardCorePackages config ]
119 latestVersionSet :: PackageSet
120 latestVersionSet = Map.map (Set.findMax . Map.keysSet) hackage
122 defaultPackageOverridesSet :: PackageSet
123 defaultPackageOverridesSet = Map.fromList [ (name, resolveConstraint c hackage) | c@(Dependency (PackageName name) _) <- defaultPackageOverrides config ]
125 generatedDefaultPackageSet :: PackageSet
126 generatedDefaultPackageSet = (defaultPackageOverridesSet `Map.union` latestVersionSet) `Map.difference` corePackageSet
128 latestCorePackageSet :: PackageSet
129 latestCorePackageSet = latestVersionSet `Map.intersection` corePackageSet
131 latestOverridePackageSet :: PackageSet
132 latestOverridePackageSet = latestVersionSet `Map.intersection` defaultPackageOverridesSet
134 extraPackageSet :: PackageMultiSet
135 extraPackageSet = Map.unionsWith Set.union
136 [ Map.singleton name (Set.singleton (resolveConstraint c hackage)) | c@(Dependency (PackageName name) _) <- extraPackages config ]
138 db :: PackageMultiSet
139 db = Map.unionsWith Set.union [ Map.map Set.singleton generatedDefaultPackageSet
140 , Map.map Set.singleton latestCorePackageSet
141 , Map.map Set.singleton latestOverridePackageSet
145 knownAttributesSet :: Set String
146 knownAttributesSet = Set.union (Map.keysSet hackage) (Map.keysSet corePackageSet)
148 resolver :: Dependency -> Bool
149 resolver (Dependency (PackageName name) vrange)
150 | Just v <- Map.lookup name corePackageSet = v `withinRange` vrange
151 | Just v <- Map.lookup name generatedDefaultPackageSet = v `withinRange` vrange
154 liftIO $ do putStrLn "/* hackage-packages.nix is an auto-generated file -- DO NOT EDIT! */"
156 putStrLn "{ pkgs, stdenv, callPackage }:"
160 pkgs <- flip parMapM (Map.toAscList db) $ \(name, vs) -> do
161 defs <- forM (Set.toAscList vs) $ \pkgversion -> do
162 srcSpec <- liftIO $ sourceFromHackage UnknownHash (name ++ "-" ++ display pkgversion)
163 let -- TODO: Include list of broken dependencies in the generated output.
164 descr = hackage Map.! name Map.! pkgversion
165 (missingDeps, _, drv') = cabal2nix resolver descr
167 haskellDependencies :: Set String
168 haskellDependencies = Set.map unDep $ mconcat [ drv'^.x.haskell | x <- [libraryDepends,executableDepends,testDepends] ]
170 systemDependencies :: Set String
171 systemDependencies = Set.map unDep $ mconcat [ drv'^.x.y | x <- [libraryDepends,executableDepends,testDepends], y <- [system,pkgconfig] ]
173 haskellOrSystemDependencies :: Set String
174 haskellOrSystemDependencies = Set.map unDep $ mconcat [ drv'^.x.tool | x <- [libraryDepends,executableDepends,testDepends] ]
176 missing :: Set String
177 missing = Set.filter (`Set.notMember` knownAttributesSet) haskellDependencies
179 buildInputs :: Map Attribute (Maybe Path)
180 buildInputs = Map.unions
181 [ Map.fromList [ (n, Nothing) | n <- Set.toList missing ]
182 , Map.fromList [ (n, resolveNixpkgsAttribute nixpkgs n) | n <- Set.toAscList systemDependencies ]
183 , Map.fromList [ (n, resolveHackageThenNixpkgsAttribute nixpkgs hackage n) | n <- Set.toAscList haskellOrSystemDependencies ]
186 systemOverrides :: Doc
187 systemOverrides = fsep (map (uncurry formatOverride) (Map.toAscList buildInputs))
189 formatOverride :: Attribute -> Maybe Path -> Doc
190 formatOverride n Nothing = space <> text n <> text " = null;" -- missing attribute
191 formatOverride n (Just []) -- Haskell package:
192 | n == name = formatOverride n Nothing -- refers to a missing system library
193 | otherwise = empty -- found by callPackage
194 formatOverride n (Just p) = (text " inherit" <+> parens (text (intercalate "." p)) <+> text n) <> semi
197 overrides = systemOverrides
199 attr | Just v <- Map.lookup name generatedDefaultPackageSet, v == pkgversion = name
200 | otherwise = name ++ '_' : [ if c == '.' then '_' else c | c <- display pkgversion ]
202 drv = drv' & src .~ srcSpec
203 & jailbreak .~ (not (null missingDeps) && (name /= "jailbreak-cabal")) -- Dependency constraints aren't fulfilled
204 & metaSection . broken .~ not (Set.null missing) -- Missing Haskell dependencies!
205 & metaSection.hydraPlatforms .~ (if PackageName name `Set.member` brokenPackages config
206 then Set.singleton "stdenv.lib.platforms.none"
207 else drv'^.metaSection.hydraPlatforms)
209 return $ nest 2 $ hang (string attr <+> equals <+> text "callPackage") 2 (parens (pPrint drv)) <+> (braces overrides <> semi)
210 return (intercalate "\n\n" (map render defs))
212 liftIO $ mapM_ (\pkg -> putStrLn pkg >> putStrLn "") pkgs
213 liftIO $ putStrLn "}"
215resolveHackageThenNixpkgsAttribute :: Nixpkgs -> Hackage -> Attribute -> Maybe Path
216resolveHackageThenNixpkgsAttribute nixpkgs hackage name
217 | Just _ <- Map.lookup name hackage = Just []
218 | p@(Just _) <- resolveNixpkgsAttribute nixpkgs name = p
219 | otherwise = Nothing
221resolveNixpkgsAttribute :: Nixpkgs -> Attribute -> Maybe Path
222resolveNixpkgsAttribute nixpkgs name
223 | name `elem` ["clang","lldb","llvm"] = Just ["self","llvmPackages"]
224 | Just paths <- Map.lookup name nixpkgs = getShortestPath (Set.toList (paths `Set.intersection` goodScopes))
225 | otherwise = Nothing
227 goodScopes :: Set Path
228 goodScopes = Set.fromList [[], ["xlibs"], ["gnome"], ["gnome3"], ["kde4"]]
230 getShortestPath :: [Path] -> Maybe Path
231 getShortestPath [] = Nothing
232 getShortestPath ps = Just ("pkgs" : minimumBy (on compare length) ps)
234cabal2nix :: (Dependency -> Bool) -> GenericPackageDescription -> ([Dependency], FlagAssignment, Derivation)
235cabal2nix resolver cabal = (missingDeps, flags, drv)
237 drv = cabal2nix' descr
239 Right (descr, flags) = finalize (if null missingDeps then resolver else const True) cabal
241 missingDeps :: [Dependency]
242 missingDeps = either id (const []) (finalize resolver cabal')
244 finalize :: (Dependency -> Bool) -> GenericPackageDescription -> Either [Dependency] (PackageDescription, FlagAssignment)
245 finalize resolver' = finalizePackageDescription
246 (configureCabalFlags (package (packageDescription cabal)))
248 (platform defaultConfiguration)
249 (compilerInfo defaultConfiguration)
250 [] -- no additional constraints
252 -- A variant of the cabal file that has all test suites enabled to ensure
253 -- that their dependencies are recognized by finalizePackageDescription.
254 cabal' :: GenericPackageDescription
255 cabal' = cabal { condTestSuites = flaggedTests }
257 flaggedTests :: [(String, CondTree ConfVar [Dependency] TestSuite)]
258 flaggedTests = map (\(n, t) -> (n, mapTreeData enableTest t)) (condTestSuites cabal)
260 enableTest :: TestSuite -> TestSuite
261 enableTest t = t { testEnabled = True }
263defaultConfiguration :: Configuration
264defaultConfiguration = Configuration
265 { platform = Platform X86_64 Linux
266 , compilerInfo = unknownCompilerInfo (CompilerId GHC (Version [7,10,2] [])) NoAbiTag
268 , defaultPackageOverrides = map (\s -> fromMaybe (error (show s ++ " is not a valid override selector")) (simpleParse s))
269 [ "errors < 2" -- the update breaks some ~40 important packages
270 , "vector < 0.11" -- breaks lens 4.12
273 , corePackages = map (\s -> fromMaybe (error (show s ++ " is not a valid core package")) (simpleParse s))
278 , "bytestring-0.10.6.0"
279 , "containers-0.5.6.2"
281 , "directory-1.2.2.0"
284 , "haskeline-0.7.2.1"
287 , "integer-gmp-1.0.0.0"
290 , "template-haskell-2.10.0.0"
293 , "transformers-0.4.2.0"
298 , hardCorePackages = map (\s -> fromMaybe (error (show s ++ " is not a valid core package")) (simpleParse s))
299 [ "bin-package-db-0.0.0.0"
304 , extraPackages = map (\s -> fromMaybe (error (show s ++ " is not a valid extra package selector")) (simpleParse s))
305 [ "aeson < 0.8" -- newer versions don't work with GHC 6.12.3
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 , "cabal-install == 1.18.*" -- required for ghc-mod on 7.8.x
309 , "conduit < 1.2.4.2" -- newer versions trigger non-deterministic ID bugs in GHC versions prior to 7.10.x
310 , "containers < 0.5" -- required to build alex with GHC 6.12.3
311 , "control-monad-free < 0.6" -- newer versions don't compile with anything but GHC 7.8.x
312 , "deepseq == 1.3.0.1" -- required to build Cabal with GHC 6.12.3
313 , "descriptive < 0.1" -- required for structured-haskell-mode-1.0.8
314 , "gloss < 1.9.3" -- new versions don't compile with GHC 7.8.x
315 , "haddock-api < 2.16" -- required on GHC 7.8.x
316 , "haskell-src-exts < 1.16" -- required for structured-haskell-mode-1.0.8
317 , "mtl < 2.2" -- newer versions require transformers > 0.4.x, which we cannot provide in GHC 7.8.x
318 , "mtl-prelude < 2" -- required for to build postgrest on mtl 2.1.x platforms
319 , "optparse-applicative == 0.10.*" -- required for elm-make 0.1.1 and elm-package 0.4
320 , "parallel == 3.2.0.3" -- newer versions don't work with GHC 6.12.3
321 , "primitive == 0.5.1.*" -- required to build alex with GHC 6.12.3
322 , "QuickCheck < 2" -- required by test-framework-quickcheck and its users
323 , "seqid < 0.2" -- newer versions depend on transformers 0.4.x which we cannot provide in GHC 7.8.x
324 , "seqid-streams < 0.2" -- newer versions depend on transformers 0.4.x which we cannot provide in GHC 7.8.x
325 , "split < 0.2" -- newer versions don't work with GHC 6.12.3
326 , "tar < 0.4.2.0" -- later versions don't work with GHC < 7.6.x
327 , "vector < 0.10.10" -- newer versions don't work with GHC 6.12.3
328 , "zlib < 0.6" -- newer versions break cabal-install
331 , brokenPackages = Set.fromList $ map PackageName
332 [ "3d-graphics-examples"
336 , "abstract-par-accelerate"
339 , "accelerate-arithmetic"
341 , "accelerate-fourier"
343 , "accelerate-utility"
346 , "AC-EasyRaster-GTK"
351 , "acme-numbersystem"
352 , "acme-schoenfinkel"
360 , "Adaptive-Blaisorblade"
361 , "adaptive-containers"
366 , "adobe-swatch-exchange"
368 , "adp-multi-monadiccp"
374 , "AERN-Real-Interval"
389 , "aivika-experiment-diagrams"
390 , "aivika-transformers"
414 , "AndroidViewHierarchyImporter"
461 , "atlassian-connect-core"
462 , "atlassian-connect-descriptor"
468 , "attoparsec-iteratee"
470 , "attoparsec-text-enumerator"
486 , "aws-cloudfront-signer"
488 , "aws-elastic-transcoder"
489 , "aws-kinesis-reshard"
492 , "aws-sdk-text-converter"
493 , "aws-sdk-xml-unordered"
496 , "azure-service-api"
503 , "bamboo-plugin-highlight"
504 , "bamboo-plugin-photo"
505 , "bamboo-theme-blueprint"
506 , "bamboo-theme-mini-html5"
519 , "bed-and-breakfast"
527 , "bidirectionalization-combined"
533 , "billeksah-services"
536 , "binary-indexed-tree"
537 , "binary-protocol-zmq"
542 , "bindings-apr-util"
558 , "bindings-libstemmer"
560 , "bindings-linux-videodev2"
561 , "bindings-mpdecimal"
574 , "BiobaseTrainingData"
604 , "blaze-html-contrib"
605 , "blaze-html-hexpat"
607 , "blaze-textual-native"
610 , "BlogLiterately-diagrams"
618 , "boolean-normal-forms"
647 , "bytestring-rematch"
652 , "cabal-constraints"
657 , "cabal-install-bundle"
658 , "cabal-install-ghc72"
659 , "cabal-install-ghc74"
677 , "call-haskell-from-anything"
687 , "casadi-bindings-control"
688 , "casadi-bindings-core"
689 , "casadi-bindings-internal"
690 , "casadi-bindings-ipopt-interface"
691 , "casadi-bindings-snopt-interface"
701 , "categorical-algebra"
709 , "CC-delcont-ref-tf"
711 , "cctools-workqueue"
713 , "ceilometer-common"
714 , "cereal-enumerator"
725 , "chalkboard-viewer"
749 , "citeproc-hs-pandoc-filter"
759 , "clash-prelude-quickcheck"
760 , "clash-systemverilog"
767 , "clckwrks-plugin-bugs"
768 , "clckwrks-plugin-ircbot"
769 , "clckwrks-plugin-media"
770 , "clckwrks-plugin-page"
771 , "clckwrks-theme-bootstrap"
772 , "clckwrks-theme-clckwrks"
773 , "clckwrks-theme-geo-bootstrap"
782 , "cloudfront-signer"
797 , "cnc-spec-compiler"
800 , "Codec-Image-DevIL"
806 , "coinbase-exchange" -- outdated dependencies
812 , "collections-base-instances"
816 , "combinat-diagrams"
817 , "combinatorial-problems"
818 , "combinator-interactive"
822 , "commsec-keyexchange"
833 , "computational-algebra"
845 , "conduit-audio-lame"
846 , "conduit-audio-samplerate"
848 , "conduit-network-stream"
849 , "conduit-resumablesink"
856 , "const-math-ghc-plugin"
857 , "constrained-categories"
858 , "constructive-algebra"
867 , "control-monad-attempt"
868 , "control-monad-exception-mtl"
869 , "control-monad-failure"
870 , "control-monad-failure-mtl"
871 , "Control-Monad-MultiPass"
872 , "Control-Monad-ST2"
873 , "contstuff-monads-tf"
874 , "contstuff-transformers"
875 , "convertible-ascii"
882 , "copilot-libraries"
891 , "coroutine-iteratee"
894 , "couchdb-enumerator"
917 , "crf-chain1-constrained"
918 , "crf-chain2-generic"
924 , "crypto-cipher-benchmarks"
929 , "csound-expression"
930 , "csound-expression-opcodes"
931 , "csound-expression-typed"
962 , "darcs-buildpackage"
1005 , "ddc-source-tetra"
1008 , "dead-simple-json"
1020 , "definitive-filesystem"
1021 , "definitive-graphics"
1022 , "definitive-parser"
1023 , "definitive-reactive"
1024 , "definitive-sound"
1036 , "derivation-trees"
1047 , "diagrams-builder"
1048 , "diagrams-haddock"
1054 , "dice-entropy-conduit"
1059 , "DifferentialEvolution"
1060 , "digestive-functors-hsp"
1066 , "direct-binary-files"
1067 , "directed-cubical"
1076 , "distributed-process"
1077 , "distributed-process-async"
1078 , "distributed-process-azure"
1079 , "distributed-process-client-server"
1080 , "distributed-process-execution"
1081 , "distributed-process-extras"
1082 , "distributed-process-monad-control"
1083 , "distributed-process-p2p"
1084 , "distributed-process-platform"
1085 , "distributed-process-registry"
1086 , "distributed-process-simplelocalnet"
1087 , "distributed-process-supervisor"
1088 , "distributed-process-task"
1089 , "distributed-process-tests"
1090 , "distributed-process-zookeeper"
1091 , "distributed-static"
1093 , "distribution-plot"
1097 , "DnaProteinAlignment"
1106 , "doctest-discover"
1107 , "doctest-discover-configurator"
1109 , "dominion" -- https://github.com/egonSchiele/dominion/issues/10
1112 , "download-media-content"
1158 , "DysFRP-Craftwerk"
1176 , "effective-aspects"
1177 , "effective-aspects-mzv"
1184 , "eibd-client-simple"
1207 , "embeddock-example"
1221 , "equational-reasoning"
1236 , "Eternal10Seconds"
1238 , "ethereum-client-haskell"
1239 , "ethereum-merkle-patricia-db"
1245 , "every-bit-counts"
1251 , "expat-enumerator"
1253 , "explicit-sharing"
1255 , "exposed-containers"
1259 , "extended-categories"
1278 , "feldspar-compiler"
1279 , "feldspar-language"
1282 , "FermatsLastMargin"
1286 , "ffmpeg-tutorials"
1294 , "filesystem-conduit"
1295 , "filesystem-enumerator"
1296 , "Finance-Quote-Yahoo"
1297 , "Finance-Treasury"
1300 , "first-class-patterns"
1302 , "FirstOrderTheory"
1306 , "fixed-point-vector"
1307 , "fixed-point-vector-space"
1309 , "fixed-storable-array"
1310 , "fix-parser-simple"
1312 , "fix-symbols-gitit"
1314 , "flexiwrap-smallcheck"
1324 , "flowlocks-framework"
1328 , "foldl-incremental"
1334 , "font-opengl-basic4x6"
1357 , "free-operational"
1361 , "free-theorems-counterexamples"
1362 , "free-theorems-seq"
1363 , "free-theorems-seq-webui"
1364 , "free-theorems-webui"
1374 , "functional-arrow"
1375 , "function-combine"
1387 , "gc-monitoring-wai"
1398 , "genericserialize"
1399 , "generic-storable"
1412 , "GeomPredicates-SSE"
1417 , "ghc-events-analyze"
1418 , "ghc-events-parallel"
1447 , "gladexml-accessor"
1470 , "google-html5-slide"
1471 , "google-mail-filters"
1480 , "GPipe-TextureLoad"
1485 , "grapefruit-examples"
1487 , "grapefruit-records"
1489 , "grapefruit-ui-gtk"
1493 , "GraphHammer-examples"
1494 , "graphics-drawingcombinators"
1496 , "graphics-formats-collada"
1499 , "graph-rewriting-cl"
1500 , "graph-rewriting-gl"
1501 , "graph-rewriting-lambdascope"
1502 , "graph-rewriting-layout"
1503 , "graph-rewriting-ski"
1504 , "graph-rewriting-strategies"
1505 , "graph-rewriting-trs"
1506 , "graph-rewriting-ww"
1525 , "gtk2hs-cast-glade"
1526 , "gtk2hs-cast-gnomevfs"
1528 , "gtk2hs-cast-gtkglext"
1531 , "gtk3-mac-integration"
1535 , "gtk-mac-integration"
1537 , "gtk-serialized-event"
1539 , "guarded-rewriting"
1540 , "guess-combinator"
1545 , "hack2-handler-happstack-server"
1546 , "hack2-handler-mongrel2-http"
1547 , "hack2-handler-warp"
1548 , "hack2-interface-wai"
1558 , "hack-contrib-press"
1560 , "hack-frontend-happstack"
1561 , "hack-handler-epoll"
1562 , "hack-handler-evhttp"
1563 , "hack-handler-fastcgi"
1564 , "hack-handler-happstack"
1565 , "hack-handler-hyena"
1566 , "hack-handler-kibro"
1567 , "hack-handler-simpleserver"
1569 , "hack-middleware-cleanpath"
1570 , "hack-middleware-clientsession"
1571 , "hack-middleware-jsonp"
1583 , "hakyll-blaze-templates"
1585 , "hakyll-contrib-links"
1602 , "happs-hsp-template"
1607 , "happstack-contrib"
1610 , "happstack-facebook"
1612 , "happstack-foundation"
1614 , "happstack-helpers"
1617 , "happstack-monad-peel"
1618 , "happstack-plugins"
1625 , "happybara-webkit"
1626 , "happybara-webkit-server"
1643 , "hashable-generics"
1659 , "haskell-brainfuck"
1661 , "haskell-course-preludes"
1662 , "haskelldb-connect-hdbc"
1663 , "haskelldb-connect-hdbc-catchio-mtl"
1664 , "haskelldb-connect-hdbc-catchio-tf"
1665 , "haskelldb-connect-hdbc-catchio-transformers"
1666 , "haskelldb-connect-hdbc-lifted"
1667 , "haskelldb-dynamic"
1669 , "haskelldb-hdbc-mysql"
1670 , "haskelldb-hdbc-odbc"
1671 , "haskelldb-hdbc-postgresql"
1672 , "haskelldb-hdbc-sqlite3"
1674 , "haskelldb-hsql-mysql"
1675 , "haskelldb-hsql-odbc"
1676 , "haskelldb-hsql-postgresql"
1677 , "haskelldb-hsql-sqlite3"
1680 , "haskell-formatter"
1682 , "haskell-in-space"
1684 , "haskell-neo4j-client"
1687 , "haskell-openflow"
1688 , "haskell-pdf-presenter"
1689 , "haskell-platform-test"
1694 , "haskell-src-meta-mwotton"
1696 , "haskell-type-exts"
1707 , "haskoin-protocol"
1712 , "haskoon-httpspec"
1715 , "haskore-realtime"
1716 , "haskore-supercollider"
1717 , "haskore-synthesizer"
1755 , "hdaemonize-buildfix"
1790 , "her-lexer-parsec"
1795 , "herringbone-embed"
1803 , "hexpat-pickle-generic"
1809 , "hfoil" -- https://github.com/ghorn/hfoil/issues/6
1817 , "HGamer3D-CAudio-Binding"
1818 , "HGamer3D-CEGUI-Binding"
1819 , "HGamer3D-Enet-Binding"
1820 , "HGamer3D-Graphics3D"
1822 , "HGamer3D-InputSystem"
1823 , "HGamer3D-Network"
1824 , "HGamer3D-Ogre-Binding"
1825 , "HGamer3D-OIS-Binding"
1826 , "HGamer3D-SDL2-Binding"
1827 , "HGamer3D-SFML-Binding"
1828 , "HGamer3D-WinEvent"
1843 , "hierarchical-clustering"
1844 , "hierarchical-clustering-diagrams"
1852 , "hinduce-classifier"
1853 , "hinduce-classifier-decisiontree"
1854 , "hinduce-examples"
1872 , "HLearn-datastructures"
1877 , "hlibsass" -- https://github.com/jakubfijalkowski/hsass/issues/1
1886 , "hmatrix-gsl-stats"
1887 , "hmatrix-quadprogpp"
1916 , "Holumbus-Distribution"
1917 , "Holumbus-MapReduce"
1918 , "Holumbus-Searchengine"
1919 , "Holumbus-Storage"
1992 , "hs-carbon-examples"
1998 , "hscurses-fish-ex"
2035 , "hsndfile-storablevector"
2037 , "hs-nombre-generator"
2046 , "hspec-experimental"
2055 , "hsqml-demo-morris"
2056 , "hsqml-demo-samples"
2066 , "HStringTemplateHelpers"
2068 , "hs-twitterarchiver"
2086 , "html-email-validate"
2089 , "http-client-request-modifiers"
2090 , "http-conduit-browser"
2091 , "http-conduit-downloader"
2096 , "https-everywhere-rules"
2097 , "https-everywhere-rules-raw"
2112 , "hunt-searchengine"
2115 , "husk-scheme-libs"
2129 , "hyakko" -- https://github.com/sourrust/hyakko/issues/2
2134 , "hydrogen-cli-args"
2136 , "hydrogen-parsing"
2137 , "hydrogen-prelude"
2138 , "hydrogen-prelude-parsec"
2161 , "ige-mac-integration"
2167 , "ihaskell-display"
2169 , "ihaskell" -- https://github.com/gibiansky/IHaskell/issues/495
2170 , "ihaskell-juicypixels"
2174 , "ihaskell-rlangqq"
2182 , "ImperativeHaskell"
2188 , "incremental-computing"
2189 , "incremental-sat-solver"
2196 , "InfixApplicative"
2200 , "instant-generics"
2204 , "interleavableGen"
2207 , "interpolatedstring-qq"
2208 , "interpolatedstring-qq-mwotton"
2218 , "iptables-helpers"
2229 , "iteratee-compress"
2239 , "ivory-quickcheck"
2253 , "java-bridge-extras"
2266 , "jose-jwt" -- https://github.com/tekul/jose-jwt/issues/6
2276 , "JSON-Combinator-Examples"
2285 , "JuicyPixels-repa"
2286 , "JunkDB-driver-gdbm"
2290 , "kansas-lava-cores"
2291 , "kansas-lava-papilio"
2292 , "kansas-lava-shake"
2294 , "keera-hails-mvc-model-lightmodel"
2295 , "keera-hails-reactive-gtk"
2303 , "kickass-torrents-dump-parser"
2310 , "koellner-phonetic"
2314 , "kure-your-boilerplate"
2318 , "labyrinth-server"
2323 , "lambdabot-haskell-plugins"
2324 , "lambdabot-novelty-plugins"
2327 , "LambdaCalculator"
2332 , "lambdacube-bullet"
2333 , "lambdacube-engine"
2334 , "lambdacube-examples"
2336 , "lambdacube-samples"
2341 , "LambdaPrettyQuote"
2349 , "language-c-comments"
2350 , "language-c-inline"
2353 , "language-java-classfile"
2356 , "language-python-colour"
2358 , "language-spelling"
2363 , "latest-npm-version"
2367 , "layout-bootstrap"
2377 , "learn-physics-examples"
2383 , "leveldb-haskell-fork"
2401 , "libsystemd-daemon"
2407 , "lighttpd-conf-qq"
2413 , "linear-algebra-cblas"
2415 , "linearscan-hoopl"
2416 , "linearscan" -- https://github.com/jwiegley/linearscan/issues/1
2427 , "liquid-fixpoint" -- https://github.com/ucsd-progsys/liquid-fixpoint/issues/66
2429 , "listlike-instances"
2430 , "list-t-html-parser"
2437 , "llvm-general-quote"
2445 , "LogicGrowsOnTrees"
2446 , "LogicGrowsOnTrees-MPI"
2447 , "LogicGrowsOnTrees-network"
2448 , "LogicGrowsOnTrees-processes"
2483 , "manatee-anything"
2488 , "manatee-filemanager"
2489 , "manatee-imageviewer"
2491 , "manatee-pdfviewer"
2492 , "manatee-processmanager"
2494 , "manatee-template"
2495 , "manatee-terminal"
2505 , "markov-processes"
2507 , "marmalade-upload"
2521 , "MaybeT-monads-tf"
2522 , "MaybeT-transformers"
2527 , "mdcat" -- https://github.com/dorafmon/mdcat/issues/2
2537 , "meta-par-accelerate"
2576 , "modular-prelude-classy"
2577 , "module-management"
2582 , "monad-atom-simple"
2584 , "MonadCatchIO-mtl-foreign"
2585 , "MonadCatchIO-transformers-foreign"
2588 , "monadiccp-gecode"
2589 , "monad-interleave"
2594 , "monad-mersenne-random"
2599 , "monad-stlike-stm"
2607 , "mongrel2-handler"
2638 , "multiplate-simplified"
2639 , "multirec-alt-deriver"
2644 , "musicbrainz-email"
2658 , "mwc-random-monad"
2660 , "mysnapsession-example"
2661 , "mysql-simple-quasi"
2662 , "mysql-simple-typed"
2691 , "network-anonymous-i2p"
2693 , "network-bytestring"
2694 , "network-connection"
2696 , "network-minihttp"
2701 , "network-simple-tls"
2702 , "network-topic-models"
2703 , "network-transport-amqp"
2704 , "network-transport-zeromq"
2705 , "network-websocket"
2730 , "not-gloss-examples"
2757 , "ois-input-manager"
2771 , "openexchangerates"
2777 , "openpgp-crypto-api"
2779 , "openssh-github-keys"
2790 , "order-maintenance"
2801 , "pandoc-csv2table" -- https://github.com/baig/pandoc-csv2table/issues/8
2808 , "parameterized-data"
2810 , "parco-attoparsec"
2811 , "parconc-examples"
2845 , "persistent-hssqlppp"
2847 , "persistent-protobuf"
2867 , "pipes-cereal-plus"
2869 , "pipes-network-tls"
2870 , "pipes-p2p-examples"
2880 , "plugins-multistage"
2886 , "pointless-haskell"
2887 , "pointless-lenses"
2888 , "pointless-rewrite"
2892 , "polytypeable-utils"
2893 , "pontarius-mediaserver"
2908 , "postgresql-simple-typed"
2909 , "postgresql-typed"
2921 , "prelude-generalize"
2923 , "preprocess-haskell"
2929 , "PriorityChansConverger"
2931 , "ProbabilityMonads"
2935 , "process-listlike"
2936 , "process-progress"
2938 , "procrastinating-structure"
2939 , "procrastinating-variable"
2942 , "profunctor-extras"
2947 , "proj4-hs-bindings"
2950 , "prolog-graph-lib"
2956 , "protocol-buffers"
2957 , "protocol-buffers-descriptor"
2958 , "protocol-buffers-descriptor-fork"
2959 , "protocol-buffers-fork"
2960 , "prove-everywhere-server"
2964 , "publicsuffixlistcreate"
2980 , "push-notify-general"
2983 , "puzzle-draw-cmdline"
2992 , "querystring-pickle"
2997 , "quickcheck-regex"
2998 , "quickcheck-relaxng"
2999 , "quickcheck-rematch"
3000 , "quickcheck-webdriver"
3009 , "radium-formula-parser"
3010 , "rail-compiler-editor"
3016 , "random-access-list"
3020 , "random-hypergeometric"
3029 , "raven-haskell-scotty"
3038 , "reactive-banana-sdl"
3039 , "reactive-banana-threepenny"
3040 , "reactive-fieldtrip"
3044 , "really-simple-xml-parser"
3048 , "record-preprocessor"
3052 , "recursion-schemes"
3058 , "reflection-extras"
3070 , "regional-pointers"
3072 , "regions-monadsfd"
3073 , "regions-monadstf"
3080 , "relational-postgresql8"
3081 , "relational-query"
3082 , "relational-query-HDBC"
3083 , "relational-record"
3084 , "relational-record-examples"
3085 , "relational-schemas"
3101 , "representable-functors"
3102 , "representable-profunctors"
3103 , "representable-tries"
3109 , "restricted-workers"
3111 , "resumable-exceptions"
3113 , "rethinkdb-client-driver"
3115 , "rethinkdb-wereHamster"
3125 , "ripple-federation"
3138 , "roguestar-engine"
3141 , "RollingDirectory"
3149 , "roundtrip-string"
3171 , "safer-file-handles"
3172 , "safer-file-handles-bytestring"
3173 , "safer-file-handles-text"
3181 , "salvia-websocket"
3182 , "samtools-iteratee"
3186 , "satchmo-backends"
3187 , "satchmo-examples"
3194 , "scan-vector-machine"
3199 , "scholdoc-citeproc"
3234 , "semigroups-actions"
3242 , "seqloc-datafiles"
3248 , "servant-postgresql"
3250 , "serversession-backend-persistent"
3251 , "serversession-backend-redis"
3252 , "serversession-frontend-wai"
3255 , "ses-html-snaplet"
3272 , "shakespeare-i18n"
3277 , "Shellac-compatline"
3278 , "Shellac-editline"
3279 , "Shellac-haskeline"
3280 , "Shellac-readline"
3294 , "simple-bluetooth"
3304 , "simple-log-syslog"
3307 , "simple-postgresql-orm"
3312 , "simple-templates"
3341 , "snaplet-actionlog"
3342 , "snaplet-auth-acid"
3344 , "snaplet-environments"
3349 , "snaplet-mongodb-minimalistic"
3350 , "snaplet-mysql-simple"
3352 , "snaplet-purescript"
3357 , "snaplet-ses-html"
3358 , "snaplet-sqlite-simple"
3360 , "snaplet-typed-sessions"
3361 , "snaplet-wordpress"
3366 , "sndfile-enumerators"
3379 , "sonic-visualiser"
3383 , "source-code-server"
3393 , "special-functors"
3395 , "speculation-transformers"
3409 , "sqlite-simple-typed"
3411 , "sql-simple-mysql"
3413 , "sql-simple-postgresql"
3414 , "sql-simple-sqlite"
3421 , "stackage-curator"
3426 , "statistics-dirichlet"
3427 , "statistics-fusion"
3432 , "stm-chunked-queues"
3437 , "storable-static-array"
3439 , "storablevector-carray"
3440 , "storablevector-streamfusion"
3441 , "Strafunski-Sdf2Haskell"
3442 , "StrappedTemplates"
3447 , "strict-concurrency"
3452 , "structural-induction"
3453 , "structured-mongoDB"
3458 , "sunroof-compiler"
3459 , "sunroof-examples"
3461 , "supercollider-midi"
3478 , "synchronous-channels"
3481 , "syntax-attoparsec"
3483 , "syntax-example-json"
3488 , "syntax-trees-fork-bairyn"
3490 , "synthesizer-alsa"
3491 , "synthesizer-core"
3492 , "synthesizer-dimensional"
3493 , "synthesizer-midi"
3495 , "system-canonicalpath"
3497 , "system-random-effect"
3502 , "tagged-exception-core"
3513 , "tamarin-prover-term"
3514 , "tamarin-prover-theory"
3515 , "tamarin-prover-utils"
3527 , "template-default"
3528 , "template-haskell-util"
3535 , "termbox-bindings"
3539 , "test-framework-doctest"
3540 , "test-framework-quickcheck"
3553 , "text-register-machine"
3555 , "text-xml-generic"
3562 , "theoremquest-client"
3593 , "timestamp-subprocess-lines"
3605 , "tokyocabinet-haskell"
3611 , "to-string-instances"
3617 , "transactional-events"
3618 , "transformers-convert"
3619 , "transformers-runnable"
3622 , "treemap-html-tools"
3633 , "tsession-happstack"
3642 , "twentefp-rosetree"
3654 , "twitter-enumerator"
3657 , "twitter-types-lens"
3666 , "type-equality-check"
3673 , "typelevel-tensor"
3678 , "type-ord-spine-cereal"
3686 , "typography-geometry"
3700 , "unbounded-delays-units"
3701 , "unboxed-containers"
3703 , "unicode-normalization"
3704 , "unicode-properties"
3713 , "unix-process-conduit"
3715 , "unordered-containers-rematch"
3727 , "uri-enumerator-file"
3731 , "urldisp-happstack"
3742 , "uvector-algorithms"
3753 , "vaultaire-common"
3757 , "vector-bytestring"
3761 , "vector-functorlazy"
3762 , "vector-instances-collections"
3764 , "vector-read-instances"
3765 , "vector-space-opengl"
3777 , "visual-graphrewrite"
3791 , "wai-handler-devel"
3792 , "wai-handler-snap"
3793 , "wai-handler-webkit"
3796 , "wai-logger-prefork"
3797 , "wai-middleware-cache"
3798 , "wai-middleware-cache-redis"
3799 , "wai-middleware-catch"
3800 , "wai-middleware-consul"
3801 , "wai-middleware-etag"
3802 , "wai-middleware-headers"
3803 , "wai-middleware-hmac-client"
3804 , "wai-middleware-preprocessor"
3805 , "wai-middleware-route"
3806 , "wai-middleware-static-caching"
3811 , "wai-session-clientsession"
3812 , "wai-session-tokyocabinet"
3813 , "wai-static-cache"
3815 , "waitra" -- https://github.com/futurice/waitra/issues/4
3824 , "WebBits-multiplate"
3825 , "web-browser-in-haskell"
3828 , "webdriver-angular"
3833 , "webkit-javascriptcore"
3837 , "web-routes-quasi"
3838 , "web-routes-transformers"
3854 , "Win32-dhcp-server"
3857 , "Win32-junction-point"
3861 , "Win32-services-wrapper"
3884 , "wumpus-microprint"
3903 , "xhaskell-library"
3916 , "xml-conduit-parse"
3918 , "xml-enumerator-combinators"
3927 , "xmms2-client-glib"
3928 , "xmonad-bluetilebranch"
3929 , "xmonad-contrib-bluetilebranch"
3944 , "yahoo-web-search"
3960 , "yesod-angular-ui"
3961 , "yesod-auth-account-fork"
3962 , "yesod-auth-kerberos"
3965 , "yesod-auth-smbclient"
3967 , "yesod-continuations"
3968 , "yesod-crud-persist"
3969 , "yesod-datatables"
3971 , "yesod-eventsource"
3978 , "yesod-pagination"
3982 , "yesod-purescript"
3984 , "yesod-routes-typescript"
3987 , "yesod-session-redis"
3988 , "yesod-static-angular"
3994 , "yet-another-logger"
4003 , "Yogurt-Standalone"
4027 , "zoom-cache-sndfile"
4038 , "postgresql-schema"
4043 , "amazon-emailer-client-snap"
4045 , "android-lint-summary"
4046 , "apiary-purescript"
4057 , "nagios-plugin-ekg"
4060 , "pg-harness-server"
4069 , "serversession-frontend-snap"
4075 , "snap-error-collector"
4078 , "snaplet-acid-state"
4083 , "snaplet-hslogger"
4084 , "snaplet-influxdb"
4085 , "snaplet-mandrill"
4086 , "snaplet-persistent"
4087 , "snaplet-postgresql-simple"
4088 , "snaplet-postmark"
4089 , "snaplet-recaptcha"
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