module Main where
import List
import Monad
import System
import Text.ParserCombinators.Poly
import CabalParse
-- A simple way of reading information from a .cabal file
-- for use by other external programs, e.g. in a shell script or Makefile.
-- The cmdline arg "-slash" just replaces dots by slashes (e.g. to translate
-- module names from Haskell notation to filepaths).
main = do
args <- getArgs
(dir,pkgs,action) <-
case args of
(dir:"depends":pkgs)
-> return (dir, pkgs, recursiveDeps)
_ -> stop "Usage: nhc98-pkg
depends ..."
depList <- action dir pkgs
putStrLn (unwords depList)
-- Given a directory in which to look for cabal files, and a list of starting
-- packages, return a list of all package dependencies in dep order, i.e.
-- top-most in the lattice first.
recursiveDeps :: FilePath -> [String] -> IO [String]
recursiveDeps dir [] = return []
recursiveDeps dir (pkg:pkgs) = do
deps <- depends dir pkg
newdeps <- recursiveDeps dir deps
rest <- recursiveDeps dir pkgs
return . minimise . (pkg:) $ newdeps++rest
-- Given a directory in which to look for cabal files, and a package name,
-- return the single-level (direct) dependencies noted in the .cabal file.
depends :: FilePath -> String -> IO [String]
depends dir pkg = do
content <- readFile (dir++"/"++pkg++".cabal")
cabal <- case runParser cabalFile (lexToken content) of
(Left e, _) -> stop e
(Right cabal, _) -> return cabal
let results = map (\field-> cabalLookup cabal field id)
["depends","build-depends"]
return . nub . words . unwords $ [ r | Right r <- results ]
-- Given a list of values in dependency order, remove duplicates from
-- the list, keeping the more basic items towards the end, i.e. those
-- with greater inward deps, and lesser outward deps.
minimise :: Eq a => [a] -> [a]
minimise = reverse . nub . reverse