| 239 | |
| 240 | |
| 241 | class Perforce: |
| 242 | def __init__(self, action, cl_desc): |
| 243 | self._action = action |
| 244 | self._cl_desc = cl_desc |
| 245 | self._cl = None |
| 246 | |
| 247 | def pre_build(self, paths): |
| 248 | if self._action == 'none': |
| 249 | return |
| 250 | logging.info(f'Checking out {len(paths)} files in Perforce') |
| 251 | self._p4('edit', paths) |
| 252 | |
| 253 | logging.debug('Creating new change list') |
| 254 | self._cl = self._create_cl() |
| 255 | logging.info(f'Created CL {self._cl}') |
| 256 | logging.debug(f'Moving files to CL {self._cl}') |
| 257 | self._p4('reopen', ['-c', self._cl] + paths) |
| 258 | |
| 259 | def submit(self, paths, success): |
| 260 | if self._action == 'none': |
| 261 | return |
| 262 | if self._action == 'revert': |
| 263 | self._revert(paths) |
| 264 | else: |
| 265 | try: |
| 266 | action_verb = 'Submitting' if self._action == 'submit' else 'Saving' |
| 267 | logging.info(f'{action_verb} {len(paths)} files to Perforce') |
| 268 | logging.debug('Adding new files to Perforce') |
| 269 | self._p4('add', ['-tbinary+m'] + paths) |
| 270 | logging.debug(f'Moving new files to CL {self._cl}') |
| 271 | self._p4('reopen', ['-c', self._cl] + paths) |
| 272 | if self._action == 'submit': |
| 273 | if not success: |
| 274 | logging.debug(f'Reverting unchanged files in CL {self._cl}') |
| 275 | self._p4('revert', ['-a', '-c', self._cl]) |
| 276 | logging.debug(f'Submitting CL {self._cl}') |
| 277 | self._p4('submit', ['-c', self._cl]) |
| 278 | except subprocess.CalledProcessError: |
| 279 | logging.exception(f'Failed to {self._action} compiled files') |
| 280 | self._revert(paths) |
| 281 | |
| 282 | def _revert(self, paths): |
| 283 | logging.info(f'Reverting {len(paths)} files in Perforce') |
| 284 | self._p4('revert', paths) |
| 285 | logging.debug(f'Removing CL {self._cl}') |
| 286 | self._p4('change', ['-d', self._cl]) |
| 287 | |
| 288 | def _create_cl(self): |
| 289 | desc = f""" |
| 290 | Change: new |
| 291 | |
| 292 | Description: |
| 293 | \t{self._cl_desc} |
| 294 | """ |
| 295 | p = subprocess.Popen(['p4', 'change', '-i'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| 296 | stdout, stderr = p.communicate(desc.encode()) |
| 297 | if p.returncode != 0: |
| 298 | raise subprocess.CalledProcessError(p.returncode, 'p4', stderr.decode()) |