Skip to content

Instantly share code, notes, and snippets.

@nkpart
Created December 7, 2012 04:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nkpart/4230735 to your computer and use it in GitHub Desktop.
Save nkpart/4230735 to your computer and use it in GitHub Desktop.
cahoogle - hoogle within the dependencies specified in a cabal file

cahoogle

Hoogle your cabal file's dependencies. These get turned into +package flags for hoogle.

Usage

Copy, stick on your path, chmod +x it.

You should have already installed hoogle, and generated data for your installed packages.

Then, use it just like hoogle:

$ cd ~/my-project
$ ls *.cabal
kit.cabal
$ cahoogle globDir1
["+base","+glob","+attoparsec","+ansi-terminal","+cabal-file-th","+cmdargs","+containers","+errors","+yaml","+directory","+filepath","+mtl","+process","+unordered-containers","+text","+unix"]
System.FilePath.Glob globDir1 :: Pattern -> FilePath -> IO [FilePath]    
#!/usr/bin/env runghc
import System.Directory (getCurrentDirectory, getDirectoryContents)
import Data.List (isSuffixOf)
import Distribution.Verbosity (silent)
import System.Process (readProcess)
import System.Environment (getArgs)
import Distribution.PackageDescription.Parse (readPackageDescription)
import Distribution.PackageDescription (condLibrary, condExecutables, condTestSuites, condBenchmarks, condTreeConstraints)
import Distribution.Package (Dependency(..))
import Distribution.Text (display)
import Data.Maybe (maybeToList)
import Data.Char (toLower)
main :: IO ()
main = do
args <- getArgs
dir <- getCurrentDirectory
files <- getDirectoryContents dir
let cabalFiles = filter (".cabal" `isSuffixOf`) files
case cabalFiles of
(c:_) -> putStrLn =<< cahoogle c args
[] -> error $ "Couldn't find a cabal file in the current working directory (" ++ dir ++ ")"
cahoogle :: FilePath -> [String] -> IO String
cahoogle cabalFile opts = do
deps <- map depOpts `fmap` allDependencies cabalFile
print deps
readProcess "hoogle" (deps ++ opts) ""
allDependencies :: FilePath -> IO [Dependency]
allDependencies cabalFile = do
v <- readPackageDescription silent cabalFile
let f ct = condTreeConstraints =<< ct v
return $ f (maybeToList . condLibrary) ++ f (map snd . condExecutables) ++ f (map snd . condTestSuites) ++ f (map snd . condBenchmarks)
depOpts :: Dependency -> String
depOpts = ("+"++) . map toLower . display . \v -> case v of (Dependency a _) -> a
-- -- Old dep-finding method, this might be the way to go for old-style
-- -- cabal files?
-- deps :: PackageDescription -> [Dependency]
-- deps pd = let base = buildDepends pd
-- exes = fmap buildInfo (executables pd) >>= targetBuildDepends
-- libs = maybe [] (targetBuildDepends . libBuildInfo) $ library pd
-- in base ++ exes ++ libs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment