54 lines
1.5 KiB
Haskell
54 lines
1.5 KiB
Haskell
{-# LANGUAGE ConstraintKinds #-}
|
|
module Context (
|
|
CodePath(..)
|
|
, Context(..)
|
|
, Contextual
|
|
, Path(..)
|
|
, packages
|
|
) where
|
|
|
|
import Control.Monad.Reader (MonadReader)
|
|
import Data.List (intercalate)
|
|
import System.Directory (doesDirectoryExist)
|
|
import System.Environment (lookupEnv)
|
|
import System.FilePath ((</>))
|
|
import System.Posix.User (getRealUserID, getUserEntryForID, homeDirectory)
|
|
import Text.ParserCombinators.ReadP (char, munch, sepBy)
|
|
import Text.ParserCombinators.ReadPrec (lift)
|
|
import Text.Read (readPrec)
|
|
|
|
newtype Path = Path [String] deriving (Eq, Ord)
|
|
newtype CodePath = CodePath [FilePath]
|
|
|
|
data Context = Context {
|
|
codePaths :: CodePath
|
|
, mainModule :: Path
|
|
}
|
|
|
|
type Contextual = MonadReader Context
|
|
|
|
instance Show Path where
|
|
show (Path components) = intercalate "." components
|
|
|
|
instance Read Path where
|
|
readPrec = fmap Path . lift $
|
|
munch (/= '.') `sepBy` char '.'
|
|
|
|
instance Show CodePath where
|
|
show (CodePath dirs) = intercalate ":" dirs
|
|
|
|
dbDirectory :: IO FilePath
|
|
dbDirectory = do
|
|
unixHome <- homeDirectory <$> (getUserEntryForID =<< getRealUserID)
|
|
home <- maybe unixHome id <$> lookupEnv "HOME"
|
|
maybe (home </> ".sjw") id <$> lookupEnv "SJW_PACKAGE_DB"
|
|
|
|
packages :: [String] -> IO [FilePath]
|
|
packages names = do
|
|
db <- dbDirectory
|
|
mapM (pathOrPackageName db) names
|
|
where
|
|
pathOrPackageName db name = do
|
|
directoryExists <- doesDirectoryExist name
|
|
return $ if directoryExists then name else db </> name
|