module Stan.Inspection
(
Inspection (..)
, categoryL
, descriptionL
, solutionL
, severityL
, analysisL
, InspectionAnalysis (..)
, InspectionsMap
, sortById
, prettyShowInspection
, prettyShowInspectionShort
, inspectionsMd
) where
import Relude.Extra.Lens (Lens', lens)
import Colourista (blue, bold, formatWith, green)
import Colourista.Short (b, i)
import Data.Aeson.Micro (ToJSON (..), object, (.=))
import Stan.Category (Category (..), prettyShowCategory)
import Stan.Core.Id (Id (..))
import Stan.Pattern.Ast (PatternAst)
import Stan.Severity (Severity, prettyShowSeverity)
import qualified Data.HashMap.Strict as HM
import qualified Data.Text as T
data Inspection = Inspection
{ Inspection -> Id Inspection
inspectionId :: !(Id Inspection)
, Inspection -> Text
inspectionName :: !Text
, Inspection -> Text
inspectionDescription :: !Text
, Inspection -> [Text]
inspectionSolution :: ![Text]
, Inspection -> NonEmpty Category
inspectionCategory :: !(NonEmpty Category)
, Inspection -> Severity
inspectionSeverity :: !Severity
, Inspection -> InspectionAnalysis
inspectionAnalysis :: !InspectionAnalysis
} deriving stock (Int -> Inspection -> ShowS
[Inspection] -> ShowS
Inspection -> String
(Int -> Inspection -> ShowS)
-> (Inspection -> String)
-> ([Inspection] -> ShowS)
-> Show Inspection
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Inspection -> ShowS
showsPrec :: Int -> Inspection -> ShowS
$cshow :: Inspection -> String
show :: Inspection -> String
$cshowList :: [Inspection] -> ShowS
showList :: [Inspection] -> ShowS
Show, Inspection -> Inspection -> Bool
(Inspection -> Inspection -> Bool)
-> (Inspection -> Inspection -> Bool) -> Eq Inspection
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Inspection -> Inspection -> Bool
== :: Inspection -> Inspection -> Bool
$c/= :: Inspection -> Inspection -> Bool
/= :: Inspection -> Inspection -> Bool
Eq)
instance ToJSON Inspection where
toJSON :: Inspection -> Value
toJSON Inspection{[Text]
NonEmpty Category
Text
Id Inspection
Severity
InspectionAnalysis
inspectionId :: Inspection -> Id Inspection
inspectionName :: Inspection -> Text
inspectionDescription :: Inspection -> Text
inspectionSolution :: Inspection -> [Text]
inspectionCategory :: Inspection -> NonEmpty Category
inspectionSeverity :: Inspection -> Severity
inspectionAnalysis :: Inspection -> InspectionAnalysis
inspectionId :: Id Inspection
inspectionName :: Text
inspectionDescription :: Text
inspectionSolution :: [Text]
inspectionCategory :: NonEmpty Category
inspectionSeverity :: Severity
inspectionAnalysis :: InspectionAnalysis
..} = [Pair] -> Value
object
[ Text
"id" Text -> Id Inspection -> Pair
forall v. ToJSON v => Text -> v -> Pair
.= Id Inspection
inspectionId
, Text
"name" Text -> Text -> Pair
forall v. ToJSON v => Text -> v -> Pair
.= Text
inspectionName
, Text
"description" Text -> Text -> Pair
forall v. ToJSON v => Text -> v -> Pair
.= Text
inspectionDescription
, Text
"solution" Text -> [Text] -> Pair
forall v. ToJSON v => Text -> v -> Pair
.= [Text]
inspectionSolution
, Text
"category" Text -> [Category] -> Pair
forall v. ToJSON v => Text -> v -> Pair
.= NonEmpty Category -> [Category]
forall a. NonEmpty a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty Category
inspectionCategory
, Text
"severity" Text -> Severity -> Pair
forall v. ToJSON v => Text -> v -> Pair
.= Severity
inspectionSeverity
]
descriptionL :: Lens' Inspection Text
descriptionL :: Lens' Inspection Text
descriptionL = (Inspection -> Text)
-> (Inspection -> Text -> Inspection) -> Lens' Inspection Text
forall s a. (s -> a) -> (s -> a -> s) -> Lens' s a
lens
Inspection -> Text
inspectionDescription
(\Inspection
inspection Text
new -> Inspection
inspection { inspectionDescription = new })
solutionL :: Lens' Inspection [Text]
solutionL :: Lens' Inspection [Text]
solutionL = (Inspection -> [Text])
-> (Inspection -> [Text] -> Inspection) -> Lens' Inspection [Text]
forall s a. (s -> a) -> (s -> a -> s) -> Lens' s a
lens
Inspection -> [Text]
inspectionSolution
(\Inspection
inspection [Text]
new -> Inspection
inspection { inspectionSolution = new })
categoryL :: Lens' Inspection (NonEmpty Category)
categoryL :: Lens' Inspection (NonEmpty Category)
categoryL = (Inspection -> NonEmpty Category)
-> (Inspection -> NonEmpty Category -> Inspection)
-> Lens' Inspection (NonEmpty Category)
forall s a. (s -> a) -> (s -> a -> s) -> Lens' s a
lens
Inspection -> NonEmpty Category
inspectionCategory
(\Inspection
inspection NonEmpty Category
new -> Inspection
inspection { inspectionCategory = new })
severityL :: Lens' Inspection Severity
severityL :: Lens' Inspection Severity
severityL = (Inspection -> Severity)
-> (Inspection -> Severity -> Inspection)
-> Lens' Inspection Severity
forall s a. (s -> a) -> (s -> a -> s) -> Lens' s a
lens
Inspection -> Severity
inspectionSeverity
(\Inspection
inspection Severity
new -> Inspection
inspection { inspectionSeverity = new })
analysisL :: Lens' Inspection InspectionAnalysis
analysisL :: Lens' Inspection InspectionAnalysis
analysisL = (Inspection -> InspectionAnalysis)
-> (Inspection -> InspectionAnalysis -> Inspection)
-> Lens' Inspection InspectionAnalysis
forall s a. (s -> a) -> (s -> a -> s) -> Lens' s a
lens
Inspection -> InspectionAnalysis
inspectionAnalysis
(\Inspection
inspection InspectionAnalysis
new -> Inspection
inspection { inspectionAnalysis = new })
type InspectionsMap = HashMap (Id Inspection) Inspection
sortById :: InspectionsMap -> [Inspection]
sortById :: InspectionsMap -> [Inspection]
sortById = (Inspection -> Id Inspection) -> [Inspection] -> [Inspection]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortWith Inspection -> Id Inspection
inspectionId ([Inspection] -> [Inspection])
-> (InspectionsMap -> [Inspection])
-> InspectionsMap
-> [Inspection]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InspectionsMap -> [Inspection]
forall k v. HashMap k v -> [v]
HM.elems
data InspectionAnalysis
= FindAst !PatternAst
| Infix
| LazyField
| BigTuples
| PatternMatchOn_
| UseCompare
deriving stock (Int -> InspectionAnalysis -> ShowS
[InspectionAnalysis] -> ShowS
InspectionAnalysis -> String
(Int -> InspectionAnalysis -> ShowS)
-> (InspectionAnalysis -> String)
-> ([InspectionAnalysis] -> ShowS)
-> Show InspectionAnalysis
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> InspectionAnalysis -> ShowS
showsPrec :: Int -> InspectionAnalysis -> ShowS
$cshow :: InspectionAnalysis -> String
show :: InspectionAnalysis -> String
$cshowList :: [InspectionAnalysis] -> ShowS
showList :: [InspectionAnalysis] -> ShowS
Show, InspectionAnalysis -> InspectionAnalysis -> Bool
(InspectionAnalysis -> InspectionAnalysis -> Bool)
-> (InspectionAnalysis -> InspectionAnalysis -> Bool)
-> Eq InspectionAnalysis
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: InspectionAnalysis -> InspectionAnalysis -> Bool
== :: InspectionAnalysis -> InspectionAnalysis -> Bool
$c/= :: InspectionAnalysis -> InspectionAnalysis -> Bool
/= :: InspectionAnalysis -> InspectionAnalysis -> Bool
Eq)
prettyShowInspection :: Inspection -> Text
prettyShowInspection :: Inspection -> Text
prettyShowInspection Inspection{[Text]
NonEmpty Category
Text
Id Inspection
Severity
InspectionAnalysis
inspectionId :: Inspection -> Id Inspection
inspectionName :: Inspection -> Text
inspectionDescription :: Inspection -> Text
inspectionSolution :: Inspection -> [Text]
inspectionCategory :: Inspection -> NonEmpty Category
inspectionSeverity :: Inspection -> Severity
inspectionAnalysis :: Inspection -> InspectionAnalysis
inspectionId :: Id Inspection
inspectionName :: Text
inspectionDescription :: Text
inspectionSolution :: [Text]
inspectionCategory :: NonEmpty Category
inspectionSeverity :: Severity
inspectionAnalysis :: InspectionAnalysis
..} = [Text] -> Text
forall t. IsText t "unlines" => [t] -> t
unlines ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$
[ Text -> Text
forall str. (IsString str, Semigroup str) => str -> str
b Text
"~~~STAN INSPECTION~~~"
, Text
""
, Text -> Text
forall str. (IsString str, Semigroup str) => str -> str
i Text
" ✲ ID: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
forall str. (IsString str, Semigroup str) => str -> str
b (Id Inspection -> Text
forall a. Id a -> Text
unId Id Inspection
inspectionId)
, Text -> Text
forall str. (IsString str, Semigroup str) => str -> str
i Text
" ✲ Name: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
inspectionName
, Text -> Text
forall str. (IsString str, Semigroup str) => str -> str
i Text
" ✲ Description: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
inspectionDescription
, Text -> Text
forall str. (IsString str, Semigroup str) => str -> str
i Text
" ✲ Severity: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Severity -> Text
prettyShowSeverity Severity
inspectionSeverity
, Text -> Text
forall str. (IsString str, Semigroup str) => str -> str
i Text
" ✲ Category: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> [Text] -> Text
T.intercalate Text
" " ((Category -> Text) -> [Category] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Category -> Text
prettyShowCategory ([Category] -> [Text]) -> [Category] -> [Text]
forall a b. (a -> b) -> a -> b
$ NonEmpty Category -> [Category]
forall a. NonEmpty a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty Category
inspectionCategory)
, Text
""
, [Text] -> Text -> Text
forall str. (IsString str, Semigroup str) => [str] -> str -> str
formatWith [Text
forall str. IsString str => str
green] Text
"Possible solutions:"
] [Text] -> [Text] -> [Text]
forall a. Semigroup a => a -> a -> a
<> (Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Text
" - " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) [Text]
inspectionSolution
prettyShowInspectionShort :: Inspection -> Text
prettyShowInspectionShort :: Inspection -> Text
prettyShowInspectionShort Inspection{[Text]
NonEmpty Category
Text
Id Inspection
Severity
InspectionAnalysis
inspectionId :: Inspection -> Id Inspection
inspectionName :: Inspection -> Text
inspectionDescription :: Inspection -> Text
inspectionSolution :: Inspection -> [Text]
inspectionCategory :: Inspection -> NonEmpty Category
inspectionSeverity :: Inspection -> Severity
inspectionAnalysis :: Inspection -> InspectionAnalysis
inspectionId :: Id Inspection
inspectionName :: Text
inspectionDescription :: Text
inspectionSolution :: [Text]
inspectionCategory :: NonEmpty Category
inspectionSeverity :: Severity
inspectionAnalysis :: InspectionAnalysis
..} =
Text
" ❋ "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Text] -> Text -> Text
forall str. (IsString str, Semigroup str) => [str] -> str -> str
formatWith [Text
forall str. IsString str => str
bold, Text
forall str. IsString str => str
blue] (Text
"[" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Id Inspection -> Text
forall a. Id a -> Text
unId Id Inspection
inspectionId Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"] ")
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
forall str. (IsString str, Semigroup str) => str -> str
i Text
inspectionName
inspectionsMd :: [Inspection] -> Text
inspectionsMd :: [Inspection] -> Text
inspectionsMd [Inspection]
inss = Text
intro Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
toc Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
forall t. IsText t "unlines" => [t] -> t
unlines ((Inspection -> Text) -> [Inspection] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Inspection -> Text
inspectionToMd [Inspection]
inss)
where
intro :: Text
intro :: Text
intro = Text
"This document contains information about all inspections used in Stan to find observations in your projects. Below you can see more details about each inspection individually\n\n"
toc :: Text
toc :: Text
toc = Text
"## Table of all Inspections\n\n" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
forall t. IsText t "unlines" => [t] -> t
unlines ((Inspection -> Text) -> [Inspection] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Inspection -> Text
insLink [Inspection]
inss) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\n"
insLink :: Inspection -> Text
insLink :: Inspection -> Text
insLink (Id Inspection -> Text
forall a. Id a -> Text
unId (Id Inspection -> Text)
-> (Inspection -> Id Inspection) -> Inspection -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Inspection -> Id Inspection
inspectionId -> Text
ins)= Text
" * [" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
ins Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"](#" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
ins Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
inspectionToMd :: Inspection -> Text
inspectionToMd :: Inspection -> Text
inspectionToMd Inspection{[Text]
NonEmpty Category
Text
Id Inspection
Severity
InspectionAnalysis
inspectionId :: Inspection -> Id Inspection
inspectionName :: Inspection -> Text
inspectionDescription :: Inspection -> Text
inspectionSolution :: Inspection -> [Text]
inspectionCategory :: Inspection -> NonEmpty Category
inspectionSeverity :: Inspection -> Severity
inspectionAnalysis :: Inspection -> InspectionAnalysis
inspectionId :: Id Inspection
inspectionName :: Text
inspectionDescription :: Text
inspectionSolution :: [Text]
inspectionCategory :: NonEmpty Category
inspectionSeverity :: Severity
inspectionAnalysis :: InspectionAnalysis
..} = [Text] -> Text
forall t. IsText t "unlines" => [t] -> t
unlines ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$
[ Text
"## " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Id Inspection -> Text
forall a. Id a -> Text
unId Id Inspection
inspectionId
, Text
""
, Text
"[[Back to the Table of all Inspections] ↑](#table-of-all-inspections)"
, Text
""
, Text
"| Property | Value |"
, Text
"|--|--|"
, Text
"| ID | " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Id Inspection -> Text
forall a. Id a -> Text
unId Id Inspection
inspectionId Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" |"
, Text
"| Name | " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
inspectionName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" |"
, Text
"| Description | " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
inspectionDescription Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" |"
, Text
"| Severity | " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Severity -> Text
forall b a. (Show a, IsString b) => a -> b
show Severity
inspectionSeverity Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" |"
, Text
"| Category | " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"#" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> [Text] -> Text
T.intercalate Text
" #" ((Category -> Text) -> [Category] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Category -> Text
unCategory ([Category] -> [Text]) -> [Category] -> [Text]
forall a b. (a -> b) -> a -> b
$ NonEmpty Category -> [Category]
forall a. NonEmpty a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty Category
inspectionCategory) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" |"
, Text
""
, Text
"#### Possible solutions for " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Id Inspection -> Text
forall a. Id a -> Text
unId Id Inspection
inspectionId
] [Text] -> [Text] -> [Text]
forall a. Semigroup a => a -> a -> a
<> (Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Text
" - " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) [Text]
inspectionSolution