Skip to content

Commit f534caa

Browse files
committed
Enhancements
* Replace call with check_call to throw exception on failure * Check if binaries actually been changes before calling git commit * Docstrings for all functions * Small refactor
1 parent 92cc3d0 commit f534caa

File tree

1 file changed

+147
-69
lines changed

1 file changed

+147
-69
lines changed

tools/psa/release.py

Lines changed: 147 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -21,140 +21,222 @@
2121
import shutil
2222
from argparse import ArgumentParser
2323

24-
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
24+
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__),
25+
os.pardir, os.pardir))
2526
sys.path.insert(0, ROOT)
2627
from tools.targets import Target, TARGET_MAP, TARGET_NAMES
2728

2829
MAKE_PY_LOCATTION = os.path.join(ROOT, 'tools', 'make.py')
2930
TEST_PY_LOCATTION = os.path.join(ROOT, 'tools', 'test.py')
30-
MBED_PSA_TESTS = '*psa-spm*,*psa-crypto_access_control'
3131
TFM_MBED_APP = os.path.join(ROOT, 'tools', 'psa', 'tfm', 'mbed_app.json')
32+
MBED_PSA_TESTS = '*psa-spm*,*psa-crypto_access_control'
3233
TFM_TESTS = {
3334
'*psa-spm_smoke': ['USE_PSA_TEST_PARTITIONS', 'USE_SMOKE_TESTS_PART1'],
3435
'*psa-spm_client': ['USE_PSA_TEST_PARTITIONS', 'USE_CLIENT_TESTS_PART1'],
35-
'*psa-spm_server': ['USE_PSA_TEST_PARTITIONS', 'USE_SERVER_TESTS_PART1', 'USE_SERVER_TESTS_PART2'],
36-
'*psa-crypto_access_control': ['USE_PSA_TEST_PARTITIONS', 'USE_CRYPTO_ACL_TEST']
36+
'*psa-spm_server': ['USE_PSA_TEST_PARTITIONS', 'USE_SERVER_TESTS_PART1',
37+
'USE_SERVER_TESTS_PART2'],
38+
'*psa-crypto_access_control': ['USE_PSA_TEST_PARTITIONS',
39+
'USE_CRYPTO_ACL_TEST']
3740
}
3841

3942

40-
def _psa_backend(target_name):
41-
return 'TFM' if 'TFM' in Target.get_target(target_name).labels else 'MBED_SPM'
43+
def _psa_backend(target):
44+
"""
45+
Returns a target PSA backend.
46+
47+
:param target: Target name as in targets.json
48+
:return: PSA backend as string (TFM/MBED_SPM)
49+
"""
50+
return 'TFM' if 'TFM' in Target.get_target(target).labels else 'MBED_SPM'
51+
52+
53+
def _get_target_info(target):
54+
"""
55+
Creates a PSA target tuple with default toolchain and
56+
artifact delivery directory.
57+
58+
:param target: Target name.
59+
:return: tuple (target, toolchain, delivery directory).
60+
"""
61+
delivery_dir = os.path.join(ROOT, 'targets',
62+
TARGET_MAP[target].delivery_dir)
63+
64+
if not os.path.exists(delivery_dir):
65+
raise Exception("{} does not have delivery_dir".format(target))
66+
67+
return tuple([TARGET_MAP[target].name,
68+
TARGET_MAP[target].default_toolchain,
69+
delivery_dir])
4270

4371

44-
def get_mbed_official_psa_release():
72+
def get_mbed_official_psa_release(target=None):
73+
"""
74+
Creates a list of PSA targets with default toolchain and
75+
artifact delivery directory.
76+
77+
:param target: Ask for specific target, None for all targets.
78+
:return: List of tuples (target, toolchain, delivery directory).
79+
"""
4580
psa_targets_release_list = []
46-
psa_secure_targets = [t for t in TARGET_NAMES if Target.get_target(t).is_PSA_secure_target]
47-
for t in psa_secure_targets:
48-
delivery_dir = os.path.join(ROOT, 'targets', TARGET_MAP[t].delivery_dir)
49-
if not os.path.exists(delivery_dir):
50-
raise Exception("{} does not have delivery_dir".format(TARGET_MAP[t].name))
51-
psa_targets_release_list.append(
52-
tuple(
53-
[
54-
TARGET_MAP[t].name,
55-
TARGET_MAP[t].default_toolchain,
56-
delivery_dir,
57-
]
58-
)
59-
)
81+
psa_secure_targets = [t for t in TARGET_NAMES if
82+
Target.get_target(t).is_PSA_secure_target]
83+
if target is not None:
84+
if target not in psa_secure_targets:
85+
raise Exception("{} is not a PSA secure target".format(target))
86+
psa_targets_release_list.append(_get_target_info(target))
87+
else:
88+
for t in psa_secure_targets:
89+
psa_targets_release_list.append(_get_target_info(target))
6090

