@@ -17,7 +17,7 @@ import Text.ParserCombinators.ReadP ( readP_to_S )
1717import Distribution.PackageDescription.Parse ( parsePackageDescription, ParseResult(..) )
1818import Distribution.PackageDescription ( GenericPackageDescription() )
1919import System.Console.GetOpt ( OptDescr(..), ArgDescr(..), ArgOrder(..), usageInfo, getOpt )
20−import Cabal2Nix.Package ( cabal2nix, showNixPkg, PkgName, PkgSHA256, PkgPlatforms, PkgMaintainers, PkgNoHaddock )
20+import Cabal2Nix.Package ( cabal2nix, showNixPkg, PkgName, PkgVersion, PkgSHA256, PkgPlatforms, PkgMaintainers, PkgNoHaddock )
2121
2222type PkgSet = Set.Set Pkg
2323
@@ -62,24 +62,17 @@ readCabalFile name vers = do
6262
6363discoverNixFiles :: (FilePath -> Hackage4Nix ()) -> FilePath -> Hackage4Nix ()
6464discoverNixFiles yield dirOrFile
65− | "." `isPrefixOf` takeFileName dirOrFile = msgDebug $ "ignore file or directory " ++ dirOrFile
65+ | "." `isPrefixOf` takeFileName dirOrFile = return ()
6666 | otherwise = do
6767 isFile <- io (doesFileExist dirOrFile)
6868 case (isFile, takeExtension dirOrFile) of
69− (True,".nix") -> do
70− msgDebug ("discovered file " ++ dirOrFile)
71− yield dirOrFile
72− (True,_) -> msgDebug $ "ignore file " ++ dirOrFile
73− (False,_) -> do
74− msgDebug ("discovered dir " ++ dirOrFile)
75− io (readDirectory dirOrFile) >>= mapM_ (discoverNixFiles yield . (dirOrFile </>))
76−
77−type PkgVersion = String
78−data Pkg = Pkg PkgName PkgVersion PkgSHA256 PkgNoHaddock PkgPlatforms PkgMaintainers FilePath
79− deriving (Show, Eq, Ord)
69+ (True,".nix") -> yield dirOrFile
70+ (True,_) -> return ()
71+ (False,_) -> io (readDirectory dirOrFile) >>= mapM_ (discoverNixFiles yield . (dirOrFile </>))
8072
81−regmatch :: String -> String -> Bool
82−regmatch buf patt = match (makeRegexOpts compExtended execBlank patt) buf
73+type Regenerate = Bool
74+data Pkg = Pkg PkgName PkgVersion PkgSHA256 PkgNoHaddock PkgPlatforms PkgMaintainers FilePath Regenerate
75+ deriving (Show, Eq, Ord)
8376
8477regsubmatch :: String -> String -> [String]
8578regsubmatch buf patt = let (_,_,_,x) = f in x
@@ -93,16 +86,13 @@ normalizeMaintainer x
9386
9487parseNixFile :: FilePath -> String -> Hackage4Nix (Maybe Pkg)
9588parseNixFile path buf
96− | not (buf `regmatch` "cabal.mkDerivation")
89+ | not (buf =~ "cabal.mkDerivation")
9790 = msgDebug ("ignore non-cabal package " ++ path) >> return Nothing
98− | True <- path `regmatch` (concat (intersperse "|" badPackages))
91+ | any (`isSuffixOf`path) badPackagePaths
9992 = msgDebug ("ignore known bad package " ++ path) >> return Nothing
100− | True <- buf `regmatch` "src = (fetchgit|sourceFromHead)"
93+ | buf =~ "src = (fetchurl|fetchgit|sourceFromHead)"
10194 = msgDebug ("ignore non-hackage package " ++ path) >> return Nothing
102− | buf `regmatch` "preConfigure|configureFlags|postInstall|patchPhase"
103− = msgInfo ("ignore patched package " ++ path) >> return Nothing
104− | True <- buf =~ "cabal.mkDerivation"
105− , [name] <- buf `regsubmatch` "name *= *\"([^\"]+)\""
95+ | [name] <- buf `regsubmatch` "name *= *\"([^\"]+)\""
10696 , [vers] <- buf `regsubmatch` "version *= *\"([^\"]+)\""
10797 , [sha] <- buf `regsubmatch` "sha256 *= *\"([^\"]+)\""
10898 , plats <- buf `regsubmatch` "platforms *= *([^;]+);"
@@ -113,17 +103,13 @@ parseNixFile path buf
113103 noHaddock
114104 | "true":[] <- haddock = True
115105 | otherwise = False
106+ regenerate = not (name `elem` patchedPackages) &&
107+ not (buf =~ "preConfigure|configureFlags|postInstall|patchPhase")
116108 in
117− return $ Just $ Pkg name
118− vers
119− sha
120− noHaddock
121− plats'
109+ return $ Just $ Pkg name vers sha noHaddock plats'
122110 (map normalizeMaintainer maint')
123− path
124− | True <- buf `regmatch` "cabal.mkDerivation"
125− = msgInfo ("failed to parse file " ++ path) >> return Nothing
126− | otherwise = return Nothing
111+ path regenerate
112+ | otherwise = msgInfo ("failed to parse file " ++ path) >> return Nothing
127113
128114readVersion :: String -> Version
129115readVersion str =
@@ -134,10 +120,10 @@ readVersion str =
134120selectLatestVersions :: PkgSet -> PkgSet
135121selectLatestVersions = Set.fromList . nubBy f2 . sortBy f1 . Set.toList
136122 where
137− f1 (Pkg n1 v1 _ _ _ _ _) (Pkg n2 v2 _ _ _ _ _)
123+ f1 (Pkg n1 v1 _ _ _ _ _ _) (Pkg n2 v2 _ _ _ _ _ _)
138124 | n1 == n2 = compare v2 v1
139125 | otherwise = compare n1 n2
140− f2 (Pkg n1 _ _ _ _ _ _) (Pkg n2 _ _ _ _ _ _)
126+ f2 (Pkg n1 _ _ _ _ _ _ _) (Pkg n2 _ _ _ _ _ _ _)
141127 = n1 == n2
142128
143129discoverUpdates :: PkgName -> PkgVersion -> Hackage4Nix [PkgVersion]
@@ -145,7 +131,7 @@ discoverUpdates name vers = do
145131 hackage <- gets _hackageDb
146132 versionStrings <- io $ readDirectory (hackage </> name)
147133 let versions = map readVersion versionStrings
148− return [ showVersion v | v <- versions, v > readVersion vers ]
134+ return (sort [ showVersion v | v <- versions, v > readVersion vers ])
149135
150136updateNixPkgs :: [FilePath] -> Hackage4Nix ()
151137updateNixPkgs paths = do
@@ -154,44 +140,45 @@ updateNixPkgs paths = do
154140 flip discoverNixFiles fileOrDir $ \file -> do
155141 nix' <- io (readFile file) >>= parseNixFile file
156142 flip (maybe (return ())) nix' $ \nix -> do
157− let Pkg name vers sha noHaddock plats maints path = nix
158− maints' = nub (sort (maints ++ ["andres","simons"]))
159− plats'
160− | null plats && not (null maints) = ["self.ghc.meta.platforms"]
161− | otherwise = plats
162− msgDebug ("re-generate " ++ path)
163− when (null maints) (msgInfo ("no maintainers configured for " ++ path))
164− pkg <- readCabalFile name vers
165− io $ writeFile path (showNixPkg (cabal2nix pkg sha noHaddock plats' maints'))
143+ let Pkg name vers sha noHaddock plats maints path regenerate = nix
166144 modify $ \cfg -> cfg { _pkgset = Set.insert nix (_pkgset cfg) }
145+ when regenerate $ do
146+ msgDebug ("re-generate " ++ path)
147+ let maints' = nub (sort (maints ++ ["andres","simons"]))
148+ plats'
149+ | null plats && not (null maints) = ["self.ghc.meta.platforms"]
150+ | otherwise = plats
151+ when (null maints) (msgInfo ("no maintainers configured for " ++ path))
152+ pkg <- readCabalFile name vers
153+ io $ writeFile path (showNixPkg (cabal2nix pkg sha noHaddock plats' maints'))
167154 pkgset <- gets (selectLatestVersions . _pkgset)
168155 updates' <- flip mapM (Set.elems pkgset) $ \pkg -> do
169− let Pkg name vers _ _ _ _ _ = pkg
156+ let Pkg name vers _ _ _ _ _ _ = pkg
170157 updates <- discoverUpdates name vers
171158 return (pkg,updates)
172159 let updates = [ u | u@(_,(_:_)) <- updates' ]
173160 when (not (null updates)) $ do
174161 msgInfo "The following updates are available:"
175162 flip mapM_ updates $ \(pkg,versions) -> do
176− let Pkg name vers _ noHaddock plats maints path = pkg
163+ let Pkg name vers _ noHaddock plats maints path regenerate = pkg
177164 msgInfo ""
178165 msgInfo $ name ++ "-" ++ vers ++ ":"
179166 flip mapM_ versions $ \newVersion -> do
180− msgInfo $ " " ++ genCabal2NixCmdline (Pkg name newVersion undefined noHaddock plats maints path)
167+ msgInfo $ " " ++ genCabal2NixCmdline (Pkg name newVersion undefined noHaddock plats maints path regenerate)
181168 return ()
182169
183170genCabal2NixCmdline :: Pkg -> String
184−genCabal2NixCmdline (Pkg name vers _ noHaddock plats maints path) = unwords $ ["cabal2nix"] ++ opts ++ [">"++path']
171+genCabal2NixCmdline (Pkg name vers _ noHaddock plats maints path _) = unwords $ ["cabal2nix"] ++ opts ++ [">"++path']
185172 where
186173 opts = [cabal] ++ maints' ++ plats' ++ if noHaddock then ["--no-haddock"] else []
187174 cabal = "cabal://" ++ name ++ "-" ++ vers
188175 maints' = [ "--maintainer=" ++ m | m <- maints ]
189176 plats'
190− | ["self.ghc.meta.platforms"] == plats = []
191− | otherwise = [ "--platform=" ++ p | p <- plats ]
177+ | ["self.ghc.meta.platforms"] == plats = []
178+ | otherwise = [ "--platform=" ++ p | p <- plats ]
192179 path'
193− | path `regmatch` "/[0-9\\.]+\\.nix$" = replaceFileName path (vers <.> "nix")
194− | otherwise = path
180+ | path =~ "/[0-9\\.]+\\.nix$" = replaceFileName path (vers <.> "nix")
181+ | otherwise = path
195182
196183data CliOption = PrintHelp | Verbose | HackageDB FilePath
197184 deriving (Eq)
@@ -240,50 +227,48 @@ main = bracket (return ()) (\() -> hFlush stdout >> hFlush stderr) $ \() -> do
240227 flip evalStateT cfg (updateNixPkgs args)
241228
242229
230+-- Packages that we cannot parse.
231+
232+badPackagePaths :: [FilePath]
233+badPackagePaths = ["haskell-platform/2011.2.0.1.nix"]
243234
244235-- Packages that we cannot regenerate automatically yet. This list
245236-- should be empty.
246237
247−badPackages :: [String]
248−badPackages = [ "/"++p++"/" | p <- names ]
249− where names =
250− [ "alex" -- undeclared dependencies
251− , "CS173Tourney" -- parser error
252− , "get-options" -- parser error
253− , "WebServer" -- these two are not on Hackage
254− , "WebServer-Extras"
255− , "cairo" -- undeclared dependencies
256− , "citeproc-hs" -- undeclared dependencies
257− , "editline" -- undeclared dependencies
258− , "flapjax" -- parser error
259− , "glade" -- undeclared dependencies
260− , "glib" -- undeclared dependencies
261− , "epic" -- undeclared dependencies
262− , "GLUT" -- undeclared dependencies
263− , "gtk" -- undeclared dependencies
264− , "gtksourceview2" -- undeclared dependencies
265− , "haddock" -- undeclared dependencies
266− , "haskell-platform" -- not on Hackage
267− , "haskell-src" -- undeclared dependencies
268− , "hmatrix" -- undeclared dependencies
269− , "hp2any-graph" -- undeclared dependencies
270− , "lhs2tex" -- undeclared dependencies
271− , "OpenAL" -- undeclared dependencies
272− , "OpenGL" -- undeclared dependencies
273− , "pango" -- undeclared dependencies
274− , "idris" -- undeclared dependencies
275− , "readline" -- undeclared dependencies
276− , "repa-examples" -- undeclared dependencies
277− , "scion" -- expects non-existent networkBytestring
278− , "SDL" -- undeclared dependencies
279− , "SDL-image" -- undeclared dependencies
280− , "SDL-mixer" -- undeclared dependencies
281− , "SDL-ttf" -- undeclared dependencies
282− , "svgcairo" -- undeclared dependencies
283− , "terminfo" -- undeclared dependencies
284− , "xmonad" -- undeclared dependencies
285− , "vacuum" -- undeclared dependencies
286− , "wxHaskell" -- undeclared dependencies
287− , "X11"
288− , "X11-xft"
289− ]
238+patchedPackages :: [String]
239+patchedPackages =
240+ [ "alex" -- undeclared dependencies
241+ , "cairo" -- undeclared dependencies
242+ , "citeproc-hs" -- undeclared dependencies
243+ , "editline" -- undeclared dependencies
244+ , "glade" -- undeclared dependencies
245+ , "glib" -- undeclared dependencies
246+ , "epic" -- undeclared dependencies
247+ , "GLUT" -- undeclared dependencies
248+ , "gtk" -- undeclared dependencies
249+ , "gtksourceview2" -- undeclared dependencies
250+ , "haddock" -- undeclared dependencies
251+ , "haskell-src" -- undeclared dependencies
252+ , "hmatrix" -- undeclared dependencies
253+ , "hp2any-graph" -- undeclared dependencies
254+ , "lhs2tex" -- undeclared dependencies
255+ , "OpenAL" -- undeclared dependencies
256+ , "OpenGL" -- undeclared dependencies
257+ , "pango" -- undeclared dependencies
258+ , "idris" -- undeclared dependencies
259+ , "readline" -- undeclared dependencies
260+ , "repa-examples" -- undeclared dependencies
261+ , "scion" -- expects non-existent networkBytestring
262+ , "SDL" -- undeclared dependencies
263+ , "SDL-image" -- undeclared dependencies
264+ , "SDL-mixer" -- undeclared dependencies
265+ , "SDL-ttf" -- undeclared dependencies
266+ , "svgcairo" -- undeclared dependencies
267+ , "terminfo" -- undeclared dependencies
268+ , "xmonad" -- undeclared dependencies
269+ , "xmonad-extras" -- undeclared dependencies
270+ , "vacuum" -- undeclared dependencies
271+ , "wxcore" -- undeclared dependencies
272+ , "X11" -- undeclared dependencies
273+ , "X11-xft" -- undeclared dependencies
274+ ]