-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Separate user code into client and server directories #753
Changes from 11 commits
4e09b34
86e70fe
bb4107e
cc7f353
492f247
d88e204
51b426a
789dc8f
6d29601
11846e7
4f834ec
385b35c
a7753d2
53dc889
8388b0f
40f56d2
936116b
1d4e0d8
dc753f4
281c3cf
a64832c
b30e3de
f40a8ce
ddc8682
eb29d50
9fa7e9a
8674887
997fe72
0cb6369
8bb94cc
5f47855
54e0b02
0ae2631
c5c326e
fc76fb6
dc29140
36e5766
cd101ab
bed02f1
f384d14
d4a4c07
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,18 +6,18 @@ where | |
import Control.Monad.Except (throwError) | ||
import Control.Monad.IO.Class (liftIO) | ||
import Data.List (intercalate) | ||
import StrongPath (Abs, Dir, File', Path', Rel, reldir, relfile, (</>)) | ||
import qualified StrongPath as SP | ||
import System.Directory (createDirectory, getCurrentDirectory) | ||
import qualified System.Directory | ||
import Path.IO (copyDirRecur, doesDirExist) | ||
import StrongPath (Abs, Dir, Path, Path', System, fromAbsFile, parseAbsDir, reldir, relfile, (</>)) | ||
import StrongPath.Path (toPathAbsDir) | ||
import System.Directory (getCurrentDirectory) | ||
import qualified System.FilePath as FP | ||
import Text.Printf (printf) | ||
import Wasp.Analyzer.Parser (isValidWaspIdentifier) | ||
import Wasp.AppSpec.ExternalCode (SourceExternalCodeDir) | ||
import Wasp.Cli.Command (Command, CommandError (..)) | ||
import qualified Wasp.Cli.Command.Common as Command.Common | ||
import qualified Wasp.Cli.Common as Common | ||
import qualified Wasp.Data | ||
import Wasp.Common (WaspProjectDir) | ||
import qualified Wasp.Common as Common (WaspProjectDir) | ||
import qualified Wasp.Data as Data | ||
import Wasp.Util (indent, kebabToCamelCase) | ||
import qualified Wasp.Util.Terminal as Term | ||
|
||
|
@@ -26,99 +26,70 @@ data ProjectInfo = ProjectInfo | |
_appName :: String | ||
} | ||
|
||
createNewProject :: String -> Command () | ||
createNewProject projectName = do | ||
projectInfo <- parseProjectInfo projectName | ||
createWaspProjectDir projectInfo | ||
liftIO printGettingStartedInstructions | ||
where | ||
printGettingStartedInstructions = do | ||
putStrLn $ Term.applyStyles [Term.Green] ("Created new Wasp app in ./" ++ projectName ++ " directory!") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is fine to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I know what you mean. I'll change it. |
||
putStrLn "To run it, do:" | ||
putStrLn "" | ||
putStrLn $ Term.applyStyles [Term.Bold] (" cd " ++ projectName) | ||
putStrLn $ Term.applyStyles [Term.Bold] " wasp start" | ||
putStrLn "" | ||
putStrLn Command.Common.alphaWarningMessage | ||
|
||
-- Takes a project name String | ||
-- Returns either the ProjectInfo type that contains both the Project name | ||
-- and the App name (which might be the same), or an error describing why the name is invalid | ||
parseProjectInfo :: String -> Either String ProjectInfo | ||
parseProjectInfo :: String -> Command ProjectInfo | ||
Martinsos marked this conversation as resolved.
Show resolved
Hide resolved
|
||
parseProjectInfo name | ||
| isValidWaspIdentifier appName = Right (ProjectInfo name appName) | ||
| isValidWaspIdentifier appName = return $ ProjectInfo name appName | ||
| otherwise = | ||
Left $ | ||
intercalate | ||
"\n" | ||
[ "The project's name is not in the valid format!", | ||
indent 2 "- It can start with a letter or an underscore.", | ||
indent 2 "- It can contain only letters, numbers, dashes, or underscores.", | ||
indent 2 "- It can't be a Wasp keyword." | ||
] | ||
throwProjectCreationError $ | ||
intercalate | ||
"\n" | ||
[ "The project's name is not in the valid format!", | ||
indent 2 "- It can start with a letter or an underscore.", | ||
indent 2 "- It can contain only letters, numbers, dashes, or underscores.", | ||
indent 2 "- It can't be a Wasp keyword." | ||
] | ||
where | ||
appName = kebabToCamelCase name | ||
|
||
createNewProject :: String -> Command () | ||
createNewProject name = | ||
case parseProjectInfo name of | ||
Right projectInfo -> createNewProject' projectInfo | ||
Left parsedError -> | ||
throwError $ | ||
CommandError "Project creation failed" parsedError | ||
|
||
createNewProject' :: ProjectInfo -> Command () | ||
createNewProject' (ProjectInfo projectName appName) = do | ||
createWaspProjectDir :: ProjectInfo -> Command () | ||
createWaspProjectDir projectInfo = do | ||
absWaspProjectDir <- getAbsoluteWaspProjectDir projectInfo | ||
dirExists <- doesDirExist $ toPathAbsDir absWaspProjectDir | ||
if dirExists | ||
then throwProjectCreationError $ show absWaspProjectDir ++ " is an existing directory" | ||
else liftIO $ do | ||
initializeProjectFromSkeleton absWaspProjectDir | ||
writeMainWaspFile absWaspProjectDir projectInfo | ||
|
||
getAbsoluteWaspProjectDir :: ProjectInfo -> Command (Path System Abs (Dir WaspProjectDir)) | ||
shayneczyzewski marked this conversation as resolved.
Show resolved
Hide resolved
|
||
getAbsoluteWaspProjectDir (ProjectInfo projectName _) = do | ||
absCwd <- liftIO getCurrentDirectory | ||
waspProjectDir <- case SP.parseAbsDir $ absCwd FP.</> projectName of | ||
Left err -> | ||
throwError $ | ||
CommandError | ||
"Project creation failed" | ||
( "Failed to parse absolute path to wasp project dir: " | ||
++ show err | ||
) | ||
case parseAbsDir $ absCwd FP.</> projectName of | ||
Right sp -> return sp | ||
liftIO $ do | ||
createDirectorySP waspProjectDir | ||
writeFileSP (waspProjectDir </> mainWaspFileInWaspProjectDir) mainWaspFileContent | ||
writeFileSP (waspProjectDir </> gitignoreFileInWaspProjectDir) gitignoreFileContent | ||
writeFileSP | ||
(waspProjectDir </> Common.dotWaspRootFileInWaspProjectDir) | ||
"File marking the root of Wasp project." | ||
|
||
let extCodeDir = waspProjectDir </> Common.extCodeDirInWaspProjectDir | ||
liftIO $ do | ||
createDirectorySP extCodeDir | ||
dataDir <- Wasp.Data.getAbsDataDirPath | ||
|
||
let copyTemplateFile' = copyTemplateFile dataDir extCodeDir | ||
|
||
writeFileSP (extCodeDir </> waspignoreFileInExtCodeDir) waspignoreFileContent | ||
|
||
copyTemplateFile' | ||
[relfile|new/ext/MainPage.js|] | ||
mainPageJsFileInExtCodeDir | ||
|
||
copyTemplateFile' | ||
[relfile|new/ext/Main.css|] | ||
mainCssFileInExtCodeDir | ||
|
||
copyTemplateFile' | ||
[relfile|new/ext/waspLogo.png|] | ||
waspLogoFileInExtCodeDir | ||
|
||
liftIO $ do | ||
putStrLn $ Term.applyStyles [Term.Green] ("Created new Wasp app in ./" ++ projectName ++ " directory!") | ||
putStrLn "To run it, do:" | ||
putStrLn "" | ||
putStrLn $ Term.applyStyles [Term.Bold] (" cd " ++ projectName) | ||
putStrLn $ Term.applyStyles [Term.Bold] " wasp start" | ||
putStrLn "" | ||
putStrLn Command.Common.alphaWarningMessage | ||
Left err -> | ||
throwProjectCreationError $ | ||
"Failed to parse absolute path to wasp project dir: " ++ show err | ||
|
||
-- To avoid creating the initial files for a new project dynamically, | ||
Martinsos marked this conversation as resolved.
Show resolved
Hide resolved
|
||
-- we copy the project directory skeleton from our templates. | ||
initializeProjectFromSkeleton :: Path' Abs (Dir Common.WaspProjectDir) -> IO () | ||
Martinsos marked this conversation as resolved.
Show resolved
Hide resolved
|
||
initializeProjectFromSkeleton absWaspProjectDir = do | ||
dataDir <- Data.getAbsDataDirPath | ||
let absSkeletonDir = dataDir </> [reldir|Cli/templates/new|] | ||
copyDirRecur (toPathAbsDir absSkeletonDir) (toPathAbsDir absWaspProjectDir) | ||
|
||
writeMainWaspFile :: Path System Abs (Dir WaspProjectDir) -> ProjectInfo -> IO () | ||
writeMainWaspFile waspProjectDir (ProjectInfo projectName appName) = writeFile absMainWaspFile mainWaspFileContent | ||
where | ||
copyTemplateFile :: | ||
Path' Abs (Dir Wasp.Data.DataDir) -> | ||
Path' Abs (Dir SourceExternalCodeDir) -> | ||
Path' (Rel Common.CliTemplatesDir) File' -> | ||
Path' (Rel SourceExternalCodeDir) File' -> | ||
IO () | ||
copyTemplateFile dataDir extCodeDir srcTmplFile dstExtDirFile = | ||
System.Directory.copyFile | ||
(SP.fromAbsFile (dataDir </> cliTemplatesDirInDataDir </> srcTmplFile)) | ||
(SP.fromAbsFile (extCodeDir </> dstExtDirFile)) | ||
|
||
cliTemplatesDirInDataDir :: Path' (Rel Wasp.Data.DataDir) (Dir Common.CliTemplatesDir) | ||
cliTemplatesDirInDataDir = [reldir|Cli/templates|] | ||
|
||
mainWaspFileInWaspProjectDir :: Path' (Rel Common.WaspProjectDir) File' | ||
mainWaspFileInWaspProjectDir = [relfile|main.wasp|] | ||
|
||
absMainWaspFile = fromAbsFile $ waspProjectDir </> [relfile|main.wasp|] | ||
mainWaspFileContent = | ||
unlines | ||
[ "app %s {" `printf` appName, | ||
|
@@ -131,34 +102,5 @@ createNewProject' (ProjectInfo projectName appName) = do | |
"}" | ||
] | ||
|
||
gitignoreFileInWaspProjectDir :: Path' (Rel Common.WaspProjectDir) File' | ||
gitignoreFileInWaspProjectDir = [relfile|.gitignore|] | ||
|
||
gitignoreFileContent = | ||
unlines | ||
[ "/.wasp/", | ||
"/.env.server", | ||
"/.env.client" | ||
] | ||
|
||
waspignoreFileInExtCodeDir :: Path' (Rel SourceExternalCodeDir) File' | ||
waspignoreFileInExtCodeDir = [relfile|.waspignore|] | ||
|
||
waspignoreFileContent = | ||
sodic marked this conversation as resolved.
Show resolved
Hide resolved
|
||
unlines | ||
[ "# Ignore editor tmp files", | ||
"**/*~", | ||
"**/#*#" | ||
] | ||
|
||
mainPageJsFileInExtCodeDir :: Path' (Rel SourceExternalCodeDir) File' | ||
mainPageJsFileInExtCodeDir = [relfile|MainPage.js|] | ||
|
||
mainCssFileInExtCodeDir :: Path' (Rel SourceExternalCodeDir) File' | ||
mainCssFileInExtCodeDir = [relfile|Main.css|] | ||
|
||
waspLogoFileInExtCodeDir :: Path' (Rel SourceExternalCodeDir) File' | ||
waspLogoFileInExtCodeDir = [relfile|waspLogo.png|] | ||
|
||
writeFileSP = writeFile . SP.fromAbsFile | ||
createDirectorySP = createDirectory . SP.fromAbsDir | ||
throwProjectCreationError :: String -> Command a | ||
throwProjectCreationError = throwError . CommandError "Project creation failed" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/.wasp/ | ||
/.env.server | ||
/.env.client |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
File marking the root of Wasp project. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Ignore editor tmp files | ||
**/*~ | ||
**/#*# |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I introduced a lot of changes to this file. The best way to review it is probably to avoid looking at the diff altogether.
The main (non-refactor) changes are:
main.wasp
file which depends onProjectInfo
).