diff --git a/Language/Haskell/GhcMod/Cradle.hs b/Language/Haskell/GhcMod/Cradle.hs index 8deea9a..780ff71 100644 --- a/Language/Haskell/GhcMod/Cradle.hs +++ b/Language/Haskell/GhcMod/Cradle.hs @@ -4,6 +4,7 @@ module Language.Haskell.GhcMod.Cradle ( findCradle , findCradleWithoutSandbox , getPackageDbDir + , getPackageDbPackages ) where import Data.Char (isSpace) @@ -141,3 +142,43 @@ extractGhcVer dir = ver (verStr1,_:left) = break (== '.') $ findVer file (verStr2,_) = break (== '.') left ver = read verStr1 * 100 + read verStr2 + +-- | Obtaining packages installed in a package db directory. +getPackageDbPackages :: FilePath -> IO [Package] +getPackageDbPackages cdir = (getPkgDb >>= listDbPackages) `E.catch` handler + where + getPkgDb = getPackageDbDir (cdir configFile) + handler :: SomeException -> IO [Package] + handler _ = return [] + +listDbPackages :: FilePath -> IO [Package] +listDbPackages pkgdir = do + files <- filter (".conf" `isSuffixOf`) <$> getDirectoryContents pkgdir + mapM extractPackage $ map (pkgdir ) files + +extractPackage :: FilePath -> IO Package +extractPackage pconf = do + contents <- lines <$> readFile pconf + -- Be strict to ensure that an error can be caught. + let !name = extractName $ parseName contents + !pid = extractId $ parseId contents + return (name, Just pid) + where + parseName = parse nameKey + extractName = extract nameKeyLength + parseId = parse idKey + extractId = extract idKeyLength + parse key = head . filter (key `isPrefixOf`) + extract keylen = fst . break isSpace . dropWhile isSpace . drop keylen + +nameKey :: String +nameKey = "name:" + +idKey :: String +idKey = "id:" + +nameKeyLength :: Int +nameKeyLength = length nameKey + +idKeyLength :: Int +idKeyLength = length idKey diff --git a/test/CradleSpec.hs b/test/CradleSpec.hs index c6d0243..87c47ad 100644 --- a/test/CradleSpec.hs +++ b/test/CradleSpec.hs @@ -53,6 +53,11 @@ spec = do it "throws an error if a config file is broken" $ do getPackageDbDir "test/data/bad.config" `shouldThrow` anyException + describe "getPackageDbPackages" $ do + it "find a config file and extracts packages with their ids" $ do + pkgs <- getPackageDbPackages "test/data/check-packageid" + pkgs `shouldBe` [("template-haskell", Just "template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c")] + relativeCradle :: FilePath -> Cradle -> Cradle relativeCradle dir cradle = cradle { cradleCurrentDir = toRelativeDir dir $ cradleCurrentDir cradle diff --git a/test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf b/test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf new file mode 100644 index 0000000..26a27e3 --- /dev/null +++ b/test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf @@ -0,0 +1,37 @@ +name: template-haskell +version: 2.8.0.0 +id: template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c +license: BSD3 +copyright: +maintainer: libraries@haskell.org +stability: +homepage: +package-url: +synopsis: +description: Facilities for manipulating Haskell source code using Template Haskell. +category: +author: +exposed: True +exposed-modules: Language.Haskell.TH.Syntax + Language.Haskell.TH.PprLib Language.Haskell.TH.Ppr + Language.Haskell.TH.Lib Language.Haskell.TH.Quote + Language.Haskell.TH +hidden-modules: +trusted: False +import-dirs: /usr/lib64/ghc-7.6.3/template-haskell-2.8.0.0 +library-dirs: /usr/lib64/ghc-7.6.3/template-haskell-2.8.0.0 +hs-libraries: HStemplate-haskell-2.8.0.0 +extra-libraries: +extra-ghci-libraries: +include-dirs: +includes: +depends: base-4.6.0.1-2bc8d09dc7b7883c4b97d1eb4a9d4ac8 + containers-0.5.0.0-120bacdd7a06bf9f1f601811aa72d6c3 + pretty-1.1.1.0-65070790589ca7952412e425f427ac56 +hugs-options: +cc-options: +ld-options: +framework-dirs: +frameworks: +haddock-interfaces: /usr/share/doc/ghc-7.6.3/html/libraries/template-haskell-2.8.0.0/template-haskell.haddock +haddock-html: /usr/share/doc/ghc-7.6.3/html/libraries/template-haskell-2.8.0.0 diff --git a/test/data/check-packageid/cabal.sandbox.config b/test/data/check-packageid/cabal.sandbox.config new file mode 100644 index 0000000..4de501a --- /dev/null +++ b/test/data/check-packageid/cabal.sandbox.config @@ -0,0 +1,25 @@ +-- This is a Cabal package environment file. +-- THIS FILE IS AUTO-GENERATED. DO NOT EDIT DIRECTLY. +-- Please create a 'cabal.config' file in the same directory +-- if you want to change the default settings for this sandbox. + + +local-repo: /home/me/work/ghc-mod/test/data/.cabal-sandbox/packages +logs-dir: /home/me/work/ghc-mod/test/data/.cabal-sandbox/logs +world-file: /home/me/work/ghc-mod/test/data/.cabal-sandbox/world +user-install: False +package-db: test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d +build-summary: /home/me/work/ghc-mod/test/data/.cabal-sandbox/logs/build.log + +install-dirs + prefix: /home/me/work/ghc-mod/test/data/.cabal-sandbox + bindir: $prefix/bin + libdir: $prefix/lib + libsubdir: $arch-$os-$compiler/$pkgid + libexecdir: $prefix/libexec + datadir: $prefix/share + datasubdir: $arch-$os-$compiler/$pkgid + docdir: $datadir/doc/$arch-$os-$compiler/$pkgid + htmldir: $docdir/html + haddockdir: $htmldir + sysconfdir: $prefix/etc