| OLD | NEW |
| (Empty) |
| 1 import os, types | |
| 2 from twisted.python import log, failure, runtime | |
| 3 from twisted.internet import reactor, defer, task | |
| 4 from buildbot.process.buildstep import RemoteCommand, BuildStep | |
| 5 from buildbot.process.buildstep import SUCCESS, FAILURE | |
| 6 from twisted.internet.protocol import ProcessProtocol | |
| 7 | |
| 8 class MasterShellCommand(BuildStep): | |
| 9 """ | |
| 10 Run a shell command locally - on the buildmaster. The shell command | |
| 11 COMMAND is specified just as for a RemoteShellCommand. Note that extra | |
| 12 logfiles are not sopported. | |
| 13 """ | |
| 14 name='MasterShellCommand' | |
| 15 description='Running' | |
| 16 descriptionDone='Ran' | |
| 17 | |
| 18 def __init__(self, command, **kwargs): | |
| 19 BuildStep.__init__(self, **kwargs) | |
| 20 self.addFactoryArguments(command=command) | |
| 21 self.command=command | |
| 22 | |
| 23 class LocalPP(ProcessProtocol): | |
| 24 def __init__(self, step): | |
| 25 self.step = step | |
| 26 | |
| 27 def outReceived(self, data): | |
| 28 self.step.stdio_log.addStdout(data) | |
| 29 | |
| 30 def errReceived(self, data): | |
| 31 self.step.stdio_log.addStderr(data) | |
| 32 | |
| 33 def processEnded(self, status_object): | |
| 34 self.step.stdio_log.addHeader("exit status %d\n" % status_object.val
ue.exitCode) | |
| 35 self.step.processEnded(status_object) | |
| 36 | |
| 37 def start(self): | |
| 38 # render properties | |
| 39 properties = self.build.getProperties() | |
| 40 command = properties.render(self.command) | |
| 41 # set up argv | |
| 42 if type(command) in types.StringTypes: | |
| 43 if runtime.platformType == 'win32': | |
| 44 argv = os.environ['COMSPEC'].split() # allow %COMSPEC% to have a
rgs | |
| 45 if '/c' not in argv: argv += ['/c'] | |
| 46 argv += [command] | |
| 47 else: | |
| 48 # for posix, use /bin/sh. for other non-posix, well, doesn't | |
| 49 # hurt to try | |
| 50 argv = ['/bin/sh', '-c', command] | |
| 51 else: | |
| 52 if runtime.platformType == 'win32': | |
| 53 argv = os.environ['COMSPEC'].split() # allow %COMSPEC% to have a
rgs | |
| 54 if '/c' not in argv: argv += ['/c'] | |
| 55 argv += list(command) | |
| 56 else: | |
| 57 argv = command | |
| 58 | |
| 59 self.stdio_log = stdio_log = self.addLog("stdio") | |
| 60 | |
| 61 if type(command) in types.StringTypes: | |
| 62 stdio_log.addHeader(command.strip() + "\n\n") | |
| 63 else: | |
| 64 stdio_log.addHeader(" ".join(command) + "\n\n") | |
| 65 stdio_log.addHeader("** RUNNING ON BUILDMASTER **\n") | |
| 66 stdio_log.addHeader(" in dir %s\n" % os.getcwd()) | |
| 67 stdio_log.addHeader(" argv: %s\n" % (argv,)) | |
| 68 | |
| 69 # TODO add a timeout? | |
| 70 proc = reactor.spawnProcess(self.LocalPP(self), argv[0], argv) | |
| 71 # (the LocalPP object will call processEnded for us) | |
| 72 | |
| 73 def processEnded(self, status_object): | |
| 74 if status_object.value.exitCode != 0: | |
| 75 self.step_status.setText(["failed (%d)" % status_object.value.exitCo
de]) | |
| 76 self.finished(FAILURE) | |
| 77 else: | |
| 78 self.step_status.setText(["succeeded"]) | |
| 79 self.finished(SUCCESS) | |
| OLD | NEW |