@@ -6,6 +6,7 @@ import qualified Data.Graph as Graph
6import qualified Data.List as List
6import qualified Data.List as List
7import qualified Data.Map as Map
7import qualified Data.Map as Map
8import qualified Data.Set as Set
8import qualified Data.Set as Set
9+import System.Directory
9import System.Exit
10import System.Exit
10import System.FilePath as FP
11import System.FilePath as FP
11import Text.PrettyPrint (Doc)
12import Text.PrettyPrint (Doc)
@@ -62,9 +63,9 @@ buildFromSource noPrelude interfaces source =
62 return $ metaModule { types = types }
63 return $ metaModule { types = types }
65−getSortedDependencies :: Bool -> FilePath -> IO [String]
66+getSortedDependencies :: [FilePath] -> Bool -> FilePath -> IO [String]
66−getSortedDependencies noPrelude root =
67+getSortedDependencies srcDirs noPrelude root =
67− sortDeps =<< readDeps noPrelude root
68+ sortDeps =<< readDeps srcDirs noPrelude root
69type Deps = (FilePath, String, [String])
70type Deps = (FilePath, String, [String])
@@ -79,18 +80,18 @@ sortDeps depends =
79 mistakes = filter (\scc -> length scc > 1) sccs
80 mistakes = filter (\scc -> length scc > 1) sccs
80 msg = "A cyclical module dependency or was detected in: "
81 msg = "A cyclical module dependency or was detected in: "
82−readDeps :: Bool -> FilePath -> IO [Deps]
83+readDeps :: [FilePath] -> Bool -> FilePath -> IO [Deps]
83−readDeps noPrelude root = evalStateT (go root) Set.empty
84+readDeps srcDirs noPrelude root = evalStateT (go root) Set.empty
85 builtIns = if noPrelude then Set.empty
86 builtIns = if noPrelude then Set.empty
86 else Set.fromList (Map.keys Prelude.interfaces)
87 else Set.fromList (Map.keys Prelude.interfaces)
88 go :: FilePath -> StateT (Set.Set String) IO [Deps]
89 go :: FilePath -> StateT (Set.Set String) IO [Deps]
89 go root = do
90 go root = do
90− txt <- liftIO $ readFile root
91+ (root', txt) <- liftIO $ getFile srcDirs root
91 case Parse.dependencies txt of
92 case Parse.dependencies txt of
92 Left err -> liftIO (putStrLn msg >> print err >> exitFailure)
93 Left err -> liftIO (putStrLn msg >> print err >> exitFailure)
93− where msg = "Error resolving dependencies in " ++ root ++ ":"
94+ where msg = "Error resolving dependencies in " ++ root' ++ ":"
95 Right (name,deps) ->
96 Right (name,deps) ->
96 do seen <- get
97 do seen <- get
@@ -98,8 +99,21 @@ readDeps noPrelude root = evalStateT (go root) Set.empty
98 newDeps = Set.difference (Set.filter (not . isNative) realDeps) seen
99 newDeps = Set.difference (Set.filter (not . isNative) realDeps) seen
99 put (Set.insert name (Set.union newDeps seen))
100 put (Set.insert name (Set.union newDeps seen))
100 rest <- mapM (go . toFilePath) (Set.toList newDeps)
101 rest <- mapM (go . toFilePath) (Set.toList newDeps)
101− return ((makeRelative "." root, name, Set.toList realDeps) : concat rest)
102+ return ((makeRelative "." root', name, Set.toList realDeps) : concat rest)
104+getFile :: [FilePath] -> FilePath -> IO (FilePath,String)
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." ]
111+getFile (dir:dirs) path = do
112+ let path' = dir </> path
113+ exists <- doesFileExist path'
115+ True -> (,) path' `fmap` readFile path'
116+ False -> getFile dirs path
104isNative name = List.isPrefixOf "Native." name
118isNative name = List.isPrefixOf "Native." name