Deprecated the `--expand-dependencies` flag from `element-info` usage. The flag was required and not optional. We can rely on argparse to exit non-0 when the required positional argument is not provided. Change-Id: Iaf8eb962eb600760974bc33c30b809a07a23278e Closes-Bug: 1265649
		
			
				
	
	
		
			133 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# Copyright 2013 Hewlett-Packard Development Company, L.P.
 | 
						|
#
 | 
						|
# 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.
 | 
						|
 | 
						|
from __future__ import print_function
 | 
						|
import argparse
 | 
						|
import collections
 | 
						|
import os
 | 
						|
import sys
 | 
						|
 | 
						|
 | 
						|
def get_elements_dir():
 | 
						|
    if not os.environ.get('ELEMENTS_PATH'):
 | 
						|
        raise Exception("$ELEMENTS_PATH must be set.")
 | 
						|
    return os.environ['ELEMENTS_PATH']
 | 
						|
 | 
						|
 | 
						|
def _get_set(element, fname, elements_dir=None):
 | 
						|
    if elements_dir is None:
 | 
						|
        elements_dir = get_elements_dir()
 | 
						|
 | 
						|
    for path in elements_dir.split(':'):
 | 
						|
        element_deps_path = (os.path.join(path, element, fname))
 | 
						|
        try:
 | 
						|
            with open(element_deps_path) as element_deps:
 | 
						|
                return set([line.strip() for line in element_deps])
 | 
						|
        except IOError as e:
 | 
						|
            if os.path.exists(os.path.join(path, element)) and e.errno == 2:
 | 
						|
                return set()
 | 
						|
            if e.errno == 2:
 | 
						|
                continue
 | 
						|
            else:
 | 
						|
                raise
 | 
						|
 | 
						|
    sys.stderr.write("ERROR: Element '%s' not found in '%s'\n" %
 | 
						|
                     (element, elements_dir))
 | 
						|
    sys.exit(-1)
 | 
						|
 | 
						|
 | 
						|
def provides(element, elements_dir=None):
 | 
						|
    """Return the set of elements provided by the specified element.
 | 
						|
 | 
						|
    :param element: name of a single element
 | 
						|
    :param elements_dir: the elements dir to read from. If not supplied,
 | 
						|
                         inferred by calling get_elements_dir().
 | 
						|
 | 
						|
    :return: a set just containing all elements that the specified element
 | 
						|
             provides.
 | 
						|
    """
 | 
						|
    return _get_set(element, 'element-provides', elements_dir)
 | 
						|
 | 
						|
 | 
						|
def dependencies(element, elements_dir=None):
 | 
						|
    """Return the non-transitive set of dependencies for a single element.
 | 
						|
 | 
						|
    :param element: name of a single element
 | 
						|
    :param elements_dir: the elements dir to read from. If not supplied,
 | 
						|
                         inferred by calling get_elements_dir().
 | 
						|
 | 
						|
    :return: a set just containing all elements that the specified element
 | 
						|
             depends on.
 | 
						|
    """
 | 
						|
    return _get_set(element, 'element-deps', elements_dir)
 | 
						|
 | 
						|
 | 
						|
def expand_dependencies(user_elements, elements_dir=None):
 | 
						|
    """Expand user requested elements using element-deps files.
 | 
						|
 | 
						|
    Arguments:
 | 
						|
    :param user_elements: iterable enumerating the elements a user requested
 | 
						|
    :param elements_dir: the elements dir to read from. Passed directly to
 | 
						|
                         dependencies()
 | 
						|
 | 
						|
    :return: a set containing user_elements and all dependent elements
 | 
						|
             including any transitive dependencies.
 | 
						|
    """
 | 
						|
    final_elements = set(user_elements)
 | 
						|
    check_queue = collections.deque(user_elements)
 | 
						|
    provided = set()
 | 
						|
 | 
						|
    while check_queue:
 | 
						|
        # bug #1303911 - run through the provided elements first to avoid
 | 
						|
        # adding unwanted dependencies and looking for virtual elements
 | 
						|
        element = check_queue.popleft()
 | 
						|
        if element in provided:
 | 
						|
            continue
 | 
						|
        deps = dependencies(element, elements_dir)
 | 
						|
        provided.update(provides(element, elements_dir))
 | 
						|
        check_queue.extend(deps - (final_elements | provided))
 | 
						|
        final_elements.update(deps)
 | 
						|
 | 
						|
    if "operating-system" not in provided:
 | 
						|
        sys.stderr.write(
 | 
						|
            "ERROR: Please include an operating system element.\n")
 | 
						|
        sys.exit(-1)
 | 
						|
 | 
						|
    conflicts = set(user_elements) & provided
 | 
						|
    if conflicts:
 | 
						|
        sys.stderr.write("ERROR: Following elements were explicitly required "
 | 
						|
                         "but are provided by other included elements: %s\n" %
 | 
						|
                         ", ".join(conflicts))
 | 
						|
        sys.exit(-1)
 | 
						|
    return final_elements - provided
 | 
						|
 | 
						|
 | 
						|
def main(argv):
 | 
						|
    parser = argparse.ArgumentParser()
 | 
						|
    parser.add_argument('elements', nargs='+',
 | 
						|
                        help='display dependencies of the given elements')
 | 
						|
    parser.add_argument('--expand-dependencies', '-d', action='store_true',
 | 
						|
                        default=False,
 | 
						|
                        help=('(DEPRECATED) print expanded dependencies '
 | 
						|
                              'of all args'))
 | 
						|
 | 
						|
    args = parser.parse_args(argv[1:])
 | 
						|
 | 
						|
    if args.expand_dependencies:
 | 
						|
        print("WARNING: expand-dependencies flag is deprecated,  "
 | 
						|
              "and is now on by default.", file=sys.stderr)
 | 
						|
 | 
						|
    print(' '.join(expand_dependencies(args.elements)))
 | 
						|
    return 0
 |