-
Notifications
You must be signed in to change notification settings - Fork 267
/
Welcome.hs
188 lines (171 loc) Β· 6.67 KB
/
Welcome.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
{-# LANGUAGE OverloadedStrings #-}
module Unison.CommandLine.Welcome where
import Data.Sequence (singleton)
import System.Random (randomRIO)
import Unison.Codebase (Codebase)
import qualified Unison.Codebase as Codebase
import Unison.Codebase.Editor.Input
import Unison.Codebase.Editor.RemoteRepo (ReadRemoteNamespace (..), ReadShareRemoteNamespace (..))
import Unison.Codebase.Path (Path)
import qualified Unison.Codebase.Path as Path
import qualified Unison.Codebase.SyncMode as SyncMode
import qualified Unison.Codebase.Verbosity as Verbosity
import Unison.NameSegment (NameSegment (NameSegment))
import Unison.Prelude
import qualified Unison.Util.Pretty as P
import Prelude hiding (readFile, writeFile)
data Welcome = Welcome
{ onboarding :: Onboarding, -- Onboarding States
downloadBase :: DownloadBase,
watchDir :: FilePath,
unisonVersion :: Text
}
data DownloadBase
= DownloadBase ReadShareRemoteNamespace
| DontDownloadBase
deriving (Show, Eq)
-- Previously Created is different from Previously Onboarded because a user can
-- 1.) create a new codebase
-- 2.) decide not to go through the onboarding flow until later and exit
-- 3.) then reopen their blank codebase
data CodebaseInitStatus
= NewlyCreatedCodebase -- Can transition to [Base, Author, Finished]
| PreviouslyCreatedCodebase -- Can transition to [Base, Author, Finished, PreviouslyOnboarded].
deriving (Show, Eq)
data Onboarding
= Init CodebaseInitStatus -- Can transition to [DownloadingBase, Author, Finished, PreviouslyOnboarded]
| DownloadingBase ReadShareRemoteNamespace -- Can transition to [Author, Finished]
| Author -- Can transition to [Finished]
-- End States
| Finished
| PreviouslyOnboarded
deriving (Show, Eq)
welcome :: CodebaseInitStatus -> DownloadBase -> FilePath -> Text -> Welcome
welcome initStatus downloadBase filePath unisonVersion =
Welcome (Init initStatus) downloadBase filePath unisonVersion
pullBase :: ReadShareRemoteNamespace -> Either Event Input
pullBase ns =
let seg = NameSegment "base"
rootPath = Path.Path {Path.toSeq = singleton seg}
abs = Path.Absolute {Path.unabsolute = rootPath}
pullRemote =
PullRemoteBranchI
(Just (ReadRemoteNamespaceShare ns))
(Path.Path' {Path.unPath' = Left abs})
SyncMode.Complete
PullWithHistory
Verbosity.Silent
in Right pullRemote
run :: Codebase IO v a -> Welcome -> IO [Either Event Input]
run codebase Welcome {onboarding = onboarding, downloadBase = downloadBase, watchDir = dir, unisonVersion = version} = do
go onboarding []
where
go :: Onboarding -> [Either Event Input] -> IO [Either Event Input]
go onboarding acc =
case onboarding of
Init NewlyCreatedCodebase -> do
determineFirstStep downloadBase codebase >>= \step -> go step (headerMsg : acc)
where
headerMsg = toInput (header version)
Init PreviouslyCreatedCodebase -> do
go PreviouslyOnboarded (headerMsg : acc)
where
headerMsg = toInput (header version)
DownloadingBase ns@(ReadShareRemoteNamespace {path}) ->
go Author ([pullBaseInput, downloadMsg] ++ acc)
where
downloadMsg = Right $ CreateMessage (downloading path)
pullBaseInput = pullBase ns
Author ->
go Finished (authorMsg : acc)
where
authorMsg = toInput authorSuggestion
-- These are our two terminal Welcome conditions, at the end we reverse the order of the desired input commands otherwise they come out backwards
Finished -> do
startMsg <- getStarted dir
pure $ reverse (toInput startMsg : acc)
PreviouslyOnboarded -> do
startMsg <- getStarted dir
pure $ reverse (toInput startMsg : acc)
toInput :: P.Pretty P.ColorText -> Either Event Input
toInput pretty =
Right $ CreateMessage pretty
determineFirstStep :: DownloadBase -> Codebase IO v a -> IO Onboarding
determineFirstStep downloadBase codebase = do
isEmptyCodebase <- Codebase.getRootBranchExists codebase
case downloadBase of
DownloadBase ns
| isEmptyCodebase ->
pure $ DownloadingBase ns
_ ->
pure PreviouslyOnboarded
asciiartUnison :: P.Pretty P.ColorText
asciiartUnison =
P.red " _____"
<> P.hiYellow " _ "
<> P.newline
<> P.red "| | |"
<> P.hiRed "___"
<> P.hiYellow "|_|"
<> P.hiGreen "___ "
<> P.cyan "___ "
<> P.purple "___ "
<> P.newline
<> P.red "| | | "
<> P.hiYellow "| |"
<> P.hiGreen "_ -"
<> P.cyan "| . |"
<> P.purple " |"
<> P.newline
<> P.red "|_____|"
<> P.hiRed "_|_"
<> P.hiYellow "|_|"
<> P.hiGreen "___"
<> P.cyan "|___|"
<> P.purple "_|_|"
downloading :: Path -> P.Pretty P.ColorText
downloading path =
P.lines
[ P.group (P.wrap "π£ Since this is a fresh codebase, let me download the base library for you." <> P.newline),
P.wrap
( "π Downloading"
<> P.blue (P.string (show path))
<> "of the"
<> P.bold "base library"
<> "into"
<> P.group (P.blue ".base" <> ", this may take a minute...")
)
]
header :: Text -> P.Pretty P.ColorText
header version =
asciiartUnison
<> P.newline
<> P.newline
<> P.linesSpaced
[ P.wrap "π Welcome to Unison!",
P.wrap ("You are running version: " <> P.bold (P.text version))
]
authorSuggestion :: P.Pretty P.ColorText
authorSuggestion =
P.newline
<> P.lines
[ P.wrap "π πͺΆ You might want to set up your author information next.",
P.wrap "Type" <> P.hiBlue " create.author" <> " to create an author for this codebase",
P.group (P.newline <> P.wrap "Read about how to link your author to your code at"),
P.wrap $ P.blue "https://www.unison-lang.org/learn/tooling/configuration/"
]
getStarted :: FilePath -> IO (P.Pretty P.ColorText)
getStarted dir = do
earth <- (["π", "π", "π"] !!) <$> randomRIO (0, 2)
pure $
P.linesSpaced
[ P.wrap "Get started:",
P.indentN 2 $
P.column2
[ ("π", "Type " <> P.hiBlue "help" <> " to list all commands, or " <> P.hiBlue "help <cmd>" <> " to view help for one command"),
("π¨", "Type " <> P.hiBlue "ui" <> " to open the Codebase UI in your default browser"),
("π", "Read the official docs at " <> P.blue "https://www.unison-lang.org/learn/"),
(earth, "Visit Unison Share at " <> P.blue "https://share.unison-lang.org" <> " to discover libraries"),
("π", "I'm watching for changes to " <> P.bold ".u" <> " files under " <> (P.group . P.blue $ P.string dir))
]
]