Skip to content

Commit 3aa9594

Browse files
committed
targets: Move file handling out of targets module
1 parent 14a65ef commit 3aa9594

File tree

4 files changed

+22
-89
lines changed

4 files changed

+22
-89
lines changed

src/mbed_tools/build/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"""Parses the Mbed configuration system and generates a CMake config script."""
66
import pathlib
77

8+
from mbed_tools.lib.json_helpers import decode_json_file
89
from mbed_tools.project import MbedProgram
910
from mbed_tools.targets import get_target_by_name
1011
from mbed_tools.build._internal.cmake_file import generate_mbed_config_cmake_file
@@ -23,7 +24,7 @@ def generate_config(target_name: str, toolchain: str, program: MbedProgram) -> p
2324
Returns:
2425
Path to the generated config file.
2526
"""
26-
target_build_attributes = get_target_by_name(target_name, program.mbed_os.targets_json_file)
27+
target_build_attributes = get_target_by_name(target_name, decode_json_file(program.mbed_os.targets_json_file))
2728
config = assemble_config(target_build_attributes, program.root, program.files.app_config_file)
2829
cmake_file_contents = generate_mbed_config_cmake_file(target_name, target_build_attributes, config, toolchain)
2930
cmake_config_file_path = program.files.cmake_config_file

src/mbed_tools/targets/_internal/target_attributes.py

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@
77
This information is parsed from the targets.json configuration file
88
found in the mbed-os repo.
99
"""
10-
import json
1110
import pathlib
12-
from json.decoder import JSONDecodeError
13-
from typing import Dict, Any, Set, Optional, cast
11+
from typing import Dict, Any, Set, Optional
1412

1513
from mbed_tools.lib.exceptions import ToolsError
14+
from mbed_tools.lib.json_helpers import decode_json_file
1615

