@@ -6,6 +6,7 @@ import qualified Data.Graph as Graph
66import qualified Data.List as List
77import qualified Data.Map as Map
88import qualified Data.Set as Set
9+import System.Directory
910import System.Exit
1011import System.FilePath as FP
1112import Text.PrettyPrint (Doc)
@@ -62,9 +63,9 @@ buildFromSource noPrelude interfaces source =
6263 return $ metaModule { types = types }
6364
6465
65−getSortedDependencies :: Bool -> FilePath -> IO [String]
66−getSortedDependencies noPrelude root =
67− sortDeps =<< readDeps noPrelude root
66+getSortedDependencies :: [FilePath] -> Bool -> FilePath -> IO [String]
67+getSortedDependencies srcDirs noPrelude root =
68+ sortDeps =<< readDeps srcDirs noPrelude root
6869
6970type Deps = (FilePath, String, [String])
7071
@@ -79,18 +80,18 @@ sortDeps depends =
7980 mistakes = filter (\scc -> length scc > 1) sccs
8081 msg = "A cyclical module dependency or was detected in: "
8182
82−readDeps :: Bool -> FilePath -> IO [Deps]
83−readDeps noPrelude root = evalStateT (go root) Set.empty
83+readDeps :: [FilePath] -> Bool -> FilePath -> IO [Deps]
84+readDeps srcDirs noPrelude root = evalStateT (go root) Set.empty
8485 where
8586 builtIns = if noPrelude then Set.empty
8687 else Set.fromList (Map.keys Prelude.interfaces)
8788
8889 go :: FilePath -> StateT (Set.Set String) IO [Deps]
8990 go root = do
90− txt <- liftIO $ readFile root
91+ (root', txt) <- liftIO $ getFile srcDirs root
9192 case Parse.dependencies txt of
9293 Left err -> liftIO (putStrLn msg >> print err >> exitFailure)
93− where msg = "Error resolving dependencies in " ++ root ++ ":"
94+ where msg = "Error resolving dependencies in " ++ root' ++ ":"
9495
9596 Right (name,deps) ->
9697 do seen <- get
@@ -98,8 +99,21 @@ readDeps noPrelude root = evalStateT (go root) Set.empty
9899 newDeps = Set.difference (Set.filter (not . isNative) realDeps) seen
99100 put (Set.insert name (Set.union newDeps seen))
100101 rest <- mapM (go . toFilePath) (Set.toList newDeps)
101− return ((makeRelative "." root, name, Set.toList realDeps) : concat rest)
102−
102+ return ((makeRelative "." root', name, Set.toList realDeps) : concat rest)
103+
104+getFile :: [FilePath] -> FilePath -> IO (FilePath,String)
105+getFile [] path = do
106+ putStrLn $ unlines [ "Could not find file: " ++ path
107+ , " If it is not in the root directory of your project, use"
108+ , " --src-dir to declare additional locations for source files." ]
109+ exitFailure
110+
111+getFile (dir:dirs) path = do
112+ let path' = dir </> path
113+ exists <- doesFileExist path'
114+ case exists of
115+ True -> (,) path' `fmap` readFile path'
116+ False -> getFile dirs path
103117
104118isNative name = List.isPrefixOf "Native." name
105119