summaryrefslogtreecommitdiffstats
path: root/meta/lib/patchtest/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'meta/lib/patchtest/utils.py')
-rw-r--r--meta/lib/patchtest/utils.py168
1 files changed, 168 insertions, 0 deletions
diff --git a/meta/lib/patchtest/utils.py b/meta/lib/patchtest/utils.py
new file mode 100644
index 0000000000..dd0abc22d9
--- /dev/null
+++ b/meta/lib/patchtest/utils.py
@@ -0,0 +1,168 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# utils: common methods used by the patchtest framework
5#
6# Copyright (C) 2016 Intel Corporation
7#
8# SPDX-License-Identifier: GPL-2.0-only
9#
10
11import os
12import subprocess
13import logging
14import re
15import mailbox
16
17class CmdException(Exception):
18 """ Simple exception class where its attributes are the ones passed when instantiated """
19 def __init__(self, cmd):
20 self._cmd = cmd
21 def __getattr__(self, name):
22 value = None
23 if self._cmd.has_key(name):
24 value = self._cmd[name]
25 return value
26
27def exec_cmd(cmd, cwd, ignore_error=False, input=None, strip=True, updateenv={}):
28 """
29 Input:
30
31 cmd: dict containing the following keys:
32
33 cmd : the command itself as an array of strings
34 ignore_error: if False, no exception is raised
35 strip: indicates if strip is done on the output (stdout and stderr)
36 input: input data to the command (stdin)
37 updateenv: environment variables to be appended to the current
38 process environment variables
39
40 NOTE: keys 'ignore_error' and 'input' are optional; if not included,
41 the defaults are the ones specify in the arguments
42 cwd: directory where commands are executed
43 ignore_error: raise CmdException if command fails to execute and
44 this value is False
45 input: input data (stdin) for the command
46
47 Output: dict containing the following keys:
48
49 cmd: the same as input
50 ignore_error: the same as input
51 strip: the same as input
52 input: the same as input
53 stdout: Standard output after command's execution
54 stderr: Standard error after command's execution
55 returncode: Return code after command's execution
56
57 """
58 cmddefaults = {
59 'cmd':'',
60 'ignore_error':ignore_error,
61 'strip':strip,
62 'input':input,
63 'updateenv':updateenv,
64 }
65
66 # update input values if necessary
67 cmddefaults.update(cmd)
68
69 _cmd = cmddefaults
70
71 if not _cmd['cmd']:
72 raise CmdException({'cmd':None, 'stderr':'no command given'})
73
74 # update the environment
75 env = os.environ
76 env.update(_cmd['updateenv'])
77
78 _command = [e for e in _cmd['cmd']]
79 p = subprocess.Popen(_command,
80 stdin=subprocess.PIPE,
81 stdout=subprocess.PIPE,
82 stderr=subprocess.PIPE,
83 universal_newlines=True,
84 cwd=cwd,
85 env=env)
86
87 # execute the command and strip output
88 (_stdout, _stderr) = p.communicate(_cmd['input'])
89 if _cmd['strip']:
90 _stdout, _stderr = map(str.strip, [_stdout, _stderr])
91
92 # generate the result
93 result = _cmd
94 result.update({'cmd':_command,'stdout':_stdout,'stderr':_stderr,'returncode':p.returncode})
95
96 # launch exception if necessary
97 if not _cmd['ignore_error'] and p.returncode:
98 raise CmdException(result)
99
100 return result
101
102def exec_cmds(cmds, cwd):
103 """ Executes commands
104
105 Input:
106 cmds: Array of commands
107 cwd: directory where commands are executed
108
109 Output: Array of output commands
110 """
111 results = []
112 _cmds = cmds
113
114 for cmd in _cmds:
115 result = exec_cmd(cmd, cwd)
116 results.append(result)
117
118 return results
119
120def logger_create(name):
121 logger = logging.getLogger(name)
122 loggerhandler = logging.StreamHandler()
123 loggerhandler.setFormatter(logging.Formatter("%(message)s"))
124 logger.addHandler(loggerhandler)
125 logger.setLevel(logging.INFO)
126 return logger
127
128def get_subject_prefix(path):
129 prefix = ""
130 mbox = mailbox.mbox(path)
131
132 if len(mbox):
133 subject = mbox[0]['subject']
134 if subject:
135 pattern = re.compile(r"(\[.*\])", re.DOTALL)
136 match = pattern.search(subject)
137 if match:
138 prefix = match.group(1)
139
140 return prefix
141
142def valid_branch(branch):
143 """ Check if branch is valid name """
144 lbranch = branch.lower()
145
146 invalid = lbranch.startswith('patch') or \
147 lbranch.startswith('rfc') or \
148 lbranch.startswith('resend') or \
149 re.search(r'^v\d+', lbranch) or \
150 re.search(r'^\d+/\d+', lbranch)
151
152 return not invalid
153
154def get_branch(path):
155 """ Get the branch name from mbox """
156 fullprefix = get_subject_prefix(path)
157 branch, branches, valid_branches = None, [], []
158
159 if fullprefix:
160 prefix = fullprefix.strip('[]')
161 branches = [ b.strip() for b in prefix.split(',')]
162 valid_branches = [b for b in branches if valid_branch(b)]
163
164 if len(valid_branches):
165 branch = valid_branches[0]
166
167 return branch
168