packages feed

ogma-core 1.15.0 → 1.16.0

raw patch · 33 files changed

+322/−218 lines, 33 filesdep ~QuickCheckdep ~megaparsecdep ~ogma-extraPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: QuickCheck, megaparsec, ogma-extra, ogma-language-c, ogma-language-copilot, ogma-language-csv, ogma-language-jsonspec, ogma-language-lustre, ogma-language-smv, ogma-language-xlsx, ogma-language-xmlspec, ogma-spec

API changes (from Hackage documentation)

- Command.Overview: data CommandOptions
- Command.Search: data DiagramInfo
+ Command.CFSApp: instance GHC.Classes.Eq Command.CFSApp.MsgData
+ Command.CFSApp: instance GHC.Classes.Eq Command.CFSApp.MsgInfo
+ Command.CFSApp: instance GHC.Classes.Eq Command.CFSApp.Trigger
+ Command.CFSApp: instance GHC.Classes.Eq Command.CFSApp.VarDecl
+ Command.Overview: newtype CommandOptions
+ Command.Search: newtype DiagramInfo
+ Language.Trans.Spec2Copilot: externalVariableMap :: Spec a -> [(String, String)]
+ Language.Trans.Spec2Copilot: externalVariableNames :: Spec a -> [String]
+ Language.Trans.Spec2Copilot: internalVariableMap :: Spec a -> [(String, String)]
+ Language.Trans.Spec2Copilot: internalVariableNames :: Spec a -> [String]
+ Language.Trans.Spec2Copilot: requirementNameMap :: Spec a -> [(String, String)]
+ Language.Trans.Spec2Copilot: requirementNames :: Spec a -> [String]

Files

