@@ -1,14 +1,18 @@
1module Build.Dependencies (getSortedDependencies) where
1module Build.Dependencies (getSortedDependencies) where
3import Data.Data
3import Data.Data
4+import Control.Applicative
4import Control.Monad.State
5import Control.Monad.State
6+import qualified Data.Char as Char
5import qualified Data.Graph as Graph
7import qualified Data.Graph as Graph
6import qualified Data.List as List
8import qualified Data.List as List
7import qualified Data.Map as Map
9import qualified Data.Map as Map
10+import qualified Data.Maybe as Maybe
8import qualified Data.Set as Set
11import qualified Data.Set as Set
9import System.Directory
12import System.Directory
10import System.Exit
13import System.Exit
11import System.FilePath as FP
14import System.FilePath as FP
12import Text.PrettyPrint (Doc)
16import Text.PrettyPrint (Doc)
14import SourceSyntax.Everything
18import SourceSyntax.Everything
@@ -23,7 +27,57 @@ import qualified Transform.Canonicalize as Canonical
24getSortedDependencies :: [FilePath] -> Interfaces -> FilePath -> IO [String]
28getSortedDependencies :: [FilePath] -> Interfaces -> FilePath -> IO [String]
25getSortedDependencies srcDirs builtIns root =
29getSortedDependencies srcDirs builtIns root =
30+ do extras <- additionalSourceDirs
26− sortDeps =<< readDeps srcDirs builtIns root
31+ sortDeps =<< readDeps (srcDirs ++ extras) builtIns root
33+additionalSourceDirs :: IO [FilePath]
34+additionalSourceDirs =
35+ do exists <- doesDirectoryExist deps
36+ if exists then getProjects deps else return []
38+ deps = "elm_dependencies"
41+ subs <- map (dir </>) <$> getDirectoryContents dir
42+ projects <- filterM isProject subs
43+ Maybe.catMaybes <$> mapM getLatest projects
45+ getLatest project = do
46+ subs <- getDirectoryContents project
47+ case Maybe.mapMaybe version subs of
49+ versions -> return $ Just $ (project </>) $ showVersion maxVersion
50+ where maxVersion = List.maximumBy compareVersion versions
53+ exists <- doesDirectoryExist path
54+ return $ exists && path `notElem` [".","..","_internals"]
56+showVersion (ns,tag) =
57+ List.intercalate "." (map show ns) ++ if null tag then "" else "-" ++ tag
60+ case compare (fst a) (fst b) of
61+ EQ -> compare (snd b) (snd a) -- reverse comparison to favor ""
64+version :: String -> Maybe ([Int], String)
65+version version = (,) <$> splitNumbers possibleNumbers <*> tag
67+ (possibleNumbers, possibleTag) = break (=='-') version
69+ tag = case possibleTag of
71+ '-':rest -> Just rest
74+ splitNumbers :: String -> Maybe [Int]
76+ case span Char.isDigit ns of
78+ (number, []) -> Just [read number]
79+ (number, '.':rest) -> (read number :) <$> splitNumbers rest
28type Deps = (FilePath, String, [String])
82type Deps = (FilePath, String, [String])
@@ -60,9 +114,10 @@ readDeps srcDirs builtIns root = do
61getFile :: [FilePath] -> FilePath -> IO (FilePath,String)
115getFile :: [FilePath] -> FilePath -> IO (FilePath,String)
62getFile [] path = do
116getFile [] path = do
117+ hPutStrLn stderr $ unlines
63− putStrLn $ unlines [ "Could not find file: " ++ path
118+ [ "Could not find file: " ++ path
64− , " If it is not in the root directory of your project, use"
119+ , " If it is not in the root directory of your project, use"
65− , " --src-dir to declare additional locations for source files." ]
120+ , " --src-dir to declare additional locations for source files." ]
66 exitFailure
121 exitFailure
68getFile (dir:dirs) path = do
123getFile (dir:dirs) path = do