Пример #1
0
def _assemble_config_from_sources_and_lib_files(
        target_attributes: dict,
        mbed_lib_files: Iterable[Path],
        mbed_app_file: Optional[Path] = None) -> Config:
    previous_cumulative_data = None
    target_source = Source.from_target(target_attributes)
    current_cumulative_data = CumulativeData.from_sources([target_source])
    while previous_cumulative_data != current_cumulative_data:
        current_labels = current_cumulative_data.labels | current_cumulative_data.extra_labels
        filtered_files = _filter_files(mbed_lib_files, current_labels,
                                       current_cumulative_data.features,
                                       current_cumulative_data.components)
        mbed_lib_sources = [
            Source.from_mbed_lib(file, current_labels)
            for file in filtered_files
        ]
        all_sources = [target_source] + mbed_lib_sources
        if mbed_app_file:
            all_sources = all_sources + [
                Source.from_mbed_app(mbed_app_file, current_labels)
            ]

        previous_cumulative_data = current_cumulative_data
        current_cumulative_data = CumulativeData.from_sources(all_sources)

    _update_target_attributes(target_attributes, current_cumulative_data)

    return Config.from_sources(all_sources)
Пример #2
0
    def test_from_mbed_lib(self):
        with tempfile.TemporaryDirectory() as directory:
            data = {
                "name": "foo",
                "config": {
                    "a-number": 123,
                    "a-bool": {
                        "help": "Simply a boolean",
                        "value": True
                    }
                },
                "target_overrides": {
                    "*": {
                        "a-number": 456,
                        "target.features_add": ["FOO"]
                    },
                    "NOT_THIS_TARGET": {
                        "a-string": "foo",
                        "target.features_add": ["BAR"]
                    },
                    "THIS_TARGET": {
                        "a-bool": False,
                        "other-lib.something-else": "blah"
                    },
                },
                "macros": ["MACRO=1"],
            }
            file = pathlib.Path(directory, "mbed_lib.json")
            file.write_text(json.dumps(data))

            subject = Source.from_mbed_lib(file, ["THIS_TARGET"])

        self.assertEqual(
            subject,
            Source(
                human_name=f"File: {file}",
                config={
                    "foo.a-number": 123,
                    "foo.a-bool": {
                        "help": "Simply a boolean",
                        "value": True
                    }
                },
                overrides={
                    "foo.a-number": 456,
                    "foo.a-bool": False,
                    "other-lib.something-else": "blah",
                    "target.features_add": ["FOO"],
                },
                macros=["MACRO=1"],
            ),
        )
Пример #3
0
    def test_from_mbed_app(self):
        with tempfile.TemporaryDirectory() as directory:
            data = {
                "config": {
                    "a-bool": False,
                    "a-number": {
                        "help": "Simply a number",
                        "value": 0
                    }
                },
                "target_overrides": {
                    "*": {
                        "a-bool": True,
                        "target.features_add": ["HAT"]
                    },
                    "NOT_THIS_TARGET": {
                        "a-number": 999,
                        "target.features_add": ["BOAT"]
                    },
                    "THIS_TARGET": {
                        "a-number": 2,
                        "some-lib.something-else": "blah"
                    },
                },
                "macros": ["SOME_MACRO=2"],
            }
            file = pathlib.Path(directory, "mbed_app.json")
            file.write_text(json.dumps(data))

            subject = Source.from_mbed_app(file, ["THIS_TARGET"])

        self.assertEqual(
            subject,
            Source(
                human_name=f"File: {file}",
                config={
                    "app.a-bool": False,
                    "app.a-number": {
                        "help": "Simply a number",
                        "value": 0
                    }
                },
                overrides={
                    "app.a-number": 2,
                    "app.a-bool": True,
                    "some-lib.something-else": "blah",
                    "target.features_add": ["HAT"],
                },
                macros=["SOME_MACRO=2"],
            ),
        )
Пример #4
0
def _assemble_config_from_sources_and_lib_files(
        target_source: Source,
        mbed_lib_files: Iterable[Path],
        mbed_app_file: Optional[Path] = None) -> Config:
    previous_cumulative_data = None
    current_cumulative_data = CumulativeData.from_sources([target_source])
    while previous_cumulative_data != current_cumulative_data:
        filtered_files = _filter_files(mbed_lib_files, current_cumulative_data)
        mbed_lib_sources = [
            Source.from_mbed_lib(file, current_cumulative_data.labels)
            for file in filtered_files
        ]
        all_sources = [target_source] + mbed_lib_sources
        if mbed_app_file:
            all_sources = all_sources + [
                Source.from_mbed_app(mbed_app_file,
                                     current_cumulative_data.labels)
            ]
        previous_cumulative_data = current_cumulative_data
        current_cumulative_data = CumulativeData.from_sources(all_sources)

    return Config.from_sources(all_sources)
