Example #1
0
 def getRepository(self):
     # We currently only allow a single repository in a given context.
     if hasattr(self, '_v_repository'):
         return self._v_repository
     try:    items = self.superValues('Repository')
     except: items = self.aq_inner.aq_parent.superValues('Repository')
     result = items and items[0] or None
     if result is None:
         raise VersionControlError(
             'No versioning repository was found.'
             )
     self._v_repository = result
     return result
Example #2
0
    def applyVersionControl(self, object, message=None):
        if self.isUnderVersionControl(object):
            raise VersionControlError(
                'The resource is already under version control.')
        if not self.isAVersionableResource(object):
            raise VersionControlError(
                'This resource cannot be put under version control.')

        # Need to check the parent to see if the container of the object
        # being put under version control is itself a version-controlled
        # object. If so, we need to use the branch id of the container.
        branch = 'mainline'
        parent = aq_parent(aq_inner(object))
        p_info = getattr(parent, '__vc_info__', None)
        if p_info is not None:
            sticky = p_info.sticky
            if sticky and sticky[0] == 'B':
                branch = sticky[1]

        # Create a new version history and initial version object.
        history = self.createVersionHistory(object)
        version = history.createVersion(object, branch)

        history_id = history.getId()
        version_id = version.getId()

        # Add bookkeeping information to the version controlled object.
        info = VersionInfo(history_id, version_id, VersionInfo.CHECKED_IN)
        if branch != 'mainline':
            info.sticky = ('B', branch)
        object.__vc_info__ = info

        # Save an audit record of the action being performed.
        history.addLogEntry(version_id, LogEntry.ACTION_CHECKIN,
                            _findPath(object),
                            message is None and 'Initial checkin.' or message)
        return object
Example #3
0
 def labelVersion(self, version_id, label, force=0):
     """Associate a particular version in a version history with the
        given label, removing any existing association with that label
        if force is true, or raising an error if force is false and
        an association with the given label already exists."""
     current = self._labels.get(label)
     if current is not None:
         if current == version_id:
             return
         if not force:
             raise VersionControlError(
                 'The label %s is already associated with a version.' %
                 (label))
         del self._labels[label]
     self._labels[label] = version_id
Example #4
0
 def replaceState(self, obj, new_state):
     """Internal: replace the state of a persistent object.
     """
     non_versioned = getNonVersionedData(obj)
     # XXX There ought to be some way to do this more cleanly.
     # This fills the __dict__ of the old object with new state.
     # The other way to achieve the desired effect is to replace
     # the object in its container, but this method preserves the
     # identity of the object.
     if obj.__class__ is not new_state.__class__:
         raise VersionControlError(
             "The class of the versioned object has changed. %s != %s"
             % (repr(obj.__class__, new_state.__class__)))
     obj._p_changed = 1
     for key in obj.__dict__.keys():
         if not new_state.__dict__.has_key(key):
             del obj.__dict__[key]
     for key, value in new_state.__dict__.items():
         obj.__dict__[key] = value
     if non_versioned:
         # Restore the non-versioned data into the new state.
         restoreNonVersionedData(obj, non_versioned)
     return obj
Example #5
0
    def getVersionOfResource(self, history_id, selector):
        history = self.getVersionHistory(history_id)
        sticky = None

        if not selector or selector == 'mainline':
            version = history.getLatestVersion('mainline')
        else:
            if history.hasVersionId(selector):
                version = history.getVersionById(selector)
                sticky = ('V', selector)

            elif self._labels.has_key(selector):
                version = history.getVersionByLabel(selector)
                sticky = ('L', selector)

            elif self._branches.has_key(selector):
                version = history.getLatestVersion(selector)
                sticky = ('B', selector)
            else:
                try: date = DateTime(selector)
                except:
                    raise VersionControlError(
                        'Invalid version selector: %s' % selector
                        )
                else:
                    timestamp = date.timeTime()
                    sticky = ('D', timestamp)
                    version = history.getVersionByDate('mainline', timestamp)

        object = version.copyState()

        info = VersionInfo(history_id, version.getId(), VersionInfo.CHECKED_IN)
        if sticky is not None:
            info.sticky = sticky
        object.__vc_info__ = info
        return object
Example #6
0
    def updateResource(self, object, selector=None):
        info = self.getVersionInfo(object)
        if info.status != info.CHECKED_IN:
            raise VersionControlError(
                'The selected resource must be checked in to be updated.'
                )

        history = self.getVersionHistory(info.history_id)
        version = None
        sticky = info.sticky

        if not selector:
            # If selector is null, update to the latest version taking any
            # sticky attrs into account (branch, date). Note that the sticky
            # tag could also be a date or version id. We don't bother checking
            # for those, since in both cases we do nothing (because we'll
            # always be up to date until the sticky tag changes).
            if sticky and sticky[0] == 'L':
                # A label sticky tag, so update to that label (since it is
                # possible, but unlikely, that the label has been moved).
                version = history.getVersionByLabel(sticky[1])
            elif sticky and sticky[0] == 'B':
                # A branch sticky tag. Update to latest version on branch.
                version = history.getLatestVersion(selector)
            else:
                # Update to mainline, forgetting any date or version id
                # sticky tag that was previously associated with the object.
                version = history.getLatestVersion('mainline')
                sticky = None
        else:
            # If the selector is non-null, we find the version specified
            # and update the sticky tag. Later we'll check the version we
            # found and decide whether we really need to update the object.
            if history.hasVersionId(selector):
                version = history.getVersionById(selector)
                sticky = ('V', selector)

            elif self._labels.has_key(selector):
                version = history.getVersionByLabel(selector)
                sticky = ('L', selector)

            elif self._branches.has_key(selector):
                version = history.getLatestVersion(selector)
                if selector == 'mainline':
                    sticky = None
                else:
                    sticky = ('B', selector)
            else:
                try:    date = DateTime(selector)
                except:
                    raise VersionControlError(
                        'Invalid version selector: %s' % selector
                        )
                else:
                    timestamp = date.timeTime()
                    sticky = ('D', timestamp)
                    # Fix!
                    branch = history.findBranchId(info.version_id)
                    version = history.getVersionByDate(branch, timestamp)

        # If the state of the resource really needs to be changed, do the
        # update and make a log entry for the update.
        version_id = version and version.getId() or info.version_id
        new_object = object
        if version and (version_id != info.version_id):
            new_object = version.copyState()
            new_object = self.replaceState(object, new_object)

            history.addLogEntry(version_id,
                                LogEntry.ACTION_UPDATE,
                                _findPath(new_object)
                                )

        # Update bookkeeping information.
        newinfo = info.clone(1)
        newinfo.version_id = version_id
        newinfo.status = newinfo.CHECKED_IN
        if sticky is not None:
            newinfo.sticky = sticky
        new_object.__vc_info__ = newinfo
        return new_object
Example #7
0
 def getVersionInfo(self, object):
     info = getattr(object, '__vc_info__', None)
     if info is not None:
         return info
     raise VersionControlError(
         'The specified resource is not under version control.')