1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
12import Control.Monad.Except (liftIO)
13import qualified Data.ByteString as BS
14import qualified Data.Map as Map
15import qualified Data.Time.Calendar as Day
16import qualified Data.Time.Clock as Time
17import qualified System.Directory as Dir
19import qualified Elm.Header as Header
20import qualified Elm.ModuleName as ModuleName
21import qualified Elm.Project.Json as Project
22import Elm.Project.Json (Project)
23import Elm.Project.Summary (Summary(..))
24import qualified File.IO as IO
25import qualified Reporting.Exit as Exit
26import qualified Reporting.Exit.Crawl as E
27import qualified Reporting.Task as Task
37 , _time :: Time.UTCTime
38 , _source :: BS.ByteString
39 , _imports :: [ModuleName.Raw]
43atRoot :: Task.Task_ E.Problem a -> Task.Task_ E.Exit a
45 Task.mapError (\problem -> E.DependencyProblems problem []) task
51readModule :: Summary -> ModuleName.Raw -> FilePath -> Task.Task_ E.Problem (ModuleName.Raw, Info)
52readModule summary expectedName path =
53 do time <- liftIO $ Dir.getModificationTime path
54 source <- liftIO $ IO.readUtf8 path
55 (maybeName, info) <- parse (_project summary) path time source
56 name <- checkName path expectedName maybeName
60checkName :: FilePath -> ModuleName.Raw -> Maybe ModuleName.Raw -> Task.Task_ E.Problem ModuleName.Raw
61checkName path expectedName maybeName =
64 Task.throw (E.ModuleNameMissing path expectedName)
67 if expectedName == actualName
68 then return expectedName
69 else Task.throw (E.ModuleNameMismatch path expectedName actualName)
76readOneFile :: Summary -> FilePath -> Task.Task (Maybe ModuleName.Raw, Info)
77readOneFile summary path =
78 Task.mapError Exit.Crawl $
79 do (time, source) <- readOneHelp path
80 atRoot $ parse (_project summary) path time source
83readOneHelp :: FilePath -> Task.Task_ E.Exit (Time.UTCTime, BS.ByteString)
85 do exists <- IO.exists path
87 then liftIO $ (,) <$> Dir.getModificationTime path <*> IO.readUtf8 path
88 else Task.throw $ E.RootFileNotFound path
95readManyFiles :: Summary -> FilePath -> [FilePath] -> Task.Task ((ModuleName.Raw, Info), [(ModuleName.Raw, Info)])
96readManyFiles summary file files =
97 Task.mapError Exit.Crawl $
98 do info <- readManyFilesHelp summary file
99 infos <- traverse (readManyFilesHelp summary) files
100 let nameTable = foldr insert Map.empty (info:infos)
101 _ <- Map.traverseWithKey detectDuplicateNames nameTable
104 append (x,xs) (y,ys) = (x, xs ++ y : ys)
105 insert (k,v) dict = Map.insertWith append k (v, []) dict
108readManyFilesHelp :: Summary -> FilePath -> Task.Task_ E.Exit (ModuleName.Raw, Info)
109readManyFilesHelp summary path =
110 do (time, source) <- readOneHelp path
111 (maybeName, info) <- atRoot $ parse (_project summary) path time source
114 Task.throw (E.RootNameless path)
120detectDuplicateNames :: ModuleName.Raw -> (Info, [Info]) -> Task.Task_ E.Exit ()
121detectDuplicateNames name (info, otherInfos) =
127 Task.throw (E.RootModuleNameDuplicate name (map _path (info : otherInfos)))
135readSource :: Project -> BS.ByteString -> Task.Task (Maybe ModuleName.Raw, Info)
136readSource project source =
137 Task.mapError Exit.Crawl $
138 atRoot $ parse project "elm" fakeTime source
141fakeTime :: Time.UTCTime
143 Time.UTCTime (Day.fromGregorian 3000 1 1) 0
150parse :: Project -> FilePath -> Time.UTCTime -> BS.ByteString -> Task.Task_ E.Problem (Maybe ModuleName.Raw, Info)
151parse project path time source =
152 -- TODO get regions on data extracted here
153 case Header.parse (Project.getName project) source of
154 Right (maybeDecl, deps) ->
155 do maybeName <- checkTag project path maybeDecl
156 return ( maybeName, Info path time source deps )
159 Task.throw (E.BadHeader path time source msg)
162checkTag :: Project -> FilePath -> Maybe (Header.Tag, ModuleName.Raw) -> Task.Task_ E.Problem (Maybe ModuleName.Raw)
163checkTag project path maybeDecl =
183 Task.throw (E.PortsInPackage path name)
186 if Project.isPlatformPackage project then
190 Task.throw (E.EffectsUnexpected path name)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list