| # Copyright 2020 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import collections |
| import functools |
| import operator |
| |
| DEPS = [ |
| "recipe_engine/step", |
| "recipe_engine/time", |
| ] |
| |
| # We store top-level util functions in __init__.py rather than api.py to make |
| # them slightly less verbose to import. |
| # Example: `from RECIPE_MODULES.fuchsia.utils import pluralize` |
| |
| |
| def pluralize(singular, items_or_count, plural=None): |
| """Conditionally pluralizes a noun with its count. |
| |
| Examples: |
| plural('cat', 1) == '1 cat' |
| plural('cat', 2) == '2 cats' |
| plural('mouse', 2, plural='mice') == '2 mice' |
| plural('animal', ['cat', 'mouse']) == '2 animals' |
| |
| Args: |
| singular (str): The singular form of the noun. |
| items_or_count (int or iterable): Count to use to pluralize the noun. If |
| iterable, the length of the iterable will be used as the count. |
| plural (str or None): Plural form of the noun; should be specified for |
| irregular nouns whose plural form isn't as simple as appending an 's' |
| to the singular form. |
| """ |
| if isinstance(items_or_count, collections.abc.Sized): |
| count = len(items_or_count) |
| else: |
| count = items_or_count |
| |
| if count == 1: |
| noun = singular |
| else: |
| noun = plural if plural else singular + "s" |
| return "%d %s" % (count, noun) |
| |
| |
| def product(nums): |
| return functools.reduce(operator.mul, nums) |
| |
| |
| def nice_duration(seconds): |
| """Returns a human-readable duration given a number of seconds. |
| |
| For example: 3605 seconds => '1h 5s' |
| """ |
| units = [ |
| ("d", 24), |
| ("h", 60), |
| ("m", 60), |
| ("s", 1), |
| ] |
| |
| result_parts = [] |
| divisor = product(unit_size for _, unit_size in units) |
| for i, (unit_abbrev, unit_size) in enumerate(units): |
| count, seconds = divmod(seconds, divisor) |
| if count > 0: |
| result_parts.append("%d%s" % (count, unit_abbrev)) |
| elif i == len(units) - 1 and not result_parts: |
| seconds = round(seconds, 1) |
| if seconds == 0: |
| result_parts.append("0%s" % unit_abbrev) |
| else: |
| result_parts.append("%.1f%s" % (seconds, unit_abbrev)) |
| divisor /= unit_size |
| |
| return " ".join(result_parts) |