1{-# LANGUAGE OverloadedStrings #-}
2module Reporting.Progress.Terminal
9import Control.Concurrent (forkIO)
10import Control.Concurrent.Chan (Chan, newChan, readChan)
11import Control.Concurrent.MVar (newEmptyMVar, putMVar)
12import qualified System.Info as Info
13import System.IO (hFlush, hPutStr, stdout)
14import qualified Elm.Package as Pkg
15import Elm.Package (Name, Version)
17import qualified Deps.Diff as Diff
18import Reporting.Doc ((<>), (<+>))
19import qualified Reporting.Doc as D
20import qualified Reporting.Exit as Exit
21import qualified Reporting.Exit.Help as Help
22import Reporting.Progress (Msg(..), Progress(..), Outcome(..), PublishPhase(..), BumpPhase(..))
23import qualified Reporting.Progress as Progress
24import qualified Reporting.Progress.Bar as Bar
31create :: IO Progress.Reporter
35 _ <- forkIO (loop chan (State 0 0 0) >>= putMVar mvar)
36 return (Progress.makeReporter chan mvar)
55loop :: Chan Msg -> State -> IO ()
57 do msg <- readChan chan
67 putMVar mvar =<< getApproval
71 loopHelp chan progress state
84 do putStr "Must type 'y' for yes or 'n' for no: "
88loopHelp :: Chan Msg -> Progress -> State -> IO ()
89loopHelp chan progress state@(State total good bad) =
97 Help.toStdout $ D.fillSep $
98 [ "Done!","And","check","out"
99 ,D.green "<https://guide.elm-lang.org>"
100 ,"to","learn","what","to","do","next!"
103 Help.toStdout $ D.black $ D.vcat $
104 [ "--------------------------------------------------------------------------------"
105 , "-------------------- Now back to what you were doing before --------------------"
106 , "--------------------------------------------------------------------------------"
112 do putStrLn "\nOkay, I did not create anything.\n"
119 do putStrLn "Dependencies loaded from local cache."
126 do putStrLn "Starting downloads...\n"
129 DownloadPkgStart _name _version ->
132 DownloadPkgEnd name version outcome ->
133 do Help.toStdout (makeBullet name version outcome)
147 BuildDepsStart size ->
148 do hPutStr stdout "Verifying dependencies..."
150 loop chan (State size 0 0)
154 let msg = "\rBuilding dependencies (" ++ show n ++ "/" ++ show total ++ ")"
157 loop chan (State total n 0)
160 do putStrLn "\rDependencies ready! "
161 loop chan (State 0 0 0)
167 loop chan (State size 0 0)
169 CompileFileStart _ ->
172 CompileFileEnd _ Good ->
173 do hPutStr stdout $ Bar.render (good + 1) bad total
175 loop chan (State total (good + 1) bad)
177 CompileFileEnd _ Bad ->
178 do hPutStr stdout $ Bar.render good (bad + 1) total
180 loop chan (State total good (bad + 1))
187 (0, 1) -> "Success! Compiled 1 module."
188 (0, n) -> "Success! Compiled " ++ show n ++ " modules."
189 (1, _) -> "Detected errors in 1 module."
190 (n, _) -> "Detected errors in " ++ show n ++ " modules."
192 do hPutStr stdout $ Bar.clear
194 loop chan (State 0 0 0)
199 PublishStart name version maybePublishedVersions ->
200 case maybePublishedVersions of
202 do putStrLn newPackageOverview
203 putStrLn "I will now verify that everything is in order..."
208 do putStrLn $ unwords [ "Verifying", Pkg.toString name, Pkg.versionToString version, "..." ]
212 PublishCheckBump version bumpPhase ->
213 do Help.toStdout $ bumpPhaseToChecklistDoc version bumpPhase
217 PublishProgress phase status ->
218 do Help.toStdout $ toChecklistDoc status (toChecklistMessages phase)
223 do putStrLn "Success!"
229 UnableToLoadLatestPackages ->
231 Help.toStdout $ D.dullyellow "WARNING:" <+> "I normally check <https://package.elm-lang.org> for new packages\n"
232 putStrLn "here, but my request failed. Are you offline? I will try to continue anyway.\n"
240makeBullet :: Name -> Version -> Outcome -> D.Doc
241makeBullet name version outcome =
243 nm = D.fromText (Pkg.toText name)
244 vsn = D.fromText (Pkg.versionToText version)
251 D.indent 2 $ bullet <+> nm <+> vsn <> "\n"
257 if Info.os == "mingw32" then "+" else "●"
263 if Info.os == "mingw32" then "X" else "✗"
269 if Info.os == "mingw32" then "-" else "→"
273-- OVERVIEW OF VERSIONING
276newPackageOverview :: String
279 [ "This package has never been published before. Here's how things work:"
281 , " - Versions all have exactly three parts: MAJOR.MINOR.PATCH"
283 , " - All packages start with initial version " ++ Pkg.versionToString Pkg.initialVersion
285 , " - Versions are incremented based on how the API changes:"
287 , " PATCH = the API is the same, no risk of breaking code"
288 , " MINOR = values have been added, existing values are unchanged"
289 , " MAJOR = existing values have been changed or removed"
291 , " - I will bump versions for you, automatically enforcing these rules"
300toChecklistDoc :: Maybe Outcome -> ChecklistMessages -> D.Doc
301toChecklistDoc status (ChecklistMessages waiting success failure) =
304 message ++ replicate (length waiting - length message) ' '
308 " " <> waitingMark <+> D.fromString waiting
311 "\r " <> goodMark <+> D.fromString (padded success ++ "\n")
314 "\r " <> badMark <+> D.fromString (padded failure ++ "\n\n")
317data ChecklistMessages =
325toChecklistMessages :: PublishPhase -> ChecklistMessages
326toChecklistMessages phase =
330 "Looking for README.md"
332 "Problem with your README.md"
336 "Looking for LICENSE"
338 "Problem with your LICENSE"
342 ("Is version " ++ Pkg.versionToString version ++ " tagged on GitHub?")
343 ("Version " ++ Pkg.versionToString version ++ " is tagged on GitHub")
344 ("Version " ++ Pkg.versionToString version ++ " is not tagged on GitHub!")
348 "Downloading code from GitHub..."
349 "Code downloaded successfully from GitHub"
350 "Could not download code from GitHub!"
354 "Building downloaded code and generated docs..."
355 "Downloaded code compiles successfully / docs generated\n"
356 "Cannot compile downloaded code!"
360 "Checking for uncommitted changes..."
361 "No uncommitted changes in local code"
362 "Your local code is different than the code tagged on GitHub"
369bumpPhaseToChecklistDoc :: Pkg.Version -> BumpPhase -> D.Doc
370bumpPhaseToChecklistDoc version bumpPhase =
374 ("Checking semantic versioning rules. Is " ++ Pkg.versionToString version ++ " correct?")
376 ("Version " ++ Pkg.versionToString version ++ " is not correct!")
381 toChecklistDoc Nothing $ mkMsgs ""
384 toChecklistDoc (Just Good) $ mkMsgs $
385 "All packages start at version " ++ Pkg.versionToString Pkg.initialVersion
387 GoodBump old magnitude ->
388 toChecklistDoc (Just Good) $ mkMsgs $
389 toCheckVersionSuccessMessage old version magnitude
392 toChecklistDoc (Just Bad) $ mkMsgs ""
395toCheckVersionSuccessMessage :: Pkg.Version -> Pkg.Version -> Diff.Magnitude -> String
396toCheckVersionSuccessMessage oldVersion newVersion magnitude =
398 old = Pkg.versionToString oldVersion
399 new = Pkg.versionToString newVersion
400 mag = Diff.magnitudeToString magnitude
402 "Version number " ++ new ++ " verified (" ++ mag ++ " change, " ++ old ++ " => " ++ new ++ ")"
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