1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
# -*- coding: utf-8 -*-
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
""" This module is a collection of methods commonly used in this project. """
import functools
import logging
import os
import os.path
import subprocess
import sys
def duplicate_check(method):
""" Predicate to detect duplicated entries.
Unique hash method can be use to detect duplicates. Entries are
represented as dictionaries, which has no default hash method.
This implementation uses a set datatype to store the unique hash values.
This method returns a method which can detect the duplicate values. """
def predicate(entry):
entry_hash = predicate.unique(entry)
if entry_hash not in predicate.state:
predicate.state.add(entry_hash)
return False
return True
predicate.unique = method
predicate.state = set()
return predicate
def tempdir():
""" Return the default temorary directory. """
return os.getenv('TMPDIR', os.getenv('TEMP', os.getenv('TMP', '/tmp')))
def run_command(command, cwd=None):
""" Run a given command and report the execution.
:param command: array of tokens
:param cwd: the working directory where the command will be executed
:return: output of the command
"""
def decode_when_needed(result):
""" check_output returns bytes or string depend on python version """
return result.decode('utf-8') if isinstance(result, bytes) else result
try:
directory = os.path.abspath(cwd) if cwd else os.getcwd()
logging.debug('exec command %s in %s', command, directory)
output = subprocess.check_output(command,
cwd=directory,
stderr=subprocess.STDOUT)
return decode_when_needed(output).splitlines()
except subprocess.CalledProcessError as ex:
ex.output = decode_when_needed(ex.output).splitlines()
raise ex
def initialize_logging(verbose_level):
""" Output content controlled by the verbosity level. """
level = logging.WARNING - min(logging.WARNING, (10 * verbose_level))
if verbose_level <= 3:
fmt_string = '{0}: %(levelname)s: %(message)s'
else:
fmt_string = '{0}: %(levelname)s: %(funcName)s: %(message)s'
program = os.path.basename(sys.argv[0])
logging.basicConfig(format=fmt_string.format(program), level=level)
def command_entry_point(function):
""" Decorator for command entry points. """
@functools.wraps(function)
def wrapper(*args, **kwargs):
exit_code = 127
try:
exit_code = function(*args, **kwargs)
except KeyboardInterrupt:
logging.warning('Keyboard interupt')
except Exception:
logging.exception('Internal error.')
if logging.getLogger().isEnabledFor(logging.DEBUG):
logging.error("Please report this bug and attach the output "
"to the bug report")
else:
logging.error("Please run this command again and turn on "
"verbose mode (add '-vvv' as argument).")
finally:
return exit_code
return wrapper
|