packages feed

ogma-cli 1.5.0 → 1.6.0

raw patch · 8 files changed

+530/−86 lines, 8 filesdep ~HUnitdep ~ogma-coredep ~optparse-applicative

Dependency ranges changed: HUnit, ogma-core, optparse-applicative, process, test-framework, test-framework-hunit, unix

Files

CHANGELOG.md view
@@ -1,5 +1,17 @@ # Revision history for ogma-cli +## [1.6.0] - 2025-01-21++* Version bump 1.6.0 (#208).+* Update contribution guidelines (#161).+* Provide ability to customize template in fprime command (#185).+* Provide ability to customize template in standalone command (#189).+* Add repository information to cabal package (#148).+* Add version bounds to all dependencies (#119).+* Introduce new diagram command (#194).+* Provide ability to preprocess properties via external command (#197).+* Extend support for file, property formats across backends (#204).+ ## [1.5.0] - 2024-11-21  * Version bump 1.5.0 (#178).
ogma-cli.cabal view
@@ -32,8 +32,9 @@ build-type:          Simple  name:                ogma-cli-version:             1.5.0+version:             1.6.0 homepage:            https://github.com/nasa/ogma+bug-reports:         https://github.com/nasa/ogma/issues license:             OtherLicense license-file:        LICENSE.pdf author:              Ivan Perez, Alwyn Goodloe@@ -74,6 +75,9 @@                        <https://github.com/nasa/fprime F'>                        components that use Copilot for monitoring.                      .+                     - Generating monitors from state diagrams specified using+                       a graphical notation.+                     .                      The main invocation with @--help@ lists sub-commands available.                      .                      >$ ogma --help@@ -92,6 +96,7 @@                      >  fprime                   Generate a complete F' monitoring component                      >  ros                      Generate a ROS 2 monitoring application                      >  standalone               Generate a Copilot file from an input specification+                     >  diagram                  Generate a monitor from a state machine diagram                      .                      For further information, see:                      .@@ -116,6 +121,11 @@ -- exactly what we publish, unmodified by anyone external to our project. x-curation: uncurated +source-repository head+  type:     git+  location: git@github.com:nasa/ogma.git+  subdir:   ogma-cli+ executable ogma    main-is:@@ -125,6 +135,7 @@     CLI.CommandCFSApp     CLI.CommandCStructs2Copilot     CLI.CommandCStructs2MsgHandlers+    CLI.CommandDiagram     CLI.CommandFPrimeApp     CLI.CommandROSApp     CLI.CommandStandalone@@ -133,8 +144,8 @@    build-depends:       base                 >= 4.11.0.0 && < 5-    , optparse-applicative-    , ogma-core            >= 1.5.0 && < 1.6+    , optparse-applicative >= 0.14     && < 0.19+    , ogma-core            >= 1.6.0 && < 1.7    hs-source-dirs:     src@@ -154,11 +165,11 @@    build-depends:       base                 >= 4.11.0.0 && < 5-    , HUnit-    , process-    , test-framework-    , test-framework-hunit-    , unix+    , HUnit                >= 1.2.0.0  && < 1.7+    , process              >= 1.6      && < 1.7+    , test-framework       >= 0.8.2    && < 0.9+    , test-framework-hunit >= 0.2.0    && < 0.4+    , unix                 >= 2.7.2.2  && < 2.9    hs-source-dirs:     tests
+ src/CLI/CommandDiagram.hs view
@@ -0,0 +1,264 @@+-- Copyright 2024 United States Government as represented by the Administrator+-- of the National Aeronautics and Space Administration. All Rights Reserved.+--+-- Disclaimers+--+-- No Warranty: THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY+-- OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT+-- LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO+-- SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A+-- PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT THE+-- SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT DOCUMENTATION, IF+-- PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. THIS AGREEMENT DOES NOT, IN+-- ANY MANNER, CONSTITUTE AN ENDORSEMENT BY GOVERNMENT AGENCY OR ANY PRIOR+-- RECIPIENT OF ANY RESULTS, RESULTING DESIGNS, HARDWARE, SOFTWARE PRODUCTS OR+-- ANY OTHER APPLICATIONS RESULTING FROM USE OF THE SUBJECT SOFTWARE. FURTHER,+-- GOVERNMENT AGENCY DISCLAIMS ALL WARRANTIES AND LIABILITIES REGARDING+-- THIRD-PARTY SOFTWARE, IF PRESENT IN THE ORIGINAL SOFTWARE, AND DISTRIBUTES+-- IT "AS IS."+--+-- Waiver and Indemnity: RECIPIENT AGREES TO WAIVE ANY AND ALL CLAIMS AGAINST+-- THE UNITED STATES GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL AS+-- ANY PRIOR RECIPIENT. IF RECIPIENT'S USE OF THE SUBJECT SOFTWARE RESULTS IN+-- ANY LIABILITIES, DEMANDS, DAMAGES, EXPENSES OR LOSSES ARISING FROM SUCH USE,+-- INCLUDING ANY DAMAGES FROM PRODUCTS BASED ON, OR RESULTING FROM, RECIPIENT'S+-- USE OF THE SUBJECT SOFTWARE, RECIPIENT SHALL INDEMNIFY AND HOLD HARMLESS THE+-- UNITED STATES GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL AS ANY+-- PRIOR RECIPIENT, TO THE EXTENT PERMITTED BY LAW. RECIPIENT'S SOLE REMEDY+-- FOR ANY SUCH MATTER SHALL BE THE IMMEDIATE, UNILATERAL TERMINATION OF THIS+-- AGREEMENT.+--+-- | CLI interface to the diagram subcommand.+module CLI.CommandDiagram+    (+      -- * Direct command access+      command+    , CommandOpts+    , ErrorCode++      -- * CLI+    , commandDesc+    , commandOptsParser+    )+  where++-- External imports+import Options.Applicative (Parser, help, long, metavar, optional, short,+                            showDefault, strOption, value)++-- External imports: command results+import Command.Result ( Result(..) )+import Data.Location  ( Location(..) )++-- External imports: actions or commands supported+import           Command.Diagram (diagram)+import qualified Command.Diagram++-- * Command++-- | Options to generate Copilot from diagram.+data CommandOpts = CommandOpts+  { diagramTargetDir   :: FilePath+  , diagramTemplateDir :: Maybe FilePath+  , diagramFileName    :: FilePath+  , diagramFormat      :: String+  , diagramPropFormat  :: String+  , diagramTarget      :: String+  , diagramMode        :: String+  , diagramStateVar    :: String+  , diagramInputVar    :: String+  }++-- | Transform an input diagram into a Copilot specification.+command :: CommandOpts -> IO (Result ErrorCode)+command c+  | Nothing <- diagramFormatP+  = return $+      Error+        ecFormatError+        "The diagram format specified is incorrect"+        LocationNothing++  | Nothing <- diagramModeP+  = return $+      Error ecModeError "The mode specified is incorrect" LocationNothing++  | Nothing <- diagramPropFormatP+  = return $+      Error+        ecPropFormatError+        "The format specified for transitions or edge properties is incorrect"+        LocationNothing++  | Just mode       <- diagramModeP+  , Just format     <- diagramFormatP+  , Just propFormat <- diagramPropFormatP+  = do let internalCommandOpts :: Command.Diagram.DiagramOptions+           internalCommandOpts = Command.Diagram.DiagramOptions+             { Command.Diagram.diagramTargetDir   = diagramTargetDir c+             , Command.Diagram.diagramTemplateDir = diagramTemplateDir c+             , Command.Diagram.diagramFormat      = format+             , Command.Diagram.diagramPropFormat  = propFormat+             , Command.Diagram.diagramFilename    = diagramTarget c+             , Command.Diagram.diagramMode        = mode+             , Command.Diagram.diagramStateVar    = diagramStateVar c+             , Command.Diagram.diagramInputVar    = diagramInputVar c+             }+       diagram (diagramFileName c) internalCommandOpts+  where+    diagramFormatP     = parseDiagramFormat (diagramFormat c)+    diagramModeP       = parseDiagramMode (diagramMode c)+    diagramPropFormatP = parseDiagramPropFormat (diagramPropFormat c)++    parseDiagramFormat :: String+                       -> Maybe Command.Diagram.DiagramFormat+    parseDiagramFormat "dot"      = Just Command.Diagram.Dot+    parseDiagramFormat "graphviz" = Just Command.Diagram.Dot+    parseDiagramFormat "mermaid"  = Just Command.Diagram.Mermaid+    parseDiagramFormat _          = Nothing++    parseDiagramMode :: String -> Maybe Command.Diagram.DiagramMode+    parseDiagramMode "check"     = Just Command.Diagram.CheckState+    parseDiagramMode "calculate" = Just Command.Diagram.ComputeState+    parseDiagramMode "safeguard" = Just Command.Diagram.CheckMoves+    parseDiagramMode _           = Nothing++    parseDiagramPropFormat :: String -> Maybe Command.Diagram.DiagramPropFormat+    parseDiagramPropFormat "cocospec" = Just Command.Diagram.CoCoSpec+    parseDiagramPropFormat "inputs"   = Just Command.Diagram.Inputs+    parseDiagramPropFormat "literal"  = Just Command.Diagram.Literal+    parseDiagramPropFormat "smv"      = Just Command.Diagram.SMV+    parseDiagramPropFormat _          = Nothing++-- * CLI++-- | Command description for CLI help.+commandDesc :: String+commandDesc =+  "Generate a monitor from state machine diagram"++-- | Subparser for the @diagram@ command, used to generate a Copilot+-- specification from an input diagram file.+commandOptsParser :: Parser CommandOpts+commandOptsParser = CommandOpts+  <$> strOption+        (  long "target-dir"+        <> metavar "DIR"+        <> showDefault+        <> value "copilot"+        <> help strDiagramTargetDirDesc+        )+  <*> optional+        ( strOption+            (  long "template-dir"+            <> metavar "DIR"+            <> help strDiagramTemplateDirArgDesc+            )+        )+  <*> strOption+        (  long "file-name"+        <> metavar "FILENAME"+        <> help strDiagramFilenameDesc+        )+  <*> strOption+        (  long "input-format"+        <> short 'f'+        <> metavar "FORMAT_NAME"+        <> help strDiagramFormatDesc+        <> showDefault+        <> value "mermaid"+        )+  <*> strOption+        (  long "prop-format"+        <> short 'p'+        <> metavar "FORMAT_NAME"+        <> help strDiagramPropFormatDesc+        <> showDefault+        <> value "inputs"+        )+  <*> strOption+        (  long "target-file-name"+        <> metavar "FILENAME"+        <> help strDiagramTargetDesc+        <> showDefault+        <> value "monitor"+        )+  <*> strOption+        (  long "mode"+        <> metavar "MODE"+        <> help strDiagramModeDesc+        <> showDefault+        <> value "check"+        )+  <*> strOption+        (  long "state-var"+        <> metavar "NAME"+        <> help strDiagramStateVarDesc+        <> showDefault+        <> value "state"+        )+  <*> strOption+        (  long "input-var"+        <> metavar "NAME"+        <> help strDiagramInputVarDesc+        <> showDefault+        <> value "input"+        )++-- | Target dir flag description.+strDiagramTargetDirDesc :: String+strDiagramTargetDirDesc = "Target directory"++-- | Template dir flag description.+strDiagramTemplateDirArgDesc :: String+strDiagramTemplateDirArgDesc = "Directory holding target source template"++-- | Filename flag description.+strDiagramFilenameDesc :: String+strDiagramFilenameDesc = "File with diagram source"++-- | Format flag description.+strDiagramFormatDesc :: String+strDiagramFormatDesc = "Format of the input file"++-- | Property format flag description.+strDiagramPropFormatDesc :: String+strDiagramPropFormatDesc =+  "Format of temporal or boolean properties associated to diagram edges"++-- | Target file name flag description.+strDiagramTargetDesc :: String+strDiagramTargetDesc =+  "Filename prefix for monitoring files in target language"++-- | Mode name flag description.+strDiagramModeDesc :: String+strDiagramModeDesc =+  "Mode of operation (check, calculate, safeguard)"++strDiagramInputVarDesc :: String+strDiagramInputVarDesc =+  "Name of the input variable"++strDiagramStateVarDesc :: String+strDiagramStateVarDesc =+  "Name of the state variable"++-- * Error codes++-- | Encoding of reasons why the command can fail.+--+-- The error code used is 1 for user error.+type ErrorCode = Int++-- | Error: unknown diagram format.+ecFormatError :: ErrorCode+ecFormatError = 2++-- | Error: unknown operation mode.+ecModeError :: ErrorCode+ecModeError = 3++-- | Error: unknown property format.+ecPropFormatError :: ErrorCode+ecPropFormatError = 4
src/CLI/CommandFPrimeApp.hs view
@@ -43,39 +43,50 @@   where  -- External imports-import Options.Applicative ( Parser, help, long, metavar, optional, showDefault,-                             strOption, value )+import Options.Applicative ( Parser, help, long, metavar, optional, short,+                             showDefault, strOption, value )  -- External imports: command results import Command.Result ( Result )  -- External imports: actions or commands supported-import Command.FPrimeApp ( ErrorCode, fprimeApp )+import           Command.FPrimeApp (ErrorCode, fprimeApp)+import qualified Command.FPrimeApp  -- * Command  -- | Options needed to generate the FPrime component. data CommandOpts = CommandOpts-  { fprimeAppTarget   :: String-  , fprimeAppFRETFile :: Maybe String-  , fprimeAppVarNames :: Maybe String-  , fprimeAppVarDB    :: Maybe String-  , fprimeAppHandlers :: Maybe String+  { fprimeAppInputFile   :: Maybe String+  , fprimeAppTarget      :: String+  , fprimeAppTemplateDir :: Maybe String+  , fprimeAppVarNames    :: Maybe String+  , fprimeAppVarDB       :: Maybe String+  , fprimeAppHandlers    :: Maybe String+  , fprimeAppFormat      :: String+  , fprimeAppPropFormat  :: String+  , fprimeAppPropVia     :: Maybe String   }  -- | Create <https://github.com/nasa/fprime FPrime> component that subscribe -- to obtain necessary data from the bus and call Copilot when new data -- arrives. ----- This is just an uncurried version of "Command.fprimeApp".+-- This is just a wrapper around "Command.fprimeApp". command :: CommandOpts -> IO (Result ErrorCode)-command c =-  fprimeApp-    (fprimeAppTarget c)-    (fprimeAppFRETFile c)-    (fprimeAppVarNames c)-    (fprimeAppVarDB c)-    (fprimeAppHandlers c)+command c = fprimeApp (fprimeAppInputFile c) options+  where+    options =+      Command.FPrimeApp.FPrimeAppOptions+        { Command.FPrimeApp.fprimeAppTargetDir   = fprimeAppTarget c+        , Command.FPrimeApp.fprimeAppTemplateDir = fprimeAppTemplateDir c+        , Command.FPrimeApp.fprimeAppVarNames    = fprimeAppVarNames c+        , Command.FPrimeApp.fprimeAppVariableDB  = fprimeAppVarDB c+        , Command.FPrimeApp.fprimeAppHandlers    = fprimeAppHandlers c+        , Command.FPrimeApp.fprimeAppFormat      = fprimeAppFormat c+        , Command.FPrimeApp.fprimeAppPropFormat  = fprimeAppPropFormat c+        , Command.FPrimeApp.fprimeAppPropVia     = fprimeAppPropVia c+        }  -- * CLI @@ -87,7 +98,14 @@ -- connected to Copilot monitors. commandOptsParser :: Parser CommandOpts commandOptsParser = CommandOpts-  <$> strOption+  <$> optional+        ( strOption+            (  long "input-file"+            <> metavar "FILENAME"+            <> help strFPrimeAppFileNameArgDesc+            )+        )+  <*> strOption         (  long "app-target-dir"         <> metavar "DIR"         <> showDefault@@ -96,9 +114,9 @@         )   <*> optional         ( strOption-            (  long "fret-file-name"-            <> metavar "FILENAME"-            <> help strFPrimeAppFRETFileNameArgDesc+            (  long "app-template-dir"+            <> metavar "DIR"+            <> help strFPrimeAppTemplateDirArgDesc             )         )   <*> optional@@ -122,16 +140,44 @@             <> help strFPrimeAppHandlerListArgDesc             )         )+  <*> strOption+        (  long "input-format"+        <> short 'f'+        <> metavar "FORMAT_NAME"+        <> help strFPrimeAppFormatDesc+        <> showDefault+        <> value "fcs"+        )+  <*> strOption+        (  long "prop-format"+        <> short 'p'+        <> metavar "FORMAT_NAME"+        <> help strFPrimeAppPropFormatDesc+        <> showDefault+        <> value "smv"+        )+  <*> optional+        ( strOption+            (  long "parse-prop-via"+            <> metavar "COMMAND"+            <> help strFPrimeAppPropViaDesc+            )+        )  -- | Argument target directory to FPrime component generation command strFPrimeAppDirArgDesc :: String strFPrimeAppDirArgDesc = "Target directory" --- | Argument FRET CS to FPrime component generation command-strFPrimeAppFRETFileNameArgDesc :: String-strFPrimeAppFRETFileNameArgDesc =-  "File containing FRET Component Specification"+-- | Argument template directory to FPrime component generation command+strFPrimeAppTemplateDirArgDesc :: String+strFPrimeAppTemplateDirArgDesc =+  "Directory holding F' component source template" +-- | Argument input file to FPrime component generation command+strFPrimeAppFileNameArgDesc :: String+strFPrimeAppFileNameArgDesc =+  "File containing input specification"+ -- | Argument variable list to FPrime component generation command strFPrimeAppVarListArgDesc :: String strFPrimeAppVarListArgDesc =@@ -146,3 +192,16 @@ strFPrimeAppHandlerListArgDesc :: String strFPrimeAppHandlerListArgDesc =   "File containing list of Copilot handlers used in the specification"++-- | Format flag description.+strFPrimeAppFormatDesc :: String+strFPrimeAppFormatDesc = "Format of the input file"++-- | Property format flag description.+strFPrimeAppPropFormatDesc :: String+strFPrimeAppPropFormatDesc = "Format of temporal or boolean properties"++-- | External command to pre-process individual properties.+strFPrimeAppPropViaDesc :: String+strFPrimeAppPropViaDesc =+  "Command to pre-process individual properties"
src/CLI/CommandROSApp.hs view
@@ -43,41 +43,49 @@   where  -- External imports-import Options.Applicative ( Parser, help, long, metavar, optional, showDefault,-                             strOption, value )+import Options.Applicative ( Parser, help, long, metavar, optional, short,+                             showDefault, strOption, value )  -- External imports: command results import Command.Result ( Result )  -- External imports: actions or commands supported-import Command.ROSApp ( ErrorCode, rosApp )+import           Command.ROSApp (ErrorCode, rosApp)+import qualified Command.ROSApp  -- * Command  -- | Options needed to generate the ROS application. data CommandOpts = CommandOpts-  { rosAppTarget      :: String+  { rosAppInputFile   :: Maybe String+  , rosAppTarget      :: String   , rosAppTemplateDir :: Maybe String-  , rosAppFRETFile    :: Maybe String   , rosAppVarNames    :: Maybe String   , rosAppVarDB       :: Maybe String   , rosAppHandlers    :: Maybe String+  , rosAppFormat      :: String+  , rosAppPropFormat  :: String+  , rosAppPropVia     :: Maybe String   }  -- | Create <https://www.ros.org/ Robot Operating System> (ROS) applications -- that subscribe to obtain necessary data from topics and call Copilot when -- new data arrives. ----- This is just an uncurried version of "Command.ROSApp".+-- This is just a wrapper around "Command.ROSApp". command :: CommandOpts -> IO (Result ErrorCode)-command c =-  rosApp-    (rosAppTarget c)-    (rosAppTemplateDir c)-    (rosAppFRETFile c)-    (rosAppVarNames c)-    (rosAppVarDB c)-    (rosAppHandlers c)+command c = rosApp (rosAppInputFile c) options+  where+    options = Command.ROSApp.ROSAppOptions+                { Command.ROSApp.rosAppTargetDir   = rosAppTarget c+                , Command.ROSApp.rosAppTemplateDir = rosAppTemplateDir c+                , Command.ROSApp.rosAppVariables   = rosAppVarNames c+                , Command.ROSApp.rosAppVariableDB  = rosAppVarDB c+                , Command.ROSApp.rosAppHandlers    = rosAppHandlers c+                , Command.ROSApp.rosAppFormat      = rosAppFormat c+                , Command.ROSApp.rosAppPropFormat  = rosAppPropFormat c+                , Command.ROSApp.rosAppPropVia     = rosAppPropVia c+                }  -- * CLI @@ -89,7 +97,14 @@ -- application connected to Copilot monitors. commandOptsParser :: Parser CommandOpts commandOptsParser = CommandOpts-  <$> strOption+  <$> optional+        ( strOption+            (  long "input-file"+            <> metavar "FILENAME"+            <> help strROSAppFileNameArgDesc+            )+        )+  <*> strOption         (  long "app-target-dir"         <> metavar "DIR"         <> showDefault@@ -105,13 +120,6 @@         )   <*> optional         ( strOption-            (  long "fret-file-name"-            <> metavar "FILENAME"-            <> help strROSAppFRETFileNameArgDesc-            )-        )-  <*> optional-        ( strOption             (  long "variable-file"             <> metavar "FILENAME"             <> help strROSAppVarListArgDesc@@ -131,6 +139,29 @@             <> help strROSAppHandlerListArgDesc             )         )+  <*> strOption+        (  long "input-format"+        <> short 'f'+        <> metavar "FORMAT_NAME"+        <> help strROSAppFormatDesc+        <> showDefault+        <> value "fcs"+        )+  <*> strOption+        (  long "prop-format"+        <> short 'p'+        <> metavar "FORMAT_NAME"+        <> help strROSAppPropFormatDesc+        <> showDefault+        <> value "smv"+        )+  <*> optional+        ( strOption+            (  long "parse-prop-via"+            <> metavar "COMMAND"+            <> help strROSAppPropViaDesc+            )+        )  -- | Argument target directory to ROS app generation command strROSAppDirArgDesc :: String@@ -141,10 +172,10 @@ strROSAppTemplateDirArgDesc =   "Directory holding ROS application source template" --- | Argument FRET CS to ROS app generation command-strROSAppFRETFileNameArgDesc :: String-strROSAppFRETFileNameArgDesc =-  "File containing FRET Component Specification"+-- | Argument input file to ROS app generation command+strROSAppFileNameArgDesc :: String+strROSAppFileNameArgDesc =+  "File containing input specification"  -- | Argument variable list to ROS app generation command strROSAppVarListArgDesc :: String@@ -160,3 +191,16 @@ strROSAppHandlerListArgDesc :: String strROSAppHandlerListArgDesc =   "File containing list of Copilot handlers used in the specification"++-- | Format flag description.+strROSAppFormatDesc :: String+strROSAppFormatDesc = "Format of the input file"++-- | Property format flag description.+strROSAppPropFormatDesc :: String+strROSAppPropFormatDesc = "Format of temporal or boolean properties"++-- | External command to pre-process individual properties.+strROSAppPropViaDesc :: String+strROSAppPropViaDesc =+  "Command to pre-process individual properties"
src/CLI/CommandStandalone.hs view
@@ -43,7 +43,7 @@   where  -- External imports-import Options.Applicative (Parser, help, long, metavar, many, short,+import Options.Applicative (Parser, help, long, many, metavar, optional, short,                             showDefault, strOption, switch, value)  -- External imports: command results@@ -58,11 +58,14 @@  -- | Options to generate Copilot from specification. data CommandOpts = CommandOpts-  { standaloneFileName   :: FilePath-  , standaloneFormat     :: String-  , standalonePropFormat :: String-  , standaloneTypes      :: [String]-  , standaloneTarget     :: String+  { standaloneTargetDir   :: FilePath+  , standaloneTemplateDir :: Maybe FilePath+  , standaloneFileName    :: FilePath+  , standaloneFormat      :: String+  , standalonePropFormat  :: String+  , standaloneTypes       :: [String]+  , standaloneTarget      :: String+  , standalonePropVia     :: Maybe String   }  -- | Transform an input specification into a Copilot specification.@@ -71,10 +74,13 @@   where     internalCommandOpts :: Command.Standalone.StandaloneOptions     internalCommandOpts = Command.Standalone.StandaloneOptions-      { Command.Standalone.standaloneFormat      = standaloneFormat c+      { Command.Standalone.standaloneTargetDir   = standaloneTargetDir c+      , Command.Standalone.standaloneTemplateDir = standaloneTemplateDir c+      , Command.Standalone.standaloneFormat      = standaloneFormat c       , Command.Standalone.standalonePropFormat  = standalonePropFormat c       , Command.Standalone.standaloneTypeMapping = types       , Command.Standalone.standaloneFilename    = standaloneTarget c+      , Command.Standalone.standalonePropVia     = standalonePropVia c       }      types :: [(String, String)]@@ -98,6 +104,20 @@ commandOptsParser :: Parser CommandOpts commandOptsParser = CommandOpts   <$> strOption+        (  long "target-dir"+        <> metavar "DIR"+        <> showDefault+        <> value "copilot"+        <> help strStandaloneTargetDirDesc+        )+  <*> optional+        ( strOption+            (  long "template-dir"+            <> metavar "DIR"+            <> help strStandaloneTemplateDirArgDesc+            )+        )+  <*> strOption         (  long "file-name"         <> metavar "FILENAME"         <> help strStandaloneFilenameDesc@@ -132,7 +152,22 @@         <> showDefault         <> value "monitor"         )+  <*> optional+        ( strOption+            (  long "parse-prop-via"+            <> metavar "COMMAND"+            <> help strStandalonePropViaDesc+            )+        ) +-- | Target dir flag description.+strStandaloneTargetDirDesc :: String+strStandaloneTargetDirDesc = "Target directory"++-- | Template dir flag description.+strStandaloneTemplateDirArgDesc :: String+strStandaloneTemplateDirArgDesc = "Directory holding standalone source template"+ -- | Filename flag description. strStandaloneFilenameDesc :: String strStandaloneFilenameDesc = "File with properties or requirements"@@ -153,6 +188,11 @@ strStandaloneTargetDesc :: String strStandaloneTargetDesc =   "Filename prefix for monitoring files in target language"++-- | External command to pre-process individual properties.+strStandalonePropViaDesc :: String+strStandalonePropViaDesc =+  "Command to pre-process individual properties"  -- * Error codes 
src/CLI/CommandTop.hs view
@@ -89,6 +89,7 @@ import qualified CLI.CommandCFSApp import qualified CLI.CommandCStructs2Copilot import qualified CLI.CommandCStructs2MsgHandlers+import qualified CLI.CommandDiagram import qualified CLI.CommandFPrimeApp import qualified CLI.CommandROSApp import qualified CLI.CommandStandalone@@ -104,6 +105,7 @@     CommandOptsCFSApp                    CLI.CommandCFSApp.CommandOpts   | CommandOptsCStructs2Copilot          CLI.CommandCStructs2Copilot.CommandOpts   | CommandOptsCStructs2MsgHandlers      CLI.CommandCStructs2MsgHandlers.CommandOpts+  | CommandOptsDiagram                   CLI.CommandDiagram.CommandOpts   | CommandOptsFPrimeApp                 CLI.CommandFPrimeApp.CommandOpts   | CommandOptsROSApp                    CLI.CommandROSApp.CommandOpts   | CommandOptsStandalone                CLI.CommandStandalone.CommandOpts@@ -124,6 +126,7 @@   <> subcommandFPrimeApp   <> subcommandROSApp   <> subcommandStandalone+  <> subcommandDiagram   )  -- | Modifier for the CStruct to Copilot Struct generation subcommand, linking@@ -183,6 +186,15 @@     (CommandOptsStandalone <$> CLI.CommandStandalone.commandOptsParser)     CLI.CommandStandalone.commandDesc +-- | Modifier for the diagram subcommand, linking the subcommand options and+-- description to the command @diagram@ at top level.+subcommandDiagram :: Mod CommandFields CommandOpts+subcommandDiagram =+  subcommand+    "diagram"+    (CommandOptsDiagram <$> CLI.CommandDiagram.commandOptsParser)+    CLI.CommandDiagram.commandDesc+ -- * Command dispatcher  -- | Command dispatcher that obtains the parameters from the command line and@@ -217,6 +229,8 @@   id <$> CLI.CommandROSApp.command c command (CommandOptsStandalone c) =   id <$> CLI.CommandStandalone.command c+command (CommandOptsDiagram c) =+  id <$> CLI.CommandDiagram.command c  -- We indicate to HLint that the use of (id <$>) above should not trigger a -- warning. Conceptually, there is a transformation taking place, but no change
tests/Main.hs view
@@ -42,28 +42,28 @@   , testCase "cli-cmd-cfs-fail" (runErrorCode ["cfs", "--incorrect-argument"] False)     -- Should fail due to arguments being incorrect -  , testCase "cli-cmd-fret-component-spec" (runErrorCode ["standalone", "--help" ] True)+  , testCase "cli-cmd-standalone" (runErrorCode ["standalone", "--help" ] True)     -- Should pass -  , testCase "cli-cmd-fret-component-spec-fail" (runErrorCode ["standalone", "--incorrect-argument"] False)+  , testCase "cli-cmd-standalone-fail" (runErrorCode ["standalone", "--incorrect-argument"] False)     -- Should fail due to arguments being incorrect -  , testCase "fret-cmd-fret-parse-ok" (parseFretCopilot "examples/fret.json" True)+  , testCase "cli-cmd-standalone-fcs" (parseStandaloneFCS "examples/fcs-2.json" True)     -- Should pass -  , testCase "fret-cmd-fret-file-not-found" (parseFretCopilot "tests/file-invalid.json" False)+  , testCase "cli-cmd-standalone-file-not-found" (parseStandaloneFCS "tests/file-invalid.json" False)     -- Should fail because the file does not exist -  , testCase "fret-cmd-fret-parse-fail-1" (parseFretCopilot "tests/commands-fret-error-parsing-failed-1.json" False)+  , testCase "cli-cmd-standalone-parse-fail-1" (parseStandaloneFCS "tests/commands-fcs-error-parsing-failed-1.json" False)     -- Should fail because the opening bracket is [ and not { -  , testCase "fret-cmd-fret-parse-fail-2" (parseFretCopilot "tests/commands-fret-error-parsing-failed-2.json" False)+  , testCase "cli-cmd-standalone-parse-fail-2" (parseStandaloneFCS "tests/commands-fcs-error-parsing-failed-2.json" False)     -- Should fail because a field is missing in an external variable -  , testCase "fret-cmd-fret-parse-fail-3" (parseFretCopilot "tests/commands-fret-error-parsing-failed-3.json" False)+  , testCase "cli-cmd-standalone-parse-fail-3" (parseStandaloneFCS "tests/commands-fcs-error-parsing-failed-3.json" False)     -- Should fail because a field is missing in an internal variable -  , testCase "fret-test2" (parseFretCoCoSpec "tests/fret-example1.json")+  , testCase "cli-cmd-standalone-fdb" (parseStandaloneFDB "tests/fdb-example1.json")     -- Should pass    , testCase "structs-parse-ok" (testCStructs2Copilot "tests/reduced_geofence_msgs.h" True)@@ -102,10 +102,10 @@     args     = ["structs", "--header-file-name", file]     errorMsg = "Result of processing file " ++ file ++ " failed" --- | Test FRET parser for a particular file.+-- | Test standalone backend for a FCS format and SVM. ----- This test uses the Copilot backend for FRET files, so it generates a Copilot--- file. It may be convenient to run this action in a temporary directory.+-- This test uses the standalone backend, so it generates a Copilot file. It+-- may be convenient to run this action in a temporary directory. -- -- This IO action fails if any of the following are true: --   * Ogma cannot be found in the current PATH.@@ -115,10 +115,10 @@ --   * Ogma fails due to an internal error or bug. --   * The output file cannot be created due to lack of space or permissions. ---parseFretCopilot :: FilePath  -- ^ Path to a FRET/JSON requirements file-                 -> Bool-                 -> IO ()-parseFretCopilot file success = do+parseStandaloneFCS :: FilePath  -- ^ Path to an input file+                   -> Bool+                   -> IO ()+parseStandaloneFCS file success = do     (ec, _out, _err) <- readProcessWithExitCode "ogma" args ""      -- True if success is expected and detected, or niether expected nor@@ -130,10 +130,10 @@     args     = ["standalone", "--file-name", file]     errorMsg = "Parsing file " ++ file ++ " result unexpected." --- | Test FRET CoCoSpec-based parser for a particular file.+-- | Test standalone backend for FDB format and CoCoSpec. ----- This test uses the Copilot backend for FRET files, so it generates a Copilot--- file. It may be convenient to run this action in a temporary directory.+-- This test uses the standalone backend, so it generates a Copilot file. It+-- may be convenient to run this action in a temporary directory. -- -- This IO action fails if any of the following are true: --   * Ogma cannot be found in the current PATH.@@ -143,9 +143,9 @@ --   * Ogma fails due to an internal error or bug. --   * The output file cannot be created due to lack of space or permissions. ---parseFretCoCoSpec :: FilePath  -- ^ Path to a FRET/JSON requirements file-                  -> IO ()-parseFretCoCoSpec file = do+parseStandaloneFDB :: FilePath  -- ^ Path to an input file+                   -> IO ()+parseStandaloneFDB file = do     (ec, _out, _err) <- readProcessWithExitCode "ogma" args ""     assertBool errorMsg (ec == ExitSuccess)   where