CHANGELOG.md view
@@ -1,5 +1,30 @@ # Revision history for ogma-core +## [1.16.0] - 2026-09-21++* Version bump (1.16.0) (#606).+* Replace adhoc function `mergeMaybe` with function from `base` (#516).+* Fix malformed comments (#518).+* Remove unnecessary line breaks (#520).+* Add missing periods to Haddock comments (#524).+* Fix spelling of F Prime (#526).+* Replace explicit recursion with calls to `base:Control.Monad.foldM` (#532).+* Add valid Haddock documentation to all top-level functions (#542).+* Bump upper version constraints on `QuickCheck`, `megaparsec` (#545).+* Make `Dockerfile` base image in default ROS 2 template customizable (#548).+* Allow for inputs to be deeply nested fields in ROS 2 template (#547).+* Adjust ROS 2 `Dockerfile` to run `rosdep init` only when needed (#561).+* Fix incorrect creation of two instances of ROS 2 monitoring node (#564).+* Increase detail in template expansion error messages (#390).+* Use path prefixes to specify path resolution context in project files (#567).+* Update `Dockerfile` in ROS 2 template for Space ROS `jazzy-2026.07.0` (#569).+* Introduce default input format configuration files (#575).+* Address HLint suggestions (#586).+* Remove unused imports (#590).+* Remove unused pragma (#600).+* De-duplicate cFS application data (#602).+* Fix `Command.Common.mergeSpecs` to avoid dropping externs (#551).+ ## [1.15.0] - 2026-07-21  * Version bump (1.15.0) (#508).
+ data/formats/default_literal view
@@ -0,0 +1,15 @@+JSONFormat+   { specInternalVars          = Just "..auxiliary_defs[*]"+   , specInternalVarId         = ".name"+   , specInternalVarExpr       = ".meaning"+   , specInternalVarType       = Just ".type"+   , specExternalVars          = Just "..inputs[*]"+   , specExternalVarId         = ".name"+   , specExternalVarType       = Just ".type"+   , specRequirements          = "..properties[*]"+   , specRequirementId         = ".id"+   , specRequirementDesc       = Just ".description"+   , specRequirementExpr       = ".formula"+   , specRequirementResultType = Nothing+   , specRequirementResultExpr = Nothing+   }
+ data/formats/default_lustre view
@@ -0,0 +1,15 @@+JSONFormat+   { specInternalVars          = Just "..auxiliary_defs[*]"+   , specInternalVarId         = ".name"+   , specInternalVarExpr       = ".meaning"+   , specInternalVarType       = Just ".type"+   , specExternalVars          = Just "..inputs[*]"+   , specExternalVarId         = ".name"+   , specExternalVarType       = Just ".type"+   , specRequirements          = "..properties[*]"+   , specRequirementId         = ".id"+   , specRequirementDesc       = Just ".description"+   , specRequirementExpr       = ".formula"+   , specRequirementResultType = Nothing+   , specRequirementResultExpr = Nothing+   }
+ data/formats/default_smv view
@@ -0,0 +1,15 @@+JSONFormat+   { specInternalVars          = Just "..auxiliary_defs[*]"+   , specInternalVarId         = ".name"+   , specInternalVarExpr       = ".meaning"+   , specInternalVarType       = Just ".type"+   , specExternalVars          = Just "..inputs[*]"+   , specExternalVarId         = ".name"+   , specExternalVarType       = Just ".type"+   , specRequirements          = "..properties[*]"+   , specRequirementId         = ".id"+   , specRequirementDesc       = Just ".description"+   , specRequirementExpr       = ".formula"+   , specRequirementResultType = Nothing+   , specRequirementResultExpr = Nothing+   }
ogma-core.cabal view
@@ -19,7 +19,7 @@ build-type:          Simple  name:                ogma-core-version:             1.15.0+version:             1.16.0 homepage:            https://github.com/nasa/ogma bug-reports:         https://github.com/nasa/ogma/issues license:             Apache-2.0@@ -76,6 +76,9 @@                      templates/fprime/instance-copilot                      templates/report/Report.md                      templates/standalone/Copilot.hs+                     data/formats/default_smv+                     data/formats/default_literal+                     data/formats/default_lustre                      data/formats/fcs_smv                      data/formats/fcs_lustre                      data/formats/fdb_smv@@ -160,23 +163,23 @@     , filepath                >= 1.4.2    && < 1.6     , graphviz                >= 2999.20  && < 2999.21     , hint                    >= 0.9.0    && < 1.10-    , megaparsec              >= 8.0.0    && < 9.8+    , megaparsec              >= 8.0.0    && < 9.9     , mtl                     >= 2.2.2    && < 2.4     , process                 >= 1.6      && < 1.7     , text                    >= 1.2.3.1  && < 2.2     , vector                  >= 0.12.0.1 && < 0.14     , yaml                    >= 0.11.7.0 && < 0.12 -    , ogma-extra              >= 1.15.0 && < 1.16-    , ogma-language-c         >= 1.15.0 && < 1.16-    , ogma-language-copilot   >= 1.15.0 && < 1.16-    , ogma-language-csv       >= 1.15.0 && < 1.16-    , ogma-language-jsonspec  >= 1.15.0 && < 1.16-    , ogma-language-lustre    >= 1.15.0 && < 1.16-    , ogma-language-smv       >= 1.15.0 && < 1.16-    , ogma-language-xlsx      >= 1.15.0 && < 1.16-    , ogma-language-xmlspec   >= 1.15.0 && < 1.16-    , ogma-spec               >= 1.15.0 && < 1.16+    , ogma-extra              >= 1.16.0 && < 1.17+    , ogma-language-c         >= 1.16.0 && < 1.17+    , ogma-language-copilot   >= 1.16.0 && < 1.17+    , ogma-language-csv       >= 1.16.0 && < 1.17+    , ogma-language-jsonspec  >= 1.16.0 && < 1.17+    , ogma-language-lustre    >= 1.16.0 && < 1.17+    , ogma-language-smv       >= 1.16.0 && < 1.17+    , ogma-language-xlsx      >= 1.16.0 && < 1.17+    , ogma-language-xmlspec   >= 1.16.0 && < 1.17+    , ogma-spec               >= 1.16.0 && < 1.17    hs-source-dirs:     src@@ -198,7 +201,7 @@       base                       >= 4.11.0.0 && < 5     , directory                  >= 1.3.1.5  && < 1.4     , HUnit                      >= 1.2.0.0  && < 1.7-    , QuickCheck                 >= 2.8.2    && < 2.17+    , QuickCheck                 >= 2.8.2    && < 2.19     , test-framework             >= 0.8.2    && < 0.9     , test-framework-hunit       >= 0.2.0    && < 0.4     , test-framework-quickcheck2 >= 0.3.0.4  && < 0.4
src/Command/CFSApp.hs view
@@ -36,11 +36,12 @@   where  -- External imports-import           Control.Applicative    ( liftA2, (<|>) )+import           Control.Applicative    ( (<|>) ) import qualified Control.Exception      as E import           Control.Monad.Except   ( ExceptT (..), liftEither,                                           throwError ) import           Data.Aeson             ( ToJSON (..), Value )+import           Data.List              ( nub ) import           Data.Maybe             ( fromMaybe, mapMaybe, maybeToList ) import           GHC.Generics           ( Generic ) @@ -49,14 +50,15 @@  -- Internal imports: auxiliary import Command.Result         ( Result (..) )+import Data.Either.Extra      ( mapLeft ) import Data.List.Extra        ( stripSuffix ) import Data.String.Extra      ( pascalCase ) import System.Directory.Extra ( copyTemplate )  -- Internal imports-import Command.Common                 (InputFile (..), cannotCopyTemplate,+import Command.Common                 (InputFile (..), cannotCopyTemplateF,                                        checkArguments, combineInputFiles,-                                       locateTemplateDir, makeLeftE,+                                       locateTemplateDir,                                        openVarDBFilesWithDefault,                                        parseInputFile,                                        parseRequirementsListFile,@@ -89,7 +91,7 @@     let subst = mergeObjects (toJSON appData) templateVars      -- Expand template-    ExceptT $ fmap (makeLeftE cannotCopyTemplate) $ E.try $+    ExceptT $ fmap (mapLeft cannotCopyTemplateF) $ E.try $       copyTemplate templateDir subst targetDir    where@@ -99,6 +101,8 @@     functions     = exprPair (commandPropFormat options)     templateVarsF = commandExtraVars options +-- | Generate application data describing core elements of a new cFS+-- application that implements the input requirements or diagrams. command' :: CommandOptions          -> ExprPair          -> ExceptT ErrorTriplet IO AppData@@ -110,7 +114,7 @@      specT <- maybe                (return Nothing)-               (\e -> Just . InputFileSpec <$> readInputExpr' e)+               (fmap (Just . InputFileSpec) . readInputExpr')                cExpr      specF <- if null fpA@@ -128,8 +132,7 @@      mode <- parseDiagramMode (commandDiagramMode options) -    copilotM <- sequenceA $-                  (\spec' -> processSpec spec' cExpr fpA mode) <$> spec+    copilotM <- traverse (\spec' -> processSpec spec' cExpr fpA mode) spec      let varNames = fromMaybe (defaultVarNames spec) vs         monitors = maybe (defaultMonitors spec) (map (\x -> (x, Nothing))) rs@@ -156,8 +159,8 @@     readInputFile' f =       parseInputFile f formatName propFormatName propVia exprT -    processSpec spec' expr' fp' mode =-      Command.Standalone.commandLogic expr' fp' "copilot" [] exprT spec' mode+    processSpec spec' expr' fp' =+      Command.Standalone.commandLogic expr' fp' "copilot" [] exprT spec'      defaultVarNames spec = case spec of       Just (InputFileSpec spec') -> specExtractExternalVariables (Just spec')@@ -180,10 +183,17 @@              -> [Trigger]              -> Maybe Command.Standalone.AppData              -> AppData-commandLogic varDB varNames handlers copilotM =-    AppData vars ids infos datas handlers copilotM+commandLogic varDB varNames triggers =+    AppData vars' ids' infos' datas' triggers'+   where +    vars'     = nub vars+    ids'      = nub ids+    infos'    = nub infos+    datas'    = nub datas+    triggers' = nub triggers+     -- This is a Data.List.unzip4     (vars, ids, infos, datas) = foldr f ([], [], [], []) varNames @@ -245,7 +255,7 @@        active = inputActive inputDef -  let typeVar' = fromMaybe (topicType topicDef) (typeToType <$> typeDef)+  let typeVar' = maybe (topicType topicDef) typeToType typeDef    -- Pick name for the function to process a message ID.   let mn = pascalCase $ stripSuffix "_MID" mid@@ -272,7 +282,7 @@     { varDeclName :: String     , varDeclType :: String     }-  deriving (Generic)+  deriving (Eq, Generic)  instance ToJSON VarDecl @@ -286,7 +296,7 @@     , msgInfoDesc  :: String     , msgInfoExtra :: Value     }-  deriving (Generic)+  deriving (Eq, Generic)  instance ToJSON MsgInfo @@ -300,7 +310,7 @@     , msgDataVarType   :: String     , msgDataActive    :: Bool     }-  deriving (Generic)+  deriving (Eq, Generic)  instance ToJSON MsgData @@ -310,7 +320,7 @@     , triggerType    :: Maybe String     , triggerMsgType :: Maybe String     }-  deriving (Generic)+  deriving (Eq, Generic)  instance ToJSON Trigger 
src/Command/Common.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE OverloadedStrings         #-} {-# LANGUAGE ScopedTypeVariables       #-} -- Copyright 2022 United States Government as represented by the Administrator -- of the National Aeronautics and Space Administration. All Rights Reserved.@@ -32,8 +31,7 @@     , specExtractExternalVariables     , specExtractHandlers     , processResult-    , cannotCopyTemplate-    , makeLeftE+    , cannotCopyTemplateF     , locateTemplateDir     )   where@@ -47,8 +45,9 @@ import           System.FilePath        ((</>))  -- External imports: auxiliary-import Data.ByteString.Extra as B (safeReadFile)-import Data.String.Extra     (sanitizeLCIdentifier, sanitizeUCIdentifier)+import Data.ByteString.Extra  as B (safeReadFile)+import Data.String.Extra      (sanitizeLCIdentifier, sanitizeUCIdentifier)+import System.Directory.Extra (CopyTemplateException(..))  -- External imports: ogma import Data.OgmaSpec (Requirement (..), Spec (..), externalVariableName,@@ -98,7 +97,7 @@     mergeSpecs :: Spec a -> Spec a -> Spec a     mergeSpecs s1 s2 = Spec       { internalVariables = internalVariables s1 ++ internalVariables s2-      , externalVariables = externalVariables s2 ++ externalVariables s2+      , externalVariables = externalVariables s1 ++ externalVariables s2       , requirements      = requirements s1 ++ requirements s2       } @@ -157,7 +156,7 @@ parseRequirementsListFile Nothing   = return Nothing parseRequirementsListFile (Just fp) =   ExceptT $ makeLeftE (cannotOpenHandlersFile fp) <$>-    (E.try $ Just . lines <$> readFile fp)+    E.try (Just . lines <$> readFile fp)  -- | Read a list of variable DBs. openVarDBFiles :: VariableDB@@ -226,9 +225,8 @@ -- | Extract the variables from a specification, and sanitize them. specExtractExternalVariables :: Maybe (Spec a) -> [String] specExtractExternalVariables Nothing   = []-specExtractExternalVariables (Just cs) = map sanitizeLCIdentifier-                                       $ map externalVariableName-                                       $ externalVariables cs+specExtractExternalVariables (Just cs) =+ map (sanitizeLCIdentifier . externalVariableName) $ externalVariables cs  -- | Extract the requirements from a specification, and sanitize them to match -- the names of the handlers used by Copilot.@@ -313,14 +311,12 @@  -- | Exception handler to deal with the case of files that cannot be -- copied/generated due lack of space or permissions or some I/O error.-cannotCopyTemplate :: ErrorTriplet-cannotCopyTemplate =-    ErrorTriplet ecCannotCopyTemplate msg LocationNothing+cannotCopyTemplateF :: CopyTemplateException -> ErrorTriplet+cannotCopyTemplateF e =+    ErrorTriplet ecCannotCopyTemplate (msg ++ show e) LocationNothing   where     msg =-      "Generation failed during copy/write operation. Check that"-      ++ " there's free space in the disk and that you have the necessary"-      ++ " permissions to write in the destination directory."+      "Generation failed during copy/write operation: "  -- ** Error codes 
src/Command/Diagram.hs view
@@ -187,7 +187,7 @@ exprPair Inputs = ExprPair $   ExprPairT     ((Right . read) :: String -> Either String Int)-    (\_ -> id)+    (const id)     (\x -> "input == " ++ show x)     (const [])     (-1)
src/Command/FPrimeApp.hs view
@@ -1,6 +1,5 @@ {-# LANGUAGE DeriveGeneric             #-} {-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE OverloadedStrings         #-} {-# LANGUAGE ScopedTypeVariables       #-} -- Copyright 2022 United States Government as represented by the Administrator -- of the National Aeronautics and Space Administration. All Rights Reserved.@@ -19,7 +18,7 @@ -- License for the specific language governing permissions and limitations -- under the License. ----- | Create <https://github.com/nasa/fprime FPrime> components that subscribe+-- | Create <https://github.com/nasa/fprime F Prime> components that subscribe -- to obtain data and call Copilot when new values arrive.  {- HLINT ignore "Functor law" -}@@ -31,7 +30,7 @@   where  -- External imports-import           Control.Applicative    ( liftA2, (<|>) )+import           Control.Applicative    ( (<|>) ) import qualified Control.Exception      as E import           Control.Monad.Except   ( ExceptT(..), liftEither ) import           Data.Aeson             ( ToJSON, toJSON )@@ -40,6 +39,7 @@ import           GHC.Generics           ( Generic )  -- External imports: auxiliary+import Data.Either.Extra      ( mapLeft ) import System.Directory.Extra ( copyTemplate )  import qualified Command.Standalone@@ -48,9 +48,9 @@ import Command.Result (Result (..))  -- Internal imports-import Command.Common                 (InputFile (..), cannotCopyTemplate,+import Command.Common                 (InputFile (..), cannotCopyTemplateF,                                        checkArguments, combineInputFiles,-                                       locateTemplateDir, makeLeftE,+                                       locateTemplateDir,                                        openVarDBFilesWithDefault,                                        parseInputFile,                                        parseRequirementsListFile,@@ -67,7 +67,7 @@ import Data.Spec.Parser               (readInputExpr) import Language.Trans.Diagram2Copilot (DiagramMode (..)) --- | Generate a new FPrime component connected to Copilot.+-- | Generate a new F Prime component connected to Copilot. command :: CommandOptions -- ^ Options to the ROS backend.         -> IO (Result ErrorCode) command options = processResult $ do@@ -81,7 +81,7 @@     let subst = mergeObjects (toJSON appData) templateVars      -- Expand template-    ExceptT $ fmap (makeLeftE cannotCopyTemplate) $ E.try $+    ExceptT $ fmap (mapLeft cannotCopyTemplateF) $ E.try $       copyTemplate templateDir subst targetDir    where@@ -91,6 +91,8 @@     functions     = exprPair (commandPropFormat options)     templateVarsF = commandExtraVars options +-- | Generate application data describing core elements of a new F Prime+-- component that implements the input requirements or diagrams. command' :: CommandOptions          -> ExprPair          -> ExceptT ErrorTriplet IO AppData@@ -102,7 +104,7 @@      specT <- maybe                (return Nothing)-               (\e -> Just . InputFileSpec <$> readInputExpr' e)+               (fmap (Just . InputFileSpec). readInputExpr')                cExpr      specF <- if null fpA@@ -118,7 +120,7 @@      liftEither $ checkArguments spec vs rs -    copilotM <- sequenceA $ (\spec' -> processSpec spec' cExpr fpA) <$> spec+    copilotM <- traverse (\spec' -> processSpec spec' cExpr fpA) spec      let varNames = fromMaybe (defaultVarNames spec) vs         monitors = maybe (defaultMonitors spec) (map (\x -> (x, Nothing))) rs
src/Command/Overview.hs view
@@ -1,6 +1,5 @@ {-# LANGUAGE DeriveGeneric             #-} {-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE OverloadedStrings         #-} {-# LANGUAGE ScopedTypeVariables       #-} -- Copyright 2024 United States Government as represented by the Administrator -- of the National Aeronautics and Space Administration. All Rights Reserved.@@ -202,7 +201,7 @@ instance ToJSON CommandSummaryDiagram  -- | Options used to customize the interpretation of input specifications.-data CommandOptions = CommandOptions+newtype CommandOptions = CommandOptions   { commandInputFiles :: [ OverviewFile ]   } 
src/Command/ROSApp.hs view
@@ -1,6 +1,5 @@ {-# LANGUAGE DeriveGeneric             #-} {-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE OverloadedStrings         #-} {-# LANGUAGE ScopedTypeVariables       #-} -- Copyright 2022 United States Government as represented by the Administrator -- of the National Aeronautics and Space Administration. All Rights Reserved.@@ -36,7 +35,7 @@   where  -- External imports-import           Control.Applicative  (liftA2, (<|>))+import           Control.Applicative  ((<|>)) import qualified Control.Exception    as E import           Control.Monad.Except (ExceptT (..), liftEither) import           Data.Aeson           (ToJSON (..))@@ -49,12 +48,13 @@ import qualified Command.Standalone  -- Internal imports: auxiliary-import Command.Result (Result (..))+import Command.Result    ( Result (..) )+import Data.Either.Extra ( mapLeft )  -- Internal imports-import Command.Common                 (InputFile (..), cannotCopyTemplate,+import Command.Common                 (InputFile (..), cannotCopyTemplateF,                                        checkArguments, combineInputFiles,-                                       locateTemplateDir, makeLeftE,+                                       locateTemplateDir,                                        openVarDBFilesWithDefault,                                        parseInputFile,                                        parseRequirementsListFile,@@ -87,7 +87,7 @@     let subst = mergeObjects (toJSON appData) templateVars      -- Expand template-    ExceptT $ fmap (makeLeftE cannotCopyTemplate) $ E.try $+    ExceptT $ fmap (mapLeft cannotCopyTemplateF) $ E.try $       copyTemplate templateDir subst targetDir    where@@ -97,6 +97,8 @@     functions     = exprPair (commandPropFormat options)     templateVarsF = commandExtraVars options +-- | Generate application data describing core elements of a new ROS package+-- that implements the input requirements or diagrams. command' :: CommandOptions          -> ExprPair          -> ExceptT ErrorTriplet IO AppData@@ -108,7 +110,7 @@      specT <- maybe                (return Nothing)-               (\e -> Just . InputFileSpec <$> readInputExpr' e)+               (fmap (Just . InputFileSpec) . readInputExpr')                cExpr      specF <- if null fpA@@ -124,7 +126,7 @@      liftEither $ checkArguments spec vs rs -    copilotM <- sequenceA $ (\spec' -> processSpec spec' cExpr fpA) <$> spec+    copilotM <- traverse (\spec' -> processSpec spec' cExpr fpA) spec      let varNames = fromMaybe (defaultVarNames spec) vs         monitors = maybe (defaultMonitors spec) (map (\x -> (x, Nothing))) rs@@ -232,9 +234,10 @@                 (inputType inputDef)                 (Just . typeToType)                 (findType varDB varName "ros/variable" "C")-  let typeMsg' = fromMaybe+  let typeMsg' = maybe                    (topicType topicDef)-                   (typeFromType <$> findType varDB varName "ros/message" "C")+                   typeFromType+                   (findType varDB varName "ros/message" "C")        fieldMsg = typeFromField =<< findType varDB varName "ros/message" "C" 
src/Command/Report.hs view
@@ -29,21 +29,21 @@ -- External imports import qualified Control.Exception      as E import           Control.Monad          (foldM)-import           Control.Monad.Except   (ExceptT (..), liftEither, runExceptT,-                                         withExceptT)+import           Control.Monad.Except   (ExceptT (..), liftEither, withExceptT) import           Control.Monad.IO.Class (liftIO) import           Data.Aeson             (ToJSON (..)) import           GHC.Generics           (Generic)  -- External imports: Ogma+import Data.Either.Extra      (mapLeft) import Data.OgmaSpec          (Requirement (..), Spec (..)) import Data.String.Extra      (sanitizeUCIdentifier) import System.Directory.Extra (copyTemplate)  -- Internal imports import           Command.Common              (InputFile (..),-                                              cannotCopyTemplate,-                                              locateTemplateDir, makeLeftE,+                                              cannotCopyTemplateF,+                                              locateTemplateDir,                                               parseInputFile, processResult) import           Command.Errors              (ErrorCode, ErrorTriplet (..)) import           Command.Result              (Result (..))@@ -76,7 +76,7 @@                     (commandInputFiles options)      -- Expand template-    ExceptT $ fmap (makeLeftE cannotCopyTemplate) $ E.try $+    ExceptT $ fmap (mapLeft cannotCopyTemplateF) $ E.try $       copyTemplate templateDir (toJSON reportData) targetDir    where@@ -159,7 +159,7 @@                            }          pure $ CommandSummary-                 { commandRequirementsAny = length reqListDetails > 0+                 { commandRequirementsAny = not (null reqListDetails)                  , commandRequirementList = [fileReqs]                  , commandDiagramsAny     = False                  , commandDiagramsList    = []
src/Command/Result.hs view
@@ -26,7 +26,7 @@ -- Internal imports import Data.Location ( Location ) --- | Result of the global process+-- | Result of the global process. data Result a = Success               | Error a String Location 
src/Command/Search.hs view
@@ -174,7 +174,7 @@ instance ToJSON RequirementInfo  -- | Information about a diagram that matches the search query.-data DiagramInfo = DiagramInfo+newtype DiagramInfo = DiagramInfo     { diagramInfoLocation :: FilePath     }   deriving (Generic, Show)
src/Command/Standalone.hs view
@@ -1,6 +1,5 @@ {-# LANGUAGE DeriveGeneric             #-} {-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE OverloadedStrings         #-} {-# LANGUAGE ScopedTypeVariables       #-} -- Copyright 2020 United States Government as represented by the Administrator -- of the National Aeronautics and Space Administration. All Rights Reserved.@@ -41,10 +40,10 @@ import System.Directory.Extra (copyTemplate)  -- Internal imports-import Command.Common                 (InputFile (..), cannotCopyTemplate,+import Command.Common                 (InputFile (..), cannotCopyTemplateF,                                        combineInputFiles, locateTemplateDir,-                                       makeLeftE, parseInputFile,-                                       parseTemplateVarsFile, processResult)+                                       parseInputFile, parseTemplateVarsFile,+                                       processResult) import Command.Errors                 (ErrorCode, ErrorTriplet (..)) import Command.Result                 (Result (..)) import Data.Aeson.Extra               (mergeObjects)@@ -78,7 +77,7 @@     let subst = mergeObjects (toJSON appData) templateVars      -- Expand template-    ExceptT $ fmap (makeLeftE cannotCopyTemplate) $ E.try $+    ExceptT $ fmap (mapLeft cannotCopyTemplateF) $ E.try $       copyTemplate templateDir subst targetDir    where@@ -106,7 +105,7 @@     -- definitions.     specT <- maybe                (return Nothing)-               (\e -> Just . InputFileSpec <$> readInputExpr' e)+               (fmap (Just . InputFileSpec) . readInputExpr')                triggerExprM      specF <- if null fpA@@ -121,7 +120,7 @@     let spec = specT <|> specF      case spec of-      Nothing    -> liftEither $ Left $ commandMissingSpec+      Nothing    -> liftEither $ Left commandMissingSpec       Just spec' ->         commandLogic triggerExprM fpA name typeMaps exprT spec' ComputeState 
src/Command/VariableDB.hs view
@@ -36,6 +36,8 @@   where  -- External imports+import Control.Applicative  ((<|>))+import Control.Monad        (foldM) import Control.Monad.Except (ExceptT, throwError) import Data.Aeson           (FromJSON (..), Value (Object), (.:), withObject) import Data.Aeson.KeyMap    (filterWithKey)@@ -104,8 +106,7 @@  -- | Find an input with a given name. findInput :: VariableDB -> String -> Maybe InputDef-findInput varDB name =-  find (\x -> inputName x == name) (inputs varDB)+findInput varDB name = find (\x -> inputName x == name) (inputs varDB)  -- | Find a connection a given scope. findConnection :: InputDef -> String -> Maybe Connection@@ -188,10 +189,7 @@ -- contradictory information. mergeInputs :: Monad m             => [InputDef] -> [InputDef] -> ExceptT ErrorTriplet m [InputDef]-mergeInputs is1 []     = return is1-mergeInputs is1 (i2:is2) = do-  is1' <- mergeInput is1 i2-  mergeInputs is1' is2+mergeInputs = foldM mergeInput  -- | Merge an input definition into a list of input definitions, so long as it -- does not contain contradictory information.@@ -205,10 +203,8 @@        || inputType i1 == inputType i2        )   = do cs <- mergeConnections (inputConnections i1) (inputConnections i2)-       let i1' = i1 { inputType =-                        mergeMaybe (inputType i1) (inputType i2)-                    , inputConnections =-                        cs+       let i1' = i1 { inputType        = inputType i1 <|> inputType i2+                    , inputConnections = cs                     }        return (i1' : is1) @@ -220,10 +216,7 @@ -- contradictory information. mergeConnections :: Monad m                  => [Connection] -> [Connection] -> ExceptT ErrorTriplet m [Connection]-mergeConnections cs1 []       = return cs1-mergeConnections cs1 (c2:cs2) = do-  cs1' <- mergeConnection cs1 c2-  mergeConnections cs1' cs2+mergeConnections = foldM mergeConnection  -- | Merge a connection into a list of connections, so long as it does not -- contain contradictory information.@@ -246,10 +239,7 @@ -- information. mergeTopics :: Monad m             => [TopicDef] -> [TopicDef] -> ExceptT ErrorTriplet m [TopicDef]-mergeTopics ts1 [] = return ts1-mergeTopics ts1 (t2:ts2) = do-  ts1' <- mergeTopic ts1 t2-  mergeTopics ts1' ts2+mergeTopics = foldM mergeTopic  -- | Merge a topic into a list of topics, so long as it does not contain -- contradictory information.@@ -272,10 +262,7 @@ -- contradictory information. mergeTypes :: Monad m            => [TypeDef] -> [TypeDef] -> ExceptT ErrorTriplet m [TypeDef]-mergeTypes ts1 []       = return ts1-mergeTypes ts1 (t2:ts2) = do-  ts1' <- mergeType ts1 t2-  mergeTypes ts1' ts2+mergeTypes = foldM mergeType  -- | Merge a type definition into a list of type definitions, so long as it -- does not contain contradictory information.@@ -310,13 +297,6 @@ -- | Error: one of the variable DBs provided cannot be merged. ecCannotMergeVariableDB :: ErrorCode ecCannotMergeVariableDB = 1---- | Merge two @Maybe@ values, prefering the left one if two @Just@s are--- provided.-mergeMaybe :: Maybe a -> Maybe a -> Maybe a-mergeMaybe Nothing x       = x-mergeMaybe x       Nothing = x-mergeMaybe x       _       = x  -- | Implement instances of parser to read variable DB from JSON, dropping the -- prefix in each field name.
src/Data/Aeson/Extra.hs view
@@ -28,7 +28,7 @@ -- -- Fails if the values are not objects or null. mergeObjects :: Value -> Value -> Value-mergeObjects (Object m1) (Object m2) = Object (union m1 m2)+mergeObjects (Object m1) (Object m2) = Object (m1 `union` m2) mergeObjects obj         Null        = obj mergeObjects Null        obj         = obj mergeObjects _           _           = error "The values passed are not objects"
src/Data/Diagram/Parser.hs view
@@ -64,7 +64,7 @@            (\msg -> ErrorTriplet ecCannotReadDiagram msg (LocationFile fp))            diagramE ---- | Generic function to parse a diagram.+-- | Generic function to parse a diagram. parseDiagram :: DiagramFormat          -- ^ Format of the input file              -> B.ByteString           -- ^ Contents of the diagram              -> ExprPair               -- ^ Subparser for conditions or edge
src/Data/Diagram/Parser/Mermaid.hs view
@@ -79,6 +79,7 @@    pure $ Diagram transitions +{-# ANN pGraphTransition ("HLint: ignore Redundant bracket" :: String) #-} -- | Parser for an edge in a state diagram. -- -- This parser depends on an auxiliary parser for the expressions associated to@@ -109,6 +110,8 @@    pure $ Diagram transitions +{-# ANN pStateTransition ("HLint: ignore Redundant bracket" :: String)  #-}+{-# ANN pStateTransition ("HLint: ignore Reduce duplication" :: String) #-} -- | Parser for transition label in stateDiagram-v2 mermaid diagram. pStateTransition :: ExprPair -> MermaidParser (Int, String, Int) pStateTransition ep@(ExprPair (ExprPairT { exprTParse = parseProp })) = do@@ -129,7 +132,7 @@    _ <- newline -  pure $ (from, exprPairShow ep edge, to)+  pure (from, exprPairShow ep edge, to)  -- | Parser for Mermaid diagrams of type sequenceDiagram. pSequenceDiagram :: ExprPair -> MermaidParser Diagram@@ -143,6 +146,7 @@    pure $ Diagram transitions +{-# ANN pSequenceTransition ("HLint: ignore Redundant bracket" :: String) #-} -- | Parser for a connection, message or transition in a sequence diagram. -- -- This parser depends on an auxiliary parser for the expressions associated to@@ -176,6 +180,6 @@   , string "-)"   ] --- | Consume spaces+-- | Consume spaces. spaces :: MermaidParser () spaces = L.space space1 empty empty
src/Data/ExprPair.hs view
@@ -71,14 +71,14 @@ exprPair "lustre" = ExprPair $   ExprPairT     (Lustre.pBoolSpec . Lustre.myLexer)-    (\_ -> id)+    (const id)     Lustre.boolSpec2Copilot     Lustre.boolSpecNames     (Lustre.BoolSpecSignal (Lustre.Ident "undefined")) exprPair "literal" = ExprPair $   ExprPairT     Right-    (\_ -> id)+    (const id)     id     (const [])     "undefined"
src/Data/Project.hs view
@@ -17,15 +17,22 @@ -- under the License. -- -- | Ogma projects.-module Data.Project where+module Data.Project+    ( Project(..)+    , readProject+    )+  where  -- External imports import           Control.Exception (IOException, try) import           Data.Aeson        (FromJSON, ToJSON, eitherDecodeStrict') import qualified Data.ByteString   as BS+import           Data.List         (stripPrefix) import           GHC.Generics      (Generic)+import           System.Directory  (makeAbsolute)+import           System.FilePath   (isAbsolute, takeDirectory, (</>)) --- -- Internal imports+-- Internal imports import Data.Either.Extra (mapLeft)  data Project = Project@@ -49,7 +56,49 @@ readProject :: FilePath -> IO (Either String Project) readProject path = do   bytesResult <- try (BS.readFile path)-  pure $ case bytesResult of-           Left e      -> Left (show (e :: IOException))-           Right bytes -> mapLeft ("Failed to read project: " ++)-                        $ eitherDecodeStrict' bytes+  let project = case bytesResult of+                  Left e      -> Left (show (e :: IOException))+                  Right bytes -> mapLeft ("Failed to read project: " ++)+                               $ eitherDecodeStrict' bytes++  projectDir <- takeDirectory <$> makeAbsolute path++  pure $ resolveProjectPaths projectDir <$> project++-- | Resolve paths inside a project.+resolveProjectPaths :: FilePath -> Project -> Project+resolveProjectPaths projectDir p = p+  { projectInputFiles     = resolveInputFile projectDir <$> projectInputFiles p+  , projectVariableFiles  = resolvePath projectDir <$> projectVariableFiles p+  , projectVariableDBFile = resolvePath projectDir <$> projectVariableDBFile p+  , projectHandlerFile    = resolvePath projectDir <$> projectHandlerFile p+  , projectCommandPropVia = resolvePath projectDir <$> projectCommandPropVia p+  , projectTemplateDir    = resolvePath projectDir <$> projectTemplateDir p+  , projectTargetDir      = resolvePath projectDir <$> projectTargetDir p+  , projectExtraJSONFile  = resolvePath projectDir <$> projectExtraJSONFile p+  }++-- | Resolve the locations of input file pairs, possibly in relation to the+-- project path.+resolveInputFile :: FilePath+                 -> (FilePath, String, String)+                 -> (FilePath, String, String)+resolveInputFile projectDir (filePath, fileFormat, propName) =+    (filePath', fileFormat', propName)+  where+    filePath'   = resolvePath projectDir filePath+    fileFormat' = resolvePath projectDir fileFormat++-- | Resolve the path to a file, possibly in relation to the project path.+resolvePath :: FilePath -> FilePath -> FilePath+resolvePath projectDir path+  | isAbsolute path+  = path+  | Just path' <- stripPrefix "cwd:" path+  = path'+  | Just path' <- stripPrefix "cmd:" path+  = path'+  | Just path' <- stripPrefix "project:" path+  = projectDir </> path'+  | otherwise+  = projectDir </> path
src/Data/Spec/Analysis.hs view
@@ -243,7 +243,7 @@       map ("       " ++) [ n ++ " :: " ++ t, n ++ " = " ++ i ]      formatTrigger (_, _, h, g, a) =-      map ("   " ++) [ "trigger " ++ show h ++ " (" ++ g ++ ") " ++ a ]+      [ "   trigger " ++ show h ++ " (" ++ g ++ ") " ++ a ]  -- | Default imports for a 'Spec' that was converted into a 'Copilot.Spec'. defaultSpecImports :: [(String, Maybe String)]
src/Data/Spec/Extra.hs view
@@ -33,7 +33,7 @@ addMissingIdentifiers f s = s { externalVariables = vars' }   where     vars'   = externalVariables s ++ newVars-    newVars = map (\n -> ExternalVariableDef n "") newVarNames+    newVars = map (`ExternalVariableDef` "") newVarNames      -- Names that are not defined anywhere     newVarNames = identifiers \\ existingNames
src/Data/Spec/Parser.hs view
@@ -29,19 +29,16 @@ import           Control.Monad.Except (ExceptT (..)) import           Data.Aeson           (eitherDecode) import qualified Data.ByteString.Lazy as L-import           Data.List            (isInfixOf, isPrefixOf, nub, (\\))+import           Data.List            (isInfixOf, isPrefixOf) import           System.Directory     (doesFileExist) import           System.FilePath      ((</>)) import           System.Process       (readProcess)  -- External imports: auxiliary import Data.ByteString.Extra as B (safeReadFile)-import Data.String.Extra     (sanitizeLCIdentifier, sanitizeUCIdentifier)  -- External imports: ogma-import Data.OgmaSpec            (ExternalVariableDef (..),-                                 InternalVariableDef (..), Requirement (..),-                                 Spec (..))+import Data.OgmaSpec            (Requirement (..), Spec (..)) import Language.CSVSpec.Parser  (parseCSVSpec) import Language.JSONSpec.Parser (parseJSONSpec) import Language.XLSXSpec.Parser (parseXLSXSpec)@@ -50,7 +47,6 @@  -- Internal imports: auxiliary import Command.Errors    (ErrorTriplet(..), ErrorCode)-import Data.Diagram      (Diagram) import Data.Either.Extra (mapLeft) import Data.ExprPair     (ExprPairT(..)) import Data.Location     (Location (..))@@ -79,8 +75,8 @@     -- Return the spec, transforming the error message if applicable.     pure $ mapLeft (cannotReadConditionExpr expr) spec ---- | Process input specification, if available, and return its abstract---- representation.+-- | Process input specification, if available, and return its abstract+-- representation. readInputFile :: FilePath               -> String               -> String
src/Language/Trans/CStruct2CopilotStruct.hs view
@@ -35,7 +35,7 @@ -- Internal imports import qualified Language.C.AbsC as C --- | Convert a top-level struct declaration into a CStruct+-- | Convert a top-level struct declaration into a CStruct. mkCStruct :: C.ExternalDeclaration -> Either String CStruct mkCStruct (C.MkExternalDeclarationFunctionDefinition _) = Left "C files must contain struct definitions only." mkCStruct (C.MkExternalDeclarationDeclaration (C.MkDeclaration specifiers initDecl)) =@@ -48,7 +48,7 @@       in CStruct <$> name <*> fields     _ -> Left "C files must contain struct definitions only." --- -- | Convert a declaration within a struct into a field declaration.+-- | Convert a declaration within a struct into a field declaration. buildCField :: C.StructDeclaration -> Either String CField buildCField (C.MkStructDeclaration field name)     | fieldLength > 0 = CArray <$> fieldType <*> fieldName <*> pure fieldLength@@ -77,7 +77,7 @@ showTypeSpecifier C.MkTypeSpecifierInt64  = "int64_t" showTypeSpecifier C.MkTypeSpecifierInt    = "int" --- -- | Extract the name of a field from a struct declarator.+-- | Extract the name of a field from a struct declarator. extractFieldName :: Read n => C.StructDeclarator -> Either String n extractFieldName (C.MkStructDeclaratorDeclarator (C.MkDeclarator C.MkPointerOptNothing (C.MkDirectDeclaratorIdentifier (C.Identifier d)))) = Right $ read $ show d extractFieldName (C.MkStructDeclaratorDeclarator@@ -92,8 +92,8 @@ extractFieldName _ = Left $ "only struct declarations that are IDs without a"                         ++  " pointer, or plain arrays without a pointer, are"                         ++  " supported."------ -- | Extract the length of an array field from a struct declarator.++-- | Extract the length of an array field from a struct declarator. extractFieldLength :: C.StructDeclarator -> Integer extractFieldLength (C.MkStructDeclaratorDeclarator                      (C.MkDeclarator@@ -139,7 +139,6 @@                    ) = read i extractFieldLength _ = 0 --- -- | Convert a 'String' to camel case, also eliminating the @_t@ at the end if -- present. camelCaseTypeName :: String -> String
src/Language/Trans/CStructs2Copilot.hs view
@@ -28,7 +28,6 @@  -- External imports import Data.Char ( isUpper, toLower )-import Data.List ( intercalate )  -- External imports: auxiliary import Data.List.Extra ( toHead, toTail )
src/Language/Trans/Spec2Copilot.hs view
@@ -140,31 +140,12 @@                 (Just ty, Just ex) -> "[ arg (" ++ showExpr ex ++ " ) ]"                 _                  -> "[]" -    -- Map from a variable name to its desired identifier in the code-    -- generated.-    internalVariableMap =-      map (\x -> (x, sanitizeLCIdentifier x)) internalVariableNames--    externalVariableMap =-      map (\x -> (x, sanitizeLCIdentifier x)) externalVariableNames--    requirementNameMap =-      map (\x -> (x, "prop" ++ sanitizeUCIdentifier x)) requirementNames--    nameSubstitutions = internalVariableMap-                     ++ externalVariableMap-                     ++ requirementNameMap--    -- Variable/requirement names used in the input spec.-    internalVariableNames = map internalVariableName-                          $ internalVariables spec--    externalVariableNames = map externalVariableName-                          $ externalVariables spec--    requirementNames = map requirementName-                     $ requirements spec+    nameSubstitutions = internalVariableMap spec+                     ++ externalVariableMap spec+                     ++ requirementNameMap spec +-- | Check that a specification does not contain any name clashes between+-- variables and/or requirements. specAnalyze :: Spec a -> Either String (Spec a) specAnalyze spec     | not (null evnClash)@@ -193,30 +174,9 @@                                 `union` externalVariableNames')      -- Names used.-    internalVariableNames' = map snd internalVariableMap-    externalVariableNames' = map snd externalVariableMap-    requirementNames'      = map snd requirementNameMap--    -- Map from a variable name to its desired identifier in the code-    -- generated.-    internalVariableMap =-      map (\x -> (x, sanitizeLCIdentifier x)) internalVariableNames--    externalVariableMap =-      map (\x -> (x, sanitizeLCIdentifier x)) externalVariableNames--    requirementNameMap =-      map (\x -> (x, "prop" ++ sanitizeUCIdentifier x)) requirementNames--    -- Variable/requirement names used in the input spec.-    internalVariableNames = map internalVariableName-                          $ internalVariables spec--    externalVariableNames = map externalVariableName-                          $ externalVariables spec--    requirementNames = map requirementName-                     $ requirements spec+    internalVariableNames' = map snd (internalVariableMap spec)+    externalVariableNames' = map snd (externalVariableMap spec)+    requirementNames'      = map snd (requirementNameMap spec)  -- * Auxiliary @@ -232,3 +192,33 @@ -- an end of line character at the end of the last string. unlines' :: [String] -> String unlines' = intercalate "\n"++-- | Map from an internal variable name to its desired identifier in the code+-- generated.+internalVariableMap :: Spec a -> [(String, String)]+internalVariableMap =+  map (\x -> (x, sanitizeLCIdentifier x)) . internalVariableNames++-- | Map from an external variable name to its desired identifier in the code+-- generated.+externalVariableMap :: Spec a -> [(String, String)]+externalVariableMap =+  map (\x -> (x, sanitizeLCIdentifier x)) . externalVariableNames++-- | Map from a requirement name to its desired identifier in the code+-- generated.+requirementNameMap :: Spec a -> [(String, String)]+requirementNameMap =+  map (\x -> (x, "prop" ++ sanitizeUCIdentifier x)) . requirementNames++-- | Names of all internal variables in a 'Spec'.+internalVariableNames :: Spec a -> [String]+internalVariableNames = map internalVariableName . internalVariables++-- | Names of all external variables in a 'Spec'.+externalVariableNames :: Spec a -> [String]+externalVariableNames = map externalVariableName . externalVariables++-- | Names of all requirements in a 'Spec'.+requirementNames :: Spec a -> [String]+requirementNames = map requirementName . requirements
src/Language/YAMLSpec/Parser.hs view
@@ -20,19 +20,19 @@ module Language.YAMLSpec.Parser where  -- External imports-import           Control.Monad.Except   (ExceptT (..), runExceptT)-import           Control.Monad.IO.Class (liftIO)-import           Data.Aeson             (Value (..))-import           Data.Aeson.Key         (fromString)-import qualified Data.Aeson.KeyMap      as M-import           Data.Bifunctor         (first)-import qualified Data.ByteString        as BS-import           Data.Char              (isSpace)-import           Data.List              (intercalate)-import           Data.Text              (unpack)-import qualified Data.Vector            as V-import qualified Data.Yaml              as Y-import           System.FilePath        (takeBaseName, takeFileName)+import           Control.Monad.Except (ExceptT (..), runExceptT)+import           Data.Aeson           (Value (..))+import           Data.Aeson.Key       (fromString)+import qualified Data.Aeson.KeyMap    as M+import           Data.Bifunctor       (first)+import qualified Data.ByteString      as BS+import           Data.Char            (isSpace)+import           Data.List            (intercalate)+import           Data.Maybe           (maybeToList)+import           Data.Text            (unpack)+import qualified Data.Vector          as V+import qualified Data.Yaml            as Y+import           System.FilePath      (takeBaseName, takeFileName)  -- External imports: ogma-spec import Data.Either.Extra (mapLeft)@@ -249,7 +249,7 @@ -- -- If the values are an array, it returns the values in the array directly. objectFieldValues :: String -> Value -> [Value]-objectFieldValues key (Object o) = maybe [] (:[]) $ M.lookup (fromString key) o+objectFieldValues key (Object o) = maybeToList $ M.lookup (fromString key) o objectFieldValues _   _          = []  -- ** Either-related auxiliary functions
templates/fprime/Dockerfile view
@@ -1,11 +1,11 @@-# This dockerfile compiles a monitoring application inside FPrime's Reference+# This dockerfile compiles a monitoring application inside F Prime's Reference # Application. FROM ubuntu:focal  # Avoid questions during package installation. ENV DEBIAN_FRONTEND=noninteractive -# Install FPrime dependencies and clone fprime from the repo.+# Install F Prime dependencies and clone fprime from the repo. RUN apt-get update RUN apt-get install -y git cmake gcc python3 pip default-jre 
templates/ros/Dockerfile view
@@ -1,4 +1,9 @@-FROM osrf/space-ros:jazzy-2026.04.0+{{#BASE_DOCKER_IMAGE}}+FROM {{.}}+{{/BASE_DOCKER_IMAGE}}+{{^BASE_DOCKER_IMAGE}}+FROM osrf/space-ros:jazzy-2026.07.0+{{/BASE_DOCKER_IMAGE}}  ARG USER=spaceros-user ARG PACKAGE_PATH=/home/${USER}/monitors@@ -26,7 +31,7 @@     fi  ADD excluded-pkgs*.txt /tmp/-RUN sudo rosdep init+RUN if [ ! -f "/etc/ros/rosdep/sources.list.d/20-default.list" ]; then sudo rosdep init; fi RUN rosdep update RUN source /opt/ros/spaceros/setup.bash && \     if [ -f "/tmp/excluded-pkgs.txt" ]; then \
templates/ros/copilot/src/copilot_monitor.cpp view
@@ -77,8 +77,8 @@  {{/monitors}}     // Needed so we can report messages to the log.-    static CopilotRV& getInstance() {-      static CopilotRV instance;+    static std::shared_ptr<CopilotRV> getInstance() {+      static std::shared_ptr<CopilotRV> instance = std::shared_ptr<CopilotRV>(new CopilotRV());       return instance;     } @@ -115,19 +115,19 @@ // communicate with other applications. {{#monitorType}} void {{monitorName}}({{.}} arg) {-  CopilotRV::getInstance().{{monitorName}}(arg);+  CopilotRV::getInstance()->{{monitorName}}(arg); } {{/monitorType}} {{^monitorType}} void {{monitorName}}() {-  CopilotRV::getInstance().{{monitorName}}();+  CopilotRV::getInstance()->{{monitorName}}(); } {{/monitorType}}  {{/monitors}} int main(int argc, char* argv[]) {   rclcpp::init(argc, argv);-  rclcpp::spin(std::make_shared<CopilotRV>());+  rclcpp::spin(CopilotRV::getInstance());   rclcpp::shutdown();   return 0; }
templates/ros/test_requirements/src/test_requirements.cpp view
@@ -113,10 +113,10 @@  {{#testingVariables}}        {{#varDeclMsgField}}-       {{varDeclType}} {{varDeclName}}_{{.}} = {{varDeclRandom}}();-       auto {{varDeclName}}_{{.}}_msg = {{varDeclMsgType}}();-       {{varDeclName}}_{{.}}_msg.{{.}} = {{varDeclName}}_{{.}};-       {{varDeclName}}_publisher_->publish({{varDeclName}}_{{.}}_msg);+       {{varDeclType}} {{varDeclName}}_data = {{varDeclRandom}}();+       auto {{varDeclName}}_data_msg = {{varDeclMsgType}}();+       {{varDeclName}}_data_msg.{{.}} = {{varDeclName}}_data;+       {{varDeclName}}_publisher_->publish({{varDeclName}}_data_msg);        {{/varDeclMsgField}}        {{^varDeclMsgField}}        {{varDeclType}} {{varDeclName}}_data = {{varDeclRandom}}();
tests/Main.hs view
@@ -1,4 +1,5 @@--- | Test ogma-core+{- HLint ignore "Reduce duplication" -}+-- | Test ogma-core. module Main where  import Data.Monoid                    ( mempty )@@ -14,8 +15,7 @@  -- | Run all unit tests on ogma-core. main :: IO ()-main =-  defaultMainWithOpts tests mempty+main = defaultMainWithOpts tests mempty  -- | All unit tests for ogma-core. tests :: [Test.Framework.Test]