Source code for osrf_pycommon.cli_utils.common

# 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
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# See the License for the specific language governing permissions and
# limitations under the License.

"""Commonly used, CLI related functions."""

import re

[docs]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
[docs]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 foud, 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