git.iko.soy/typeable/cabal2nix
on f2db36c help sign in
41 lines 1.5 kB history raw
1module Distribution.Nixpkgs.PackageMap where
3import qualified Data.Aeson as JSON
4import qualified Data.ByteString.Lazy as LBS
5import Data.List.Split
6import qualified Data.Map as Map
7import Data.Map.Strict ( Map )
8import Data.Set ( Set )
9import qualified Data.Set as Set
10import System.Process
12type Attribute = String
13type Path = [Attribute]
15readNixpkgAttributeSet :: FilePath -> IO (Set Attribute)
16readNixpkgAttributeSet nixpkgs = do
17 (_, Just h, _, _) <- createProcess (proc "nix-env" ["-qaP", "--json", "-f"++nixpkgs])
18 { std_out = CreatePipe
19 }
20 buf <- LBS.hGetContents h
21 let pkgmap :: Either String (Map Attribute JSON.Object)
22 pkgmap = JSON.eitherDecode buf
23 either fail (return . Map.keysSet) pkgmap
25parsePackage :: Attribute -> (Attribute, Path)
26parsePackage "" = error "empty string is not a valid package name"
27parsePackage x = (last xs, init xs) where xs = splitOn "." x
29type PackageMap = Map Attribute (Set Path)
31attributeSet2PackageMap :: Set Attribute -> PackageMap
32attributeSet2PackageMap pkgset = foldr (uncurry insertAttribute) Map.empty pkglist
33 where
34 pkglist :: [(Attribute, Path)]
35 pkglist = Set.toList (Set.map parsePackage pkgset)
37 insertAttribute :: Attribute -> Path -> PackageMap -> PackageMap
38 insertAttribute attr = Map.insertWith Set.union attr . Set.singleton
40readNixpkgPackageMap :: FilePath -> IO PackageMap
41readNixpkgPackageMap nixpkgs = fmap attributeSet2PackageMap (readNixpkgAttributeSet nixpkgs)