diff options
| -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 |
