docs/user-manual/gds/gds-dev-guide.md
This guide is for programmers who intend to maintain and develop code for the Ground Data System's command-line interface suite. For regular users who just want to use these CLI tools, please see the user guide.
The intended architecture for the CLI is:
Parsing module (if possible, a single file) which handles all argument parsing for the CLI tool; it determines what command was called and what arguments were provided to itCommand module; each CLI command has its own, independent module to handle executionCommon module (notably, no direct calls should be made to the API from a Command module without going through a Common interface first)The CLI will interact with the GDS through an appropriate API, which the CLI modules access through an interface in Common. While the REST API was initially targeted, we later decided to transition to the Integration Test API for now due to its filtering capabilities.
Not including imports used only for type hints, or dependencies for modules not part of the GDS CLI source code (generated using pydeps:
[!NOTE] The above graph has arrows pointing to the module that does the importing and away from the dependency, and does not include Python standard library imports.
fprime_cli, which imports the command modules and several external libraries to help with parsing.Common module files, as well as importing the appropriate GDS data type for the type of data it's working with (and, in the case of command_send, an appropriate exception).Common module is actually made up of several distinct, independent submodules containing related groups of common code. These import a variety of other GDS modules to help provide all necessary functionality; in particular, the testing_fw.api Integration Test module is used to access the GDS.External Dependencies (installed via setup.py):
Internal Dependencies (i.e. Other F´ modules)
common/pipeline and common/utils - Used to initialize the Test API; pipeline.dictionaries also used to get a list of available commands/events/channelscommon/data_types - Used to handle incoming GDS data and for printing outputfprime_gds/flask/json.py - Used for the --json printing flag implementationexecutables/cli.py - Used to automatically search for a dictionary file while parsingImportant Python stdlib Dependencies:
argparse - Used to handle parsing user inputParsing files (in executables)
argparse library; defines a base class for parsing and a subclass for each command. Uses argcomplete to handle tab completion if it's enabled, cli.py to search for a dictionary file, and then executes the appropriate command's function.Command files (in common/gds_cli):
base_commands.py.base_commands.py.base_commands.py.Common files (in common/gds_cli):
The GDS CLI tests can be found at Gds/test/fprime/common/gds_cli, and currently includes 2 unit test files:
filtering_utils_test.py tests that filtering lists and GDS data work as expectedutils_test.py tests misc_utils and test_api_utils functions, verifying that commands listening for data exit when interrupted, and that getting lists of items works successfullyTest coverage is fairly low; there are currently no integration tests for the CLI.
fprime_cli.py and misc_utils.py use delayed/lazy importing to avoid slow performance from several particularly long imports
fprime_gds/flask/json.py and common/logger/test_logger.py each take 100ms+ to importopenpyxl is installed since it's a slow import for the Test API--list option for performance reasonsSysData printing methods, which means console output will change if those SysData methods changefiltering_util predicates are called on entire SysData objectstest_api_utils instead of using the Test API's existing await_telemetry/etc. methods, since those only accept predicates filtering by time or one of the predefined telemetry_predicate or event_predicate fields; defining our own methods lets us use any predicate that will accept a SysData object
search filter option doesn't take multiple arguments like the other filtering options (done to allow for multi-word string queries more easily, but might not be worth breaking the multiple-filter pattern of the other ones)ids will show all data with any of those ID types, but passing --ids and --search will only show data with those IDs AND having that search term)argcomplete)openpyxl installed slowing the script down because of import time