1111import Control.Monad.IO.Class (liftIO )
1212import Data.List (intercalate )
1313import Data.List.NonEmpty (fromList )
14+ import Data.Maybe (isNothing )
1415import Path.IO (doesDirExist )
1516import StrongPath (Abs , Dir , Path' )
1617import StrongPath.Path (toPathAbsDir )
@@ -27,7 +28,7 @@ import Wasp.Cli.Command.CreateNewProject.StarterTemplates
2728 )
2829import Wasp.Cli.FileSystem (getAbsPathToDirInCwd )
2930import qualified Wasp.Cli.Interactive as Interactive
30- import Wasp.Project (WaspProjectDir )
31+ import Wasp.Project.Common (WaspProjectDir )
3132import Wasp.Util (indent , kebabToCamelCase , whenM )
3233
3334data NewProjectDescription = NewProjectDescription
@@ -37,12 +38,12 @@ data NewProjectDescription = NewProjectDescription
3738 _absWaspProjectDir :: Path' Abs (Dir WaspProjectDir )
3839 }
3940
40- data NewProjectName = NewProjectName String
41+ newtype NewProjectName = NewProjectName String
4142
4243instance Show NewProjectName where
4344 show (NewProjectName name) = name
4445
45- data NewProjectAppName = NewProjectAppName String
46+ newtype NewProjectAppName = NewProjectAppName String
4647
4748instance Show NewProjectAppName where
4849 show (NewProjectAppName name) = name
@@ -63,46 +64,50 @@ instance Show NewProjectAppName where
6364 - Template name is required, we ask the user to choose from available templates.
6465-}
6566obtainNewProjectDescription :: NewProjectArgs -> [StarterTemplate ] -> Command NewProjectDescription
66- obtainNewProjectDescription NewProjectArgs {_projectName = projectNameArg, _templateName = templateNameArg} starterTemplates =
67- case projectNameArg of
68- Just projectName -> obtainNewProjectDescriptionFromCliArgs projectName templateNameArg starterTemplates
69- Nothing -> obtainNewProjectDescriptionInteractively templateNameArg starterTemplates
70-
71- obtainNewProjectDescriptionFromCliArgs :: String -> Maybe String -> [StarterTemplate ] -> Command NewProjectDescription
72- obtainNewProjectDescriptionFromCliArgs projectName templateNameArg availableTemplates =
73- obtainNewProjectDescriptionFromProjectNameAndTemplateArg
74- projectName
75- templateNameArg
76- availableTemplates
77- (return defaultStarterTemplate)
78-
79- obtainNewProjectDescriptionInteractively :: Maybe String -> [StarterTemplate ] -> Command NewProjectDescription
80- obtainNewProjectDescriptionInteractively templateNameArg availableTemplates = do
81- projectName <- liftIO $ Interactive. askForRequiredInput " Enter the project name (e.g. my-project)"
82- obtainNewProjectDescriptionFromProjectNameAndTemplateArg
83- projectName
84- templateNameArg
85- availableTemplates
86- (liftIO askForTemplateName)
87- where
88- askForTemplateName = Interactive. askToChoose " Choose a starter template" $ fromList availableTemplates
89-
90- obtainNewProjectDescriptionFromProjectNameAndTemplateArg ::
91- String ->
92- Maybe String ->
93- [StarterTemplate ] ->
94- Command StarterTemplate ->
95- Command NewProjectDescription
96- obtainNewProjectDescriptionFromProjectNameAndTemplateArg projectName templateNameArg availableTemplates obtainTemplateWhenNoArg = do
67+ obtainNewProjectDescription NewProjectArgs {_projectName = projectNameArg, _templateName = templateNameArg} starterTemplates = do
68+ projectName <- maybe askForName return projectNameArg
69+ appName <-
70+ either throwProjectCreationError pure $
71+ parseWaspProjectNameIntoAppName projectName
72+
73+ let prefersInteractive = isNothing projectNameArg
74+ getFallbackTemplate =
75+ if prefersInteractive
76+ then askForTemplate starterTemplates
77+ else return defaultStarterTemplate
78+
79+ template <- maybe getFallbackTemplate (findTemplateOrThrow starterTemplates) templateNameArg
80+
9781 absWaspProjectDir <- obtainAvailableProjectDirPath projectName
98- selectedTemplate <- maybe obtainTemplateWhenNoArg findTemplateOrThrow templateNameArg
99- mkNewProjectDescription projectName absWaspProjectDir selectedTemplate
82+ return $ mkNewProjectDescription projectName appName absWaspProjectDir template
83+
84+ askForName :: Command String
85+ askForName =
86+ liftIO $ Interactive. askForRequiredInput " Enter the project name (e.g. my-project)"
87+
88+ askForTemplate :: [StarterTemplate ] -> Command StarterTemplate
89+ askForTemplate starterTemplates =
90+ liftIO $ Interactive. askToChoose " Choose a starter template" $ fromList starterTemplates
91+
92+ parseWaspProjectNameIntoAppName :: String -> Either String NewProjectAppName
93+ parseWaspProjectNameIntoAppName projectName
94+ | isValidWaspIdentifier appName = Right $ NewProjectAppName appName
95+ | otherwise =
96+ Left . intercalate " \n " $
97+ [ " The project's name is not in the valid format!" ,
98+ indent 2 " - It can start with a letter or an underscore." ,
99+ indent 2 " - It can contain only letters, numbers, dashes, or underscores." ,
100+ indent 2 " - It can't be a Wasp keyword."
101+ ]
100102 where
101- findTemplateOrThrow :: String -> Command StarterTemplate
102- findTemplateOrThrow templateName = case findTemplateByString availableTemplates templateName of
103- Just template -> return template
104- Nothing -> throwProjectCreationError $ makeInvalidTemplateNameError templateName
105- makeInvalidTemplateNameError templateName =
103+ appName = kebabToCamelCase projectName
104+
105+ findTemplateOrThrow :: [StarterTemplate ] -> String -> Command StarterTemplate
106+ findTemplateOrThrow availableTemplates templateName = case findTemplateByString availableTemplates templateName of
107+ Just template -> return template
108+ Nothing -> throwProjectCreationError invalidTemplateNameError
109+ where
110+ invalidTemplateNameError =
106111 " The template '"
107112 <> templateName
108113 <> " ' doesn't exist. Available starter templates are: "
@@ -126,26 +131,11 @@ obtainAvailableProjectDirPath projectName = do
126131 throwProjectCreationError $
127132 " Directory \" " ++ projectDirName ++ " \" is not empty."
128133
129- mkNewProjectDescription :: String -> Path' Abs (Dir WaspProjectDir ) -> StarterTemplate -> Command NewProjectDescription
130- mkNewProjectDescription projectName absWaspProjectDir template = do
131- appName <- either throwProjectCreationError pure $ parseWaspProjectNameIntoAppName projectName
132- return $
133- NewProjectDescription
134- { _projectName = NewProjectName projectName,
135- _appName = appName,
136- _template = template,
137- _absWaspProjectDir = absWaspProjectDir
138- }
139-
140- parseWaspProjectNameIntoAppName :: String -> Either String NewProjectAppName
141- parseWaspProjectNameIntoAppName projectName
142- | isValidWaspIdentifier appName = Right $ NewProjectAppName appName
143- | otherwise =
144- Left . intercalate " \n " $
145- [ " The project's name is not in the valid format!" ,
146- indent 2 " - It can start with a letter or an underscore." ,
147- indent 2 " - It can contain only letters, numbers, dashes, or underscores." ,
148- indent 2 " - It can't be a Wasp keyword."
149- ]
150- where
151- appName = kebabToCamelCase projectName
134+ mkNewProjectDescription :: String -> NewProjectAppName -> Path' Abs (Dir WaspProjectDir ) -> StarterTemplate -> NewProjectDescription
135+ mkNewProjectDescription projectName appName absWaspProjectDir template =
136+ NewProjectDescription
137+ { _projectName = NewProjectName projectName,
138+ _appName = appName,
139+ _template = template,
140+ _absWaspProjectDir = absWaspProjectDir
141+ }
0 commit comments