packages feed

yi-0.4: Shim/CabalInfo.hs

module Shim.CabalInfo where

import Shim.Utils

import qualified Control.Exception as CE
import System.FilePath ( takeDirectory, (</>), (<.>), dropFileName, equalFilePath )
import Control.Monad.State
import Data.Maybe

import Control.Applicative
import Distribution.Simple.Utils
import Distribution.PackageDescription 
import qualified Distribution.PackageDescription as Library (Library(..))
import qualified Distribution.PackageDescription as BuildInfo (BuildInfo(..))
import System.Directory (canonicalizePath)

guessCabalFile :: String -> IO (Maybe FilePath)
guessCabalFile sourcefile = do
  let dir = takeDirectory $ dropFileName sourcefile 
  recurseDir findCabalFile dir  -- "/bar/foo/s.hs" -> "/bar/foo"
 where findCabalFile dir = do
         logS $ "looking in: " ++ dir
         pdfile <- CE.try (findPackageDesc dir)
         case pdfile of
           Right f -> return . Just $ dir </> f
           Left _ -> return Nothing

-- | Guess what lib/exe the sourcefile belongs to.
guessCabalStanza :: FilePath -> FilePath -> PackageDescription -> IO (Maybe String, BuildInfo)
guessCabalStanza projpath sourcefile pkg_descr = do
  matchingStanzas <- filterM matchingStanza allStanzas'
  let ((name, _, bi):_) = matchingStanzas ++ allStanzas'
  return (name, bi)
  where allStanzas = 
            [ (Nothing, concatMap moduleFiles (Library.exposedModules lib) , libBuildInfo lib) 
             | Just lib <- [library pkg_descr] ]
         ++ [ (Just (exeName exe), [modulePath exe], buildInfo exe) 
             | exe <- executables pkg_descr ]
        moduleFiles mod = [dotToSep mod <.> ext | ext <- ["hs", "lhs"] ]
        allStanzas' = [(name, [projpath </> dir </> file | dir <- hsSourceDirs bi, file <- files ++ concatMap moduleFiles (BuildInfo.otherModules bi)], bi)
                       | (name, files, bi) <- allStanzas, buildable bi]
        eqPath p1 p2 = equalFilePath <$> canonicalizePath p1 <*> canonicalizePath p2
        matchingStanza (_,files,_) = or <$> mapM (eqPath sourcefile) files