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