-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathCompile.hs
More file actions
157 lines (138 loc) · 6.29 KB
/
Compile.hs
File metadata and controls
157 lines (138 loc) · 6.29 KB
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
module Wasp.Cli.Command.Compile
( compileIO,
compile,
compileWithOptions,
compileIOWithOptions,
defaultCompileOptions,
printCompilationResult,
printWarningsAndErrorsIfAny,
analyze,
analyzeWithOptions,
)
where
import Control.Monad (unless, when)
import Control.Monad.Except (throwError)
import Control.Monad.IO.Class (liftIO)
import Data.List (intercalate)
import StrongPath (Abs, Dir, Path', (</>))
import qualified StrongPath as SP
import qualified Wasp.AppSpec as AS
import Wasp.Cli.Command (Command, CommandError (..))
import Wasp.Cli.Command.Message (cliSendMessageC)
import Wasp.Cli.Command.Require (InWaspProject (InWaspProject), require)
import Wasp.Cli.Message (cliSendMessage)
import Wasp.CompileOptions (CompileOptions (..))
import qualified Wasp.Generator
import qualified Wasp.Generator.WaspInfo as WaspInfo
import qualified Wasp.Message as Msg
import Wasp.Project (CompileError, CompileWarning, WaspProjectDir)
import qualified Wasp.Project
import qualified Wasp.Project.BuildType as BuildType
import Wasp.Project.Common (generatedAppDirInWaspProjectDir)
import Wasp.Util.IO (doesDirectoryExist, removeDirectory)
-- | Same like 'compileWithOptions', but with default compile options.
compile :: Command [CompileWarning]
compile = do
-- TODO: Consider a way to remove the redundancy of finding the project root
-- here and in compileWithOptions. One option could be to add this to defaultCompileOptions
-- add make externalCodeDirPath a helper function, along with any others we typically need.
InWaspProject waspProjectDir <- require
compileWithOptions $ defaultCompileOptions waspProjectDir
-- | Compiles Wasp project that the current working directory is part of.
-- Does all the steps, from analysis to generation, and at the end writes generated code
-- to the disk, to the .wasp dir.
-- At the end, prints a report on how compilation went (by printing warnings, errors,
-- success/failure message, ...).
-- Finally, throws if there was a compile error, otherwise returns any compile warnings.
compileWithOptions :: CompileOptions -> Command [CompileWarning]
compileWithOptions options = do
InWaspProject waspProjectDir <- require
let outDir = waspProjectDir </> generatedAppDirInWaspProjectDir
generatedAppIsCompatible <-
liftIO $ buildType options `WaspInfo.isCompatibleWithExistingBuildAt` outDir
outDirExists <- liftIO $ doesDirectoryExist outDir
when (outDirExists && not generatedAppIsCompatible) $ do
cliSendMessageC $
Msg.Start $
"Clearing the content of the " ++ SP.fromRelDir generatedAppDirInWaspProjectDir ++ " directory..."
liftIO $ removeDirectory outDir
cliSendMessageC $
Msg.Success $
"Successfully cleared the contents of the " ++ SP.fromRelDir generatedAppDirInWaspProjectDir ++ " directory."
cliSendMessageC $ Msg.Start "Compiling wasp project..."
(warnings, errors) <- liftIO $ compileIOWithOptions options waspProjectDir outDir
liftIO $ printCompilationResult (warnings, errors)
if null errors
then return warnings
else
throwError $
CommandError "Compilation of wasp project failed" $
show (length errors) ++ " errors found"
-- | Given any compile warnings and errors, prints information about how compilation went:
-- reports it as success if there was no errors, or if a failure if there were errors,
-- also shows any warnings (and errors), ... .
-- Normally you will want to call this function after compile step is done and you want
-- to report to user how it went.
printCompilationResult :: ([CompileWarning], [CompileError]) -> IO ()
printCompilationResult (warns, errs) = do
if null errs
then cliSendMessage $ Msg.Success "Your wasp project has successfully compiled."
else printErrorsIfAny errs
printWarningsIfAny warns
printWarningsAndErrorsIfAny :: ([CompileWarning], [CompileError]) -> IO ()
printWarningsAndErrorsIfAny (warns, errs) = do
printWarningsIfAny warns
printErrorsIfAny errs
printWarningsIfAny :: [CompileWarning] -> IO ()
printWarningsIfAny warns = do
unless (null warns) $
cliSendMessage $
Msg.Warning "Your wasp project reported following warnings during compilation" $
formatErrorOrWarningMessages warns
printErrorsIfAny :: [CompileError] -> IO ()
printErrorsIfAny errs = do
unless (null errs) $
cliSendMessage $
Msg.Failure "Your wasp project failed to compile" $
formatErrorOrWarningMessages errs
formatErrorOrWarningMessages :: [String] -> String
formatErrorOrWarningMessages = intercalate "\n" . map ("- " ++)
-- | Compiles Wasp source code in waspProjectDir directory and generates a project
-- in given outDir directory.
compileIO ::
Path' Abs (Dir WaspProjectDir) ->
Path' Abs (Dir Wasp.Generator.GeneratedAppDir) ->
IO ([CompileWarning], [CompileError])
compileIO waspProjectDir outDir =
compileIOWithOptions (defaultCompileOptions waspProjectDir) waspProjectDir outDir
compileIOWithOptions ::
CompileOptions ->
Path' Abs (Dir WaspProjectDir) ->
Path' Abs (Dir Wasp.Generator.GeneratedAppDir) ->
IO ([CompileWarning], [CompileError])
compileIOWithOptions options waspProjectDir outDir =
Wasp.Project.compile waspProjectDir outDir options
defaultCompileOptions :: Path' Abs (Dir WaspProjectDir) -> CompileOptions
defaultCompileOptions waspProjectDir =
CompileOptions
{ waspProjectDirPath = waspProjectDir,
buildType = BuildType.Development,
sendMessage = cliSendMessage,
generatorWarningsFilter = id
}
analyze :: Path' Abs (Dir WaspProjectDir) -> Command AS.AppSpec
analyze waspProjectDir = do
analyzeWithOptions waspProjectDir $ defaultCompileOptions waspProjectDir
-- | Analyzes Wasp project that the current working directory is a part of and returns
-- AppSpec. So same like compilation, but it stops before any code generation.
-- Throws if there were any compilation errors.
analyzeWithOptions :: Path' Abs (Dir WaspProjectDir) -> CompileOptions -> Command AS.AppSpec
analyzeWithOptions waspProjectDir options = do
(appSpecOrErrors, warnings) <- liftIO $ Wasp.Project.analyzeWaspProject waspProjectDir options
liftIO $ printWarningsIfAny warnings
case appSpecOrErrors of
Left errors ->
throwError $
CommandError "Analyzing wasp project failed" $
show (length errors) <> " errors found:\n" <> formatErrorOrWarningMessages errors
Right spec -> return spec