diff options
author | Trevor Gamblin <tgamblin@baylibre.com> | 2024-05-03 09:10:30 -0400 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2024-05-13 16:28:35 +0100 |
commit | 9132e3904a8f26d49c4c425a0b7d25b71e586890 (patch) | |
tree | 8aef932caf8cb1f10ffbca9118b7ea720329ef11 /meta/lib | |
parent | e73ea1a868331bc60de1717282f1c7a4139eeb30 (diff) | |
download | poky-9132e3904a8f26d49c4c425a0b7d25b71e586890.tar.gz |
patchtest: repo: refactor to use GitPython
The repo module currently uses a custom _exec() function in order to run
various git commands as part of the patchtest setup/test process. These
can more efficiently be done with the GitPython module, so use that
instead and reduce the amount of custom code to be maintained for
patchtest in the process. Some specifics replaced using GitPython:
- get branch list
- use repo.active_branch to determine current branch
- use execute() for checkout, merge check, abort, rev-parse, reset
The _exec() function is removed entirely with this change.
(From OE-Core rev: 8ab3a0d7cb68746d7b7e1c7ff8bdf9a84a4d075d)
Signed-off-by: Trevor Gamblin <tgamblin@baylibre.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib')
-rw-r--r-- | meta/lib/patchtest/repo.py | 88 |
1 files changed, 17 insertions, 71 deletions
diff --git a/meta/lib/patchtest/repo.py b/meta/lib/patchtest/repo.py index d3788f466d..5f361ac500 100644 --- a/meta/lib/patchtest/repo.py +++ b/meta/lib/patchtest/repo.py | |||
@@ -11,6 +11,7 @@ | |||
11 | import os | 11 | import os |
12 | import utils | 12 | import utils |
13 | import logging | 13 | import logging |
14 | import git | ||
14 | from patch import PatchTestPatch | 15 | from patch import PatchTestPatch |
15 | 16 | ||
16 | logger = logging.getLogger('patchtest') | 17 | logger = logging.getLogger('patchtest') |
@@ -21,15 +22,17 @@ class PatchTestRepo(object): | |||
21 | # prefixes used for temporal branches/stashes | 22 | # prefixes used for temporal branches/stashes |
22 | prefix = 'patchtest' | 23 | prefix = 'patchtest' |
23 | 24 | ||
25 | |||
24 | def __init__(self, patch, repodir, commit=None, branch=None): | 26 | def __init__(self, patch, repodir, commit=None, branch=None): |
25 | self._repodir = repodir | 27 | self._repodir = repodir |
28 | self._repo = git.Repo.init(repodir) | ||
26 | self._patch = PatchTestPatch(patch) | 29 | self._patch = PatchTestPatch(patch) |
27 | self._current_branch = self._get_current_branch() | 30 | self._current_branch = self._repo.active_branch.name |
28 | 31 | ||
29 | # targeted branch defined on the patch may be invalid, so make sure there | 32 | # targeted branch defined on the patch may be invalid, so make sure there |
30 | # is a corresponding remote branch | 33 | # is a corresponding remote branch |
31 | valid_patch_branch = None | 34 | valid_patch_branch = None |
32 | if self._patch.branch in self.upstream_branches(): | 35 | if self._patch.branch in self._repo.branches: |
33 | valid_patch_branch = self._patch.branch | 36 | valid_patch_branch = self._patch.branch |
34 | 37 | ||
35 | # Target Branch | 38 | # Target Branch |
@@ -52,22 +55,19 @@ class PatchTestRepo(object): | |||
52 | 55 | ||
53 | self._workingbranch = "%s_%s" % (PatchTestRepo.prefix, os.getpid()) | 56 | self._workingbranch = "%s_%s" % (PatchTestRepo.prefix, os.getpid()) |
54 | 57 | ||
55 | # create working branch | 58 | # create working branch. Use the '-B' flag so that we just |
56 | self._exec({'cmd': ['git', 'checkout', '-b', self._workingbranch, self._commit]}) | 59 | # check out the existing one if it's there |
60 | self._repo.git.execute(['git', 'checkout', '-B', self._workingbranch, self._commit]) | ||
57 | 61 | ||
58 | self._patchmerged = False | 62 | self._patchmerged = False |
59 | 63 | ||
60 | # Check if patch can be merged using git-am | 64 | # Check if patch can be merged using git-am |
61 | self._patchcanbemerged = True | 65 | self._patchcanbemerged = True |
62 | try: | 66 | try: |
63 | self._exec({'cmd': ['git', 'am', '--keep-cr'], 'input': self._patch.contents}) | 67 | # Make sure to get the absolute path of the file |
64 | except utils.CmdException as ce: | 68 | self._repo.git.execute(['git', 'apply', '--check', os.path.abspath(self._patch.path)], with_exceptions=True) |
65 | self._exec({'cmd': ['git', 'am', '--abort']}) | 69 | except git.exc.GitCommandError as ce: |
66 | self._patchcanbemerged = False | 70 | self._patchcanbemerged = False |
67 | finally: | ||
68 | # if patch was applied, remove it | ||
69 | if self._patchcanbemerged: | ||
70 | self._exec({'cmd':['git', 'reset', '--hard', self._commit]}) | ||
71 | 71 | ||
72 | # for debugging purposes, print all repo parameters | 72 | # for debugging purposes, print all repo parameters |
73 | logger.debug("Parameters") | 73 | logger.debug("Parameters") |
@@ -97,78 +97,24 @@ class PatchTestRepo(object): | |||
97 | def canbemerged(self): | 97 | def canbemerged(self): |
98 | return self._patchcanbemerged | 98 | return self._patchcanbemerged |
99 | 99 | ||
100 | def _exec(self, cmds): | ||
101 | _cmds = [] | ||
102 | if isinstance(cmds, dict): | ||
103 | _cmds.append(cmds) | ||
104 | elif isinstance(cmds, list): | ||
105 | _cmds = cmds | ||
106 | else: | ||
107 | raise utils.CmdException({'cmd':str(cmds)}) | ||
108 | |||
109 | results = [] | ||
110 | cmdfailure = False | ||
111 | try: | ||
112 | results = utils.exec_cmds(_cmds, self._repodir) | ||
113 | except utils.CmdException as ce: | ||
114 | cmdfailure = True | ||
115 | raise ce | ||
116 | finally: | ||
117 | if cmdfailure: | ||
118 | for cmd in _cmds: | ||
119 | logger.debug("CMD: %s" % ' '.join(cmd['cmd'])) | ||
120 | else: | ||
121 | for result in results: | ||
122 | cmd, rc, stdout, stderr = ' '.join(result['cmd']), result['returncode'], result['stdout'], result['stderr'] | ||
123 | logger.debug("CMD: %s RCODE: %s STDOUT: %s STDERR: %s" % (cmd, rc, stdout, stderr)) | ||
124 | |||
125 | return results | ||
126 | |||
127 | def _get_current_branch(self, commit='HEAD'): | ||
128 | cmd = {'cmd':['git', 'rev-parse', '--abbrev-ref', commit]} | ||
129 | cb = self._exec(cmd)[0]['stdout'] | ||
130 | if cb == commit: | ||
131 | logger.warning('You may be detached so patchtest will checkout to master after execution') | ||
132 | cb = 'master' | ||
133 | return cb | ||
134 | |||
135 | def _get_commitid(self, commit): | 100 | def _get_commitid(self, commit): |
136 | 101 | ||
137 | if not commit: | 102 | if not commit: |
138 | return None | 103 | return None |
139 | 104 | ||
140 | try: | 105 | try: |
141 | cmd = {'cmd':['git', 'rev-parse', '--short', commit]} | 106 | return self._repo.rev_parse(commit).hexsha |
142 | return self._exec(cmd)[0]['stdout'] | 107 | except Exception as e: |
143 | except utils.CmdException as ce: | 108 | print(f"Couldn't find commit {commit} in repo") |
144 | # try getting the commit under any remotes | ||
145 | cmd = {'cmd':['git', 'remote']} | ||
146 | remotes = self._exec(cmd)[0]['stdout'] | ||
147 | for remote in remotes.splitlines(): | ||
148 | cmd = {'cmd':['git', 'rev-parse', '--short', '%s/%s' % (remote, commit)]} | ||
149 | try: | ||
150 | return self._exec(cmd)[0]['stdout'] | ||
151 | except utils.CmdException: | ||
152 | pass | ||
153 | 109 | ||
154 | return None | 110 | return None |
155 | 111 | ||
156 | def upstream_branches(self): | ||
157 | cmd = {'cmd':['git', 'branch', '--remotes']} | ||
158 | remote_branches = self._exec(cmd)[0]['stdout'] | ||
159 | |||
160 | # just get the names, without the remote name | ||
161 | branches = set(branch.split('/')[-1] for branch in remote_branches.splitlines()) | ||
162 | return branches | ||
163 | |||
164 | def merge(self): | 112 | def merge(self): |
165 | if self._patchcanbemerged: | 113 | if self._patchcanbemerged: |
166 | self._exec({'cmd': ['git', 'am', '--keep-cr'], | 114 | self._repo.git.execute(['git', 'am', '--keep-cr', os.path.abspath(self._patch.path)]) |
167 | 'input': self._patch.contents, | ||
168 | 'updateenv': {'PTRESOURCE':self._patch.path}}) | ||
169 | self._patchmerged = True | 115 | self._patchmerged = True |
170 | 116 | ||
171 | def clean(self): | 117 | def clean(self): |
172 | self._exec({'cmd':['git', 'checkout', '%s' % self._current_branch]}) | 118 | self._repo.git.execute(['git', 'checkout', self._current_branch]) |
173 | self._exec({'cmd':['git', 'branch', '-D', self._workingbranch]}) | 119 | self._repo.git.execute(['git', 'branch', '-D', self._workingbranch]) |
174 | self._patchmerged = False | 120 | self._patchmerged = False |