@@ -8,16 +8,23 @@ import System.Directory
8import System.Environment
8import System.Environment
9import System.Exit
9import System.Exit
10import Data.List
10import Data.List
11+-- import Distribution.Package
11import qualified Data.Set as Set
12import qualified Data.Set as Set
12import Control.Monad.State
13import Control.Monad.State
13import Control.Exception ( bracket )
14import Control.Exception ( bracket )
14import Text.Regex.Posix
15import Text.Regex.Posix
15import Data.Version
16import Data.Version
16−import Text.ParserCombinators.ReadP ( readP_to_S )
17+-- import Text.ParserCombinators.ReadP ( readP_to_S, readS_to_P )
17import Distribution.PackageDescription.Parse ( parsePackageDescription, ParseResult(..) )
18import Distribution.PackageDescription.Parse ( parsePackageDescription, ParseResult(..) )
18import Distribution.PackageDescription ( GenericPackageDescription() )
19import Distribution.PackageDescription ( GenericPackageDescription() )
20+import Distribution.Text
19import System.Console.GetOpt ( OptDescr(..), ArgDescr(..), ArgOrder(..), usageInfo, getOpt )
21import System.Console.GetOpt ( OptDescr(..), ArgDescr(..), ArgOrder(..), usageInfo, getOpt )
20−import Cabal2Nix.Package ( cabal2nix, showNixPkg, PkgName, PkgVersion, PkgSHA256, PkgPlatforms, PkgMaintainers, PkgNoHaddock )
22+import Cabal2Nix.Package
23+import Distribution.NixOS.Derivation.Cabal
24+import Distribution.NixOS.Derivation.Meta
26+data Pkg = Pkg Derivation FilePath Bool
27+ deriving (Show, Eq, Ord)
22type PkgSet = Set.Set Pkg
29type PkgSet = Set.Set Pkg
@@ -70,19 +77,10 @@ discoverNixFiles yield dirOrFile
70 (True,_) -> return ()
77 (True,_) -> return ()
71 (False,_) -> io (readDirectory dirOrFile) >>= mapM_ (discoverNixFiles yield . (dirOrFile </>))
78 (False,_) -> io (readDirectory dirOrFile) >>= mapM_ (discoverNixFiles yield . (dirOrFile </>))
73−type Regenerate = Bool
80+regenerateDerivation :: Derivation -> String -> Bool
74−data Pkg = Pkg PkgName PkgVersion PkgSHA256 PkgNoHaddock PkgPlatforms PkgMaintainers FilePath Regenerate
81+regenerateDerivation deriv buf = not (display (pname deriv) `elem` patchedPackages) &&
75− deriving (Show, Eq, Ord)
82+ not (buf =~ "preConfigure|configureFlags|postInstall|patchPhase")
77−regsubmatch :: String -> String -> [String]
78−regsubmatch buf patt = let (_,_,_,x) = f in x
79− where f :: (String,String,String,[String])
80− f = match (makeRegexOpts compExtended execBlank patt) buf
82−normalizeMaintainer :: String -> String
84− | "self.stdenv.lib.maintainers." `isPrefixOf` x = drop 28 x
87parseNixFile :: FilePath -> String -> Hackage4Nix (Maybe Pkg)
85parseNixFile :: FilePath -> String -> Hackage4Nix (Maybe Pkg)
88parseNixFile path buf
86parseNixFile path buf
@@ -92,46 +90,24 @@ parseNixFile path buf
92 = msgDebug ("ignore known bad package " ++ path) >> return Nothing
90 = msgDebug ("ignore known bad package " ++ path) >> return Nothing
93 | buf =~ "src = (fetchurl|fetchgit|sourceFromHead)"
91 | buf =~ "src = (fetchurl|fetchgit|sourceFromHead)"
94 = msgDebug ("ignore non-hackage package " ++ path) >> return Nothing
92 = msgDebug ("ignore non-hackage package " ++ path) >> return Nothing
95− | [name] <- buf `regsubmatch` "name *= *\"([^\"]+)\""
93+ | Just deriv <- parseDerivation buf
96− , [vers] <- buf `regsubmatch` "version *= *\"([^\"]+)\""
94+ = return (Just (Pkg deriv path (regenerateDerivation deriv buf)))
97− , [sha] <- buf `regsubmatch` "sha256 *= *\"([^\"]+)\""
98− , plats <- buf `regsubmatch` "platforms *= *([^;]+);"
99− , maint <- buf `regsubmatch` "maintainers *= *\\[([^\"]+)]"
100− , haddock <- buf `regsubmatch` "noHaddock *= *(true|false) *;"
101− = let plats' = concatMap words (map (map (\c -> if c == '+' then ' ' else c)) plats)
102− maint' = concatMap words maint
104− | "true":[] <- haddock = True
106− regenerate = not (name `elem` patchedPackages) &&
107− not (buf =~ "preConfigure|configureFlags|postInstall|patchPhase")
109− return $ Just $ Pkg name vers sha noHaddock plats'
110− (map normalizeMaintainer maint')
112 | otherwise = msgInfo ("failed to parse file " ++ path) >> return Nothing
95 | otherwise = msgInfo ("failed to parse file " ++ path) >> return Nothing
114−readVersion :: String -> Version
116− case [ v | (v,[]) <- readP_to_S parseVersion str ] of
118− _ -> error ("invalid version specifier " ++ show str)
120selectLatestVersions :: PkgSet -> PkgSet
97selectLatestVersions :: PkgSet -> PkgSet
121selectLatestVersions = Set.fromList . nubBy f2 . sortBy f1 . Set.toList
98selectLatestVersions = Set.fromList . nubBy f2 . sortBy f1 . Set.toList
123− f1 (Pkg n1 v1 _ _ _ _ _ _) (Pkg n2 v2 _ _ _ _ _ _)
100+ f1 (Pkg deriv1 _ _) (Pkg deriv2 _ _)
124− | n1 == n2 = compare v2 v1
101+ | pname deriv1 == pname deriv2 = compare (version deriv2) (version deriv1)
125− | otherwise = compare n1 n2
102+ | otherwise = compare (pname deriv1) (pname deriv2)
126− f2 (Pkg n1 _ _ _ _ _ _ _) (Pkg n2 _ _ _ _ _ _ _)
103+ f2 (Pkg deriv1 _ _) (Pkg deriv2 _ _) = pname deriv1 == pname deriv2
129−discoverUpdates :: PkgName -> PkgVersion -> Hackage4Nix [PkgVersion]
105+discoverUpdates :: String -> String -> Hackage4Nix [String]
130discoverUpdates name vers = do
106discoverUpdates name vers = do
131 hackage <- gets _hackageDb
107 hackage <- gets _hackageDb
132 versionStrings <- io $ readDirectory (hackage </> name)
108 versionStrings <- io $ readDirectory (hackage </> name)
133 let versions = map readVersion versionStrings
109 let versions = map readVersion versionStrings
134− return (sort [ showVersion v | v <- versions, v > readVersion vers ])
110+ return [ showVersion v | v <- versions, v > readVersion vers ]
136updateNixPkgs :: [FilePath] -> Hackage4Nix ()
112updateNixPkgs :: [FilePath] -> Hackage4Nix ()
137updateNixPkgs paths = do
113updateNixPkgs paths = do
@@ -140,45 +116,55 @@ updateNixPkgs paths = do
140 flip discoverNixFiles fileOrDir $ \file -> do
116 flip discoverNixFiles fileOrDir $ \file -> do
141 nix' <- io (readFile file) >>= parseNixFile file
117 nix' <- io (readFile file) >>= parseNixFile file
142 flip (maybe (return ())) nix' $ \nix -> do
118 flip (maybe (return ())) nix' $ \nix -> do
143− let Pkg name vers sha noHaddock plats maints path regenerate = nix
119+ let Pkg deriv path regenerate = nix
120+ maints = maintainers (metaSection deriv)
121+ plats = platforms (metaSection deriv)
122+ when (null maints) (msgInfo ("no maintainers configured for " ++ path))
144 modify $ \cfg -> cfg { _pkgset = Set.insert nix (_pkgset cfg) }
123 modify $ \cfg -> cfg { _pkgset = Set.insert nix (_pkgset cfg) }
145 when regenerate $ do
124 when regenerate $ do
146 msgDebug ("re-generate " ++ path)
125 msgDebug ("re-generate " ++ path)
147− let maints' = nub (sort (maints ++ ["andres","simons"]))
126+ let maints' = nub (sort (maints ++ ["self.stdenv.lib.maintainers.andres","self.stdenv.lib.maintainers.simons"]))
149 | null plats && not (null maints) = ["self.ghc.meta.platforms"]
128 | null plats && not (null maints) = ["self.ghc.meta.platforms"]
150 | otherwise = plats
129 | otherwise = plats
151− when (null maints) (msgInfo ("no maintainers configured for " ++ path))
152− pkg <- readCabalFile name vers
130+ pkg <- readCabalFile (display (pname deriv)) (display (version deriv))
153− io $ writeFile path (showNixPkg (cabal2nix pkg sha noHaddock plats' maints'))
131+ let deriv' = (cabal2nix pkg) { sha256 = sha256 deriv, runHaddock = runHaddock deriv }
132+ deriv'' = deriv' { metaSection = (metaSection deriv')
133+ { maintainers = maints'
134+ , platforms = plats'
137+ io $ writeFile path (show (disp deriv''))
154 pkgset <- gets (selectLatestVersions . _pkgset)
138 pkgset <- gets (selectLatestVersions . _pkgset)
155 updates' <- flip mapM (Set.elems pkgset) $ \pkg -> do
139 updates' <- flip mapM (Set.elems pkgset) $ \pkg -> do
156− let Pkg name vers _ _ _ _ _ _ = pkg
140+ let Pkg deriv _ _ = pkg
157− updates <- discoverUpdates name vers
141+ updates <- discoverUpdates (display (pname deriv)) (display (version deriv))
158 return (pkg,updates)
142 return (pkg,updates)
159 let updates = [ u | u@(_,(_:_)) <- updates' ]
143 let updates = [ u | u@(_,(_:_)) <- updates' ]
160 when (not (null updates)) $ do
144 when (not (null updates)) $ do
161 msgInfo "The following updates are available:"
145 msgInfo "The following updates are available:"
162 flip mapM_ updates $ \(pkg,versions) -> do
146 flip mapM_ updates $ \(pkg,versions) -> do
163− let Pkg name vers _ noHaddock plats maints path regenerate = pkg
147+ let Pkg deriv path regenerate = pkg
164 msgInfo ""
148 msgInfo ""
165− msgInfo $ name ++ "-" ++ vers ++ ":"
149+ msgInfo $ (display (pname deriv)) ++ "-" ++ (display (version deriv)) ++ ":"
166 flip mapM_ versions $ \newVersion -> do
150 flip mapM_ versions $ \newVersion -> do
151+ let deriv' = deriv { version = readVersion newVersion }
167− msgInfo $ " " ++ genCabal2NixCmdline (Pkg name newVersion undefined noHaddock plats maints path regenerate)
152+ msgInfo $ " " ++ genCabal2NixCmdline (Pkg deriv' path regenerate)
168 return ()
153 return ()
170genCabal2NixCmdline :: Pkg -> String
155genCabal2NixCmdline :: Pkg -> String
171−genCabal2NixCmdline (Pkg name vers _ noHaddock plats maints path _) = unwords $ ["cabal2nix"] ++ opts ++ [">"++path']
156+genCabal2NixCmdline (Pkg deriv path _) = unwords $ ["cabal2nix"] ++ opts ++ [">"++path']
158+ meta = metaSection deriv
173− opts = [cabal] ++ maints' ++ plats' ++ if noHaddock then ["--no-haddock"] else []
159+ opts = [cabal] ++ maints' ++ plats' ++ if runHaddock deriv then [] else ["--no-haddock"]
174− cabal = "cabal://" ++ name ++ "-" ++ vers
160+ cabal = "cabal://" ++ display (pname deriv) ++ "-" ++ display (version deriv)
175− maints' = [ "--maintainer=" ++ m | m <- maints ]
161+ maints' = [ "--maintainer=" ++ m | m <- maintainers meta ]
177− | ["self.ghc.meta.platforms"] == plats = []
163+ | ["self.ghc.meta.platforms"] == platforms meta = []
178− | otherwise = [ "--platform=" ++ p | p <- plats ]
164+ | otherwise = [ "--platform=" ++ p | p <- platforms meta ]
180− | path =~ "/[0-9\\.]+\\.nix$" = replaceFileName path (vers <.> "nix")
166+ | path =~ "/[0-9\\.]+\\.nix$" = replaceFileName path (display (version deriv) <.> "nix")
181− | otherwise = path
167+ | otherwise = path
183data CliOption = PrintHelp | Verbose | HackageDB FilePath
169data CliOption = PrintHelp | Verbose | HackageDB FilePath
184 deriving (Eq)
170 deriving (Eq)