6191
return psa_targets_release_list
6292

6393

6494
def create_mbed_ignore(build_dir):
95+
"""
96+
Creates a .mbedignore file in a given directory.
97+
98+
:param build_dir: Directory to create .mbedignore file.
99+
"""
65100
with open(os.path.join(build_dir, '.mbedignore'), 'w') as f:
66101
f.write('*\n')
67102

68103

69104
def build_mbed_spm_platform(target, toolchain, profile='release'):
70-
subprocess.call([
105+
"""
106+
Builds Secure images for MBED-SPM target.
107+
108+
:param target: target to be built.
109+
:param toolchain: toolchain to be used.
110+
:param profile: build profile.
111+
"""
112+
subprocess.check_call([
71113
sys.executable, '-u', TEST_PY_LOCATTION,
72114
'--greentea',
73115
'--profile', profile,
74116
'-t', toolchain,
75117
'-m', target,
76118
'--source', ROOT,
77119
'--build', os.path.join(ROOT, 'BUILD', 'tests', target),
78-
'--test-spec', os.path.join(ROOT, 'BUILD', 'tests', target, 'test_spec.json'),
79-
'--build-data', os.path.join(ROOT, 'BUILD', 'tests', target, 'build_data.json'),
120+
'--test-spec', os.path.join(ROOT, 'BUILD', 'tests',
121+
target, 'test_spec.json'),
122+
'--build-data', os.path.join(ROOT, 'BUILD', 'tests',
123+
target, 'build_data.json'),
80124
'-n', MBED_PSA_TESTS
81-
])
125+
], stdout=subprocess.PIPE)
82126

83-
subprocess.call([
127+
subprocess.check_call([
84128
sys.executable, '-u', MAKE_PY_LOCATTION,
85129
'-t', toolchain,
86130
'-m', target,
87131
'--profile', profile,
88132
'--source', ROOT,
89133
'--build', os.path.join(ROOT, 'BUILD', target),
90134
'--artifact-name', 'psa_release_1.0'
91-
])
135+
], stdout=subprocess.PIPE)
92136

93137

94138
def _tfm_test_defines(test):
139+
"""
140+
Creates a define list to enable test partitions on TF-M.
141+
142+
:param test: Test name.
143+
:return: List of defines with a leading -D.
144+
"""
95145
return ['-D{}'.format(define) for define in TFM_TESTS[test]]
96146

97147

98148
def build_tfm_platform(target, toolchain, profile='release'):
149+
"""
150+
Builds Secure images for TF-M target.
151+
152+
:param target: target to be built.
153+
:param toolchain: toolchain to be used.
154+
:param profile: build profile.
155+
"""
99156
for test in TFM_TESTS.keys():
100-
subprocess.call([
157+
subprocess.check_call([
101158
sys.executable, '-u', TEST_PY_LOCATTION,
102159
'--greentea',
103160
'--profile', profile,
104161
'-t', toolchain,
105162
'-m', target,
106163
'--source', ROOT,
107164
'--build', os.path.join(ROOT, 'BUILD', 'tests', target),
108-
'--test-spec', os.path.join(ROOT, 'BUILD', 'tests', target, 'test_spec.json'),
109-
'--build-data', os.path.join(ROOT, 'BUILD', 'tests', target, 'build_data.json'),
110-
'--app-config', TFM_MBED_APP, '-n', test] + _tfm_test_defines(test))
111-
112-
subprocess.call([
165+
'--test-spec', os.path.join(ROOT, 'BUILD', 'tests',
166+
target, 'test_spec.json'),
167+
'--build-data', os.path.join(ROOT, 'BUILD', 'tests',
168+
target, 'build_data.json'),
169+
'--app-config', TFM_MBED_APP, '-n', test] + _tfm_test_defines(test),
170+
stdout=subprocess.PIPE)
171+
172+
subprocess.check_call([
113173
sys.executable, '-u', MAKE_PY_LOCATTION,
114174
'-t', toolchain,
115175
'-m', target,
116176
'--profile', profile,
117177
'--source', ROOT,
118178
'--build', os.path.join(ROOT, 'BUILD', target),
119179
'--app-config', TFM_MBED_APP
120-
])
180+
], stdout=subprocess.PIPE)
121181

