1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
# Copyright 2014 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Commonly used, CLI related functions."""
import re
def extract_jobs_flags(arguments):
"""Extracts make job flags from a list of other make flags, i.e. -j8 -l8
The input arguments are given as a string separated by whitespace.
Make job flags are matched and removed from the arguments, and the Make
job flags and what is left over from the input arguments are returned.
If no job flags are encountered, then an empty string is returned as the
first element of the returned tuple.
Examples:
.. code-block:: python
>> extract_jobs_flags('-j8 -l8')
('-j8 -l8', '')
>> extract_jobs_flags('-j8 ')
('-j8', ' ')
>> extract_jobs_flags('target -j8 -l8 --some-option')
('-j8 -l8', 'target --some-option')
>> extract_jobs_flags('target --some-option')
('', 'target --some-option')
:param str arguments: string of space separated arguments which may or
may not contain make job flags
:returns: tuple of make jobs flags as a space separated string and
leftover arguments as a space separated string
:rtype: tuple
"""
regex = (
r'(?:^|\s)(-?(?:j|l)(?:\s*[0-9]+|\s|$))'
r'|'
r'(?:^|\s)((?:--)?(?:jobs|load-average)(?:(?:=|\s+)[0-9]+|(?:\s|$)))'
)
matches = []
leftover = ''
last_match_end = 0
for match in re.finditer(regex, arguments) or []:
matches.append(match.groups()[0] or match.groups()[1])
leftover += arguments[last_match_end:match.start()]
last_match_end = match.end()
leftover += arguments[last_match_end:]
return ' '.join([m.strip() for m in matches]), leftover
def extract_argument_group(args, delimiting_option):
"""Extract a group of arguments from a list of arguments using a delimiter.
Here is an example:
.. code-block:: python
>>> extract_argument_group(['foo', '--args', 'bar', '--baz'], '--args')
(['foo'], ['bar', '--baz'])
The group can always be ended using the double hyphen ``--``.
In order to pass a double hyphen as arguments, use three hyphens ``---``.
Any set of hyphens encountered after the delimiter, and up to ``--``, which
have three or more hyphens and are isolated, will be captured and reduced
by one hyphen.
For example:
.. code-block:: python
>> extract_argument_group(['foo',
'--args', 'bar', '--baz', '---', '--',
'--foo-option'], '--args')
(['foo', '--foo-option'], ['bar', '--baz', '--'])
In the result the ``--`` comes from the ``---`` in the input.
The ``--args`` and the corresponding ``--`` are removed entirely.
The delimiter and ``--`` terminator combination can also happen multiple
times, in which case the bodies of arguments are combined and returned in
the order they appeared.
For example:
.. code-block:: python
>> extract_argument_group(['foo',
'--args', 'ping', '--',
'bar',
'--args', 'pong', '--',
'baz',
'--args', '--'], '--args')
(['foo', 'bar', 'baz'], ['ping', 'pong'])
Note: ``--`` cannot be used as the ``delimiting_option``.
:param list args: list of strings which are ordered arguments.
:param str delimiting_option: option which denotes where to split the args.
:returns: tuple of arguments before and after the delimiter.
:rtype: tuple
:raises: ValueError if the delimiting_option is ``--``.
"""
if delimiting_option == '--':
raise ValueError("Cannot use '--' as the delimiter")
if delimiting_option not in args:
return args, []
trimmed_args = args
extracted_args = []
# Loop through all arguments extracting groups of arguments
while True:
try:
next_delimiter = trimmed_args.index(delimiting_option)
except ValueError:
# No delimiter's left in the arguments, stop looking
break
# Capture and remove args after the delimiter
tail = trimmed_args[next_delimiter + 1:]
trimmed_args = trimmed_args[:next_delimiter]
# Look for a terminator, '--'
next_terminator = None
try:
next_terminator = tail.index('--')
except ValueError:
pass
if next_terminator is None:
# No terminator, put all args in extracted_args and stop looking
extracted_args.extend(tail)
break
else:
# Terminator found, put args up, but not including terminator
# in extracted_args
extracted_args.extend(tail[:next_terminator])
# And put arguments after the terminator back in trimmed_args
# then continue looking for additional delimiters
trimmed_args.extend(tail[next_terminator + 1:])
# Iterate through extracted args and shorted tokens with 3+ -'s only
for i, token in enumerate(extracted_args):
# '--' should have been removed from extracted_args in the above loop
assert token != '--', "this shouldn't happen"
# Skip single hyphens
if token == '-':
continue
# Check for non-hyphen characters
if [c for c in token if c != '-']:
# contains something other than -, continue
continue
# Must be only hyphens with more than two, Shorted by one -
extracted_args[i] = token[1:]
return trimmed_args, extracted_args
|