Home | History | Annotate | Download | only in audio
      1 #!/usr/bin/python
      2 
      3 # Copyright 2017 The Chromium OS Authors. All rights reserved.
      4 # Use of this source code is governed by a BSD-style license that can be
      5 # found in the LICENSE file.
      6 
      7 """Command line tool to pack audio related modules into a zip file."""
      8 
      9 import argparse
     10 import logging
     11 import os
     12 import subprocess
     13 
     14 
     15 MODULES = ['audio_quality_measurement.py', 'audio_data.py', 'audio_analysis.py']
     16 ENTRY = '__main__.py'
     17 ENTRY_TARGET = 'check_quality.py'
     18 
     19 def add_args(parser):
     20     """Adds command line arguments."""
     21     parser.add_argument('-d', '--debug', action='store_true', default=False,
     22                         help='Show debug message.')
     23     parser.add_argument('-o', '--out', type=str, default='audio_quality.zip',
     24                         help='Output file name. Default is audio_quality.zip.')
     25     parser.add_argument('-s', '--skip-cleanup', action='store_true', default=False,
     26                         help='Skip cleaning up temporary files. Default is False')
     27 
     28 
     29 def parse_args(parser):
     30     """Parses args.
     31 
     32     @param parser: An argparse.ArgumentParser.
     33 
     34     @returns: The namespace parsed from command line arguments.
     35 
     36     """
     37     args = parser.parse_args()
     38     return args
     39 
     40 
     41 def create_link():
     42     """Creates a symbolic link from ENTRY to ENTRY_TARGET.
     43 
     44     With this symlink, python can execute the zip file directly to execute
     45     ENTRY_TARGET.
     46 
     47     """
     48     command = ['ln', '-sf', ENTRY_TARGET, ENTRY]
     49     logging.debug('Link command: %s', command)
     50     subprocess.check_call(command)
     51 
     52 
     53 def pack_files(out_file):
     54     """Packs audio related modules into a zip file.
     55 
     56     Packs audio related modules in MODULES into a zip file.
     57     Packs the symlink pointing to ENTRY_TARGET.
     58 
     59     @param out_file: Zip file name.
     60 
     61     """
     62     command = ['zip']
     63     command.append(out_file)
     64     command += MODULES
     65     command.append(ENTRY)
     66     command.append(ENTRY_TARGET)
     67     logging.debug('Zip command: %s', command)
     68     subprocess.check_call(command)
     69 
     70 
     71 def check_packed_file(out_file):
     72     """Checks the packed file can be executed by python.
     73 
     74     @param out_file: Zip file name.
     75 
     76     """
     77     command = ['python', out_file, '--help']
     78     logging.debug('Check command: %s', command)
     79     output = subprocess.check_output(command)
     80     logging.debug('output: %s', output)
     81 
     82 
     83 def cleanup():
     84     """Cleans up the symobolic link."""
     85     if os.path.exists(ENTRY):
     86         os.unlink(ENTRY)
     87 
     88 
     89 def repo_is_dirty():
     90     """Checks if a repo is dirty by git diff command.
     91 
     92     @returns: True if there are uncommitted changes. False otherwise.
     93 
     94     """
     95     try:
     96         subprocess.check_call(['git', 'diff', '--quiet'])
     97         subprocess.check_call(['git', 'diff', '--cached', '--quiet'])
     98     except subprocess.CalledProcessError:
     99         return True
    100     return False
    101 
    102 
    103 def get_git_sha1():
    104     """Returns git SHA-1 hash of HEAD.
    105 
    106     @returns: git SHA-1 has of HEAD with minimum length 9.
    107 
    108     """
    109     return subprocess.check_output(
    110             ['git', 'rev-parse', '--short', 'HEAD']).strip()
    111 
    112 
    113 def append_name_with_git_hash(out_file):
    114     """Append the file with git SHA-1 hash.
    115 
    116     For out_file like ABC.xyz, append the name ABC with git SHA-1 of HEAD, like
    117     ABC_f4610bdd3.xyz.
    118     If current repo contains uncommitted changes, it will be
    119     ABC_f4610bdd3_dirty.xyz.
    120 
    121     """
    122     basename, ext = os.path.splitext(out_file)
    123     basename += '_'
    124     basename += get_git_sha1()
    125     if repo_is_dirty():
    126         basename += '_dirty'
    127     return basename + ext
    128 
    129 
    130 if __name__ == '__main__':
    131     parser = argparse.ArgumentParser(
    132         description='Pack audio related modules into a zip file.')
    133 
    134     add_args(parser)
    135     args = parse_args(parser)
    136 
    137     level = logging.DEBUG if args.debug else logging.INFO
    138     format = '%(asctime)-15s:%(levelname)s:%(pathname)s:%(lineno)d: %(message)s'
    139     logging.basicConfig(format=format, level=level)
    140 
    141     out_file = append_name_with_git_hash(args.out)
    142 
    143     try:
    144         create_link()
    145         pack_files(out_file)
    146         check_packed_file(out_file)
    147     finally:
    148         if not args.skip_cleanup:
    149             cleanup()
    150 
    151     logging.info('Packed file: %s', out_file)
    152