Home | History | Annotate | Download | only in lib
      1 # Copyright (C) 2016 The Android Open-Source Project
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #      http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 
     15 """Various utility functions"""
     16 
     17 import logging
     18 import os
     19 import shlex
     20 import subprocess
     21 
     22 
     23 # The default location in which symbols and minidumps will be saved.
     24 _DEFAULT_ARTIFACT_CACHE_ROOT = os.environ.get('ARC_ARTIFACT_CACHE_ROOT',
     25                                               '/tmp/arc-artifact-cache')
     26 
     27 
     28 def get_command_str(command):
     29   """Returns a quoted version of the command, friendly to copy/paste."""
     30   return ' '.join(shlex.quote(arg) for arg in command)
     31 
     32 
     33 def check_call(*subprocess_args, sudo=False, dryrun=False, **kwargs):
     34   """Runs a subprocess and returns its exit code."""
     35   if sudo:
     36     subprocess_args = ('/usr/bin/sudo',) + subprocess_args
     37   if logging.getLogger().isEnabledFor(logging.DEBUG):
     38     if kwargs:
     39       logging.debug('Calling: %s (kwargs %r)', get_command_str(subprocess_args),
     40                     kwargs)
     41     else:
     42       logging.debug('Calling: %s', get_command_str(subprocess_args))
     43   if dryrun:
     44     return
     45   try:
     46     return subprocess.check_call(subprocess_args, **kwargs)
     47   except subprocess.CalledProcessError as e:
     48     logging.error('Error while executing %s', get_command_str(subprocess_args))
     49     logging.error(e.output)
     50     raise
     51 
     52 
     53 def check_output(*subprocess_args, sudo=False, dryrun=False,
     54                  universal_newlines=True, **kwargs):
     55   """Runs a subprocess and returns its output."""
     56   if sudo:
     57     subprocess_args = ('/usr/bin/sudo',) + subprocess_args
     58   if logging.getLogger().isEnabledFor(logging.DEBUG):
     59     if kwargs:
     60       logging.debug('Calling: %s (kwargs %r)', get_command_str(subprocess_args),
     61                     kwargs)
     62     else:
     63       logging.debug('Calling: %s', get_command_str(subprocess_args))
     64   if dryrun:
     65     logging.info('Cannot return any output without running the command. '
     66                  'Returning an empty string instead.')
     67     return ''
     68   try:
     69     return subprocess.check_output(subprocess_args,
     70                                    universal_newlines=universal_newlines,
     71                                    **kwargs)
     72   except subprocess.CalledProcessError as e:
     73     logging.error('Error while executing %s', get_command_str(subprocess_args))
     74     logging.error(e.output)
     75     raise
     76 
     77 
     78 def find_repo_root(path=None):
     79   """Locate the top level of this repo checkout starting at |path|."""
     80   if path is None:
     81     path = os.getcwd()
     82   orig_path = path
     83   path = os.path.abspath(path)
     84   while not os.path.exists(os.path.join(path, '.repo')):
     85     path = os.path.dirname(path)
     86     if path == '/':
     87       raise ValueError('Could not locate .repo in %s' % orig_path)
     88   return path
     89 
     90 
     91 def makedirs(path):
     92   """Makes directories if necessary, like 'mkdir -p'"""
     93   if not os.path.exists(path):
     94     os.makedirs(path)
     95 
     96 
     97 def get_prebuilt(tool):
     98   """Locates a prebuilt file to run."""
     99   return os.path.abspath(os.path.join(
    100       os.path.dirname(os.path.dirname(__file__)), 'prebuilt/x86-linux/', tool))
    101 
    102 
    103 def helper_temp_path(*path, artifact_cache_root=_DEFAULT_ARTIFACT_CACHE_ROOT):
    104   """Returns the path to use for temporary/cached files."""
    105   return os.path.join(artifact_cache_root, *path)
    106 
    107 
    108 def get_product_arch(product):
    109   """Returns the architecture of a given target |product|."""
    110   # The prefix can itself have other prefixes, like 'generic_' or 'aosp_'.
    111   for product_prefix in ('bertha_', 'cheets_'):
    112     idx = product.find(product_prefix)
    113     if idx < 0:
    114       continue
    115     return product[idx + len(product_prefix):]
    116   raise Exception('Unrecognized product: %s' % product)
    117 
    118 
    119 def get_product_name(product):
    120   """Returns the name of a given target |product|."""
    121   # The prefix can itself have other prefixes, like 'generic_' or 'aosp_'.
    122   for product_prefix in ('bertha_', 'cheets_'):
    123     idx = product.find(product_prefix)
    124     if idx < 0:
    125       continue
    126     return product_prefix.rstrip('_')
    127   raise Exception('Unrecognized product: %s' % product)
    128 
    129 
    130 def get_image_type(image_path):
    131   """Returns the type of a given image |image_path|."""
    132   if 'Squashfs' in subprocess.check_output(
    133       ['/usr/bin/file', '--brief', image_path], universal_newlines=True):
    134     return 'squashfs'
    135   else:
    136     return 'ext4'
    137