Skip to content
Snippets Groups Projects
Unverified Commit 1c82540a authored by stuebinm's avatar stuebinm
Browse files

can collect dependencies!

There's now a Lint type, which may be either a "true lint" (which is a
Hint, which contains some message and level of severity), or a Depends,
which indicates that this map depends on some ressource or other (and is
otherwise treated as a special info Hint in all other cases)
parent 77d1f4ce
Branches
No related tags found
No related merge requests found
...@@ -16,18 +16,20 @@ import qualified Data.Text as T ...@@ -16,18 +16,20 @@ import qualified Data.Text as T
import qualified Data.Vector as V import qualified Data.Vector as V
import GHC.Generics (Generic) import GHC.Generics (Generic)
import LintWriter (Hint (..), Level (..), import LintWriter (Level (..), Lint (..),
LintResult (..), LintWriter, hint) LintResult (..), LintWriter, hint,
lintLevel)
import Properties (checkProperty) import Properties (checkProperty)
import Tiled2 (Layer (layerName, layerProperties), import Tiled2 (Layer (layerName, layerProperties),
Tiledmap (tiledmapLayers), Tiledmap (tiledmapLayers),
loadTiledmap) loadTiledmap)
import Util (prettyprint, PrettyPrint (prettyprint)) import Util (PrettyPrint (prettyprint),
prettyprint)
-- | What this linter produces: lints for a single map -- | What this linter produces: lints for a single map
data MapResult a = MapResult data MapResult a = MapResult
{ mapresultLayer :: Maybe (Map Text (LintResult a)) { mapresultLayer :: Maybe (Map Text (LintResult a))
, mapresultGeneral :: [Hint] , mapresultGeneral :: [Lint]
} deriving (Generic, ToJSON) } deriving (Generic, ToJSON)
...@@ -83,12 +85,12 @@ showContext ctxt = " (in layer " <> ctxt <> ")\n" ...@@ -83,12 +85,12 @@ showContext ctxt = " (in layer " <> ctxt <> ")\n"
-- a wrapper type for that – but I wasn't really in the mood) -- a wrapper type for that – but I wasn't really in the mood)
showResult :: Text -> LintResult a -> Maybe Text showResult :: Text -> LintResult a -> Maybe Text
showResult ctxt (LintResult res) = case res of showResult ctxt (LintResult res) = case res of
Left hint -> Just $ "ERROR: " <> hintMsg hint <> showContext ctxt Left hint -> Just $ "Fatal: " <> prettyprint hint
Right (_, []) -> Nothing Right (_, []) -> Nothing
Right (_, hints) -> Just $ T.concat (mapMaybe showHint hints) Right (_, hints) -> Just $ T.concat (mapMaybe showHint hints)
where where
-- TODO: make the "log level" configurable -- TODO: make the "log level" configurable
showHint hint = case hintLevel hint of showHint hint = case lintLevel hint of
Info -> Nothing Info -> Nothing
_ -> Just $ prettyprint hint <> ctxtHint _ -> Just $ prettyprint hint <> ctxtHint
ctxtHint = showContext ctxt ctxtHint = showContext ctxt
...@@ -9,10 +9,11 @@ module LintWriter where ...@@ -9,10 +9,11 @@ module LintWriter where
import Control.Monad.Trans.Maybe () import Control.Monad.Trans.Maybe ()
import Control.Monad.Writer (MonadTrans (lift), import Control.Monad.Writer (MonadTrans (lift),
MonadWriter (tell), WriterT) MonadWriter (tell), WriterT)
import Data.Aeson (ToJSON (toJSON)) import Data.Aeson (ToJSON (toJSON), (.=))
import Data.Text (Text) import Data.Text (Text)
import GHC.Generics (Generic) import GHC.Generics (Generic)
import qualified Data.Aeson as A
import Util (PrettyPrint (..), showText) import Util (PrettyPrint (..), showText)
-- | Levels of errors and warnings, collectively called -- | Levels of errors and warnings, collectively called
...@@ -20,28 +21,51 @@ import Util (PrettyPrint(..), showText) ...@@ -20,28 +21,51 @@ import Util (PrettyPrint(..), showText)
data Level = Warning | Suggestion | Info | Forbidden | Error | Fatal data Level = Warning | Suggestion | Info | Forbidden | Error | Fatal
deriving (Show, Generic, ToJSON) deriving (Show, Generic, ToJSON)
-- | a hint comes with an explanation (and a level) -- | a hint comes with an explanation (and a level), or is a dependency
-- (in which case it'll be otherwise treated as an info hint)
data Lint = Depends Dep | Lint Hint
data Hint = Hint data Hint = Hint
{ hintLevel :: Level { hintLevel :: Level
, hintMsg :: Text , hintMsg :: Text
} deriving (Generic, ToJSON) } deriving (Generic, ToJSON)
instance PrettyPrint Hint where lintLevel :: Lint -> Level
prettyprint Hint { hintMsg, hintLevel } = lintLevel (Lint h) = hintLevel h
lintLevel (Depends dep) = Info
instance PrettyPrint Lint where
prettyprint (Lint Hint { hintMsg, hintLevel } ) =
showText hintLevel <> ": " <> hintMsg showText hintLevel <> ": " <> hintMsg
prettyprint (Depends dep) =
"Info: found dependency: " <> prettyprint dep
instance ToJSON Lint where
toJSON (Lint l) = toJSON l
toJSON (Depends dep) = A.object
[ "hintMsg" .= prettyprint dep
, "hintLevel" .= A.String "Dependency Info" ]
-- shorter constructor -- shorter constructor
hint :: Level -> Text -> Hint hint :: Level -> Text -> Lint
hint level msg = Hint { hintLevel = level, hintMsg = msg } hint level msg = Lint Hint { hintLevel = level, hintMsg = msg }
-- | TODO: add a reasonable representation of possible urls
newtype Dep = Dep Text
deriving (Generic, ToJSON)
instance PrettyPrint Dep where
prettyprint (Dep txt) = txt
-- | a monad to collect hints. If it yields Left, then the -- | a monad to collect hints. If it yields Left, then the
-- map is flawed in some fundamental way which prevented us -- map is flawed in some fundamental way which prevented us
-- from getting any hints at all except whatever broke it -- from getting any hints at all except whatever broke it
type LintWriter a = WriterT [Hint] (Either Hint) a type LintWriter a = WriterT [Lint] (Either Lint) a
-- this is wrapped in a newtype because Aeson is silly and wants -- this is wrapped in a newtype because Aeson is silly and wants
-- to serialise Either as { "Right" : … } or { "Left" : … } ... -- to serialise Either as { "Right" : … } or { "Left" : … } ...
type LintResult' a = Either Hint (a, [Hint]) type LintResult' a = Either Lint (a, [Lint])
newtype LintResult a = LintResult (LintResult' a) newtype LintResult a = LintResult (LintResult' a)
-- better, less confusing serialisation of an Either Hint (a, [Hint]). -- better, less confusing serialisation of an Either Hint (a, [Hint]).
...@@ -58,6 +82,9 @@ instance ToJSON a => ToJSON (LintResult a) where ...@@ -58,6 +82,9 @@ instance ToJSON a => ToJSON (LintResult a) where
lint :: Level -> Text -> LintWriter () lint :: Level -> Text -> LintWriter ()
lint level = tell . (: []) . hint level lint level = tell . (: []) . hint level
require :: Text -> LintWriter ()
require dep = tell . (: []) $ Depends (Dep dep)
warn = lint Warning warn = lint Warning
info = lint Info info = lint Info
forbid = lint Forbidden forbid = lint Forbidden
...@@ -74,7 +101,7 @@ unwrap hint maybe = case maybe of ...@@ -74,7 +101,7 @@ unwrap hint maybe = case maybe of
Nothing -> Left hint Nothing -> Left hint
-- | unwrap and produce a warning if the value was Nothing -- | unwrap and produce a warning if the value was Nothing
unwrapWarn :: Text -> Maybe a -> Either Hint a unwrapWarn :: Text -> Maybe a -> Either Lint a
unwrapWarn msg = unwrap $ hint Warning msg unwrapWarn msg = unwrap $ hint Warning msg
-- | same as unwrapWarn, but for booleans -- | same as unwrapWarn, but for booleans
......
...@@ -7,11 +7,12 @@ module Properties (checkProperty) where ...@@ -7,11 +7,12 @@ module Properties (checkProperty) where
import Control.Monad (unless) import Control.Monad (unless)
import Data.Text (Text) import Data.Text (Text)
import Tiled2 (Layer (layerProperties), Property, propertyName, propertyValue) import Tiled2 (Layer (layerProperties), Property, propertyName,
propertyValue)
import Util (prettyprint) import Util (prettyprint)
import LintWriter (LintWriter, complain, forbid, info, import LintWriter (LintWriter, complain, forbid, info, require,
suggest, warn, Dep(..), require) suggest, warn)
-- | the point of this module -- | the point of this module
-- --
...@@ -45,6 +46,7 @@ checkProperty layer prop = case propName of ...@@ -45,6 +46,7 @@ checkProperty layer prop = case propName of
requireProperty "playAudio" requireProperty "playAudio"
"openWebsite" -> do "openWebsite" -> do
suggestPropertyValue "openWebsiteTrigger" "onaction" suggestPropertyValue "openWebsiteTrigger" "onaction"
require $ propertyValue prop
"openWebsiteTrigger" -> "openWebsiteTrigger" ->
requireProperty "openWebsite" requireProperty "openWebsite"
"openWebsitePolicy" -> "openWebsitePolicy" ->
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment