"Fossies" - the Fresh Open Source Software Archive

Member "buildbot-2.3.1/buildbot/steps/source/darcs.py" (23 May 2019, 8652 Bytes) of package /linux/misc/buildbot-2.3.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "darcs.py" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.0.1_vs_2.1.0.

    1 # This file is part of Buildbot.  Buildbot is free software: you can
    2 # redistribute it and/or modify it under the terms of the GNU General Public
    3 # License as published by the Free Software Foundation, version 2.
    4 #
    5 # This program is distributed in the hope that it will be useful, but WITHOUT
    6 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    7 # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    8 # details.
    9 #
   10 # You should have received a copy of the GNU General Public License along with
   11 # this program; if not, write to the Free Software Foundation, Inc., 51
   12 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   13 #
   14 # Copyright Buildbot Team Members
   15 """
   16 Source step code for darcs
   17 """
   18 
   19 
   20 from twisted.internet import defer
   21 from twisted.internet import reactor
   22 from twisted.python import log
   23 
   24 from buildbot.config import ConfigErrors
   25 from buildbot.interfaces import WorkerTooOldError
   26 from buildbot.process import buildstep
   27 from buildbot.process import remotecommand
   28 from buildbot.process.results import SUCCESS
   29 from buildbot.steps.source.base import Source
   30 
   31 
   32 class Darcs(Source):
   33 
   34     """ Class for Darcs with all smarts """
   35 
   36     name = 'darcs'
   37 
   38     renderables = ['repourl']
   39     possible_methods = ('clobber', 'copy')
   40 
   41     def __init__(self, repourl=None, mode='incremental',
   42                  method=None, **kwargs):
   43 
   44         self.repourl = repourl
   45         self.method = method
   46         self.mode = mode
   47         super().__init__(**kwargs)
   48         errors = []
   49 
   50         if not self._hasAttrGroupMember('mode', self.mode):
   51             errors.append("mode %s is not one of %s" %
   52                           (self.mode, self._listAttrGroupMembers('mode')))
   53         if self.mode == 'incremental' and self.method:
   54             errors.append("Incremental mode does not require method")
   55 
   56         if self.mode == 'full':
   57             if self.method is None:
   58                 self.method = 'copy'
   59             elif self.method not in self.possible_methods:
   60                 errors.append("Invalid method for mode == %s" % (self.mode))
   61 
   62         if repourl is None:
   63             errors.append("you must provide repourl")
   64 
   65         if errors:
   66             raise ConfigErrors(errors)
   67 
   68     def startVC(self, branch, revision, patch):
   69         self.revision = revision
   70         self.stdio_log = self.addLogForRemoteCommands("stdio")
   71 
   72         d = self.checkDarcs()
   73 
   74         @d.addCallback
   75         def checkInstall(darcsInstalled):
   76             if not darcsInstalled:
   77                 raise WorkerTooOldError("Darcs is not installed on worker")
   78             return 0
   79         d.addCallback(lambda _: self.sourcedirIsPatched())
   80 
   81         @d.addCallback
   82         def checkPatched(patched):
   83             if patched:
   84                 return self.copy()
   85             return 0
   86 
   87         d.addCallback(self._getAttrGroupMember('mode', self.mode))
   88 
   89         if patch:
   90             d.addCallback(self.patch, patch)
   91         d.addCallback(self.parseGotRevision)
   92         d.addCallback(self.finish)
   93         d.addErrback(self.failed)
   94         return d
   95 
   96     def checkDarcs(self):
   97         cmd = remotecommand.RemoteShellCommand(self.workdir, ['darcs', '--version'],
   98                                                env=self.env,
   99                                                logEnviron=self.logEnviron,
  100                                                timeout=self.timeout)
  101         cmd.useLog(self.stdio_log, False)
  102         d = self.runCommand(cmd)
  103 
  104         @d.addCallback
  105         def evaluate(_):
  106             return cmd.rc == 0
  107         return d
  108 
  109     @defer.inlineCallbacks
  110     def mode_full(self, _):
  111         if self.method == 'clobber':
  112             yield self.clobber()
  113             return
  114         elif self.method == 'copy':
  115             yield self.copy()
  116             return
  117 
  118     @defer.inlineCallbacks
  119     def mode_incremental(self, _):
  120         updatable = yield self._sourcedirIsUpdatable()
  121         if not updatable:
  122             yield self._checkout()
  123         else:
  124             command = ['darcs', 'pull', '--all', '--verbose']
  125             yield self._dovccmd(command)
  126 
  127     def copy(self):
  128         cmd = remotecommand.RemoteCommand('rmdir', {'dir': self.workdir,
  129                                                     'logEnviron': self.logEnviron,
  130                                                     'timeout': self.timeout, })
  131         cmd.useLog(self.stdio_log, False)
  132         d = self.runCommand(cmd)
  133 
  134         self.workdir = 'source'
  135         d.addCallback(self.mode_incremental)
  136 
  137         @d.addCallback
  138         def copy(_):
  139             cmd = remotecommand.RemoteCommand('cpdir',
  140                                               {'fromdir': 'source',
  141                                                'todir': 'build',
  142                                                'logEnviron': self.logEnviron,
  143                                                'timeout': self.timeout, })
  144             cmd.useLog(self.stdio_log, False)
  145             d = self.runCommand(cmd)
  146             return d
  147 
  148         @d.addCallback
  149         def resetWorkdir(_):
  150             self.workdir = 'build'
  151             return 0
  152         return d
  153 
  154     def clobber(self):
  155         d = self.runRmdir(self.workdir)
  156         d.addCallback(lambda _: self._checkout())
  157         return d
  158 
  159     def _clone(self, abandonOnFailure=False):
  160         command = ['darcs', 'get', '--verbose',
  161                    '--lazy', '--repo-name', self.workdir]
  162         d = defer.succeed(0)
  163         if self.revision:
  164             d.addCallback(
  165                 lambda _: self.downloadFileContentToWorker('.darcs-context', self.revision))
  166             command.append('--context')
  167             command.append('.darcs-context')
  168 
  169         command.append(self.repourl)
  170         d.addCallback(lambda _: self._dovccmd(command, abandonOnFailure=abandonOnFailure,
  171                                               wkdir='.'))
  172 
  173         return d
  174 
  175     def _checkout(self):
  176 
  177         if self.retry:
  178             abandonOnFailure = (self.retry[1] <= 0)
  179         else:
  180             abandonOnFailure = True
  181 
  182         d = self._clone(abandonOnFailure)
  183 
  184         def _retry(res):
  185             if self.stopped or res == 0:
  186                 return res
  187             delay, repeats = self.retry
  188             if repeats > 0:
  189                 log.msg("Checkout failed, trying %d more times after %d seconds"
  190                         % (repeats, delay))
  191                 self.retry = (delay, repeats - 1)
  192                 df = defer.Deferred()
  193                 df.addCallback(lambda _: self.runRmdir(self.workdir))
  194                 df.addCallback(lambda _: self._checkout())
  195                 reactor.callLater(delay, df.callback, None)
  196                 return df
  197             return res
  198 
  199         if self.retry:
  200             d.addCallback(_retry)
  201         return d
  202 
  203     def finish(self, res):
  204         d = defer.succeed(res)
  205 
  206         @d.addCallback
  207         def _gotResults(results):
  208             self.setStatus(self.cmd, results)
  209             log.msg("Closing log, sending result of the command %s " %
  210                     (self.cmd))
  211             return results
  212         d.addCallback(self.finished)
  213         return d
  214 
  215     @defer.inlineCallbacks
  216     def parseGotRevision(self, _):
  217         revision = yield self._dovccmd(['darcs', 'changes', '--max-count=1'], collectStdout=True)
  218         self.updateSourceProperty('got_revision', revision)
  219         return 0
  220 
  221     def _dovccmd(self, command, collectStdout=False, initialStdin=None, decodeRC=None,
  222                  abandonOnFailure=True, wkdir=None):
  223         if not command:
  224             raise ValueError("No command specified")
  225 
  226         if decodeRC is None:
  227             decodeRC = {0: SUCCESS}
  228         workdir = wkdir or self.workdir
  229         cmd = remotecommand.RemoteShellCommand(workdir, command,
  230                                                env=self.env,
  231                                                logEnviron=self.logEnviron,
  232                                                timeout=self.timeout,
  233                                                collectStdout=collectStdout,
  234                                                initialStdin=initialStdin,
  235                                                decodeRC=decodeRC)
  236         cmd.useLog(self.stdio_log, False)
  237         d = self.runCommand(cmd)
  238 
  239         @d.addCallback
  240         def evaluateCommand(_):
  241             if abandonOnFailure and cmd.didFail():
  242                 log.msg("Source step failed while running command %s" % cmd)
  243                 raise buildstep.BuildStepFailed()
  244             if collectStdout:
  245                 return cmd.stdout
  246             return cmd.rc
  247         return d
  248 
  249     def _sourcedirIsUpdatable(self):
  250         return self.pathExists(self.build.path_module.join(self.workdir, '_darcs'))