summaryrefslogtreecommitdiffstats
path: root/meta/lib/patchtest/utils.py
diff options
context:
space:
mode:
authorTrevor Gamblin <tgamblin@baylibre.com>2023-10-16 15:44:56 -0400
committerRichard Purdie <richard.purdie@linuxfoundation.org>2023-10-17 11:41:34 +0100
commit9d137188ad03c111ff8df7396b6b3dfd59307ac0 (patch)
tree6dd7227dec950282973d21e9cfd20b5e505f6bb1 /meta/lib/patchtest/utils.py
parent790aa2096f7c6be92f994a1f8ec22d3bef91f337 (diff)
downloadpoky-9d137188ad03c111ff8df7396b6b3dfd59307ac0.tar.gz
patchtest: add supporting modules
Add modules that support core patchtest functionality to meta/lib/patchtest. These include classes and functions for handling repository and patch objects, parsing the patchtest CLI arguments, and other utilities. (From OE-Core rev: 499cdad7a16f6cc256837069c7add294132127a4) Signed-off-by: Trevor Gamblin <tgamblin@baylibre.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib/patchtest/utils.py')
-rw-r--r--meta/lib/patchtest/utils.py179
1 files changed, 179 insertions, 0 deletions
diff --git a/meta/lib/patchtest/utils.py b/meta/lib/patchtest/utils.py
new file mode 100644
index 0000000000..23428ae1c5
--- /dev/null
+++ b/meta/lib/patchtest/utils.py
@@ -0,0 +1,179 @@
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# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License version 2 as
10# published by the Free Software Foundation.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program; if not, write to the Free Software Foundation, Inc.,
19# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21import os
22import subprocess
23import logging
24import sys
25import re
26import mailbox
27
28class CmdException(Exception):
29 """ Simple exception class where its attributes are the ones passed when instantiated """
30 def __init__(self, cmd):
31 self._cmd = cmd
32 def __getattr__(self, name):
33 value = None
34 if self._cmd.has_key(name):
35 value = self._cmd[name]
36 return value
37
38def exec_cmd(cmd, cwd, ignore_error=False, input=None, strip=True, updateenv={}):
39 """
40 Input:
41
42 cmd: dict containing the following keys:
43
44 cmd : the command itself as an array of strings
45 ignore_error: if False, no exception is raised
46 strip: indicates if strip is done on the output (stdout and stderr)
47 input: input data to the command (stdin)
48 updateenv: environment variables to be appended to the current
49 process environment variables
50
51 NOTE: keys 'ignore_error' and 'input' are optional; if not included,
52 the defaults are the ones specify in the arguments
53 cwd: directory where commands are executed
54 ignore_error: raise CmdException if command fails to execute and
55 this value is False
56 input: input data (stdin) for the command
57
58 Output: dict containing the following keys:
59
60 cmd: the same as input
61 ignore_error: the same as input
62 strip: the same as input
63 input: the same as input
64 stdout: Standard output after command's execution
65 stderr: Standard error after command's execution
66 returncode: Return code after command's execution
67
68 """
69 cmddefaults = {
70 'cmd':'',
71 'ignore_error':ignore_error,
72 'strip':strip,
73 'input':input,
74 'updateenv':updateenv,
75 }
76
77 # update input values if necessary
78 cmddefaults.update(cmd)
79
80 _cmd = cmddefaults
81
82 if not _cmd['cmd']:
83 raise CmdException({'cmd':None, 'stderr':'no command given'})
84
85 # update the environment
86 env = os.environ
87 env.update(_cmd['updateenv'])
88
89 _command = [e for e in _cmd['cmd']]
90 p = subprocess.Popen(_command,
91 stdin=subprocess.PIPE,
92 stdout=subprocess.PIPE,
93 stderr=subprocess.PIPE,
94 universal_newlines=True,
95 cwd=cwd,
96 env=env)
97
98 # execute the command and strip output
99 (_stdout, _stderr) = p.communicate(_cmd['input'])
100 if _cmd['strip']:
101 _stdout, _stderr = map(str.strip, [_stdout, _stderr])
102
103 # generate the result
104 result = _cmd
105 result.update({'cmd':_command,'stdout':_stdout,'stderr':_stderr,'returncode':p.returncode})
106
107 # launch exception if necessary
108 if not _cmd['ignore_error'] and p.returncode:
109 raise CmdException(result)
110
111 return result
112
113def exec_cmds(cmds, cwd):
114 """ Executes commands
115
116 Input:
117 cmds: Array of commands
118 cwd: directory where commands are executed
119
120 Output: Array of output commands
121 """
122 results = []
123 _cmds = cmds
124
125 for cmd in _cmds:
126 result = exec_cmd(cmd, cwd)
127 results.append(result)
128
129 return results
130
131def logger_create(name):
132 logger = logging.getLogger(name)
133 loggerhandler = logging.StreamHandler()
134 loggerhandler.setFormatter(logging.Formatter("%(message)s"))
135 logger.addHandler(loggerhandler)
136 logger.setLevel(logging.INFO)
137 return logger
138
139def get_subject_prefix(path):
140 prefix = ""
141 mbox = mailbox.mbox(path)
142
143 if len(mbox):
144 subject = mbox[0]['subject']
145 if subject:
146 pattern = re.compile("(\[.*\])", re.DOTALL)
147 match = pattern.search(subject)
148 if match:
149 prefix = match.group(1)
150
151 return prefix
152
153def valid_branch(branch):
154 """ Check if branch is valid name """
155 lbranch = branch.lower()
156
157 invalid = lbranch.startswith('patch') or \
158 lbranch.startswith('rfc') or \
159 lbranch.startswith('resend') or \
160 re.search('^v\d+', lbranch) or \
161 re.search('^\d+/\d+', lbranch)
162
163 return not invalid
164
165def get_branch(path):
166 """ Get the branch name from mbox """
167 fullprefix = get_subject_prefix(path)
168 branch, branches, valid_branches = None, [], []
169
170 if fullprefix:
171 prefix = fullprefix.strip('[]')
172 branches = [ b.strip() for b in prefix.split(',')]
173 valid_branches = [b for b in branches if valid_branch(b)]
174
175 if len(valid_branches):
176 branch = valid_branches[0]
177
178 return branch
179