diff options
Diffstat (limited to 'meta/lib/patchtest/repo.py')
-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 |