def assemble_config(target_attributes: dict, search_paths: Iterable[Path],
                    mbed_app_file: Optional[Path]) -> Config:
    """Assemble config for given target and program directory.

    Mbed library and application specific config parameters are parsed from mbed_lib.json and mbed_app.json files
    located in the project source tree.
    The config files contain sets of "labels" which correspond to directory names in the mbed-os source tree. These
    labels are used to determine which mbed_lib.json files to include in the final configuration.

    The mbed_app.json config overrides must be applied after all the mbed_lib.json files have been parsed.
    Unfortunately, mbed_app.json may also contain filter labels to tell us which mbed libs we're depending on.
    This means we have to collect the filter labels from mbed_app.json before parsing any other config files.
    Then we parse all the required mbed_lib config and finally apply the app overrides.

    Args:
        target_attributes: Mapping of target specific config parameters.
        search_paths: Iterable of paths to search for mbed_lib.json files.
        mbed_app_file: The path to mbed_app.json. This can be None.
    """
    mbed_lib_files = list(
        set(
            itertools.chain.from_iterable(
                find_files("mbed_lib.json",
                           path.absolute().resolve())
                for path in search_paths)))
    return _assemble_config_from_sources(target_attributes, mbed_lib_files,
                                         mbed_app_file)
    def test_updates_target_labels_from_config(self):
        target = {
            "config": {"foo": None},
            "macros": {"NO"},
            "labels": {"A"},
            "extra_labels": set(),
            "features": set(),
            "components": set(),
            "c_lib": "std",
            "printf_lib": "minimal-printf",
        }
        mbed_lib_files = [
            {
                "path": Path("TARGET_A", "mbed_lib.json"),
                "json_contents": {"name": "a", "target_overrides": {"*": {"target.features_add": ["RED"]}}},
            },
            {
                "path": Path("subdir", "FEATURE_RED", "mbed_lib.json"),
                "json_contents": {
                    "name": "red",
                    "target_overrides": {
                        "A": {
                            "target.macros_remove": ["NO"],
                            "target.features_add": ["BLUE"],
                            "target.components_add": ["LEG"],
                        }
                    },
                    "macros": ["RED_MACRO"],
                },
            },
        ]
        mbed_app_file = {
            "path": Path("mbed_app.json"),
            "json_contents": {
                "target_overrides": {
                    "*": {
                        "target.foo": "bar",
                        "target.labels_add": ["PICKLE"],
                        "target.extra_labels_add": ["EXTRA_HOT"],
                        "target.macros_add": ["TICKER"],
                    }
                }
            },
        }

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

            config = _assemble_config_from_sources(
                target, find_files("mbed_lib.json", Path(directory)), created_mbed_app_file
            )

            assert config["features"] == {"RED", "BLUE"}
            assert config["components"] == {"LEG"}
            assert config["extra_labels"] == {"EXTRA_HOT"}
            assert config["labels"] == {"A", "PICKLE"}
            assert config["macros"] == {"TICKER", "RED_MACRO"}
Exemple #3
0
def assemble_config(target_attributes: dict, mbed_program_directory: Path,
                    mbed_app_file: Optional[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.
    """
    mbed_lib_files = find_files("mbed_lib.json", mbed_program_directory)
    return _assemble_config_from_sources_and_lib_files(target_attributes,
                                                       mbed_lib_files,
                                                       mbed_app_file)
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)
    def test_respects_legacy_filters(self):
        matching_paths = [
            Path("file.txt"),
        ]
        excluded_paths = [
            Path("TESTS", "file.txt"),
            Path("bar", "TEST_APPS"
                 "file.txt"),
        ]
        with create_files(matching_paths + excluded_paths) as directory:
            subject = find_files("file.txt", directory)

        self.assertEqual(len(subject), len(matching_paths))
        for path in matching_paths:
            self.assertIn(Path(directory, path), subject)
    def test_finds_files_by_name(self):
        matching_paths = [
            Path("file.txt"),
            Path("sub_directory", "file.txt"),
        ]
        excluded_paths = [
            Path("not_interested.txt"),
            Path("sub_directory", "not_interested.txt"),
        ]

        with create_files(matching_paths + excluded_paths) as directory:
            subject = find_files("file.txt", directory)

        self.assertEqual(len(subject), len(matching_paths))
        for path in matching_paths:
            self.assertIn(Path(directory, path), subject)
    def test_respects_mbedignore(self):
        matching_paths = [
            Path("file.txt"),
        ]
        excluded_paths = [
            Path("foo", "file.txt"),
            Path("bar", "file.txt"),
        ]
        with create_files(matching_paths + excluded_paths) as directory:
            Path(directory, ".mbedignore").write_text("foo/*")
            Path(directory, "bar", ".mbedignore").write_text("*")

            subject = find_files("file.txt", directory)

        self.assertEqual(len(subject), len(matching_paths))
        for path in matching_paths:
            self.assertIn(Path(directory, path), subject)
Exemple #8
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)
    def test_assembles_config_using_all_relevant_files(self):
        target = {
            "config": {
                "foo": {
                    "value": None
                }
            },
            "macros": [],
            "labels": ["A"],
            "extra_labels": [],
            "features": ["RED"],
            "components": [],
            "c_lib": "std",
            "printf_lib": "minimal-printf",
        }
        mbed_lib_files = [
            {
                "path": Path("subdir", "FEATURE_RED", "mbed_lib.json"),
                "json_contents": {
                    "name": "red",
                    "config": {
                        "bool": {
                            "value": False
                        }
                    },
                    "target_overrides": {
                        "A": {
                            "bool": True,
                            "target.features_add": ["BLUE"],
                            "target.components_add": ["LEG"]
                        }
                    },
                    "macros": ["RED_MACRO"],
                },
            },
            {
                "path": Path("TARGET_A", "mbed_lib.json"),
                "json_contents": {
                    "name": "a",
                    "config": {
                        "number": {
                            "value": 123
                        }
                    },
                    "target_overrides": {
                        "*": {
                            "target.features_add": ["RED"]
                        }
                    },
                },
            },
            {
                "path": Path("COMPONENT_LEG", "mbed_lib.json"),
                "json_contents": {
                    "name": "leg",
                    "config": {
                        "number-of-fingers": {
                            "value": 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(
                target, find_files("mbed_lib.json", Path(directory)),
                created_mbed_app_file)

            mbed_lib_sources = [
                prepare(decode_json_file(Path(directory, file)),
                        target_filters=["A"])
                for file in created_mbed_lib_files
            ]
            mbed_app_source = prepare(decode_json_file(
                Path(directory, created_mbed_app_file)),
                                      target_filters=["A"])
            expected_config = Config(prepare(target, source_name="target"))
            for source in mbed_lib_sources + [mbed_app_source]:
                expected_config.update(source)

            subject["config"].sort(key=lambda x: x.name)
            expected_config["config"].sort(key=lambda x: x.name)
            assert subject == expected_config