on c299dfe help sign in
elk/builder/src/File/Find.hs
99 lines 2.7 kB history raw
1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module File.Find
4 ( Asset(..)
5 , find
6 )
7 where
9import Control.Monad.Except (liftIO)
10import qualified Data.Map as Map
11import qualified Data.Maybe as Maybe
12import qualified System.Directory as Dir
13import System.FilePath ((</>), (<.>))
15import qualified Elm.Compiler.Module as Module
16import qualified Elm.Name as N
17import qualified Elm.Package as Pkg
19import qualified Elm.Project.Json as Project
20import qualified Elm.Project.Summary as Summary
21import qualified Reporting.Error.Crawl as E
22import qualified Reporting.Task as Task
26-- ASSET
29data Asset
30 = Local FilePath
31 | Kernel FilePath (Maybe FilePath)
32 | Foreign Pkg.Package
36-- FIND
39find :: Summary.Summary -> E.Origin -> Module.Raw -> Task.Task_ E.Problem Asset
40find (Summary.Summary root project exposed _ _) origin name =
41 case project of
42 Project.App info ->
43 do let srcDirs = map (root </>) (Project._app_source_dirs info)
44 findElm srcDirs exposed origin name
46 Project.Pkg _ ->
47 if N.startsWith "Elm.Kernel." name then
48 if Project.isPlatformPackage project then
49 findKernel (root </> "src") origin name
50 else
51 Task.throw $ E.ModuleNameReservedForKernel origin name
53 else
54 findElm [ root </> "src" ] exposed origin name
58-- FIND ELM
61findElm :: [FilePath] -> Summary.ExposedModules -> E.Origin -> Module.Raw -> Task.Task_ E.Problem Asset
62findElm srcDirs exposed origin name =
63 do
64 paths <- liftIO $ Maybe.catMaybes <$> mapM (elmExists name) srcDirs
66 case (paths, Map.lookup name exposed) of
67 ([path], Nothing) ->
68 return (Local path)
70 ([], Just [pkg]) ->
71 return (Foreign pkg)
73 ([], Nothing) ->
74 Task.throw $ E.ModuleNotFound origin name
76 (_, maybePkgs) ->
77 Task.throw $ E.ModuleAmbiguous origin name paths (maybe [] id maybePkgs)
80elmExists :: Module.Raw -> FilePath -> IO (Maybe FilePath)
81elmExists name srcDir =
82 do let path = srcDir </> Module.nameToSlashPath name <.> "elm"
83 exists <- Dir.doesFileExist path
84 return $ if exists then Just path else Nothing
88-- FIND KERNEL
91findKernel :: FilePath -> E.Origin -> Module.Raw -> Task.Task_ E.Problem Asset
92findKernel srcDir origin name =
93 do let clientPath = srcDir </> Module.nameToSlashPath name <.> "js"
94 let serverPath = srcDir </> Module.nameToSlashPath name <.> "server.js"
95 client <- liftIO $ Dir.doesFileExist clientPath
96 server <- liftIO $ Dir.doesFileExist serverPath
97 if client
98 then return $ Kernel clientPath (if server then Just serverPath else Nothing)
99 else Task.throw $ E.ModuleNotFound origin name