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 +5/−0
- LICENSE +21/−0
- README.md +3/−0
- sarif.cabal +58/−0
- src/Data/Aeson/Optional.hs +56/−0
- src/Data/SARIF.hs +26/−0
- src/Data/SARIF/Artifact.hs +41/−0
- src/Data/SARIF/Level.hs +45/−0
- src/Data/SARIF/Location.hs +98/−0
- src/Data/SARIF/Log.hs +67/−0
- src/Data/SARIF/MultiformatMessageString.hs +51/−0
- src/Data/SARIF/ReportingDescriptor.hs +110/−0
- src/Data/SARIF/Result.hs +54/−0
- src/Data/SARIF/Run.hs +48/−0
- src/Data/SARIF/Tool.hs +98/−0
+ 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 = []+}++--------------------------------------------------------------------------------