2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Task.Http
16import Control.Concurrent (forkIO)
17import Control.Concurrent.Chan (Chan, newChan, readChan, writeChan)
18import Control.Concurrent.MVar (MVar, newEmptyMVar, putMVar, readMVar)
19import Control.Exception (Exception, SomeException, catch)
20import Control.Monad (forever, join, replicateM_, void)
21import qualified Data.ByteString.Char8 as BS
22import qualified Network.HTTP as Http (urlEncodeVars)
23import qualified Network.HTTP.Client as Http
24import qualified Network.HTTP.Types.Header as Http (hAcceptEncoding, hUserAgent)
26import qualified Elm.Compiler as Compiler
27import qualified Elm.Package as Pkg
28import qualified Reporting.Exit as Exit
29import qualified Reporting.Exit.Http as E
30import qualified Reporting.Progress as Progress
31import qualified Reporting.Task as Task
39 Package :: String -> [(String,String)] -> Handler a -> Fetch a
40 Anything :: String -> Handler a -> Fetch a
41 AndThen :: Fetch a -> (a -> Fetch b) -> Fetch b
42 Parallel :: [Fetch a] -> Fetch [a]
43 Report :: Progress.Progress -> (Progress.Outcome -> Progress.Progress) -> Fetch a -> Fetch a
47 Http.Request -> Http.Manager -> IO (Either E.Exit a)
50package :: String -> [(String,String)] -> Handler a -> Fetch a
55anything :: String -> Handler a -> Fetch a
60andThen :: Fetch a -> (a -> Fetch b) -> Fetch b
65parallel :: [Fetch a] -> Fetch [a]
70report :: Progress.Progress -> (Progress.Outcome -> Progress.Progress) -> Fetch a -> Fetch a
79run :: Fetch a -> Task.Task a
81 Task.runHttp $ \manager tell ->
83 replicateM_ 4 $ forkIO $ forever $ join (readChan chan)
84 readMVar =<< runHelp chan manager tell fetch
87runHelp :: Chan (IO ()) -> Http.Manager -> (Progress.Progress -> IO ()) -> Fetch a -> IO (MVar (Either Exit.Exit a))
88runHelp chan manager tell fetch =
90 Package path params handler ->
91 do mvar <- newEmptyMVar
92 let url = makePackageUrl path params
93 writeChan chan $ putMVar mvar =<< fetchSafe url manager handler
96 Anything url handler ->
97 do mvar <- newEmptyMVar
98 writeChan chan $ putMVar mvar =<< fetchSafe url manager handler
101 AndThen subFetch callback ->
102 do subMVar <- runHelp chan manager tell subFetch
105 do result <- readMVar subMVar
111 readMVar =<< runHelp chan manager tell (callback value)
115 do mvars <- mapM (runHelp chan manager tell) fetches
118 do results <- mapM readMVar mvars
119 putMVar mvar (sequence results)
122 Report start toEnd subFetch ->
124 subMVar <- runHelp chan manager tell subFetch
127 do result <- readMVar subMVar
129 either (\_ -> Progress.Bad) (\_ -> Progress.Good) result
138packageDomain :: String
140 "https://alpha.elm-lang.org"
143makePackageUrl :: String -> [(String,String)] -> String
144makePackageUrl path params =
150 "?" ++ Http.urlEncodeVars params
152 packageDomain ++ "/" ++ path ++ query
159fetchSafe :: String -> Http.Manager -> Handler a -> IO (Either Exit.Exit a)
160fetchSafe url manager handler =
161 fetchUnsafe url manager handler
162 `catch` \e -> handleAnyError url (e :: SomeException)
165fetchUnsafe :: String -> Http.Manager -> Handler a -> IO (Either Exit.Exit a)
166fetchUnsafe url manager handler =
167 do request <- Http.parseUrlThrow url
168 result <- handler (addHeaders request) manager
174 return (Left (Exit.BadHttp url problem))
177handleAnyError :: (Exception e) => String -> e -> IO (Either Exit.Exit a)
178handleAnyError url exception =
179 return $ Left $ Exit.BadHttp url $ E.Unknown $ show exception
182addHeaders :: Http.Request -> Http.Request
185 { Http.requestHeaders =
186 [ (Http.hUserAgent, userAgent)
187 , (Http.hAcceptEncoding, "gzip")
192{-# NOINLINE userAgent #-}
193userAgent :: BS.ByteString
195 BS.pack ("elm/" ++ Pkg.versionToString Compiler.version)
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