forked from mirrors/gecko-dev
Differential Revision: https://phabricator.services.mozilla.com/D60898 --HG-- extra : moz-landing-system : lando
77 lines
2.6 KiB
Python
77 lines
2.6 KiB
Python
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
from __future__ import absolute_import, print_function, unicode_literals
|
|
|
|
from .attributes import keymatch
|
|
|
|
|
|
def evaluate_keyed_by(value, item_name, attributes):
|
|
"""
|
|
For values which can either accept a literal value, or be keyed by some
|
|
attributes, perform that lookup and return the result.
|
|
|
|
For example, given item::
|
|
|
|
by-test-platform:
|
|
macosx-10.11/debug: 13
|
|
win.*: 6
|
|
default: 12
|
|
|
|
a call to `evaluate_keyed_by(item, 'thing-name', {'test-platform': 'linux96')`
|
|
would return `12`.
|
|
|
|
The `item_name` parameter is used to generate useful error messages.
|
|
Items can be nested as deeply as desired::
|
|
|
|
by-test-platform:
|
|
win.*:
|
|
by-project:
|
|
ash: ..
|
|
cedar: ..
|
|
linux: 13
|
|
default: 12
|
|
"""
|
|
while True:
|
|
if not isinstance(value, dict) or len(value) != 1:
|
|
return value
|
|
value_key = next(iter(value))
|
|
if not value_key.startswith('by-'):
|
|
return value
|
|
|
|
keyed_by = value_key[3:] # strip off 'by-' prefix
|
|
key = attributes.get(keyed_by)
|
|
alternatives = next(iter(value.values()))
|
|
|
|
if len(alternatives) == 1 and 'default' in alternatives:
|
|
# Error out when only 'default' is specified as only alternatives,
|
|
# because we don't need to by-{keyed_by} there.
|
|
raise Exception(
|
|
"Keyed-by '{}' unnecessary with only value 'default' "
|
|
"found, when determining item {}".format(
|
|
keyed_by, item_name))
|
|
|
|
if key is None:
|
|
if 'default' in alternatives:
|
|
value = alternatives['default']
|
|
continue
|
|
else:
|
|
raise Exception(
|
|
"No attribute {} and no value for 'default' found "
|
|
"while determining item {}".format(
|
|
keyed_by, item_name))
|
|
|
|
matches = keymatch(alternatives, key)
|
|
if len(matches) > 1:
|
|
raise Exception(
|
|
"Multiple matching values for {} {!r} found while "
|
|
"determining item {}".format(
|
|
keyed_by, key, item_name))
|
|
elif matches:
|
|
value = matches[0]
|
|
continue
|
|
|
|
raise Exception(
|
|
"No {} matching {!r} nor 'default' found while determining item {}".format(
|
|
keyed_by, key, item_name))
|