fprime-gds 4.0.0a10__tar.gz → 4.0.2a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/PKG-INFO +1 -1
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/pyproject.toml +1 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/distributor/distributor.py +12 -6
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/pipeline/standard.py +2 -1
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/testing_fw/api.py +86 -23
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/executables/cli.py +6 -0
- fprime_gds-4.0.2a1/src/fprime_gds/executables/dictionary_merge.py +206 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds.egg-info/PKG-INFO +1 -1
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds.egg-info/SOURCES.txt +1 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds.egg-info/entry_points.txt +1 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/.github/actions/codeql/security-pack.yml +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/.github/actions/spelling/excludes.txt +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/.github/actions/spelling/expect.txt +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/.github/actions/spelling/patterns.txt +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/.github/pull_request_template.md +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/.github/resources/RefTopologyAppDictionary.xml +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/.github/workflows/codeql-security-scan.yml +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/.github/workflows/fprime-gds-tests.yml +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/.github/workflows/gds-cli-tests.yml +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/.github/workflows/publish.yml +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/.github/workflows/spelling.yml +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/.gitignore +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/Doxyfile +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/LICENSE.txt +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/NOTICE.txt +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/README.md +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/configs/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/docs/README.md +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/docs/_static/css/rtd_width.css +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/docs/conf.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/docs/gendoc.bash +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/docs/index.rst +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/examples/simple_sequence.bin +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/examples/simple_sequence.seq +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/setup.cfg +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/setup.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fastentrypoints.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/communication/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/communication/adapters/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/communication/adapters/base.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/communication/adapters/ip.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/communication/adapters/uart.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/communication/ccsds/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/communication/ccsds/apid.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/communication/ccsds/chain.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/communication/ccsds/space_data_link.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/communication/ccsds/space_packet.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/communication/checksum.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/communication/framing.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/communication/ground.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/communication/updown.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/controllers/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/data_types/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/data_types/ch_data.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/data_types/cmd_data.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/data_types/event_data.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/data_types/exceptions.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/data_types/file_data.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/data_types/pkt_data.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/data_types/sys_data.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/decoders/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/decoders/ch_decoder.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/decoders/decoder.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/decoders/event_decoder.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/decoders/file_decoder.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/decoders/pkt_decoder.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/distributor/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/encoders/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/encoders/ch_encoder.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/encoders/cmd_encoder.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/encoders/encoder.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/encoders/event_encoder.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/encoders/file_encoder.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/encoders/pkt_encoder.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/encoders/seq_writer.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/files/File Decoder Documentation.txt +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/files/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/files/downlinker.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/files/helpers.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/files/uplinker.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/fpy/README.md +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/fpy/SPEC.md +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/fpy/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/fpy/bytecode/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/fpy/bytecode/directives.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/fpy/codegen.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/fpy/grammar.lark +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/fpy/main.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/fpy/parser.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/gds_cli/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/gds_cli/base_commands.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/gds_cli/channels.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/gds_cli/command_send.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/gds_cli/events.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/gds_cli/filtering_utils.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/gds_cli/test_api_utils.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/handlers.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/history/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/history/chrono.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/history/history.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/history/ram.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/history/test.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/loaders/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/loaders/ch_json_loader.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/loaders/ch_xml_loader.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/loaders/cmd_json_loader.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/loaders/cmd_xml_loader.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/loaders/dict_loader.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/loaders/event_json_loader.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/loaders/event_xml_loader.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/loaders/fw_type_json_loader.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/loaders/json_loader.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/loaders/pkt_json_loader.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/loaders/pkt_xml_loader.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/loaders/prm_json_loader.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/loaders/xml_loader.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/logger/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/logger/data_logger.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/logger/test_logger.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/models/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/models/common/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/models/common/channel_telemetry.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/models/common/command.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/models/common/event.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/parsers/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/parsers/seq_file_parser.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/pipeline/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/pipeline/dictionaries.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/pipeline/encoding.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/pipeline/files.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/pipeline/histories.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/pipeline/router.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/templates/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/templates/ch_template.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/templates/cmd_template.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/templates/data_template.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/templates/event_template.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/templates/pkt_template.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/templates/prm_template.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/testing_fw/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/testing_fw/predicates.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/testing_fw/pytest_integration.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/tools/README.md +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/tools/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/tools/params.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/tools/seqgen.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/transport.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/utils/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/utils/config_manager.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/utils/data_desc_type.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/utils/event_severity.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/utils/string_util.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/zmq_transport.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/executables/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/executables/apps.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/executables/comm.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/executables/data_product_writer.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/executables/fprime_cli.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/executables/run_deployment.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/executables/tcpserver.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/executables/utils.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/app.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/channels.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/commands.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/components.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/default_settings.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/errors.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/events.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/json.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/logs.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/requirements.txt +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/resource.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/sequence.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/.idea/.gitignore +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/.idea/misc.xml +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/.idea/modules.xml +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/.idea/static.iml +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/.idea/vcs.xml +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/advanced-settings/addon-templates.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/advanced-settings/addon.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/channel-render/addon.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/channel-render/channel-render-template.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/channel-render/channel-render.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/chart-display/addon-templates.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/chart-display/addon.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/chart-display/config.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/chart-display/modified-vendor/chartjs-plugin-streaming.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/chart-display/modified-vendor/chartjs-plugin-zoom.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/chart-display/modified-vendor/flat.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/chart-display/sibling.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/chart-display/vendor/chart.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/chart-display/vendor/chartjs-adapter-luxon.min.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/chart-display/vendor/hammer.min.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/commanding/addon.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/commanding/argument-templates.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/commanding/arguments.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/commanding/command-history-template.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/commanding/command-history.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/commanding/command-input-template.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/commanding/command-input.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/commanding/command-string-template.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/commanding/command-string.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/dictionary/addon-templates.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/dictionary/addon.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/enabled.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/image-display/addon.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/image-display/dashboard.xml +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/sequencer/README.md +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/sequencer/addon-templates.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/sequencer/addon.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/sequencer/autocomplete.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/sequencer/lint.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/sequencer/third/code-mirror.es.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/sequencer/third/rollup/.gitignore +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/sequencer/third/rollup/index.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/sequencer/third/rollup/language.grammer +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/sequencer/third/rollup/package.json +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/addons/sequencer/third/rollup/rollup.config.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/css/fprime.css +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/css/fpstyle.css +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/favicon.ico +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/img/error.svg +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/img/logo.svg +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/img/success.svg +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/index.html +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/config.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/datastore.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/gds.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/json.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/loader.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/performance.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/settings.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/uploader.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/validate.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/vue-support/channel.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/vue-support/dashboard-box.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/vue-support/dashboard-row.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/vue-support/dashboard.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/vue-support/downlink.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/vue-support/event.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/vue-support/fp-row.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/vue-support/fptable.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/vue-support/log.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/vue-support/tabetc.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/vue-support/uplink.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/js/vue-support/utils.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/css/all.min.css +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/css/bootstrap.min.css +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/css/vue-select.css +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/js/luxon.min.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/js/sorttable.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/js/v-runtime-template.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/js/vue-select.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/js/vue.min.js +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/webfonts/fa-brands-400.eot +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/webfonts/fa-brands-400.svg +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/webfonts/fa-brands-400.ttf +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/webfonts/fa-brands-400.woff +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/webfonts/fa-brands-400.woff2 +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/webfonts/fa-regular-400.eot +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/webfonts/fa-regular-400.svg +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/webfonts/fa-regular-400.ttf +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/webfonts/fa-regular-400.woff +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/webfonts/fa-regular-400.woff2 +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/webfonts/fa-solid-900.eot +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/webfonts/fa-solid-900.svg +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/webfonts/fa-solid-900.ttf +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/webfonts/fa-solid-900.woff +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/static/third-party/webfonts/fa-solid-900.woff2 +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/stats.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/flask/updown.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/plugin/__init__.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/plugin/definitions.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/plugin/system.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/version.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds.egg-info/dependency_links.txt +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds.egg-info/requires.txt +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds.egg-info/top_level.txt +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/communication/ccsds/test_space_data_link.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/communication/ccsds/test_space_packet.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/data_types/test_cmd_data.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/distributor/test_distributor.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/encoders/test_ch_encoder.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/encoders/test_event_encoder.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/encoders/test_pkt_encoder.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/fpy/disabled_test_compiler.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/gds_cli/filtering_utils_test.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/gds_cli/utils_test.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/history/chronohistory_unit_test.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/history/testhistory_unit_test.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/loaders/resources/RefTopologyDictionary.json +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/loaders/test_json_loader.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/testing_fw/UnitTestDictionary.xml +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/testing_fw/api_unit_test.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/testing_fw/logs/.gitignore +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/testing_fw/predicate_unit_test.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/tools/expected/simple_expected.bin +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/tools/expected/simple_paramdb.dat +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/tools/input/simple_bad_paramdb.json +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/tools/input/simple_bad_sequence.seq +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/tools/input/simple_paramdb.json +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/tools/input/simple_sequence.seq +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/tools/resources/simple_dictionary.json +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/tools/resources/simple_dictionary.xml +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/tools/seqgen_unit_test.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/tools/test_paramdb_gen.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/common/utils/test_string_util.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/.gitignore +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/dp_writer_data/dictionary.json +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/dp_writer_data/makeBool.bin +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/dp_writer_data/makeComplex.bin +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/dp_writer_data/makeDataArray.bin +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/dp_writer_data/makeEnum.bin +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/dp_writer_data/makeF32.bin +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/dp_writer_data/makeF64.bin +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/dp_writer_data/makeFppArray.bin +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/dp_writer_data/makeI16.bin +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/dp_writer_data/makeI32.bin +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/dp_writer_data/makeI64.bin +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/dp_writer_data/makeI8.bin +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/dp_writer_data/makeU32.bin +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/dp_writer_data/makeU32Array.bin +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/dp_writer_data/makeU8Array.bin +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/test_data_product_writer.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/test_run_deployment.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/executables/test_utils.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/sample/dictionary.xml +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/fprime_gds/test_plugins.py +0 -0
- {fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/test/gui/GUI_Test_Procedure.md +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: fprime-gds
|
3
|
-
Version: 4.0.
|
3
|
+
Version: 4.0.2a1
|
4
4
|
Summary: F Prime Flight Software Ground Data System layer
|
5
5
|
Author-email: Michael Starch <Michael.D.Starch@jpl.nasa.gov>, Thomas Boyer-Chammard <Thomas.Boyer.Chammard@jpl.nasa.gov>
|
6
6
|
License:
|
@@ -67,6 +67,7 @@ fprime-dp-write = "fprime_gds.executables.data_product_writer:main"
|
|
67
67
|
fprime-gds = "fprime_gds.executables.run_deployment:main"
|
68
68
|
fprime-prm-write = "fprime_gds.common.tools.params:main"
|
69
69
|
fprime-fpyc = "fprime_gds.common.fpy.main:main"
|
70
|
+
fprime-merge-dictionary = "fprime_gds.executables.dictionary_merge:main"
|
70
71
|
|
71
72
|
# For Pytest fixtures
|
72
73
|
[project.entry-points."pytest11"]
|
@@ -13,6 +13,7 @@ descriptor header will be passed on to the registered objects.
|
|
13
13
|
|
14
14
|
@bug No known bugs
|
15
15
|
"""
|
16
|
+
|
16
17
|
import logging
|
17
18
|
|
18
19
|
from fprime_gds.common.decoders.decoder import DecodingException
|
@@ -193,18 +194,23 @@ class Distributor(DataHandler):
|
|
193
194
|
self.__buf.extend(data)
|
194
195
|
|
195
196
|
(leftover_data, raw_msgs) = self.parse_into_raw_msgs_api(self.__buf)
|
196
|
-
assert
|
197
|
+
assert (
|
198
|
+
leftover_data == self.__buf
|
199
|
+
), "Leftover data is not equivalent to the remaining data in buffer"
|
197
200
|
|
198
201
|
for raw_msg in raw_msgs:
|
199
202
|
(length, data_desc, msg) = self.parse_raw_msg_api(raw_msg)
|
200
203
|
|
201
204
|
data_desc_key = data_desc_type.DataDescType(data_desc).name
|
202
|
-
|
205
|
+
decoders = self.__decoders[data_desc_key]
|
206
|
+
|
207
|
+
if not decoders:
|
208
|
+
LOGGER.warning(f"No decoder registered for: {data_desc_key}")
|
209
|
+
|
210
|
+
for d in decoders:
|
203
211
|
try:
|
204
212
|
d.data_callback(msg)
|
205
213
|
except DecodingException as dexc:
|
206
|
-
LOGGER.warning("Decoding error:
|
214
|
+
LOGGER.warning(f"Decoding error: {dexc}")
|
207
215
|
except Exception as exc:
|
208
|
-
LOGGER.warning("Parsing error:
|
209
|
-
else:
|
210
|
-
LOGGER.warning("No decoder registered for: %s", data_desc_type.DataDescType(data_desc).name)
|
216
|
+
LOGGER.warning(f"Parsing error: {exc}")
|
@@ -63,6 +63,7 @@ class StandardPipeline:
|
|
63
63
|
logging_prefix=None,
|
64
64
|
packet_spec=None,
|
65
65
|
packet_set_name=None,
|
66
|
+
data_logging_enabled=True
|
66
67
|
):
|
67
68
|
"""
|
68
69
|
Setup the standard pipeline for moving data from the middleware layer through the GDS layers using the standard
|
@@ -113,7 +114,7 @@ class StandardPipeline:
|
|
113
114
|
# Register distributor to client socket
|
114
115
|
self.client_socket.register(self.distributor)
|
115
116
|
# Final setup step is to make a logging directory, and register in the logger
|
116
|
-
if logging_prefix:
|
117
|
+
if logging_prefix and data_logging_enabled:
|
117
118
|
self.setup_logging(logging_prefix)
|
118
119
|
|
119
120
|
@property
|
@@ -7,6 +7,7 @@ telemetry and dictionaries.
|
|
7
7
|
|
8
8
|
:author: koran
|
9
9
|
"""
|
10
|
+
|
10
11
|
import signal
|
11
12
|
import time
|
12
13
|
from pathlib import Path
|
@@ -71,11 +72,12 @@ class IntegrationTestAPI(DataHandler):
|
|
71
72
|
# Copy dictionaries and binary file to output directory
|
72
73
|
if logpath is not None:
|
73
74
|
base_dir = Path(self.pipeline.dictionary_path).parents[1]
|
74
|
-
for subdir in [
|
75
|
+
for subdir in ["bin", "dict"]:
|
75
76
|
dir_path = base_dir / subdir
|
76
77
|
if dir_path.is_dir():
|
77
|
-
shutil.copytree(
|
78
|
-
|
78
|
+
shutil.copytree(
|
79
|
+
dir_path, Path(logpath) / subdir, dirs_exist_ok=True
|
80
|
+
)
|
79
81
|
|
80
82
|
# A predicate used as a filter to choose which events to log automatically
|
81
83
|
self.event_log_filter = self.get_event_pred()
|
@@ -84,7 +86,7 @@ class IntegrationTestAPI(DataHandler):
|
|
84
86
|
self.last_evr = None
|
85
87
|
|
86
88
|
def setup(self):
|
87
|
-
"""
|
89
|
+
"""Set up the API, assumes pipeline is now setup"""
|
88
90
|
self.pipeline.coders.register_event_consumer(self)
|
89
91
|
|
90
92
|
def teardown(self):
|
@@ -162,10 +164,10 @@ class IntegrationTestAPI(DataHandler):
|
|
162
164
|
fail_color = TestLogger.ORANGE
|
163
165
|
|
164
166
|
if value:
|
165
|
-
ast_msg = f
|
167
|
+
ast_msg = f"{ast_msg} succeeded: {msg}"
|
166
168
|
self.__log(ast_msg, TestLogger.GREEN)
|
167
169
|
else:
|
168
|
-
ast_msg = f
|
170
|
+
ast_msg = f"{ast_msg} failed: {msg}"
|
169
171
|
self.__log(ast_msg, fail_color)
|
170
172
|
|
171
173
|
if not expect:
|
@@ -209,7 +211,7 @@ class IntegrationTestAPI(DataHandler):
|
|
209
211
|
self.event_history.clear()
|
210
212
|
self.telemetry_history.clear()
|
211
213
|
msg = "Clearing Test Histories"
|
212
|
-
|
214
|
+
|
213
215
|
self.__log(msg, TestLogger.WHITE)
|
214
216
|
self.command_history.clear()
|
215
217
|
|
@@ -239,9 +241,9 @@ class IntegrationTestAPI(DataHandler):
|
|
239
241
|
dictionary = str(self.pipeline.dictionary_path)
|
240
242
|
|
241
243
|
try:
|
242
|
-
with open(dictionary,
|
244
|
+
with open(dictionary, "r") as file:
|
243
245
|
data = json.load(file)
|
244
|
-
return data[
|
246
|
+
return data["metadata"].get("deploymentName")
|
245
247
|
except FileNotFoundError:
|
246
248
|
msg = f"Error: File not found at path: {dictionary}"
|
247
249
|
self.__log(msg, TestLogger.YELLOW)
|
@@ -273,7 +275,7 @@ class IntegrationTestAPI(DataHandler):
|
|
273
275
|
count, channels=channels, history=history, start=start, timeout=timeout
|
274
276
|
)
|
275
277
|
if not result:
|
276
|
-
msg = f
|
278
|
+
msg = f"Failed to detect any data flow for {timeout} s."
|
277
279
|
self.__log(msg, TestLogger.RED)
|
278
280
|
assert False, msg
|
279
281
|
self.remove_telemetry_subhistory(history)
|
@@ -300,7 +302,7 @@ class IntegrationTestAPI(DataHandler):
|
|
300
302
|
config_file = self.get_config_file_path()
|
301
303
|
|
302
304
|
try:
|
303
|
-
with open(config_file,
|
305
|
+
with open(config_file, "r") as file:
|
304
306
|
result = json.load(file)
|
305
307
|
return result
|
306
308
|
except FileNotFoundError:
|
@@ -351,7 +353,7 @@ class IntegrationTestAPI(DataHandler):
|
|
351
353
|
if data:
|
352
354
|
try:
|
353
355
|
filepath = data["Svc.PrmDb.filename"]
|
354
|
-
if filepath.startswith(
|
356
|
+
if filepath.startswith("/"):
|
355
357
|
return filepath
|
356
358
|
else:
|
357
359
|
msg = f"Error: {filepath} did not start with a forward slash"
|
@@ -549,7 +551,15 @@ class IntegrationTestAPI(DataHandler):
|
|
549
551
|
return self.await_event_sequence(events, start=start, timeout=timeout)
|
550
552
|
return self.await_event(events, start=start, timeout=timeout)
|
551
553
|
|
552
|
-
def send_and_assert_command(
|
554
|
+
def send_and_assert_command(
|
555
|
+
self,
|
556
|
+
command,
|
557
|
+
args=[],
|
558
|
+
max_delay=None,
|
559
|
+
timeout=5,
|
560
|
+
events=None,
|
561
|
+
commander="cmdDisp",
|
562
|
+
):
|
553
563
|
"""
|
554
564
|
This helper will send a command and verify that the command was dispatched and completed
|
555
565
|
within the F' deployment. This helper can retroactively check that the delay between
|
@@ -566,7 +576,9 @@ class IntegrationTestAPI(DataHandler):
|
|
566
576
|
returns a list of the EventData objects found by the search
|
567
577
|
"""
|
568
578
|
cmd_id = self.translate_command_name(command)
|
569
|
-
dispatch = [
|
579
|
+
dispatch = [
|
580
|
+
self.get_event_pred(f"{commander}.OpCodeDispatched", [cmd_id, None])
|
581
|
+
]
|
570
582
|
complete = [self.get_event_pred(f"{commander}.OpCodeCompleted", [cmd_id])]
|
571
583
|
events = dispatch + (events if events else []) + complete
|
572
584
|
results = self.send_and_assert_event(command, args, events, timeout=timeout)
|
@@ -576,7 +588,6 @@ class IntegrationTestAPI(DataHandler):
|
|
576
588
|
assert delay < max_delay, msg
|
577
589
|
return results
|
578
590
|
|
579
|
-
|
580
591
|
######################################################################################
|
581
592
|
# Command Asserts
|
582
593
|
######################################################################################
|
@@ -652,14 +663,18 @@ class IntegrationTestAPI(DataHandler):
|
|
652
663
|
"""
|
653
664
|
if isinstance(channel, str):
|
654
665
|
ch_dict = self.pipeline.dictionaries.channel_name
|
655
|
-
matching = [
|
666
|
+
matching = [
|
667
|
+
ch_dict[name].get_id()
|
668
|
+
for name in ch_dict.keys()
|
669
|
+
if name.endswith(f".{channel}")
|
670
|
+
]
|
656
671
|
if channel in ch_dict:
|
657
672
|
return ch_dict[channel].get_id()
|
658
673
|
if force_component or not matching:
|
659
674
|
msg = f"The telemetry mnemonic, {channel}, wasn't in the dictionary"
|
660
675
|
raise KeyError(msg)
|
661
676
|
return matching
|
662
|
-
|
677
|
+
|
663
678
|
ch_dict = self.pipeline.dictionaries.channel_id
|
664
679
|
if channel in ch_dict:
|
665
680
|
return channel
|
@@ -689,7 +704,11 @@ class IntegrationTestAPI(DataHandler):
|
|
689
704
|
|
690
705
|
if not predicates.is_predicate(channel) and channel is not None:
|
691
706
|
channel = self.translate_telemetry_name(channel, force_component=False)
|
692
|
-
channel =
|
707
|
+
channel = (
|
708
|
+
predicates.is_a_member_of(channel)
|
709
|
+
if isinstance(channel, list)
|
710
|
+
else predicates.equal_to(channel)
|
711
|
+
)
|
693
712
|
|
694
713
|
if not predicates.is_predicate(value) and value is not None:
|
695
714
|
value = predicates.equal_to(value)
|
@@ -873,7 +892,11 @@ class IntegrationTestAPI(DataHandler):
|
|
873
892
|
"""
|
874
893
|
if isinstance(event, str):
|
875
894
|
event_dict = self.pipeline.dictionaries.event_name
|
876
|
-
matching = [
|
895
|
+
matching = [
|
896
|
+
event_dict[name].get_id()
|
897
|
+
for name in event_dict.keys()
|
898
|
+
if name.endswith(f".{event}")
|
899
|
+
]
|
877
900
|
if event in event_dict:
|
878
901
|
return event_dict[event].get_id()
|
879
902
|
if force_component or not matching:
|
@@ -910,7 +933,11 @@ class IntegrationTestAPI(DataHandler):
|
|
910
933
|
|
911
934
|
if not predicates.is_predicate(event) and event is not None:
|
912
935
|
event = self.translate_event_name(event, force_component=False)
|
913
|
-
event =
|
936
|
+
event = (
|
937
|
+
predicates.is_a_member_of(event)
|
938
|
+
if isinstance(event, list)
|
939
|
+
else predicates.equal_to(event)
|
940
|
+
)
|
914
941
|
|
915
942
|
if not predicates.is_predicate(args) and args is not None:
|
916
943
|
args = predicates.args_predicate(args)
|
@@ -1097,6 +1124,38 @@ class IntegrationTestAPI(DataHandler):
|
|
1097
1124
|
self.__assert_pred("Event count", count_pred, len(results), msg)
|
1098
1125
|
return results
|
1099
1126
|
|
1127
|
+
######################################################################################
|
1128
|
+
# File Uplink functions
|
1129
|
+
######################################################################################
|
1130
|
+
|
1131
|
+
def uplink_file_and_await_completion(self, file_path, destination=None, timeout=10):
|
1132
|
+
"""
|
1133
|
+
This function will upload a file and wait for its completion, awaiting for the
|
1134
|
+
FileReceived event.
|
1135
|
+
|
1136
|
+
Args:
|
1137
|
+
file_path: the path to the file to upload
|
1138
|
+
destination: the destination path for the uploaded file
|
1139
|
+
timeout: the maximum time to wait for the event
|
1140
|
+
"""
|
1141
|
+
self.uplink_file(file_path, destination)
|
1142
|
+
self.await_event("FileReceived", timeout=timeout)
|
1143
|
+
|
1144
|
+
def uplink_file(self, file_path, destination=None):
|
1145
|
+
"""
|
1146
|
+
This function will upload a file to the specified location.
|
1147
|
+
|
1148
|
+
Note: this will simply put the file on the outgoing queue. No guarantee
|
1149
|
+
is made on when the file will be delivered. To wait for the completion of
|
1150
|
+
the file uplink, use uplink_file_and_await_completion()
|
1151
|
+
|
1152
|
+
Args:
|
1153
|
+
file_path: the path to the file to upload
|
1154
|
+
"""
|
1155
|
+
uplink_file = Path(self.pipeline.up_store) / Path(file_path).name
|
1156
|
+
shutil.copy2(file_path, uplink_file)
|
1157
|
+
self.pipeline.files.uplinker.enqueue(str(uplink_file), destination)
|
1158
|
+
|
1100
1159
|
######################################################################################
|
1101
1160
|
# History Searches
|
1102
1161
|
######################################################################################
|
@@ -1207,11 +1266,13 @@ class IntegrationTestAPI(DataHandler):
|
|
1207
1266
|
return searcher.get_return_value()
|
1208
1267
|
time.sleep(0.1)
|
1209
1268
|
except self.TimeoutException:
|
1210
|
-
self.__log(
|
1269
|
+
self.__log(
|
1270
|
+
f"{name} timed out and ended unsuccessfully.", TestLogger.YELLOW
|
1271
|
+
)
|
1211
1272
|
finally:
|
1212
1273
|
signal.alarm(0)
|
1213
1274
|
else:
|
1214
|
-
self.__log(f
|
1275
|
+
self.__log(f"{name} ended unsuccessfully.", TestLogger.YELLOW)
|
1215
1276
|
return searcher.get_return_value()
|
1216
1277
|
|
1217
1278
|
def find_history_item(self, search_pred, history, start=None, timeout=0):
|
@@ -1365,7 +1426,9 @@ class IntegrationTestAPI(DataHandler):
|
|
1365
1426
|
self.log(f"Count search counted another item: {item}")
|
1366
1427
|
self.ret_val.append(item)
|
1367
1428
|
if self.count_pred(len(self.ret_val)):
|
1368
|
-
msg =
|
1429
|
+
msg = (
|
1430
|
+
f"Count search found a correct amount: {len(self.ret_val)}"
|
1431
|
+
)
|
1369
1432
|
self.log(msg, TestLogger.YELLOW)
|
1370
1433
|
return True
|
1371
1434
|
return False
|
@@ -851,6 +851,11 @@ class LogDeployParser(ParserBase):
|
|
851
851
|
"default": "INFO",
|
852
852
|
"help": "Set the logging level of GDS processes [default: %(default)s]",
|
853
853
|
},
|
854
|
+
("--disable-data-logging",): {
|
855
|
+
"action": "store_true",
|
856
|
+
"default": False,
|
857
|
+
"help": "Disable logging of each data item",
|
858
|
+
},
|
854
859
|
}
|
855
860
|
|
856
861
|
def handle_arguments(self, args, **kwargs):
|
@@ -1071,6 +1076,7 @@ class StandardPipelineParser(CompositeParser):
|
|
1071
1076
|
"packet_spec": args_ns.packet_spec,
|
1072
1077
|
"packet_set_name": args_ns.packet_set_name,
|
1073
1078
|
"logging_prefix": args_ns.logs,
|
1079
|
+
"data_logging_enabled": not args_ns.disable_data_logging
|
1074
1080
|
}
|
1075
1081
|
pipeline = pipeline if pipeline else StandardPipeline()
|
1076
1082
|
pipeline.transport_implementation = args_ns.connection_transport
|
@@ -0,0 +1,206 @@
|
|
1
|
+
""" fprime_gds.executables.dictionary_merge: script to merge two F Prime dictionaries """
|
2
|
+
|
3
|
+
import argparse
|
4
|
+
import functools
|
5
|
+
import json
|
6
|
+
import re
|
7
|
+
import sys
|
8
|
+
from pathlib import Path
|
9
|
+
|
10
|
+
|
11
|
+
def validate_metadata(metadata1, metadata2):
|
12
|
+
""" Check consistency between metadata blocks
|
13
|
+
|
14
|
+
The JSON dictionary has multiple fields in the metadata block. This function will check that there is consistency
|
15
|
+
between these two blocks.
|
16
|
+
|
17
|
+
Args:
|
18
|
+
metadata1: metadata from the first dictionary
|
19
|
+
metadata2: metadata from the second dictionary
|
20
|
+
"""
|
21
|
+
for field in ["projectVersion", "frameworkVersion", "dictionarySpecVersion"]:
|
22
|
+
value1 = metadata1[field]
|
23
|
+
value2 = metadata2[field]
|
24
|
+
if value1 != value2:
|
25
|
+
raise ValueError(f"Inconsistent metadata values for field '{field}'. ({value1} vs {value2})")
|
26
|
+
|
27
|
+
def validate_non_unique(non_unique1, non_unique2):
|
28
|
+
""" Validate non-unique definitions are consistent between dictionaries """
|
29
|
+
indexed_non_unique1 = {value.get("qualifiedName"): value for value in non_unique1}
|
30
|
+
|
31
|
+
for value2 in non_unique2:
|
32
|
+
value1 = indexed_non_unique1.get(value2["qualifiedName"], None)
|
33
|
+
if value1 is not None and value1 != value2:
|
34
|
+
raise ValueError(f"'{value2['qualifiedName']}' has inconsistent definitions")
|
35
|
+
|
36
|
+
def validate_unique(unique1, unique2):
|
37
|
+
""" Validate unique definitions have no duplication """
|
38
|
+
ids = {item.get("id", item.get("opcode", "")) for item in unique1}
|
39
|
+
names = {item.get("name") for item in unique1}
|
40
|
+
|
41
|
+
|
42
|
+
for value2 in unique2:
|
43
|
+
name = value2['name']
|
44
|
+
id = value2.get("id", value2.get("opcode", ""))
|
45
|
+
if name in names:
|
46
|
+
raise ValueError(f"'{name}' appears in both dictionaries")
|
47
|
+
if id and id in ids:
|
48
|
+
raise ValueError(f"ID/Opcode {id} used in both dictionaries")
|
49
|
+
|
50
|
+
|
51
|
+
def merge_metadata(meta1, meta2, name=None, permissive=False):
|
52
|
+
""" Merge JSON dictionary metadata blocks
|
53
|
+
|
54
|
+
The JSON dictionary starts with a metadata block. This function will merge the two metadata blocks preferring the
|
55
|
+
first when there is a discrepancy. 'name' will be supplied as the new name defaulting to "name1_name2_merged" when
|
56
|
+
not supplied. If 'permissive' is true, version discrepancies will be ignored otherwise this will throw a ValueError
|
57
|
+
if the versions do not match.
|
58
|
+
|
59
|
+
Args:
|
60
|
+
meta1: first metadata block
|
61
|
+
meta2: second metadata block
|
62
|
+
name: (optional) name for the new dictionary (Default: meta.name_meta2.name_merged)
|
63
|
+
permissive: (optional) True to allow version miss-matching. (Default: False)
|
64
|
+
Return:
|
65
|
+
merged metadata block
|
66
|
+
Throws:
|
67
|
+
ValueError on version miss-match without the permissive flag
|
68
|
+
"""
|
69
|
+
if not permissive:
|
70
|
+
validate_metadata(meta1, meta2)
|
71
|
+
if name is None:
|
72
|
+
name = f"{meta1.get('deploymentName', 'unknown')}_{meta2.get('deploymentName', 'unknown')}_merged"
|
73
|
+
return {
|
74
|
+
**meta1,
|
75
|
+
**{
|
76
|
+
"deploymentName": name
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
def merge_lists(list1, list2, validator):
|
81
|
+
""" Merge list-like entities
|
82
|
+
|
83
|
+
This will merge two list-like entities using the supplied validator.
|
84
|
+
|
85
|
+
Args:
|
86
|
+
list1: first list-like
|
87
|
+
list2: second list-like
|
88
|
+
validator: validate the lists are consistent or non-colliding
|
89
|
+
|
90
|
+
"""
|
91
|
+
validator(list1, list2)
|
92
|
+
singular = {item.get("qualifiedName", item.get("name", "")): item for item in list1 + list2}
|
93
|
+
return list(singular.values())
|
94
|
+
|
95
|
+
def merge_non_unique(non_unique1, non_unique2):
|
96
|
+
""" Merge the non-unique blocks in JSON dictionaries
|
97
|
+
|
98
|
+
JSON dictionaries have some non-unique definitions (e.g. "typeDefinitions") that must be merged ensuring
|
99
|
+
consistency but ignoring duplication. This function will create a superset of the two blocks. Inconsistent
|
100
|
+
definitions will result in a ValueError.
|
101
|
+
|
102
|
+
Args:
|
103
|
+
non_unique1: first non unique block
|
104
|
+
non_unique2: second non unique block
|
105
|
+
"""
|
106
|
+
return merge_lists(non_unique1, non_unique2, validate_non_unique)
|
107
|
+
|
108
|
+
|
109
|
+
def merge_unique(unique1, unique2):
|
110
|
+
""" Merge the unique blocks in JSON dictionaries
|
111
|
+
|
112
|
+
JSON dictionaries have some unique definitions (e.g. "eventDefinitions") that must be merged ensuring that entries
|
113
|
+
are not duplicated between the sets. This function will create a superset of the two blocks. Duplicated definitions
|
114
|
+
will result in a ValueError.
|
115
|
+
|
116
|
+
Args:
|
117
|
+
unique1: first unique block
|
118
|
+
unique2: second unique block
|
119
|
+
"""
|
120
|
+
return merge_lists(unique1, unique2, validate_unique)
|
121
|
+
|
122
|
+
|
123
|
+
def merge_dictionaries(dictionary1, dictionary2, name=None, permissive=False):
|
124
|
+
""" Merge two dictionaries
|
125
|
+
|
126
|
+
This will merge two JSON dictionaries' major top-level sections. Unknown fields will be preserved preferring
|
127
|
+
dictionary1's content for unknown fields.
|
128
|
+
|
129
|
+
Args:
|
130
|
+
dictionary1: dictionary 1's content
|
131
|
+
dictionary2: dictionary 2's content
|
132
|
+
name: new 'deploymentName' field
|
133
|
+
permissive: allow miss-matched dictionary versions
|
134
|
+
|
135
|
+
Return: merged dictionaries
|
136
|
+
|
137
|
+
"""
|
138
|
+
merge_metadata_fn = functools.partial(merge_metadata, name=name, permissive=permissive)
|
139
|
+
|
140
|
+
stages = [
|
141
|
+
("metadata", merge_metadata_fn),
|
142
|
+
("typeDefinitions", merge_non_unique),
|
143
|
+
("constants", merge_non_unique),
|
144
|
+
("commands", merge_unique),
|
145
|
+
("parameters", merge_unique),
|
146
|
+
("events", merge_unique),
|
147
|
+
("telemetryChannels", merge_unique),
|
148
|
+
("records", merge_unique),
|
149
|
+
("containers", merge_unique),
|
150
|
+
("telemetryPacketSets", merge_unique),
|
151
|
+
|
152
|
+
]
|
153
|
+
|
154
|
+
merged = {**dictionary2, **dictionary1}
|
155
|
+
for field, merger in stages:
|
156
|
+
object1 = dictionary1[field]
|
157
|
+
object2 = dictionary2[field]
|
158
|
+
try:
|
159
|
+
merged[field] = merger(object1, object2)
|
160
|
+
except ValueError as value_error:
|
161
|
+
raise ValueError(f"Merging '{field}' failed. {value_error}")
|
162
|
+
except KeyError as key_error:
|
163
|
+
raise ValueError(f"Malformed dictionary section '{field}'. Missing key: {key_error}")
|
164
|
+
return merged
|
165
|
+
|
166
|
+
def parse_arguments():
|
167
|
+
""" Parse arguments for this script """
|
168
|
+
parser = argparse.ArgumentParser(description="Merge two dictionaries")
|
169
|
+
parser.add_argument("--name", type=str, default=None, help="Name to use as the new 'deploymentName' field")
|
170
|
+
parser.add_argument("--output", type=Path, default=Path("MergedAppDictionary.json"),
|
171
|
+
help="Output dictionary path. Default: MergedAppDictionary.json")
|
172
|
+
parser.add_argument("--permissive", action="store_true", default=False,
|
173
|
+
help="Ignore discrepancies between dictionaries")
|
174
|
+
parser.add_argument("dictionary1", type=Path, help="Primary dictionary to merge")
|
175
|
+
parser.add_argument("dictionary2", type=Path, help="Secondary dictionary to merge")
|
176
|
+
|
177
|
+
args = parser.parse_args()
|
178
|
+
|
179
|
+
# Validate arguments
|
180
|
+
if args.name is not None and not re.match("[a-zA-Z_][a-zA-Z_0-9]*"):
|
181
|
+
raise ValueError(f"--name '{args.name}' is an invalid identifier")
|
182
|
+
if not args.dictionary1.exists():
|
183
|
+
raise ValueError(f"'{args.dictionary1}' does not exist")
|
184
|
+
if not args.dictionary2.exists():
|
185
|
+
raise ValueError(f"'{args.dictionary2}' does not exist")
|
186
|
+
return args
|
187
|
+
|
188
|
+
def main():
|
189
|
+
""" Main entry point """
|
190
|
+
try:
|
191
|
+
args = parse_arguments()
|
192
|
+
# Open dictionaries
|
193
|
+
with open(args.dictionary1, "r") as dictionary1_fh:
|
194
|
+
dictionary1 = json.load(dictionary1_fh)
|
195
|
+
with open(args.dictionary2, "r") as dictionary2_fh:
|
196
|
+
dictionary2 = json.load(dictionary2_fh)
|
197
|
+
output = merge_dictionaries(dictionary1, dictionary2, args.name, args.permissive)
|
198
|
+
with open(args.output, "w") as output_fh:
|
199
|
+
json.dump(output, output_fh, indent=2)
|
200
|
+
except Exception as exception:
|
201
|
+
print(f"[ERROR] {exception}", file=sys.stderr)
|
202
|
+
sys.exit(1)
|
203
|
+
sys.exit(0)
|
204
|
+
|
205
|
+
if __name__ == "__main__":
|
206
|
+
main()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: fprime-gds
|
3
|
-
Version: 4.0.
|
3
|
+
Version: 4.0.2a1
|
4
4
|
Summary: F Prime Flight Software Ground Data System layer
|
5
5
|
Author-email: Michael Starch <Michael.D.Starch@jpl.nasa.gov>, Thomas Boyer-Chammard <Thomas.Boyer.Chammard@jpl.nasa.gov>
|
6
6
|
License:
|
@@ -159,6 +159,7 @@ src/fprime_gds/executables/apps.py
|
|
159
159
|
src/fprime_gds/executables/cli.py
|
160
160
|
src/fprime_gds/executables/comm.py
|
161
161
|
src/fprime_gds/executables/data_product_writer.py
|
162
|
+
src/fprime_gds/executables/dictionary_merge.py
|
162
163
|
src/fprime_gds/executables/fprime_cli.py
|
163
164
|
src/fprime_gds/executables/run_deployment.py
|
164
165
|
src/fprime_gds/executables/tcpserver.py
|
@@ -3,6 +3,7 @@ fprime-cli = fprime_gds.executables.fprime_cli:main
|
|
3
3
|
fprime-dp-write = fprime_gds.executables.data_product_writer:main
|
4
4
|
fprime-fpyc = fprime_gds.common.fpy.main:main
|
5
5
|
fprime-gds = fprime_gds.executables.run_deployment:main
|
6
|
+
fprime-merge-dictionary = fprime_gds.executables.dictionary_merge:main
|
6
7
|
fprime-prm-write = fprime_gds.common.tools.params:main
|
7
8
|
fprime-seqgen = fprime_gds.common.tools.seqgen:main
|
8
9
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{fprime_gds-4.0.0a10 → fprime_gds-4.0.2a1}/src/fprime_gds/common/communication/adapters/__init__.py
RENAMED
File without changes
|