sourcestamp.py :  » Build » Buildbot » buildbot-0.8.0 » buildbot » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Build » Buildbot 
Buildbot » buildbot 0.8.0 » buildbot » sourcestamp.py
# -*- test-case-name: buildbot.test.test_sourcestamp -*-

from zope.interface import implements
from twisted.persisted import styles
from buildbot import util,interfaces

class SourceStamp(util.ComparableMixin, styles.Versioned):
    """This is a tuple of (branch, revision, patchspec, changes, project, repository).

    C{branch} is always valid, although it may be None to let the Source
    step use its default branch. There are three possibilities for the
    remaining elements:
     - (revision=REV, patchspec=None, changes=None): build REV. If REV is
       None, build the HEAD revision from the given branch. Note that REV
       must always be a string: SVN, Perforce, and other systems which use
       integers should provide a string here, but the Source checkout step
       will integerize it when making comparisons.
     - (revision=REV, patchspec=(LEVEL, DIFF), changes=None): checkout REV,
       then apply a patch to the source, with C{patch -pPATCHLEVEL <DIFF}.
       If REV is None, checkout HEAD and patch it.
     - (revision=None, patchspec=None, changes=[CHANGES]): let the Source
       step check out the latest revision indicated by the given Changes.
       CHANGES is a tuple of L{buildbot.changes.changes.Change} instances,
       and all must be on the same branch.
    """

    persistenceVersion = 2

    # all six of these are publically visible attributes
    branch = None
    revision = None
    patch = None
    changes = ()
    project = ''
    repository = ''
    ssid = None # filled in by db.get_sourcestampid()

    compare_attrs = ('branch', 'revision', 'patch', 'changes', 'project', 'repository')

    implements(interfaces.ISourceStamp)

    def __init__(self, branch=None, revision=None, patch=None,
                 changes=None, project='', repository=''):
        if revision is not None:
            if isinstance(revision, int):
                revision = str(revision)
        if patch is not None:
            patch_level = patch[0]
            patch_level = int(patch_level)
            patch_diff = patch[1]
            if len(patch) > 2:
                patch_subdir = patch[2]
        self.branch = branch
        self.revision = revision
        self.patch = patch
        self.project = project
        self.repository = repository
        if changes:
            self.changes = tuple(changes)
            # set branch and revision to most recent change
            self.branch = changes[-1].branch
            self.revision = str(changes[-1].revision)
            if not self.project:
                self.project = changes[-1].project
            if not self.repository:
                self.repository = changes[-1].repository

    def canBeMergedWith(self, other):
        if other.repository != self.repository:
            return False
        if other.branch != self.branch:
            return False # the builds are completely unrelated
        if other.project != self.project:
            return False

        if self.changes and other.changes:
            # TODO: consider not merging these. It's a tradeoff between
            # minimizing the number of builds and obtaining finer-grained
            # results.
            return True
        elif self.changes and not other.changes:
            return False # we're using changes, they aren't
        elif not self.changes and other.changes:
            return False # they're using changes, we aren't

        if self.patch or other.patch:
            return False # you can't merge patched builds with anything
        if self.revision == other.revision:
            # both builds are using the same specific revision, so they can
            # be merged. It might be the case that revision==None, so they're
            # both building HEAD.
            return True

        return False

    def mergeWith(self, others):
        """Generate a SourceStamp for the merger of me and all the other
        BuildRequests. This is called by a Build when it starts, to figure
        out what its sourceStamp should be."""

        # either we're all building the same thing (changes==None), or we're
        # all building changes (which can be merged)
        changes = []
        changes.extend(self.changes)
        for req in others:
            assert self.canBeMergedWith(req) # should have been checked already
            changes.extend(req.changes)
        newsource = SourceStamp(branch=self.branch,
                                revision=self.revision,
                                patch=self.patch,
                                project=self.project,
                                repository=self.repository,
                                changes=changes)
        return newsource

    def getAbsoluteSourceStamp(self, got_revision):
        return SourceStamp(branch=self.branch, revision=got_revision,
                           patch=self.patch, repository=self.repository,
                           project=self.project)

    def getText(self):
        # note: this won't work for VC systems with huge 'revision' strings
        text = []
        if self.project:
            text.append("for %s" % self.project)
        if self.repository:
            text.append("in %s" % self.repository)
        if self.revision is None:
            return text + [ "latest" ]
        text.append(str(self.revision))
        if self.branch:
            text.append("in '%s'" % self.branch)
        if self.patch:
            text.append("[patch]")
        return text

    def asDict(self):
        result = {}
        # Constant
        result['revision'] = self.revision
        # TODO(maruel): Make the patch content a suburl.
        result['hasPatch']= self.patch is not None
        result['branch'] = self.branch
        result['changes'] = [c.asDict() for c in getattr(self, 'changes', [])]
        result['project'] = self.project
        result['repository'] = self.repository
        return result

    def upgradeToVersion1(self):
        # version 0 was untyped; in version 1 and later, types matter.
        if self.branch is not None and not isinstance(self.branch, str):
            self.branch = str(self.branch)
        if self.revision is not None and not isinstance(self.revision, str):
            self.revision = str(self.revision)
        if self.patch is not None:
            self.patch = ( int(self.patch[0]), str(self.patch[1]) )

    def upgradeToVersion2(self):
        # version 1 did not have project or repository; just set them to a default ''
        self.project = ''
        self.repository = ''

# vim: set ts=4 sts=4 sw=4 et:
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.