122182

123-
def commit_biannries(target, delivery_dir):
124-
cmd = [
125-
'git',
126-
'-C', ROOT,
127-
'add', os.path.relpath(delivery_dir, ROOT)
128-
]
183+
def commit_binaries(target, delivery_dir):
184+
"""
185+
Commits changes in secure binaries.
129186
130-
subprocess.call(cmd)
131-
commit_message = 'Update secure binaries for {}'.format(target)
132-
cmd = [
187+
:param target: Target name.
188+
:param delivery_dir: Secure images should be moved to this folder
189+
by the build system.
190+
"""
191+
changes_made = subprocess.call([
133192
'git',
134193
'-C', ROOT,
135-
'commit',
136-
'-m', commit_message
137-
]
138-
139-
subprocess.call(cmd)
140-
141-
142-
def build_psa_platform(target, toolchain, delivery_dir, debug=False, git_commit=False):
194+
'diff', '--exit-code',
195+
delivery_dir
196+
], stdout=subprocess.PIPE)
197+
198+
if changes_made:
199+
subprocess.check_call([
200+
'git',
201+
'-C', ROOT,
202+
'add', os.path.relpath(delivery_dir, ROOT)
203+
], stdout=subprocess.PIPE)
204+
205+
commit_message = '-m\"Update secure binaries for {}\"'.format(target)
206+
subprocess.check_call([
207+
'git',
208+
'-C', ROOT,
209+
'commit',
210+
commit_message
211+
], stdout=subprocess.PIPE)
212+
213+
214+
def build_psa_platform(target, toolchain, delivery_dir, debug=False,
215+
git_commit=False):
216+
"""
217+
Calls the correct build function and commits if requested.
218+
219+
:param target: Target name.
220+
:param toolchain: Toolchain to be used.
221+
:param delivery_dir: Artifact directory, where images should be placed.
222+
:param debug: Build with debug profile.
223+
:param git_commit: Commit the changes.
224+
"""
143225
profile = 'debug' if debug else 'release'
144226
if _psa_backend(target) is 'TFM':
145227
build_tfm_platform(target, toolchain, profile)
146228
else:
147229
build_mbed_spm_platform(target, toolchain, profile)
148230

149231
if git_commit:
150-
commit_biannries(target, delivery_dir)
232+
commit_binaries(target, delivery_dir)
151233

152234

153235
def get_parser():
154236
parser = ArgumentParser()
155237
parser.add_argument("-m", "--mcu",
156238
help="build for the given MCU",
157-
default='*',
239+
default=None,
158240
metavar="MCU")
159241

160242
parser.add_argument("-d", "--debug",
@@ -170,30 +252,26 @@ def get_parser():
170252
return parser
171253

172254

173-
def filter_target(mcu):
174-
def filter_func(t):
175-
return t[0] == mcu
176-
177-
return filter_func
178-
179-
180-
def main():
181-
parser = get_parser()
182-
options = parser.parse_args()
255+
def prep_build_dir():
256+
"""
257+
Creates a clean BUILD directory
258+
"""
183259
build_dir = os.path.join(ROOT, 'BUILD')
184260
if os.path.exists(build_dir):
185261
shutil.rmtree(build_dir)
186262

187263
os.makedirs(build_dir)
188264
create_mbed_ignore(build_dir)
189-
target_filter_function = None
190-
psa_platforms_list = get_mbed_official_psa_release()
191265

192-
if options.mcu is not '*':
193-
target_filter_function = filter_target(options.mcu)
194266

195-
for target, toolchain, delivery_dir in filter(target_filter_function, psa_platforms_list):
196-
build_psa_platform(target, toolchain, delivery_dir, options.debug, options.commit)
267+
def main():
268+
parser = get_parser()
269+
options = parser.parse_args()
270+
prep_build_dir()
271+
psa_platforms_list = get_mbed_official_psa_release(options.mcu)
272+
273+
for target, tc, directory in psa_platforms_list:
274+
build_psa_platform(target, tc, directory, options.debug, options.commit)
197275

198276

199277
if __name__ == '__main__':

0 commit comments

Comments
 (0)