packages feed

sarif (empty) → 0.1

raw patch · 15 files changed

+781/−0 lines, 15 filesdep +aesondep +basedep +bytestring

Dependencies added: aeson, base, bytestring, containers, text, uuid-types

Files

+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Changelog for `sarif`++## 0.1 - 22 December 2022++* First release with an initial implementation of some key aspects of the SARIF specification
+ LICENSE view
@@ -0,0 +1,21 @@+MIT License++Copyright (c) 2022 Michael B. Gale++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
+ README.md view
@@ -0,0 +1,3 @@+# SARIF implementation for Haskell++This Haskell library provides types and JSON instances for the [Static Analysis Results Interchange Format (SARIF)](https://sarifweb.azurewebsites.net). Static analysis tools written in Haskell may use this library to export their results which can then be consumed by e.g. [GitHub Code Scanning](https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning).
+ sarif.cabal view
@@ -0,0 +1,58 @@+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.35.1.+--+-- see: https://github.com/sol/hpack++name:           sarif+version:        0.1+synopsis:       SARIF implementation for Haskell+description:    Provides types and JSON instances for the Static Analysis Results Interchange Format (SARIF).+category:       Data+homepage:       https://github.com/mbg/sarif#readme+bug-reports:    https://github.com/mbg/sarif/issues+author:         Michael B. Gale+maintainer:     github@michael-gale.co.uk+copyright:      Copyright (c) Michael B. Gale+license:        MIT+license-file:   LICENSE+build-type:     Simple+extra-source-files:+    README.md+    CHANGELOG.md++source-repository head+  type: git+  location: https://github.com/mbg/sarif++library+  exposed-modules:+      Data.Aeson.Optional+      Data.SARIF+      Data.SARIF.Artifact+      Data.SARIF.Level+      Data.SARIF.Location+      Data.SARIF.Log+      Data.SARIF.MultiformatMessageString+      Data.SARIF.ReportingDescriptor+      Data.SARIF.Result+      Data.SARIF.Run+      Data.SARIF.Tool+  other-modules:+      Paths_sarif+  hs-source-dirs:+      src+  default-extensions:+      DeriveAnyClass+      DeriveGeneric+      OverloadedStrings+      RecordWildCards+  ghc-options: -Wall+  build-depends:+      aeson+    , base >=4.8 && <5+    , bytestring+    , containers+    , text+    , uuid-types+  default-language: Haskell2010
+ src/Data/Aeson/Optional.hs view
@@ -0,0 +1,56 @@+--------------------------------------------------------------------------------+-- SARIF implementation for Haskell+--------------------------------------------------------------------------------+-- This source code is licensed under the MIT license found in the LICENSE    --+-- file in the root directory of this source tree.                            --+--------------------------------------------------------------------------------++{-# LANGUAGE CPP #-}++-- | Provides extensions to "Data.Aeson" for constructing JSON objects which+-- omit fields that are @null@.+module Data.Aeson.Optional (+    module Aeson,+    object,+    (.=),+    (.=?)+) where++--------------------------------------------------------------------------------++import Data.Aeson as Aeson hiding (object, (.=))+import Data.Aeson.Types (Pair)+import qualified Data.Aeson as JSON (object)+import Data.Maybe+#if !MIN_VERSION_aeson(2,0,0)+import Data.Text+#endif++--------------------------------------------------------------------------------++-- | `object` @pairList@ constructs a JSON objects from @pairList@, omitting+-- all `Nothing` values.+object :: [Maybe Pair] -> Value+object = JSON.object . catMaybes++infixr 8 .=?, .=+-- | Construct an optional field from an optional value. If the value is+-- `Nothing`, then the field will be omitted from the JSON object.+#if MIN_VERSION_aeson(2,0,0)+(.=?) :: ToJSON a => Key -> Maybe a -> Maybe Pair+#else+(.=?) :: ToJSON a => Text -> Maybe a -> Maybe Pair+#endif+_ .=? Nothing = Nothing+key .=? Just val = Just (key, toJSON val)++-- | Construct a mandatory field from a value. The resulting field will always+-- be present in the resulting JSON object.+#if MIN_VERSION_aeson(2,0,0)+(.=) :: ToJSON a => Key -> a -> Maybe Pair+#else+(.=) :: ToJSON a => Text -> a -> Maybe Pair+#endif+key .= val = Just (key, toJSON val)++--------------------------------------------------------------------------------
+ src/Data/SARIF.hs view
@@ -0,0 +1,26 @@+--------------------------------------------------------------------------------+-- SARIF implementation for Haskell+--------------------------------------------------------------------------------+-- This source code is licensed under the MIT license found in the LICENSE    --+-- file in the root directory of this source tree.                            --+--------------------------------------------------------------------------------++-- | Re-exports all modules from this library. You probably want to import+-- this module as qualified.+module Data.SARIF (+    module SARIF+) where++--------------------------------------------------------------------------------++import Data.SARIF.Artifact as SARIF+import Data.SARIF.Level as SARIF+import Data.SARIF.Location as SARIF+import Data.SARIF.Log as SARIF+import Data.SARIF.MultiformatMessageString as SARIF+import Data.SARIF.ReportingDescriptor as SARIF+import Data.SARIF.Result as SARIF+import Data.SARIF.Run as SARIF+import Data.SARIF.Tool as SARIF++--------------------------------------------------------------------------------
+ src/Data/SARIF/Artifact.hs view
@@ -0,0 +1,41 @@+--------------------------------------------------------------------------------+-- SARIF implementation for Haskell+--------------------------------------------------------------------------------+-- This source code is licensed under the MIT license found in the LICENSE    --+-- file in the root directory of this source tree.                            --+--------------------------------------------------------------------------------++-- | Provides the `Artifact` type to represent SARIF artifacts.+module Data.SARIF.Artifact (+    Artifact(..)+) where++--------------------------------------------------------------------------------++import Data.Aeson.Optional+import Data.Text++import Data.SARIF.Location++--------------------------------------------------------------------------------++-- | An artifact represents e.g. a source file.+data Artifact = MkArtifact {+    -- | The location where the artifact was found.+    artifactLocation :: ArtifactLocation,+    -- | The mime type of the artifact.+    artifactMimeType :: Maybe Text+} deriving (Eq, Show)++instance ToJSON Artifact where+    toJSON MkArtifact{..} = object+        [ "location" .= artifactLocation+        , "mimeType" .=? artifactMimeType+        ]++instance FromJSON Artifact where+    parseJSON = withObject "Artifact" $ \obj ->+        MkArtifact <$> obj .: "location"+                   <*> obj .:? "mimeType"++--------------------------------------------------------------------------------
+ src/Data/SARIF/Level.hs view
@@ -0,0 +1,45 @@+--------------------------------------------------------------------------------+-- SARIF implementation for Haskell+--------------------------------------------------------------------------------+-- This source code is licensed under the MIT license found in the LICENSE    --+-- file in the root directory of this source tree.                            --+--------------------------------------------------------------------------------++-- | Provides the `Level` type, which enumerates SARIF result levels.+-- See https://docs.oasis-open.org/sarif/sarif/v2.1.0/cs01/sarif-v2.1.0-cs01.html#_Ref493511208+module Data.SARIF.Level (+    Level(..)+) where++--------------------------------------------------------------------------------++import Data.Aeson.Optional hiding (Error)++--------------------------------------------------------------------------------++-- | A `Level` value represents the severity of a result.+data Level+    -- | The concept of “severity” does not apply.+    = None+    -- | A minor problem or an opportunity to improve the code was found.+    | Note+    -- | A problem was found.+    | Warning+    -- | A serious problem was found.+    | Error+    deriving (Eq, Show)++instance ToJSON Level where+    toJSON None = "none"+    toJSON Note = "note"+    toJSON Warning = "warning"+    toJSON Error = "error"++instance FromJSON Level where+    parseJSON (String "none") = pure None+    parseJSON (String "note") = pure Note+    parseJSON (String "warning") = pure Warning+    parseJSON (String "error") = pure Error+    parseJSON _ = fail "Unexpected value for result level"++--------------------------------------------------------------------------------
+ src/Data/SARIF/Location.hs view
@@ -0,0 +1,98 @@+--------------------------------------------------------------------------------+-- SARIF implementation for Haskell+--------------------------------------------------------------------------------+-- This source code is licensed under the MIT license found in the LICENSE    --+-- file in the root directory of this source tree.                            --+--------------------------------------------------------------------------------++-- | Provides types used to refer to different sorts of locations, such as+-- files, as well as parts of files.+module Data.SARIF.Location (+    Location(..),+    ArtifactLocation(..),+    Region(..),+    PhysicalLocation(..)+) where++--------------------------------------------------------------------------------++import Data.Aeson+import Data.Text++--------------------------------------------------------------------------------++-- | Represents locations.+newtype Location = MkLocation {+    -- | The physical location (i.e. part of a file) to which this location+    -- refers to.+    locationPhysicalLocation :: Maybe PhysicalLocation+} deriving (Eq, Show)++instance ToJSON Location where+    toJSON MkLocation{..} = object+        [ "physicalLocation" .= locationPhysicalLocation+        ]++instance FromJSON Location where+    parseJSON = withObject "Location" $ \obj ->+        MkLocation <$> obj .:? "physicalLocation"++-- | Represents artifact locations such as file paths.+newtype ArtifactLocation = MkArtifactLocation {+    artifactLocationUri :: Text+} deriving (Eq, Show)++instance ToJSON ArtifactLocation where+    toJSON MkArtifactLocation{..} = object+        [ "uri" .= artifactLocationUri+        ]++instance FromJSON ArtifactLocation where+    parseJSON = withObject "ArtifactLocation" $ \obj ->+        MkArtifactLocation <$> obj .: "uri"++-- | Represents regions of code with a start and an end.+data Region = MkRegion {+    -- | The line on which this region starts.+    regionStartLine :: Int,+    -- | The column within the starting line where this region starts.+    regionStartColumn :: Int,+    -- | The line on which this region ends.+    regionEndLine :: Int,+    -- | The column within the ending line where this region ends.+    regionEndColumn :: Int+} deriving (Eq, Show)++instance ToJSON Region where+    toJSON MkRegion{..} = object+        [ "startLine" .= regionStartLine+        , "startColumn" .= regionStartColumn+        , "endLine" .= regionEndLine+        , "endColumn" .= regionEndColumn+        ]++instance FromJSON Region where+    parseJSON = withObject "Region" $ \obj ->+        MkRegion <$> obj .: "startLine"+                 <*> obj .: "startColumn"+                 <*> obj .: "endLine"+                 <*> obj .: "endColumn"++-- | Represents parts of artifacts, e.g. a `Region` within a file.+data PhysicalLocation = MkPhysicalLocation {+    physicalLocationArtifactLocation :: ArtifactLocation,+    physicalLocationRegion :: Region+} deriving (Eq, Show)++instance ToJSON PhysicalLocation where+    toJSON MkPhysicalLocation{..} = object+        [ "artifactLocation" .= physicalLocationArtifactLocation+        , "region" .= physicalLocationRegion+        ]++instance FromJSON PhysicalLocation where+    parseJSON = withObject "PhysicalLocation" $ \obj ->+        MkPhysicalLocation <$> obj .: "artifactLocation"+                           <*> obj .: "region"++--------------------------------------------------------------------------------
+ src/Data/SARIF/Log.hs view
@@ -0,0 +1,67 @@+--------------------------------------------------------------------------------+-- SARIF implementation for Haskell+--------------------------------------------------------------------------------+-- This source code is licensed under the MIT license found in the LICENSE    --+-- file in the root directory of this source tree.                            --+--------------------------------------------------------------------------------++-- | Provides the top-level structure of SARIF.+module Data.SARIF.Log (+    Log(..),+    defaultLog,+    decodeSarifFileStrict,+    encodeSarifAsLBS+) where++--------------------------------------------------------------------------------++import Data.Aeson+import qualified Data.ByteString.Lazy as LBS+import Data.Text++import Data.SARIF.Run (Run(..))++--------------------------------------------------------------------------------++-- | Each SARIF file contains one `Log` value at the top.+data Log = MkLog {+    -- | The version identifier of the SARIF format used by the file.+    logVersion :: Text,+    -- | A list of descriptions of runs of static analysis tools.+    logRuns :: [Run]+} deriving (Eq, Show)++-- | The URL of the JSON schema that describes SARIF.+schemaUrl :: Text+schemaUrl = "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"++instance ToJSON Log where+    toJSON MkLog{..} = object+        [ "version" .= logVersion+        , "runs" .= logRuns+        , "$schema" .= schemaUrl+        ]++instance FromJSON Log where+    parseJSON = withObject "Log" $ \obj ->+        MkLog <$> obj .: "version"+              <*> obj .: "runs"++-- | Represents a default `Log` value.+defaultLog :: Log+defaultLog = MkLog{+    logVersion = "2.1.0",+    logRuns = []+}++-- | `decodeSarifFileStrict` @filepath@ is a type-specialised version of+-- `eitherDecodeFileStrict` for `Log`.+decodeSarifFileStrict :: FilePath -> IO (Either String Log)+decodeSarifFileStrict = eitherDecodeFileStrict++-- | `encodeSarifAsLBS` @log@ encodes a `Log` value as a lazy `LBS.ByteString`.+-- This is a type-specialised version of `encode`.+encodeSarifAsLBS :: Log -> LBS.ByteString+encodeSarifAsLBS = encode++--------------------------------------------------------------------------------
+ src/Data/SARIF/MultiformatMessageString.hs view
@@ -0,0 +1,51 @@+--------------------------------------------------------------------------------+-- SARIF implementation for Haskell+--------------------------------------------------------------------------------+-- This source code is licensed under the MIT license found in the LICENSE    --+-- file in the root directory of this source tree.                            --+--------------------------------------------------------------------------------++-- | Provides the `MultiformatMessageString` type which is used to represent+-- messages in different formats, such as text or markdown.+module Data.SARIF.MultiformatMessageString (+    MultiformatMessageString(..),+    defaultMultiformatMessageString+) where++--------------------------------------------------------------------------------++import Data.Aeson.Optional+import Data.Text++--------------------------------------------------------------------------------++-- | Represents a message in at least textual representation, but also allowing+-- it to be provided in other formats such as markdown.+data MultiformatMessageString = MkMultiformatMessageString {+    -- | A textual representation of the message, which is mandatory.+    mmsText :: Text,+    -- | Optionally, a markdown representation of the message.+    mmsMarkdown :: Maybe Text+} deriving (Eq, Show)++instance ToJSON MultiformatMessageString where+    toJSON MkMultiformatMessageString{..} = object+        [ "text" .= mmsText+        , "markdown" .=? mmsMarkdown+        ]++instance FromJSON MultiformatMessageString where+    parseJSON = withObject "MultiformatMessageString" $ \obj ->+        MkMultiformatMessageString <$> obj .: "text"+                                   <*> obj .:? "markdown"++-- | `defaultMultiformatMessageString` @messageText@ constructs a+-- `MultiformatMessageString` value where @messageText@ is the textual+-- representation of the message.+defaultMultiformatMessageString :: Text -> MultiformatMessageString+defaultMultiformatMessageString text = MkMultiformatMessageString{+    mmsText = text,+    mmsMarkdown = Nothing+}++--------------------------------------------------------------------------------
+ src/Data/SARIF/ReportingDescriptor.hs view
@@ -0,0 +1,110 @@+--------------------------------------------------------------------------------+-- SARIF implementation for Haskell+--------------------------------------------------------------------------------+-- This source code is licensed under the MIT license found in the LICENSE    --+-- file in the root directory of this source tree.                            --+--------------------------------------------------------------------------------++-- | Provides the `ReportingDescriptor` type, which is essentially used to+-- represent descriptions of rules that a static analysis tool has applied.+module Data.SARIF.ReportingDescriptor (+    ReportingConfiguration(..),+    defaultReportingConfiguration,+    ReportingDescriptor(..),+    defaultReportingDescriptor+) where++--------------------------------------------------------------------------------++import Data.Aeson.Optional+import qualified Data.Map.Lazy as M+import Data.Text++import Data.SARIF.Level+import Data.SARIF.MultiformatMessageString++--------------------------------------------------------------------------------++-- | Represents default configurations for `ReportingDescriptor` values. That is+-- properties which may be overriden by individual results.+newtype ReportingConfiguration = MkReportingConfiguration {+    -- | The default severity of the reporting descriptor.+    rcLevel :: Maybe Level+} deriving (Eq, Show)++instance ToJSON ReportingConfiguration where+    toJSON MkReportingConfiguration{..} = object+        [ "level" .=? rcLevel+        ]+instance FromJSON ReportingConfiguration where+    parseJSON = withObject "ReportingConfiguration" $ \obj ->+        MkReportingConfiguration <$> obj .: "level"++-- | `defaultReportingConfiguration` is a default+-- `ReportingConfiguration` value.+defaultReportingConfiguration :: ReportingConfiguration+defaultReportingConfiguration = MkReportingConfiguration{+    rcLevel = Nothing+}++-- | Represents rules that a static analysis tool+data ReportingDescriptor = MkReportingDescriptor {+    -- | The unique ID of the rule.+    rdId :: Text,+    -- | A friendly name for the rule, which should be one word in+    -- upper camel case.+    rdName :: Maybe Text,+    -- | A short description for the rule, which may contain spaces+    -- and symbols.+    rdShortDescription :: Maybe MultiformatMessageString,+    -- | The full description.+    rdFullDescription :: Maybe MultiformatMessageString,+    -- | A URL to some help for this rule.+    rdHelpUri :: Maybe Text,+    -- | A recommendation for what to do in order to resolve an occurrence+    -- of this rule.+    rdHelp :: Maybe MultiformatMessageString,+    -- | The default reporting configuration for the rule.+    rdDefaultConfiguration :: Maybe ReportingConfiguration,+    -- | Extra properties for this rule.+    rdProperties :: M.Map Text Value+} deriving (Eq, Show)++instance ToJSON ReportingDescriptor where+    toJSON MkReportingDescriptor{..} = object+        [ "id" .= rdId+        , "name" .=? rdName+        , "shortDescription" .=? rdShortDescription+        , "fullDescription" .=? rdFullDescription+        , "helpUri" .=? rdHelpUri+        , "help" .=? rdHelp+        , "defaultConfiguration" .=? rdDefaultConfiguration+        , "properties" .= rdProperties+        ]++instance FromJSON ReportingDescriptor where+    parseJSON = withObject "ReportingDescriptor" $ \obj ->+        MkReportingDescriptor <$> obj .: "id"+                              <*> obj .:? "name"+                              <*> obj .:? "shortDescription"+                              <*> obj .:? "fullDescription"+                              <*> obj .:? "helpUri"+                              <*> obj .:? "help"+                              <*> obj .:? "defaultConfiguration"+                              <*> obj .: "properties" .!= M.empty++-- | `defaultReportingDescriptor` @id@ constructs a default+-- `ReportingDescriptor` with the given @id@, which must be unique.+defaultReportingDescriptor :: Text -> ReportingDescriptor+defaultReportingDescriptor ident = MkReportingDescriptor{+    rdId = ident,+    rdName = Nothing,+    rdShortDescription = Nothing,+    rdFullDescription = Nothing,+    rdHelpUri = Nothing,+    rdHelp = Nothing,+    rdDefaultConfiguration = Nothing,+    rdProperties = M.empty+}++--------------------------------------------------------------------------------
+ src/Data/SARIF/Result.hs view
@@ -0,0 +1,54 @@+--------------------------------------------------------------------------------+-- SARIF implementation for Haskell+--------------------------------------------------------------------------------+-- This source code is licensed under the MIT license found in the LICENSE    --+-- file in the root directory of this source tree.                            --+--------------------------------------------------------------------------------++-- | Provides the `Result` type which represents results of a+-- static analysis tool.+module Data.SARIF.Result (+    Level(..),+    Result(..)+) where++--------------------------------------------------------------------------------++import Data.Aeson.Optional hiding (Result, Error)+import Data.Text++import Data.SARIF.Level+import Data.SARIF.Location+import Data.SARIF.MultiformatMessageString++--------------------------------------------------------------------------------++-- | Represents the results of a run of a static analysis tool.+data Result = MkResult {+    -- | The unique ID of the rule of which this result is an occurrence of.+    resultRuleId :: Text,+    -- | A result-specific message which may refer to specific variable names+    -- etc. which caused the rule to trigger.+    resultMessage :: MultiformatMessageString,+    -- | A list of locations which caused the rule to trigger.+    resultLocations :: [Location],+    -- | An optional override for the default `Level` of the rule.+    resultLevel :: Maybe Level+} deriving (Eq, Show)++instance ToJSON Result where+    toJSON MkResult{..} = object+        [ "ruleId" .= resultRuleId+        , "message" .= resultMessage+        , "locations" .= resultLocations+        , "level" .=? resultLevel+        ]++instance FromJSON Result where+    parseJSON = withObject "Result" $ \obj ->+        MkResult <$> obj .: "ruleId"+                 <*> obj .: "message"+                 <*> obj .: "locations"+                 <*> obj .: "level"++--------------------------------------------------------------------------------
+ src/Data/SARIF/Run.hs view
@@ -0,0 +1,48 @@+--------------------------------------------------------------------------------+-- SARIF implementation for Haskell+--------------------------------------------------------------------------------+-- This source code is licensed under the MIT license found in the LICENSE    --+-- file in the root directory of this source tree.                            --+--------------------------------------------------------------------------------++-- | Provides the `Run` type which represents a single run of a+-- static analysis tool.+module Data.SARIF.Run (+    Run(..)+) where++--------------------------------------------------------------------------------++import Data.Aeson hiding (Result)++import Data.SARIF.Artifact+import Data.SARIF.Result (Result(..))+import Data.SARIF.Tool (Tool(..))++--------------------------------------------------------------------------------++-- | Represents individual runs of static analysis tools.+data Run = MkRun {+    -- | A description of the tool that was run.+    runTool :: Tool,+    -- | A list of the artifacts that were scanned by the tool.+    runArtifacts :: [Artifact],+    -- | The results produced by the tool as a result of scanning+    -- the artifacts.+    runResults :: [Result]+} deriving (Eq, Show)++instance ToJSON Run where+    toJSON MkRun{..} = object+        [ "tool" .= runTool+        , "artifacts" .= runArtifacts+        , "results" .= runResults+        ]++instance FromJSON Run where+    parseJSON = withObject "Run" $ \obj ->+        MkRun <$> obj .: "tool"+              <*> obj .: "artifacts" .!= []+              <*> obj .: "results" .!= []++--------------------------------------------------------------------------------
+ src/Data/SARIF/Tool.hs view
@@ -0,0 +1,98 @@+--------------------------------------------------------------------------------+-- SARIF implementation for Haskell+--------------------------------------------------------------------------------+-- This source code is licensed under the MIT license found in the LICENSE    --+-- file in the root directory of this source tree.                            --+--------------------------------------------------------------------------------++-- | Provides the `Tool` type which is used to describe static analysis tools.+module Data.SARIF.Tool (+    Tool(..),+    ToolComponent(..),+    defaultToolComponent+) where++--------------------------------------------------------------------------------++import GHC.Generics++import Data.Aeson.Optional+import Data.Text+import Data.UUID.Types++import Data.SARIF.ReportingDescriptor++--------------------------------------------------------------------------------++-- | Used to describe static analysis tools.+data Tool = MkTool {+    -- | The description of the tool itself.+    toolDriver :: ToolComponent,+    -- | Descriptions of any extensions to the tool that were used.+    toolExtensions :: [ToolComponent]+} deriving (Eq, Show, Generic)++instance ToJSON Tool where+    toJSON MkTool{..} = object+        [ "driver" .= toolDriver+        , "extensions" .= toolExtensions+        ]++instance FromJSON Tool where+    parseJSON = withObject "Tool" $ \obj ->+        MkTool <$> obj .: "driver"+               <*> obj .: "extensions" .!= []++-- | A description of a tool component, such as a static analysis tool or+-- an extension to one.+data ToolComponent = MkToolComponent {+    -- | The short name of the tool component.+    toolComponentName :: Maybe Text,+    -- | The full name of the tool component.+    toolComponentFullName :: Maybe Text,+    -- | The semver of the tool component.+    toolComponentSemanticVersion :: Maybe Text,+    -- | The version of the tool component.+    toolComponentVersion :: Maybe Text,+    -- | A GUID which identifies the tool component.+    toolComponentGUID :: Maybe UUID,+    -- | A URI pointing to more information about the tool component.+    toolComponentInformationUri :: Maybe Text,+    -- | A list of rules that the tool component applies.+    toolComponentRules :: [ReportingDescriptor]+} deriving (Eq, Show, Generic)++instance ToJSON ToolComponent where+    toJSON MkToolComponent{..} = object+        [ "name" .= toolComponentName+        , "fullName" .=? toolComponentFullName+        , "semanticVersion" .=? toolComponentSemanticVersion+        , "version" .=? toolComponentVersion+        , "guid" .=? toolComponentGUID+        , "informationUri" .=? toolComponentInformationUri+        , "rules" .= toolComponentRules+        ]++instance FromJSON ToolComponent where+    parseJSON = withObject "ToolComponent" $ \obj ->+        MkToolComponent <$> obj .: "name"+                        <*> obj .: "fullName"+                        <*> obj .:? "semanticVersion"+                        <*> obj .:? "version"+                        <*> obj .:? "guid"+                        <*> obj .:? "informationUri"+                        <*> obj .: "rules" .!= []++-- | `defaultToolComponent` is a default value of the `ToolComponent` type.+defaultToolComponent :: ToolComponent+defaultToolComponent = MkToolComponent{+    toolComponentName = Nothing,+    toolComponentFullName = Nothing,+    toolComponentSemanticVersion = Nothing,+    toolComponentVersion = Nothing,+    toolComponentGUID = Nothing,+    toolComponentInformationUri = Nothing,+    toolComponentRules = []+}++--------------------------------------------------------------------------------