diff --git a/ihp-ide/IHP/IDE/CodeGen/MigrationGenerator.hs b/ihp-ide/IHP/IDE/CodeGen/MigrationGenerator.hs index c9855dd37..0b9e93ff8 100644 --- a/ihp-ide/IHP/IDE/CodeGen/MigrationGenerator.hs +++ b/ihp-ide/IHP/IDE/CodeGen/MigrationGenerator.hs @@ -97,9 +97,12 @@ diffSchemas targetSchema' actualSchema' = (drop <> create) isCreateTableStatement (StatementCreateTable { unsafeGetCreateTable = table }) | table.name == tableName = True isCreateTableStatement otherwise = False - (Just actualTable) = actualSchema |> find \case + actualTable = case actualSchema |> find \case StatementCreateTable { unsafeGetCreateTable = table } -> table.name == tableName - otherwise -> False + otherwise -> False of + Just stmt@(StatementCreateTable {}) -> stmt + Just _ -> error $ "Internal error in patchTable: Expected StatementCreateTable but got different Statement type" + Nothing -> error $ "Internal error in patchTable: Could not find table " <> cs tableName <> " in actual schema" patchTable (s:rest) = s:(patchTable rest) patchTable [] = [] @@ -117,9 +120,12 @@ diffSchemas targetSchema' actualSchema' = (drop <> create) isCreateEnumTypeStatement CreateEnumType { name = n } = name == n isCreateEnumTypeStatement otherwise = False - (Just actualEnumType) = actualSchema |> find \case + actualEnumType = case actualSchema |> find \case CreateEnumType { name = enum } -> enum == name - otherwise -> False + otherwise -> False of + Just enumType@CreateEnumType{} -> enumType + Just _ -> error $ "Internal error in patchEnumType: Expected CreateEnumType but got different Statement type" + Nothing -> error $ "Internal error in patchEnumType: Could not find enum type " <> cs name <> " in actual schema" patchEnumType (s:rest) = s:(patchEnumType rest) patchEnumType [] = [] @@ -134,6 +140,7 @@ diffSchemas targetSchema' actualSchema' = (drop <> create) to = createTable'.name in (RenameTable { from, to }):(applyRenameTable (fixIdentifiers from to (delete createTable statements))) + Just _ -> s:(applyRenameTable statements) -- Not a StatementCreateTable, skip rename Nothing -> s:(applyRenameTable statements) where createTable :: Maybe Statement @@ -143,13 +150,14 @@ diffSchemas targetSchema' actualSchema' = (drop <> create) isCreateTableStatement (StatementCreateTable { unsafeGetCreateTable = table }) = (table.name /= actualTable'.name) && ((actualTable' :: CreateTable) { name = "" } == (table :: CreateTable) { name = "" }) isCreateTableStatement otherwise = False - (Just actualTable) = actualSchema |> find \case + maybeActualTable = actualSchema |> find \case StatementCreateTable { unsafeGetCreateTable = table } -> table.name == tableName otherwise -> False actualTable' :: CreateTable - actualTable' = case actualTable of - StatementCreateTable { unsafeGetCreateTable = table } -> table + actualTable' = case maybeActualTable of + Just (StatementCreateTable { unsafeGetCreateTable = table }) -> table + _ -> error $ "Internal error in applyRenameTable: Could not find table " <> cs tableName <> " in actual schema" fixIdentifiers :: Text -> Text -> [Statement] -> [Statement] fixIdentifiers tableFrom tableTo statements = map fixIdentifier statements @@ -252,9 +260,10 @@ migrateTable StatementCreateTable { unsafeGetCreateTable = targetTable } Stateme Nothing -> s:(applyMakeUnique statements) where dropColumn :: Column - (Just dropColumn) = actualColumns - |> find \case - Column { name } -> name == columnName + dropColumn = case actualColumns |> find \case + Column { name } -> name == columnName of + Just col -> col + Nothing -> error $ "Internal error in applyMakeUnique: Could not find column " <> cs columnName <> " in actual columns" updateConstraint = if dropColumn.isUnique then DropConstraint { tableName, constraintName = tableName <> "_" <> (dropColumn.name) <> "_key" } @@ -289,9 +298,10 @@ migrateTable StatementCreateTable { unsafeGetCreateTable = targetTable } Stateme Nothing -> s:(applySetDefault statements) where dropColumn :: Column - (Just dropColumn) = actualColumns - |> find \case - Column { name } -> name == columnName + dropColumn = case actualColumns |> find \case + Column { name } -> name == columnName of + Just col -> col + Nothing -> error $ "Internal error in applySetDefault: Could not find column " <> cs columnName <> " in actual columns" matchingCreateColumn :: Maybe Statement matchingCreateColumn = find isMatchingCreateColumn statements @@ -318,9 +328,10 @@ migrateTable StatementCreateTable { unsafeGetCreateTable = targetTable } Stateme Nothing -> s:(applyToggleNull statements) where dropColumn :: Column - (Just dropColumn) = actualColumns - |> find \case - Column { name } -> name == columnName + dropColumn = case actualColumns |> find \case + Column { name } -> name == columnName of + Just col -> col + Nothing -> error $ "Internal error in applyToggleNull: Could not find column " <> cs columnName <> " in actual columns" updateConstraint = if dropColumn.notNull then DropNotNull { tableName, columnName = dropColumn.name } diff --git a/ihp-ide/data/lib/IHP/Makefile.dist b/ihp-ide/data/lib/IHP/Makefile.dist index 3559e5bad..6afa7ce8b 100644 --- a/ihp-ide/data/lib/IHP/Makefile.dist +++ b/ihp-ide/data/lib/IHP/Makefile.dist @@ -55,7 +55,9 @@ GHC_EXTENSIONS+= -XPartialTypeSignatures GHC_EXTENSIONS+= -XStandaloneDeriving GHC_EXTENSIONS+= -XDerivingVia GHC_EXTENSIONS+= -Werror=missing-fields -GHC_EXTENSIONS+= -fwarn-incomplete-patterns +# Incomplete patterns are treated as errors to catch potential bugs at compile time +# If you need to disable this temporarily for a specific module, add {-# OPTIONS_GHC -Wno-error=incomplete-patterns #-} at the top of that module +GHC_EXTENSIONS+= -Werror=incomplete-patterns GHC_EXTENSIONS+= -XTemplateHaskell GHC_EXTENSIONS+= -XDeepSubsumption GHC_EXTENSIONS+= -XOverloadedRecordDot diff --git a/ihp-ide/ihp-ide.cabal b/ihp-ide/ihp-ide.cabal index 7d310201c..1cfbc542a 100644 --- a/ihp-ide/ihp-ide.cabal +++ b/ihp-ide/ihp-ide.cabal @@ -109,6 +109,9 @@ common shared-properties , TemplateHaskell , OverloadedRecordDot , DeepSubsumption + ghc-options: + -Werror=incomplete-patterns + -Werror=missing-fields if flag(FastBuild) ghc-options: -threaded diff --git a/ihp/IHP/ValidationSupport/ValidateField.hs b/ihp/IHP/ValidationSupport/ValidateField.hs index ba516ef04..f301ab07b 100644 --- a/ihp/IHP/ValidationSupport/ValidateField.hs +++ b/ihp/IHP/ValidationSupport/ValidateField.hs @@ -135,6 +135,7 @@ withCustomErrorMessage :: Text -> (value -> ValidatorResult) -> value -> Validat withCustomErrorMessage errorMessage validator value = case validator value of Failure _ -> Failure errorMessage + FailureHtml _ -> FailureHtml errorMessage Success -> Success {-# INLINABLE withCustomErrorMessage #-} diff --git a/ihp/IHP/View/CSSFramework.hs b/ihp/IHP/View/CSSFramework.hs index f230ea634..ac7694136 100644 --- a/ihp/IHP/View/CSSFramework.hs +++ b/ihp/IHP/View/CSSFramework.hs @@ -461,6 +461,7 @@ bootstrap4 = def renderInner = case formField.fieldType of TextInput -> styledTextFormField cssFramework "text" formField validationResult NumberInput -> styledTextFormField cssFramework "number" formField validationResult + UrlInput -> styledTextFormField cssFramework "url" formField validationResult PasswordInput -> styledTextFormField cssFramework "password" formField validationResult ColorInput -> styledTextFormField cssFramework "color" formField validationResult EmailInput -> styledTextFormField cssFramework "email" formField validationResult diff --git a/ihp/ihp.cabal b/ihp/ihp.cabal index f43fea857..15227d044 100644 --- a/ihp/ihp.cabal +++ b/ihp/ihp.cabal @@ -154,6 +154,9 @@ common shared-properties , TemplateHaskell , OverloadedRecordDot , DeepSubsumption + ghc-options: + -Werror=incomplete-patterns + -Werror=missing-fields library import: shared-properties