Пример #5
0
    def test_from_target(self):
        # Warning: Target is a dataclass and dataclasses provide no type safety when mocking
        target = dict(
            features={"feature_1"},
            components={"component_1"},
            labels={"label_1"},
            extra_labels={"label_2"},
            config={
                "foo": "bar",
                "target.bool": True
            },
            macros=["MACRO_A"],
            c_lib="std",
            printf_lib="minimal-printf",
        )

        subject = Source.from_target(target)

        self.assertEqual(
            subject,
            Source(
                human_name=f"mbed_target.Target for {target}",
                config={
                    "target.foo": "bar",
                    "target.bool": True
                },
                overrides={
                    "target.features": target["features"],
                    "target.components": target["components"],
                    "target.labels": target["labels"],
                    "target.extra_labels": target["extra_labels"],
                    "target.macros": target["macros"],
                    "target.c_lib": target["c_lib"],
                    "target.printf_lib": target["printf_lib"],
                },
                macros=[],
            ),
        )
Пример #6
0
def assemble_config(mbed_target: str, mbed_program_directory: Path) -> Config:
    """Assemble Config for given target and program directory.

    The structure and configuration of MbedOS requires us to do multiple passes over
    configuration files, as each pass might affect which configuration files should be included
    in the final configuration.
    """
    target_source = Source.from_target(mbed_target, mbed_program_directory)
    mbed_lib_files = find_files("mbed_lib.json", mbed_program_directory)
    mbed_program = MbedProgram.from_existing(mbed_program_directory)
    mbed_app_file = mbed_program.files.app_config_file
    return _assemble_config_from_sources_and_lib_files(target_source,
                                                       mbed_lib_files,
                                                       mbed_app_file)
Пример #7
0
    def test_assembles_config_using_all_relevant_files(self):
        target = {
            "config": {
                "foo": None
            },
            "macros": {},
            "labels": set("A"),
            "extra_labels": set(),
            "features": set("RED"),
            "components": set(),
            "c_lib": "std",
            "printf_lib": "minimal-printf",
        }
        mbed_lib_files = [
            {
                "path": Path("TARGET_A", "mbed_lib.json"),
                "json_contents": {
                    "name": "a",
                    "config": {
                        "number": 123
                    },
                    "target_overrides": {
                        "*": {
                            "target.features_add": ["RED"]
                        }
                    },
                },
            },
            {
                "path": Path("subdir", "FEATURE_RED", "mbed_lib.json"),
                "json_contents": {
                    "name": "red",
                    "config": {
                        "bool": False
                    },
                    "target_overrides": {
                        "A": {
                            "bool": True,
                            "target.features_add": ["BLUE"],
                            "target.components_add": ["LEG"]
                        }
                    },
                    "macros": ["RED_MACRO"],
                },
            },
            {
                "path": Path("COMPONENT_LEG", "mbed_lib.json"),
                "json_contents": {
                    "name": "leg",
                    "config": {
                        "number-of-fingers": 5
                    },
                    "macros": ["LEG_MACRO"]
                },
            },
        ]
        unused_mbed_lib_file = {
            "path": Path("subdir", "FEATURE_BROWN", "mbed_lib.json"),
            "json_contents": {
                "name": "brown",
                "target_overrides": {
                    "*": {
                        "red.bool": "DON'T USE ME"
                    }
                },
                "macros": ["DONT_USE_THIS_MACRO"],
            },
        }
        mbed_app_file = {
            "path": Path("mbed_app.json"),
            "json_contents": {
                "target_overrides": {
                    "*": {
                        "target.foo": "bar"
                    }
                }
            },
        }

        with TemporaryDirectory() as directory:
            created_mbed_lib_files = create_files(directory, mbed_lib_files)
            created_mbed_app_file = create_files(directory, [mbed_app_file])[0]
            create_files(directory, [unused_mbed_lib_file])

            subject = _assemble_config_from_sources_and_lib_files(
                target, find_files("mbed_lib.json", Path(directory)),
                created_mbed_app_file)

            mbed_lib_sources = [
                Source.from_mbed_lib(Path(directory, file), ["A"])
                for file in created_mbed_lib_files
            ]
            mbed_app_source = Source.from_mbed_app(created_mbed_app_file,
                                                   ["A"])
            expected_config = Config.from_sources(
                [Source.from_target(target)] + mbed_lib_sources +
                [mbed_app_source])

            self.assertEqual(subject, expected_config)