1
1
{-# LANGUAGE FlexibleContexts #-}
2
2
{-# LANGUAGE FlexibleInstances #-}
3
3
{-# LANGUAGE GADTs #-}
4
- {-# LANGUAGE OverloadedStrings #-}
5
4
6
5
module Restyler.App.Class
7
- ( MonadApp (.. )
6
+ (
7
+ -- * Data
8
+ HasOptions (.. )
9
+ , HasConfig (.. )
10
+ , HasPullRequest (.. )
11
+ , HasRestyledPullRequest (.. )
12
+ , HasWorkingDirectory (.. )
13
+
14
+ -- * Capabilities
15
+ , HasSystem (.. )
16
+ , HasExit (.. )
17
+ , HasProcess (.. )
18
+ , HasDownloadFile (.. )
19
+ , HasGitHub (.. )
20
+ , runGitHubFirst
21
+ , runGitHub_
8
22
9
23
-- * Re-exports
10
24
-- |
@@ -21,129 +35,47 @@ module Restyler.App.Class
21
35
22
36
import Restyler.Prelude
23
37
24
- import Conduit (runResourceT , sinkFile )
25
38
import GitHub.Endpoints.Issues.Comments hiding (comment , comments )
26
39
import GitHub.Endpoints.Issues.Labels
27
40
import GitHub.Endpoints.PullRequests hiding (pullRequest )
28
41
import GitHub.Endpoints.PullRequests.ReviewRequests
29
42
import GitHub.Endpoints.Repos.Statuses
30
- import GitHub.Request
31
- import Network.HTTP.Client.TLS
32
- import Network.HTTP.Simple hiding (Request )
33
- import Restyler.App.Type
34
- import qualified RIO.Directory as Directory
35
- import qualified RIO.Text as T
43
+ import Restyler.Config
44
+ import Restyler.Options
45
+ import Restyler.PullRequest
36
46
import qualified RIO.Vector as V
37
- import qualified System.Exit as Exit
38
- import qualified System.Process as Process
39
47
40
- class
41
- ( Monad m
42
- , MonadLogger m
43
- , MonadReader App m
44
- , MonadError AppError m
45
- )
46
- => MonadApp m where
47
- runGitHub :: Request k a -> m a
48
+ class HasWorkingDirectory env where
49
+ workingDirectoryL :: Lens' env FilePath
48
50
49
- -- | Fetch the first page using @'runGitHub'@, return the first item
50
- runGitHubFirst :: (FetchCount -> Request k (Vector a )) -> m (Maybe a )
51
- runGitHubFirst f = (V. !? 0 ) <$> runGitHub (f 1 )
51
+ class HasSystem env where
52
+ getCurrentDirectory :: RIO env FilePath
53
+ setCurrentDirectory :: FilePath -> RIO env ()
54
+ doesFileExist :: FilePath -> RIO env Bool
55
+ readFile :: FilePath -> RIO env Text
52
56
53
- -- | @'void' . 'runGitHub'@
54
- runGitHub_ :: Request k a -> m ()
55
- runGitHub_ = void . runGitHub
57
+ class HasExit env where
58
+ exitSuccess :: RIO env ()
56
59
57
- getCurrentDirectory :: m FilePath
58
- setCurrentDirectory :: FilePath -> m ()
60
+ class HasProcess env where
61
+ callProcess :: String -> [String ] -> RIO env ()
62
+ readProcess :: String -> [String ] -> String -> RIO env String
59
63
60
- doesFileExist :: FilePath -> m Bool
61
- readFile :: FilePath -> m Text
64
+ -- class HasProcess env => HasGit env where
62
65
63
- exitSuccess :: m ()
66
+ class HasDownloadFile env where
67
+ downloadFile :: Text -> FilePath -> RIO env ()
64
68
65
- callProcess :: String -> [ String ] -> m ()
66
- readProcess :: String -> [ String ] -> String -> m String
69
+ class HasGitHub env where
70
+ runGitHub :: Request k a -> RIO env a
67
71
68
- downloadFile :: Text -> FilePath -> m ()
72
+ -- | Fetch the first page using @'runGitHub'@, return the first item
73
+ runGitHubFirst
74
+ :: HasGitHub env
75
+ => (FetchCount -> Request k (Vector a ))
76
+ -> RIO env (Maybe a )
77
+ runGitHubFirst f = (V. !? 0 ) <$> runGitHub (f 1 )
69
78
70
- instance MonadIO m => MonadApp (AppT m ) where
71
- runGitHub req = do
72
- logDebugN $ " GitHub request: " <> showGitHubRequest req
73
- auth <- asks $ OAuth . encodeUtf8 . appAccessToken
74
- result <- appIO OtherError $ do
75
- mgr <- getGlobalManager
76
- executeRequestWithMgr mgr auth req
77
- either (throwError . GitHubError ) pure result
78
-
79
- getCurrentDirectory = do
80
- logDebugN " getCurrentDirectory"
81
- appIO SystemError Directory. getCurrentDirectory
82
-
83
- setCurrentDirectory path = do
84
- logDebugN $ " setCurrentDirectory: " <> tshow path
85
- appIO SystemError $ Directory. setCurrentDirectory path
86
-
87
- doesFileExist path = do
88
- logDebugN $ " doesFileExist: " <> tshow path
89
- appIO SystemError $ Directory. doesFileExist path
90
-
91
- readFile path = do
92
- logDebugN $ " readFile: " <> tshow path
93
- appIO SystemError $ readFileUtf8 path
94
-
95
- exitSuccess = do
96
- logDebugN " exitSuccess"
97
- appIO SystemError Exit. exitSuccess
98
-
99
- callProcess cmd args = do
100
- -- N.B. this includes access tokens in log messages when used for
101
- -- git-clone. That's acceptable because:
102
- --
103
- -- - These tokens are ephemeral (5 minutes)
104
- -- - We generally accept secrets in DEBUG messages
105
- --
106
- logDebugN $ pack $ " call: " <> cmd <> " " <> show args
107
- appIO SystemError $ Process. callProcess cmd args
108
-
109
- readProcess cmd args stdin' = do
110
- logDebugN $ pack $ " read: " <> cmd <> " " <> show args
111
- output <- appIO SystemError $ Process. readProcess cmd args stdin'
112
- output <$ logDebugN (" output: " <> pack output)
113
-
114
- downloadFile url path = do
115
- logDebugN $ " HTTP GET: " <> tshow url <> " => " <> tshow path
116
- appIO HttpError $ do
117
- request <- parseRequest $ unpack url
118
- runResourceT $ httpSink request $ \ _ -> sinkFile path
119
-
120
- -- | Run an @'IO'@ computation and capture @'IOException'@s to the given type
121
- appIO :: MonadIO m => (IOException -> AppError ) -> IO a -> AppT m a
122
- appIO err f = AppT $ do
123
- result <- liftIO $ tryIO f
124
- either (throwError . err) pure result
125
-
126
- -- | Show a GitHub @'Request'@, useful for debugging
127
- -- brittany-disable-next-binding
128
- showGitHubRequest :: Request k a -> Text
129
- showGitHubRequest (SimpleQuery (Query ps qs)) = mconcat
130
- [ " [GET] "
131
- , " /" <> T. intercalate " /" ps
132
- , " ?" <> T. intercalate " &" (queryParts qs)
133
- ]
134
- showGitHubRequest (SimpleQuery (PagedQuery ps qs fc)) = mconcat
135
- [ " [GET] "
136
- , " /" <> T. intercalate " /" ps
137
- , " ?" <> T. intercalate " &" (queryParts qs)
138
- , " (" <> tshow fc <> " )"
139
- ]
140
- showGitHubRequest (SimpleQuery (Command m ps _body)) = mconcat
141
- [ " [" <> T. toUpper (tshow m) <> " ] "
142
- , " /" <> T. intercalate " /" ps
143
- ]
144
- showGitHubRequest (StatusQuery _ _) = " <status query>"
145
- showGitHubRequest (HeaderQuery _ _) = " <header query>"
146
- showGitHubRequest (RedirectQuery _) = " <redirect query>"
147
-
148
- queryParts :: QueryString -> [Text ]
149
- queryParts = map $ \ (k, mv) -> decodeUtf8 k <> " =" <> maybe " " decodeUtf8 mv
79
+ -- | @'void' . 'runGitHub'@
80
+ runGitHub_ :: HasGitHub env => Request k a -> RIO env ()
81
+ runGitHub_ = void . runGitHub
0 commit comments