"""
The version control service is a service that manages version control
of objects. In Zope 3, it will be a bona fide service. In Zope 2.x, it
will be implemented as a CMF tool.
As a general rule, we adopt the jargon of the WebDAV Delta-V spec. In
Delta-V terms, the version control service implements the repository,
maintaining a unique version history for each object under version
control. The version control service also provides the interfaces to
version control operations.
A 'versionable resource' is an object that may be put under version
control. In this implementation, any object whose state is entirely
ZODB-based and that supports the setting of an '__vc_info__' attribute
is considered a versionable resource.
The goal of this iteration of the version control service is to support
simple linear versioning, with support for labelled versions. It is
anticipated that a future version of the service and its interfaces will
support more advanced versioning concepts such as branching and merging.
Issues:
- Should user info appear in the API or be implicit?
"""
class VersionControlService:
"""The version control service interface serves as the main API for
version control operations. The version control service hides all
of the details of version data storage and retrieval."""
def isAVersionableResource(self, object):
"""
Returns true if the given object is a versionable resource.
Permission: public
"""
def isUnderVersionControl(self, object):
"""
Returns true if the given object is under version control.
Permission: public
"""
def isResourceUpToDate(self, object):
"""
Returns true if a resource is based on the latest version.
Permission: public
"""
def isResourceDirty(self, object):
"""
Returns true if changes have been made to a resource since it was
checked out.
Permission: public
"""
def getVersionInfo(self, object):
"""
Return the VersionInfo associated with the given object, or None
if the object is not under version control. The VersionInfo object
contains version control bookkeeping information.
Permission: public
"""
def applyVersionControl(self, object, description=''):
"""
Place the given object under version control. The optional text
description may be used by the service implementation to help users
locate resources in user interfaces. A VersionControlError will be
raised if the object is already under version control.
After being placed under version control, the resource is logically
in the 'checked-in' state.
Permission: ???
"""
def checkoutResourceTo(self, vh_id, place):
"""
TODO: document this.
Permission: ???
"""
def checkoutResource(self, object):
"""
Put the given version-controlled object into the 'checked-out'
state, allowing changes to be made to the object. If the object is
not under version control or the object is already checked out, a
VersionControlError will be raised.
Permission: ???
"""
def checkinResource(self, object, message=''):
"""
Check-in (create a new version) of the given object, updating the
state and bookkeeping information of the given object. The optional
message should describe the changes being committed. If the object
is not under version control or is already in the checked-in state,
a VersionControlError will be raised.
Permission: ???
"""
def uncheckoutResource(self, object):
"""
Discard changes to the given object made since the last checkout.
If the object is not under version control or is not checked out,
a VersionControlError will be raised.
Permission: ???
"""
def updateResource(self, object, selector=None):
"""
Update the state of the given object to that of a specific version
of the object. The object must be in the checked-in state to be
updated. The selector must be either a VersionSelector object or a
string that can be used to initialize a VersionSelector.
Permission: ???
"""
def getVersionOfResource(self, history_id, selector):
"""
Given a version history id and a version selector, return the
object as of that version. Note that the returned object has no
acquisition context. The selector must be either a VersionSelector
or a string that may be used to create a VersionSelector.
Permission: private (unrestricted code only)
"""
def getVersionIds(self, object):
"""
Return a sequence of the (string) version ids corresponding to the
available versions of an object. This should be used by UI elements
to populate version selection widgets, etc.
Permission: public
"""
def getVersionLabels(self, object):
"""
Return a sequence of the (string) labels corresponding to the
versions of the given object that have been associated with a
label. This should be used by UI elements to populate version
selection widgets, etc.
Permission: public
"""
def getVersionIdForLabel(self, object, label):
"""
In the context of the given version controlled object, return the
version id associated label, or None if no associated version id
is found.
Permission: public
"""
class VersionSelector:
"""A VersionSelector encapsulates the spelling and the details of
specifying a particular version from a version history. The
default selector understands explicit version ids and labels."""
def getVersionId(self, service, object):
"""
Get the specific version id that the selector refers to.
Permission: public
"""
class VersionInfo:
"""A VersionInfo object contains bookkeeping information for version
controlled objects. The bookkeeping information can be read (but
not changed) by restricted code."""
def getVersionHistoryId(self):
"""
Return the id of the version history associated with this object.
Permission: public
"""
def getSourceVersionId(self):
"""
Return the id of the version on which the current object is based.
Permission: public
"""
def getLabelInfo(self):
"""
Return any label that was associated with the object at checkout.
Permission: public
"""
def getStatus(self):
"""
Return a flag indicating the current status of the resource.
Permission: public
"""
# Status constants
CHECKED_OUT = 0
CHECKED_IN = 1
class ActionRecord:
"""An ActionRecord contains audit information about a version control
operation. Actions that cause audit records to be created include
checkout and checkin. Action record information can be read (but
not changed) by restricted code."""
def getTimeStamp(self):
"""
Return a (float) timestamp for the date / time of the action.
Permission: public
"""
def getActivityId(self):
"""
Return the id of the activity (branch) the action relates to. This
always returns None in the current version of the API.
Permission: public
"""
def getVersionId(self):
"""
Return the version id that the action was related to.
Permission: public
"""
def getAction(self):
"""
Return the action that was performed to cause this record, as one
of the possible action constants.
Permission: public
"""
# These action constants represent the possible auditable actions.
ACTION_CHECKOUT = 0
ACTION_CHECKIN = 1
def getMessage(self):
"""
Return the user-provided message associated with the action, or
the empty string if no message is associated with the action.
Permission: public
"""
def getResourcePath(self):
"""
Return a string representing the path of the resource that was the
original target of the operation causing the record.
Permission: public
"""
def getUserId(self):
"""
Return the user identifier (as a path) of the user that caused
the action.
Permission: public
"""
def ex_1():
# This example shows putting an object under version control.
object = folder.getObject('MyDocument.html')
portal_version_control.applyVersionControl(object)
# Now the object has version control info, which we can use to
# print or report version information.
vc_info = portal_version_control.getVersionInfo(object)
print 'This is version: %s' % vc_info.getSourceVersionId()
def ex_2():
# This example shows checking out a version controlled resource,
# making some changes, and checking it back in.
object = folder.getObject('MyDocument.html')
portal_version_control.checkoutResource(object)
# Make a bunch of changes...
object.manage_editFoo('bar')
portal_version_control.checkinResource(
message='Fixed typos in document properties.'
)