on master help sign in
Add --src-dir flag

Can be used multiple times. Makes it possible to have complex directory structure without cluttering up module names in Elm files.

commitde52caca8ea6c6a442b58ff3e63cf19eb7c26533 authorEvan Czaplicki <info@elm-lang.org> dateSat 5 Oct 2013, 16:12 (13 years ago) parenta505f7e
2 files changed+28−10
compiler/Compiler.hs+5−1 compiler/Initialize.hs+23−9
compiler/Compiler.hs+5−1
@@ -42,6 +42,7 @@ data Flags =
4242 , no_prelude :: Bool
4343 , cache_dir :: FilePath
4444 , build_dir :: FilePath
45+ , src_dir :: [FilePath]
4546 }
4647 deriving (Data,Typeable,Show,Eq)
4748
@@ -61,6 +62,8 @@ flags = Flags
6162 &= help "Directory for files cached to make builds faster. Defaults to cache/ directory."
6263 , build_dir = "build" &= typFile
6364 &= help "Directory for generated HTML and JS files. Defaults to build/ directory."
65+ , src_dir = ["."] &= typFile
66+ &= help "Additional source directories besides project root. Searched when using --make"
6467 , print_types = False
6568 &= help "Print out infered types of top-level definitions."
6669 , print_program = False
@@ -173,7 +176,8 @@ getRuntime flags =
173176build :: Flags -> FilePath -> IO ()
174177build flags rootFile = do
175178 let noPrelude = no_prelude flags
176− files <- if make flags then getSortedDependencies noPrelude rootFile else return [rootFile]
179+ files <- if make flags then getSortedDependencies (src_dir flags) noPrelude rootFile
180+ else return [rootFile]
177181 let ifaces = if noPrelude then Map.empty else Prelude.interfaces
178182 (moduleName, interfaces) <- buildFiles flags (length files) ifaces "" files
179183 js <- foldM appendToOutput BS.empty files
compiler/Initialize.hs+23−9
@@ -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