-
-
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
Validates tailwindcss
if Tailwind is used
#2465
base: main
Are you sure you want to change the base?
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
app todoApp { | ||
wasp: { | ||
version: "^0.15.0" | ||
version: "^0.16.0" | ||
}, | ||
title: "ToDo App", | ||
// head: [], | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,9 +4,11 @@ module Wasp.Generator.ConfigFile | |
) | ||
where | ||
|
||
import Data.List (find) | ||
import Data.Map (fromList) | ||
import Data.Maybe (isJust) | ||
import StrongPath (File', Path', Rel, castRel, relfile, (</>)) | ||
import Wasp.AppSpec (AppSpec, doesConfigFileExist) | ||
import qualified Wasp.AppSpec.ConfigFile as CF | ||
import Wasp.ConfigFile (ConfigFileRelocationMap) | ||
import Wasp.Generator.Common (ProjectRootDir) | ||
import Wasp.Generator.WebAppGenerator.Common (webAppRootDirInProjectRootDir) | ||
|
@@ -24,12 +26,16 @@ asProjectRootDirConfigFile = (webAppRootDirInProjectRootDir </>) . castRel | |
-- | Helper that determines if Tailwind used. For our purposes, we allow | ||
-- developers to opt-in by creating both a tailwind config file and | ||
-- postcss config file in their wasp project dir. | ||
isTailwindUsed :: AppSpec -> Bool | ||
isTailwindUsed spec = | ||
doesConfigFileExist spec tailwindConfigFile | ||
&& doesConfigFileExist spec postcssConfigFile | ||
isTailwindUsed :: [CF.ConfigFileRelocator] -> Bool | ||
isTailwindUsed configFileRelocators = | ||
doesConfigFileExist tailwindConfigFile | ||
&& doesConfigFileExist postcssConfigFile | ||
where | ||
doesConfigFileExist :: Path' (Rel WaspProjectDir) File' -> Bool | ||
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. This is only used for 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. If you know it is a general utility, I would pull it out immediately, since then it is easier for somebody else to see it there and use it. If it was more tied down to this specific place then mabye not, but it seems quite ready to isolate right now, and I can easily imagine somebody else will want to check if certain congfi file exists, so yeah, let's go for it right now. |
||
doesConfigFileExist file = | ||
isJust $ find ((==) file . CF._pathInWaspProjectDir) configFileRelocators | ||
|
||
-- | Establishes the mapping of what config files to copy and where from/to. | ||
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. Ormolu |
||
-- Establishes the mapping of what config files to copy and where from/to. | ||
-- NOTE: In the future, we could allow devs to configure what files we look for and where we copy them. | ||
configFileRelocationMap :: ConfigFileRelocationMap | ||
configFileRelocationMap = | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,22 +7,29 @@ import qualified Data.Map as M | |
import qualified Wasp.ExternalConfig.PackageJson as P | ||
import Wasp.Generator.Common (prismaVersion) | ||
import Wasp.Generator.ExternalConfig.Common (ErrorMsg) | ||
import Wasp.Generator.SdkGenerator.Common (tailwindCssVersion) | ||
import Wasp.Generator.WebAppGenerator.Common (reactRouterVersion, reactVersion) | ||
|
||
validatePackageJson :: P.PackageJson -> [ErrorMsg] | ||
validatePackageJson packageJson = | ||
validatePackageJson :: Bool -> P.PackageJson -> [ErrorMsg] | ||
validatePackageJson isTailwindUsed packageJson = | ||
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 had to thread through the 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 get what you mean, and I agree it would be much going for Reader now. |
||
concat | ||
[ validate ("wasp", "file:.wasp/out/sdk/wasp") IsListedWithExactVersion, | ||
validate ("prisma", show prismaVersion) IsListedAsDevWithExactVersion, | ||
-- Installing the wrong version of "react-router-dom" can make users believe that they | ||
-- can use features that are not available in the version that Wasp supports. | ||
validate ("react-router-dom", show reactRouterVersion) IsListedWithExactVersion, | ||
validate ("react", show reactVersion) IsListedWithExactVersion, | ||
validate ("react-dom", show reactVersion) IsListedWithExactVersion | ||
] | ||
( [ validate ("wasp", "file:.wasp/out/sdk/wasp") IsListedWithExactVersion, | ||
validate ("prisma", show prismaVersion) IsListedAsDevWithExactVersion, | ||
-- Installing the wrong version of "react-router-dom" can make users believe that they | ||
-- can use features that are not available in the version that Wasp supports. | ||
validate ("react-router-dom", show reactRouterVersion) IsListedWithExactVersion, | ||
validate ("react", show reactVersion) IsListedWithExactVersion, | ||
validate ("react-dom", show reactVersion) IsListedWithExactVersion | ||
] | ||
++ tailwindValidations | ||
) | ||
where | ||
validate = validateDep packageJson | ||
|
||
tailwindValidations = | ||
[ validate ("tailwindcss", show tailwindCssVersion) IsListedWithExactVersion | isTailwindUsed | ||
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. If Tailwind is used, validate that the |
||
] | ||
|
||
data PackageValidationType = IsListedWithExactVersion | IsListedAsDevWithExactVersion | HasExactVersionIfListed | ||
|
||
validateDep :: P.PackageJson -> (P.PackageName, P.PackageVersion) -> PackageValidationType -> [String] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ import StrongPath | |
fromAbsDir, | ||
) | ||
import qualified Wasp.AppSpec as AS | ||
import qualified Wasp.AppSpec.ConfigFile as CF | ||
import Wasp.AppSpec.Core.Decl.JSON () | ||
import qualified Wasp.AppSpec.Valid as ASV | ||
import Wasp.CompileOptions (CompileOptions) | ||
|
@@ -51,6 +52,10 @@ analyzeWaspProject :: | |
IO (Either [CompileError] AS.AppSpec, [CompileWarning]) | ||
analyzeWaspProject waspDir options = do | ||
waspFilePathOrError <- left (: []) <$> findWaspFile waspDir | ||
configFiles <- CF.discoverConfigFiles waspDir G.CF.configFileRelocationMap | ||
|
||
let isTailwindUsed = G.CF.isTailwindUsed configFiles | ||
|
||
case waspFilePathOrError of | ||
Left err -> return (Left err, []) | ||
Right waspFilePath -> | ||
|
@@ -61,25 +66,25 @@ analyzeWaspProject waspDir options = do | |
analyzeWaspFile waspDir prismaSchemaAst waspFilePath >>= \case | ||
Left errors -> return (Left errors, []) | ||
Right declarations -> | ||
EC.analyzeExternalConfigs waspDir (getSrcTsConfigInWaspProjectDir waspFilePath) >>= \case | ||
EC.analyzeExternalConfigs isTailwindUsed waspDir (getSrcTsConfigInWaspProjectDir waspFilePath) >>= \case | ||
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 wasn't sure if I wanted to thread the 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. Hm maybe they don't need it all, but this function is called Usually in Haskell we aim for "context" args at start, and then "core" args after that. So what I would consider is turning this function's signature into And it's not a problem if it takes a bit too much info -> it will analyze what it needs to analyze. We don't want to guess how it will analyze them, that is implementation detail. |
||
Left errors -> return (Left errors, []) | ||
Right externalConfigs -> constructAppSpec waspDir options externalConfigs prismaSchemaAst declarations | ||
Right externalConfigs -> constructAppSpec waspDir options externalConfigs configFiles prismaSchemaAst declarations | ||
|
||
constructAppSpec :: | ||
Path' Abs (Dir WaspProjectDir) -> | ||
CompileOptions -> | ||
EC.ExternalConfigs -> | ||
[CF.ConfigFileRelocator] -> | ||
Psl.Schema.Schema -> | ||
[AS.Decl] -> | ||
IO (Either [CompileError] AS.AppSpec, [CompileWarning]) | ||
constructAppSpec waspDir options externalConfigs parsedPrismaSchema decls = do | ||
constructAppSpec waspDir options externalConfigs configFiles parsedPrismaSchema decls = do | ||
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. What confuses me a bit is that this function takes both external configs and congif file relocators. Actually those two kind of make sense -> I guess it takes them, and then rules how to relocate them, I am not up to date with this piece of code completely so I am not quite sure -> but then for relocators you use |
||
externalCodeFiles <- ExternalFiles.readCodeFiles waspDir | ||
externalPublicFiles <- ExternalFiles.readPublicFiles waspDir | ||
customViteConfigPath <- findCustomViteConfigPath waspDir | ||
|
||
maybeMigrationsDir <- findMigrationsDir waspDir | ||
maybeUserDockerfileContents <- loadUserDockerfileContents waspDir | ||
configFiles <- CF.discoverConfigFiles waspDir G.CF.configFileRelocationMap | ||
let dbSystem = getValidDbSystemFromPrismaSchema parsedPrismaSchema | ||
let devDbUrl = makeDevDatabaseUrl waspDir dbSystem decls | ||
serverEnvVars <- readDotEnvServer waspDir | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,11 +23,12 @@ data ExternalConfigs = ExternalConfigs | |
deriving (Show) | ||
|
||
analyzeExternalConfigs :: | ||
Bool -> | ||
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. In general, seeing a Bool like this, where I can't tell from signature at all what it could be, is a bit suspicious. I commented more above why this one is probably not the right choice here. |
||
Path' Abs (Dir WaspProjectDir) -> | ||
Path' (Rel WaspProjectDir) (File SrcTsConfigFile) -> | ||
IO (Either [CompileError] ExternalConfigs) | ||
analyzeExternalConfigs waspDir srcTsConfigFile = runExceptT $ do | ||
packageJsonContent <- ExceptT $ analyzePackageJsonFile waspDir | ||
analyzeExternalConfigs isTailwindUsed waspDir srcTsConfigFile = runExceptT $ do | ||
packageJsonContent <- ExceptT $ analyzePackageJsonFile isTailwindUsed waspDir | ||
tsConfigContent <- ExceptT $ analyzeSrcTsConfigFile waspDir srcTsConfigFile | ||
|
||
return $ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,11 +18,11 @@ import Wasp.Project.Common | |
) | ||
import qualified Wasp.Util.IO as IOUtil | ||
|
||
analyzePackageJsonFile :: Path' Abs (Dir WaspProjectDir) -> IO (Either [String] P.PackageJson) | ||
analyzePackageJsonFile waspProjectDir = runExceptT $ do | ||
analyzePackageJsonFile :: Bool -> Path' Abs (Dir WaspProjectDir) -> IO (Either [String] P.PackageJson) | ||
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. We should probably rework this signature also, with similar approach as to how I suggested in other comments. |
||
analyzePackageJsonFile isTailwindUsed waspProjectDir = runExceptT $ do | ||
packageJsonFile <- ExceptT findPackageJsonFileOrError | ||
packageJson <- ExceptT $ readPackageJsonFile packageJsonFile | ||
case validatePackageJson packageJson of | ||
case validatePackageJson isTailwindUsed packageJson of | ||
[] -> return packageJson | ||
errors -> throwError errors | ||
where | ||
|
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 needed the information if Tailwind is used (which is computed using
doesConfigFileExist
) before we have the AppSpec so I pulled it out of here and rewritten it so it doesn't need the AppSpec.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.
How is it that you needed it before?
Are we getting into a situtation where we need a lot of info from AppSpec before AppSpec exists, pointing at some potential design issue, or do you think this is ok?