on master help sign in
Automatically look in elm_dependencies/ and use the latest version available
fe7e319Evan Czaplicki
compiler/Build/Dependencies.hs+59−4
@@ -1,14 +1,18 @@
1module Build.Dependencies (getSortedDependencies) where
1module Build.Dependencies (getSortedDependencies) where
2
2
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
15+import System.IO
12import Text.PrettyPrint (Doc)
16import Text.PrettyPrint (Doc)
13
17
14import SourceSyntax.Everything
18import SourceSyntax.Everything
@@ -23,7 +27,57 @@ import qualified Transform.Canonicalize as Canonical
23
27
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
32+
33+additionalSourceDirs :: IO [FilePath]
34+additionalSourceDirs =
35+ do exists <- doesDirectoryExist deps
36+ if exists then getProjects deps else return []
37+ where
38+ deps = "elm_dependencies"
39+
40+ getProjects dir = do
41+ subs <- map (dir </>) <$> getDirectoryContents dir
42+ projects <- filterM isProject subs
43+ Maybe.catMaybes <$> mapM getLatest projects
44+
45+ getLatest project = do
46+ subs <- getDirectoryContents project
47+ case Maybe.mapMaybe version subs of
48+ [] -> return Nothing
49+ versions -> return $ Just $ (project </>) $ showVersion maxVersion
50+ where maxVersion = List.maximumBy compareVersion versions
51+
52+ isProject path = do
53+ exists <- doesDirectoryExist path
54+ return $ exists && path `notElem` [".","..","_internals"]
55+
56+showVersion (ns,tag) =
57+ List.intercalate "." (map show ns) ++ if null tag then "" else "-" ++ tag
58+
59+compareVersion a b =
60+ case compare (fst a) (fst b) of
61+ EQ -> compare (snd b) (snd a) -- reverse comparison to favor ""
62+ cmp -> cmp
63+
64+version :: String -> Maybe ([Int], String)
65+version version = (,) <$> splitNumbers possibleNumbers <*> tag
66+ where
67+ (possibleNumbers, possibleTag) = break (=='-') version
68+
69+ tag = case possibleTag of
70+ "" -> Just ""
71+ '-':rest -> Just rest
72+ _ -> Nothing
73+
74+ splitNumbers :: String -> Maybe [Int]
75+ splitNumbers ns =
76+ case span Char.isDigit ns of
77+ ("", _) -> Nothing
78+ (number, []) -> Just [read number]
79+ (number, '.':rest) -> (read number :) <$> splitNumbers rest
80+ _ -> Nothing
27
81
28type Deps = (FilePath, String, [String])
82type Deps = (FilePath, String, [String])
29
83
@@ -60,9 +114,10 @@ readDeps srcDirs builtIns root = do
60
114
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
67
122
68getFile (dir:dirs) path = do
123getFile (dir:dirs) path = do