普通文本  |  152行  |  3.99 KB

#!/usr/bin/python

# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Command line tool to pack audio related modules into a zip file."""

import argparse
import logging
import os
import subprocess


MODULES = ['audio_quality_measurement.py', 'audio_data.py', 'audio_analysis.py']
ENTRY = '__main__.py'
ENTRY_TARGET = 'check_quality.py'

def add_args(parser):
    """Adds command line arguments."""
    parser.add_argument('-d', '--debug', action='store_true', default=False,
                        help='Show debug message.')
    parser.add_argument('-o', '--out', type=str, default='audio_quality.zip',
                        help='Output file name. Default is audio_quality.zip.')
    parser.add_argument('-s', '--skip-cleanup', action='store_true', default=False,
                        help='Skip cleaning up temporary files. Default is False')


def parse_args(parser):
    """Parses args.

    @param parser: An argparse.ArgumentParser.

    @returns: The namespace parsed from command line arguments.

    """
    args = parser.parse_args()
    return args


def create_link():
    """Creates a symbolic link from ENTRY to ENTRY_TARGET.

    With this symlink, python can execute the zip file directly to execute
    ENTRY_TARGET.

    """
    command = ['ln', '-sf', ENTRY_TARGET, ENTRY]
    logging.debug('Link command: %s', command)
    subprocess.check_call(command)


def pack_files(out_file):
    """Packs audio related modules into a zip file.

    Packs audio related modules in MODULES into a zip file.
    Packs the symlink pointing to ENTRY_TARGET.

    @param out_file: Zip file name.

    """
    command = ['zip']
    command.append(out_file)
    command += MODULES
    command.append(ENTRY)
    command.append(ENTRY_TARGET)
    logging.debug('Zip command: %s', command)
    subprocess.check_call(command)


def check_packed_file(out_file):
    """Checks the packed file can be executed by python.

    @param out_file: Zip file name.

    """
    command = ['python', out_file, '--help']
    logging.debug('Check command: %s', command)
    output = subprocess.check_output(command)
    logging.debug('output: %s', output)


def cleanup():
    """Cleans up the symobolic link."""
    if os.path.exists(ENTRY):
        os.unlink(ENTRY)


def repo_is_dirty():
    """Checks if a repo is dirty by git diff command.

    @returns: True if there are uncommitted changes. False otherwise.

    """
    try:
        subprocess.check_call(['git', 'diff', '--quiet'])
        subprocess.check_call(['git', 'diff', '--cached', '--quiet'])
    except subprocess.CalledProcessError:
        return True
    return False


def get_git_sha1():
    """Returns git SHA-1 hash of HEAD.

    @returns: git SHA-1 has of HEAD with minimum length 9.

    """
    return subprocess.check_output(
            ['git', 'rev-parse', '--short', 'HEAD']).strip()


def append_name_with_git_hash(out_file):
    """Append the file with git SHA-1 hash.

    For out_file like ABC.xyz, append the name ABC with git SHA-1 of HEAD, like
    ABC_f4610bdd3.xyz.
    If current repo contains uncommitted changes, it will be
    ABC_f4610bdd3_dirty.xyz.

    """
    basename, ext = os.path.splitext(out_file)
    basename += '_'
    basename += get_git_sha1()
    if repo_is_dirty():
        basename += '_dirty'
    return basename + ext


if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='Pack audio related modules into a zip file.')

    add_args(parser)
    args = parse_args(parser)

    level = logging.DEBUG if args.debug else logging.INFO
    format = '%(asctime)-15s:%(levelname)s:%(pathname)s:%(lineno)d: %(message)s'
    logging.basicConfig(format=format, level=level)

    out_file = append_name_with_git_hash(args.out)

    try:
        create_link()
        pack_files(out_file)
        check_packed_file(out_file)
    finally:
        if not args.skip_cleanup:
            cleanup()

    logging.info('Packed file: %s', out_file)