1716
from mbed_tools.targets._internal.targets_json_parsers.accumulating_attribute_parser import (
1817
get_accumulating_attributes_for_target,
@@ -39,25 +38,22 @@ class TargetNotFoundError(TargetAttributesError):
3938
"""Target definition not found in targets.json."""
4039

4140

42-
def get_target_attributes(path_to_targets_json: pathlib.Path, target_name: str) -> dict:
41+
def get_target_attributes(targets_json_data: dict, target_name: str) -> dict:
4342
"""Retrieves attribute data taken from targets.json for a single target.
4443
4544
Args:
46-
path_to_targets_json: an absolute or relative path to the location of targets.json.
45+
targets_json_data: target definitions from targets.json
4746
target_name: the name of the target (often a Board's board_type).
4847
4948
Returns:
5049
A dictionary representation of the attributes for the target.
5150
5251
Raises:
53-
FileNotFoundError: path provided does not lead to targets.json
5452
ParsingTargetJSONError: error parsing targets.json
5553
TargetNotFoundError: there is no target attribute data found for that target.
5654
"""
57-
targets_json_path = path_to_targets_json
58-
all_targets_data = _read_json_file(targets_json_path)
59-
target_attributes = _extract_target_attributes(all_targets_data, target_name)
60-
target_attributes["labels"] = get_labels_for_target(all_targets_data, target_name).union(
55+
target_attributes = _extract_target_attributes(targets_json_data, target_name)
56+
target_attributes["labels"] = get_labels_for_target(targets_json_data, target_name).union(
6157
_extract_core_labels(target_attributes.get("core", None))
6258
)
6359
target_attributes["extra_labels"] = set(target_attributes.get("extra_labels", []))
@@ -70,26 +66,6 @@ def get_target_attributes(path_to_targets_json: pathlib.Path, target_name: str)
7066
return target_attributes
7167

7268

73-
def _read_json_file(path_to_file: pathlib.Path) -> dict:
74-
"""Reads the data from a json file.
75-
76-
Args:
77-
path_to_file: location of the json file.
78-
79-
Returns:
80-
A dictionary representation of all the data in the json file.
81-
82-
Raises:
83-
ParsingTargetJSONError: error parsing targets.json
84-
FileNotFoundError: path provided does not lead to a valid json file
85-
"""
86-
try:
87-
# mypy doesn't recognise that json.loads always returns a dictionary
88-
return cast(dict, json.loads(path_to_file.read_text()))
89-
except JSONDecodeError as json_err:
90-
raise ParsingTargetsJSONError(f"Invalid JSON found in '{path_to_file}'.") from json_err
91-
92-
9369
def _extract_target_attributes(all_targets_data: Dict[str, Any], target_name: str) -> dict:
9470
"""Extracts the definition for a particular target from all the targets in targets.json.
9571
@@ -127,7 +103,7 @@ def _extract_core_labels(target_core: Optional[str]) -> Set[str]:
127103
if either core is undefined or no labels found for the core.
128104
"""
129105
if target_core:
130-
mbed_os_metadata = _read_json_file(MBED_OS_METADATA_FILE)
106+
mbed_os_metadata = decode_json_file(MBED_OS_METADATA_FILE)
131107
return set(mbed_os_metadata["CORE_LABELS"].get(target_core, []))
132108
return set()
133109

src/mbed_tools/targets/get_target.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,38 @@
77
An instance of `mbed_tools.targets.target.Target`
88
can be retrieved by calling one of the public functions.
99
"""
10-
import pathlib
11-
1210
from mbed_tools.targets.exceptions import TargetError
1311
from mbed_tools.targets._internal import target_attributes
1412

1513

16-
def get_target_by_name(name: str, path_to_targets_json: pathlib.Path) -> dict:
14+
def get_target_by_name(name: str, targets_json_data: dict) -> dict:
1715
"""Returns a dictionary of attributes for the target whose name matches the name given.
1816
1917
The target is as defined in the targets.json file found in the Mbed OS library.
2018
2119
Args:
2220
name: the name of the Target to be returned
23-
path_to_targets_json: path to a targets.json file containing target definitions
21+
targets_json_data: target definitions from targets.json
2422
2523
Raises:
2624
TargetError: an error has occurred while fetching target
2725
"""
2826
try:
29-
return target_attributes.get_target_attributes(path_to_targets_json, name)
27+
return target_attributes.get_target_attributes(targets_json_data, name)
3028
except (FileNotFoundError, target_attributes.TargetAttributesError) as e:
3129
raise TargetError(e) from e
3230

3331

34-
def get_target_by_board_type(board_type: str, path_to_targets_json: pathlib.Path) -> dict:
32+
def get_target_by_board_type(board_type: str, targets_json_data: dict) -> dict:
3533
"""Returns the target whose name matches a board's build_type.
3634
3735
The target is as defined in the targets.json file found in the Mbed OS library.
3836
3937
Args:
4038
board_type: a board's board_type (see `mbed_tools.targets.board.Board`)
41-
path_to_targets_json: path to a targets.json file containing target definitions
39+
targets_json_data: target definitions from targets.json
4240
4341
Raises:
4442
TargetError: an error has occurred while fetching target
4543
"""
46-
return get_target_by_name(board_type, path_to_targets_json)
44+
return get_target_by_name(board_type, targets_json_data)

tests/targets/_internal/test_target_attributes.py

Lines changed: 7 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,12 @@
33
# SPDX-License-Identifier: Apache-2.0
44
#
55
"""Tests for `mbed_tools.targets.target_attributes`."""
6-
import pathlib
7-
import tempfile
86
from unittest import TestCase, mock
97

108
from mbed_tools.targets._internal.exceptions import TargetsJsonConfigurationError
119
from mbed_tools.targets._internal.target_attributes import (
12-
ParsingTargetsJSONError,
1310
TargetNotFoundError,
1411
get_target_attributes,
15-
_read_json_file,
1612
_extract_target_attributes,
1713
_extract_core_labels,
1814
_apply_config_overrides,
@@ -55,64 +51,26 @@ def test_target_private(self):
5551
_extract_target_attributes(all_targets_data, "Target_1"),
5652

5753

58-
class TestReadTargetsJSON(TestCase):
59-
def test_valid_path(self):
60-
contents = """{
61-
"Target_Name": {
62-
"attribute_1": []
63-
}
64-
}"""
65-
with tempfile.TemporaryDirectory() as directory:
66-
json_file = pathlib.Path(directory, "targets.json")
67-
json_file.write_text(contents)
68-
result = _read_json_file(json_file)
69-
70-
self.assertEqual(type(result), dict)
71-
72-
def test_invalid_path(self):
73-
json_file = pathlib.Path("i_dont_exist")
74-
75-
with self.assertRaises(FileNotFoundError):
76-
_read_json_file(json_file)
77-
78-
def test_malformed_json(self):
79-
contents = """{
80-
"Target_Name": {
81-
[]
82-
}
83-
}"""
84-
with tempfile.TemporaryDirectory() as directory:
85-
json_file = pathlib.Path(directory, "targets.json")
86-
json_file.write_text(contents)
87-
88-
with self.assertRaises(ParsingTargetsJSONError):
89-
_read_json_file(json_file)
90-
91-
9254
class TestGetTargetAttributes(TestCase):
93-
@mock.patch("mbed_tools.targets._internal.target_attributes._read_json_file")
9455
@mock.patch("mbed_tools.targets._internal.target_attributes._extract_target_attributes")
9556
@mock.patch("mbed_tools.targets._internal.target_attributes.get_labels_for_target")
9657
@mock.patch("mbed_tools.targets._internal.target_attributes._extract_core_labels")
97-
def test_gets_attributes_for_target(
98-
self, extract_core_labels, get_labels_for_target, extract_target_attributes, read_json_file
99-
):
100-
targets_json_path = pathlib.Path("mbed-os/targets/targets.json")
58+
def test_gets_attributes_for_target(self, extract_core_labels, get_labels_for_target, extract_target_attributes):
59+
targets_json_data = {"attrs": "vals"}
10160
target_name = "My_Target"
10261
build_attributes = {"attribute": "value"}
10362
extract_target_attributes.return_value = build_attributes
10463

105-
result = get_target_attributes(targets_json_path, target_name)
64+
result = get_target_attributes(targets_json_data, target_name)
10665

107-
read_json_file.assert_called_once_with(targets_json_path)
108-
extract_target_attributes.assert_called_once_with(read_json_file.return_value, target_name)
109-
get_labels_for_target.assert_called_once_with(read_json_file.return_value, target_name)
66+
extract_target_attributes.assert_called_once_with(targets_json_data, target_name)
67+
get_labels_for_target.assert_called_once_with(targets_json_data, target_name)
11068
extract_core_labels.assert_called_once_with(build_attributes.get("core", None))
11169
self.assertEqual(result, extract_target_attributes.return_value)
11270

11371

11472
class TestExtractCoreLabels(TestCase):
115-
@mock.patch("mbed_tools.targets._internal.target_attributes._read_json_file")
73+
@mock.patch("mbed_tools.targets._internal.target_attributes.decode_json_file")
11674
def test_extract_core(self, read_json_file):
11775
core_labels = ["FOO", "BAR"]
11876
metadata = {"CORE_LABELS": {"core_name": core_labels}}
@@ -127,7 +85,7 @@ def test_no_core(self):
12785
result = _extract_core_labels(None)
12886
self.assertEqual(result, set())
12987

130-
@mock.patch("mbed_tools.targets._internal.target_attributes._read_json_file")
88+
@mock.patch("mbed_tools.targets._internal.target_attributes.decode_json_file")
13189
def test_no_labels(self, read_json_file):
13290
metadata = {"CORE_LABELS": {"not_the_same_core": []}}
13391
read_json_file.return_value = metadata

0 commit comments

Comments
 (0)