[Checkins] SVN: zf.zscp/trunk/src/zf/zscp/ Rename zscp.py to
repository.py and
Roger Ineichen
roger at projekt01.ch
Sun Apr 9 04:39:06 EDT 2006
Log message for revision 66705:
Rename zscp.py to repository.py and
implemented Repository in website
Changed:
A zf.zscp/trunk/src/zf/zscp/repository.py
A zf.zscp/trunk/src/zf/zscp/repository.txt
U zf.zscp/trunk/src/zf/zscp/tests.py
A zf.zscp/trunk/src/zf/zscp/website/repository.py
D zf.zscp/trunk/src/zf/zscp/zscp.py
D zf.zscp/trunk/src/zf/zscp/zscp.txt
-=-
Copied: zf.zscp/trunk/src/zf/zscp/repository.py (from rev 66704, zf.zscp/trunk/src/zf/zscp/zscp.py)
===================================================================
--- zf.zscp/trunk/src/zf/zscp/zscp.py 2006-04-09 08:25:41 UTC (rev 66704)
+++ zf.zscp/trunk/src/zf/zscp/repository.py 2006-04-09 08:39:05 UTC (rev 66705)
@@ -0,0 +1,216 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""ZSCP Data Management
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import os
+import os.path
+import pysvn
+import zope.event
+import zope.interface
+
+from zf.zscp import interfaces, package, publication, release, certification
+
+
+class ZSCPRepository(object):
+ """A ZSCP-compliant repository."""
+ zope.interface.implements(interfaces.IZSCPRepository)
+
+ def __init__(self, svnRoot, localRoot, password):
+ self.svnRoot = svnRoot
+ self.localRoot = localRoot
+ self.password = password
+
+ def _getClient(self):
+ """Get an SVN client."""
+ client = pysvn.Client()
+
+ def ssl_password(realm, may_save):
+ return True, self.password, True
+ client.callback_ssl_client_cert_password_prompt = ssl_password
+
+ return client
+
+ def initialize(self):
+ """See interfaces.IZSCPRepository"""
+ client = self._getClient()
+ # for each package that is already part of the ZSCP, make sure to
+ # check out the ZSCP data.
+ for name in self.fetch():
+ full_url = self.svnRoot + '/' + name + '/zscp'
+ local_path = os.path.join(self.localRoot, name)
+ client.checkout(full_url, local_path)
+ # Send out an event notification
+ zope.event.notify(interfaces.RepositoryInitializedEvent(self))
+
+ def register(self, pkg):
+ """See interfaces.IZSCPRepository"""
+ client = self._getClient()
+ full_url = self.svnRoot + '/' + pkg.name + '/zscp'
+ local_path = os.path.join(self.localRoot, pkg.name)
+ # Create a directory for zscp remotely
+ client.mkdir(full_url, 'Create a directory for the ZSCP process.')
+ # Check out the directory
+ client.checkout(full_url, local_path)
+ # Create a ZSCP.cfg file
+ zscp = {'publication': 'PUBLICATION.cfg',
+ 'releases': 'RELEASES.xml',
+ 'certifications': 'CERTIFICATIONS.xml'}
+ zscp_file = file(os.path.join(local_path, 'ZSCP.cfg'), 'w')
+ zscp_file.write(produce(zscp))
+ zscp_file.close()
+ # Now update that data
+ self.update(pkg)
+ # Add all files to the repository and check them in
+ client.add([os.path.join(local_path, 'ZSCP.cfg'),
+ os.path.join(local_path, 'PUBLICATION.cfg'),
+ os.path.join(local_path, 'RELEASES.xml'),
+ os.path.join(local_path, 'CERTIFICATIONS.xml')])
+ client.checkin(local_path, 'Initial addition of package data.')
+ # Send out an event notification
+ zope.event.notify(interfaces.PackageRegisteredEvent(pkg))
+
+ def unregister(self, pkg):
+ """See interfaces.IZSCPRepository"""
+ client = self._getClient()
+ full_url = self.svnRoot + '/' + pkg.name + '/zscp'
+ # Remove the directory
+ client.remove(full_url)
+ # Remove local checkout
+ # LAME! Simulate recursive delete!
+ def remove(arg, dirname, fnames):
+ for fname in fnames:
+ path = os.path.join(dirname, fname)
+ if os.path.isfile(path):
+ os.remove(path)
+
+ os.path.walk(os.path.join(self.localRoot, pkg.name), remove, None)
+ os.removedirs(os.path.join(self.localRoot, pkg.name))
+ # Send out an event notification
+ zope.event.notify(interfaces.PackageUnregisteredEvent(pkg))
+
+ def update(self, pkg):
+ """See interfaces.IZSCPRepository"""
+ client = self._getClient()
+ local_path = os.path.join(self.localRoot, pkg.name)
+ # Do checkout update
+ client.update(local_path)
+ # Load the ZSCP configuration
+ zscp_path = os.path.join(local_path, 'ZSCP.cfg')
+ zscp = process(file(zscp_path))
+ # Update publication
+ pub_file = file(os.path.join(local_path, zscp['publication']), 'w')
+ pub_file.write(publication.produce(pkg.publication))
+ pub_file.close()
+ # Update releases
+ rel_file = file(os.path.join(local_path, zscp['releases']), 'w')
+ rel_file.write(release.produceXML(pkg.releases))
+ rel_file.close()
+ # Update certifications
+ cert_file = file(os.path.join(local_path, zscp['certifications']), 'w')
+ cert_file.write(certification.produceXML(pkg.certifications))
+ cert_file.close()
+ # Commit the changes
+ client.checkin(local_path, 'Update of package data.')
+ # Send out an event notification
+ zope.event.notify(interfaces.PackageUpdatedEvent(pkg))
+
+ def fetch(self, all=False):
+ """See interfaces.IZSCPRepository"""
+ names = []
+ client = self._getClient()
+ for entry in client.ls(self.svnRoot):
+ name = os.path.split(entry['name'])[-1]
+ if all is True:
+ names.append(name)
+ else:
+ path = entry['name'] + '/zscp'
+ if path in [e['name'] for e in client.ls(entry['name'])]:
+ names.append(name)
+ return names
+
+ def __getitem__(self, key):
+ """See zope.interface.common.mapping.IItemMapping"""
+ if key not in os.listdir(self.localRoot):
+ raise KeyError, key
+
+ local_path = os.path.join(self.localRoot, key)
+ # Load the ZSCP configuration
+ zscp_path = os.path.join(local_path, 'ZSCP.cfg')
+ zscp = process(file(zscp_path))
+ # Create the package
+ pkg = package.Package(key)
+ # Add publication
+ pub_file = file(os.path.join(local_path, zscp['publication']), 'r')
+ pkg.publication = publication.process(pub_file)
+ pub_file.close()
+ # Add releases
+ rel_file = file(os.path.join(local_path, zscp['releases']), 'r')
+ pkg.releases = release.processXML(rel_file)
+ rel_file.close()
+ # Add certifications
+ cert_file = file(os.path.join(local_path, zscp['certifications']), 'r')
+ pkg.certifications = certification.processXML(cert_file)
+ cert_file.close()
+
+ return pkg
+
+ def keys(self):
+ """See zope.interface.common.mapping.IEnumerableMapping"""
+ return os.listdir(self.localRoot)
+
+ def get(self, key, default=None):
+ """See zope.interface.common.mapping.IReadMapping"""
+ try:
+ return self[key]
+ except KeyError:
+ return default
+
+ def __contains__(self, key):
+ """See zope.interface.common.mapping.IReadMapping"""
+ return key in self.keys()
+
+ def __iter__(self):
+ """See zope.interface.common.mapping.IEnumerableMapping"""
+ return iter(keys)
+
+ def values(self):
+ """See zope.interface.common.mapping.IEnumerableMapping"""
+ return [self[name] for name in self.keys()]
+
+ def items(self):
+ """See zope.interface.common.mapping.IEnumerableMapping"""
+ return [(name, self[name]) for name in self.keys()]
+
+ def __len__(self):
+ """See zope.interface.common.mapping.IEnumerableMapping"""
+ return len(self.keys())
+
+
+def process(file):
+ """Process the ZSCP.cfg file content."""
+ config = {}
+ for line in file.readlines():
+ line = line.strip()
+ if line.startswith('#') or not line:
+ continue
+ key, value = line.split(' ')
+ config[key] = value
+ return config
+
+def produce(zscp):
+ """Produce the ZSCP.cfg file content."""
+ return '\n'.join(['%s %s' %(key, value) for key, value in zscp.items()])
Copied: zf.zscp/trunk/src/zf/zscp/repository.txt (from rev 66704, zf.zscp/trunk/src/zf/zscp/zscp.txt)
===================================================================
--- zf.zscp/trunk/src/zf/zscp/zscp.txt 2006-04-09 08:25:41 UTC (rev 66704)
+++ zf.zscp/trunk/src/zf/zscp/repository.txt 2006-04-09 08:39:05 UTC (rev 66705)
@@ -0,0 +1,203 @@
+=====================
+A ZSCP Implementation
+=====================
+
+The zscp module,
+
+ >>> from zf.zscp import repository
+
+implements the process for an SVN repository. It is controoled by the ZSCP
+repository object:
+
+ >>> import tempfile
+ >>> localRoot = tempfile.mkdtemp()
+ >>> repos = repository.ZSCPRepository(
+ ... 'svn+ssh://svn.zope.org/repos/main', localRoot, 'mypass')
+
+The first argument of the constructor is the SVN URL to the repository, the
+second is the directory that will be used to checkout the ``zscp`` directories
+and the final argument is the passphrase for the SSL authentication.
+
+For the purpose of this test, we register a stub pysvn client:
+
+ >>> svnClient.root = 'svn+ssh://svn.zope.org/repos/main'
+ >>> repos._getClient = lambda : svnClient
+
+The initial test SVN repository looks as follows::
+
+ root/
+ zope.sample/
+ zscp/
+ ZSCP.cfg
+ PUBLICATION.cfg
+ RELEASES.xml
+ CERTIFICATIONS.xml
+ zope.sample1/
+ zope.sample2/
+
+With the setup all done, let's see how the ZSCP is realized. The first step is
+to initialize the repository, which means that all available package ``zscp``
+directories are checked out from the repository. In the local copy, those
+``zscp`` directories will be known by their package name:
+
+ >>> repos.initialize()
+
+ >>> import os
+ >>> os.listdir(localRoot)
+ ['zope.sample']
+
+Since only the ``zope.sample`` package has a ``zscp`` directory, it is the
+only one checked out. You can also use the ``fetch()`` method to get a list of
+all ZSCP packages in the repository:
+
+ >>> repos.fetch()
+ ['zope.sample']
+
+When you pass ``all=True`` to the method, then all packages in the repository
+will be returned:
+
+ >>> sorted(repos.fetch(all=True))
+ ['zope.sample', 'zope.sample1', 'zope.sample2']
+
+Once the repository is initialized, you can use the mapping interface to
+discover the content:
+
+ >>> len(repos)
+ 1
+
+ >>> 'zope.sample' in repos
+ True
+ >>> 'zope.sample1' in repos
+ False
+
+ >>> repos['zope.sample']
+ <Package 'zope.sample'>
+ >>> repos.get('zope.sample')
+ <Package 'zope.sample'>
+ >>> repos.get('zope.sample1') is None
+ True
+
+ >>> repos.keys()
+ ['zope.sample']
+ >>> repos.items()
+ [('zope.sample', <Package 'zope.sample'>)]
+ >>> repos.values()
+ [<Package 'zope.sample'>]
+
+Now we would like to register a new package with the ZSCP process. This is
+done by first creating a package ...
+
+ >>> from zf.zscp import package, publication
+ >>> sample1 = package.Package('zope.sample1')
+
+ >>> sample1.publication = publication.Publication()
+ >>> sample1.publication.packageName = 'zope.sample1'
+ >>> sample1.publication.name = u'Sample Package 1'
+ >>> sample1.publication.summary = u'This is the Sample Package 1.'
+ >>> sample1.publication.author = [u'Jane Doe']
+ >>> sample1.publication.authorEmail = [u'jane at doe.com']
+ >>> sample1.publication.license = [u'GPL 2.0']
+ >>> sample1.publication.metadataVersion = u'1.0'
+
+ >>> sample1.certifications = []
+ >>> sample1.releases = []
+
+and then registering it:
+
+ >>> repos.register(sample1)
+
+Let's make sure all the data was really stored in the SVN repository:
+
+ >>> sorted(repos.items())
+ [('zope.sample', <Package 'zope.sample'>),
+ ('zope.sample1', <Package 'zope.sample1'>)]
+
+ >>> svnClient.dir['zope.sample1']['zscp'].keys()
+ ['PUBLICATION.cfg', 'CERTIFICATIONS.xml', 'RELEASES.xml', 'ZSCP.cfg']
+
+At the beginning there are no certifications:
+
+ >>> sample1.certifications
+ []
+ >>> print svnClient.dir['zope.sample1']['zscp']['CERTIFICATIONS.xml'].read()
+ <certifications>
+ </certifications>
+
+Let's now add a certification:
+
+ >>> import datetime
+ >>> from zf.zscp import certification, contact
+ >>> listed = certification.Certification()
+ >>> listed.action = u'grant'
+ >>> listed.sourceLevel = u'none'
+ >>> listed.targetLevel = u'listed'
+ >>> listed.date = datetime.date(2006, 1, 1)
+ >>> listed.certificationManager = contact.Contact()
+ >>> listed.certificationManager.name = 'John Doe'
+ >>> listed.certificationManager.email = 'john at doe.com'
+ >>> sample1.certifications.append(listed)
+
+To update the checkout and the repository, we can do the following:
+
+ >>> repos.update(sample1)
+
+So now we should have an entry:
+
+ >>> sample1.certifications
+ [<Certification action=u'grant', source=u'none', target=u'listed'>]
+ >>> svnClient.dir['zope.sample1']['zscp']['CERTIFICATIONS.xml'].seek(0)
+ >>> print svnClient.dir['zope.sample1']['zscp']['CERTIFICATIONS.xml'].read()
+ <certifications>
+ <certification>
+ <action>grant</action>
+ <source-level>none</source-level>
+ <target-level>listed</target-level>
+ <date>2006-01-01</date>
+ <certification-manager>
+ <name>John Doe</name>
+ <email>john at doe.com</email>
+ </certification-manager>
+ </certification>
+ </certifications>
+
+In case a project wants to be removed from the ZSCP process, you simply
+unregister it:
+
+ >>> repos.unregister(sample1)
+
+It should be gone in the SVN repository and the local checkout:
+
+
+ >>> print svnClient.dir['zope.sample1'].keys()
+ []
+ >>> os.listdir(localRoot)
+ ['zope.sample']
+
+And that's it.
+
+
+Parsing and writing the ``ZSCP.cfg`` file
+-----------------------------------------
+
+It is necessary to parse the ``ZSCP.cfg`` file in order to determine the
+locations of the other data files.
+
+ >>> import StringIO
+ >>> config = StringIO.StringIO(u'''
+ ... publication PUBLICATION.cfg
+ ... releases RELEASES.xml
+ ... certifications CERTIFICATIONS.xml
+ ... ''')
+
+ >>> zscp_data = repository.process(config)
+ >>> pprint(zscp_data)
+ {u'certifications': u'CERTIFICATIONS.xml',
+ u'publication': u'PUBLICATION.cfg',
+ u'releases': u'RELEASES.xml'}
+
+On the other hand, we also need to be able create the contents of the file:
+
+ >>> print repository.produce(zscp_data)
+ certifications CERTIFICATIONS.xml
+ publication PUBLICATION.cfg
+ releases RELEASES.xml
Modified: zf.zscp/trunk/src/zf/zscp/tests.py
===================================================================
--- zf.zscp/trunk/src/zf/zscp/tests.py 2006-04-09 08:25:41 UTC (rev 66704)
+++ zf.zscp/trunk/src/zf/zscp/tests.py 2006-04-09 08:39:05 UTC (rev 66705)
@@ -197,7 +197,7 @@
DocFileSuite('publication.txt',
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
),
- DocFileSuite('zscp.txt',
+ DocFileSuite('repository.txt',
setUp=zscpSetUp,
globs={'pprint': pprint},
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
Added: zf.zscp/trunk/src/zf/zscp/website/repository.py
===================================================================
--- zf.zscp/trunk/src/zf/zscp/website/repository.py 2006-04-09 08:25:41 UTC (rev 66704)
+++ zf.zscp/trunk/src/zf/zscp/website/repository.py 2006-04-09 08:39:05 UTC (rev 66705)
@@ -0,0 +1,30 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""ZSCP Data Management
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+import persistent
+import zope.interface
+
+from zope.app.container.contained import Contained
+from zf.zscp.interfaces import IZSCPRepository
+from zf.zscp.repository import repository import ZSCPRepository
+
+
+class Repository(ZSCPRepository, persistent.Persistent, Contained):
+ """A ZSCP-compliant repository as content type."""
+ zope.interface.implements(IZSCPRepository)
Property changes on: zf.zscp/trunk/src/zf/zscp/website/repository.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Deleted: zf.zscp/trunk/src/zf/zscp/zscp.py
===================================================================
--- zf.zscp/trunk/src/zf/zscp/zscp.py 2006-04-09 08:25:41 UTC (rev 66704)
+++ zf.zscp/trunk/src/zf/zscp/zscp.py 2006-04-09 08:39:05 UTC (rev 66705)
@@ -1,218 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2005 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""ZSCP Data Management
-
-$Id$
-"""
-__docformat__ = "reStructuredText"
-import os
-import os.path
-import persistent
-import pysvn
-import zope.event
-import zope.interface
-from zope.app.container.contained import Contained
-
-from zf.zscp import interfaces, package, publication, release, certification
-
-
-class ZSCPRepository(persistent.Persistent, Contained):
- """A ZSCP-compliant repository."""
- zope.interface.implements(interfaces.IZSCPRepository)
-
- def __init__(self, svnRoot, localRoot, password):
- self.svnRoot = svnRoot
- self.localRoot = localRoot
- self.password = password
-
- def _getClient(self):
- """Get an SVN client."""
- client = pysvn.Client()
-
- def ssl_password(realm, may_save):
- return True, self.password, True
- client.callback_ssl_client_cert_password_prompt = ssl_password
-
- return client
-
- def initialize(self):
- """See interfaces.IZSCPRepository"""
- client = self._getClient()
- # for each package that is already part of the ZSCP, make sure to
- # check out the ZSCP data.
- for name in self.fetch():
- full_url = self.svnRoot + '/' + name + '/zscp'
- local_path = os.path.join(self.localRoot, name)
- client.checkout(full_url, local_path)
- # Send out an event notification
- zope.event.notify(interfaces.RepositoryInitializedEvent(self))
-
- def register(self, pkg):
- """See interfaces.IZSCPRepository"""
- client = self._getClient()
- full_url = self.svnRoot + '/' + pkg.name + '/zscp'
- local_path = os.path.join(self.localRoot, pkg.name)
- # Create a directory for zscp remotely
- client.mkdir(full_url, 'Create a directory for the ZSCP process.')
- # Check out the directory
- client.checkout(full_url, local_path)
- # Create a ZSCP.cfg file
- zscp = {'publication': 'PUBLICATION.cfg',
- 'releases': 'RELEASES.xml',
- 'certifications': 'CERTIFICATIONS.xml'}
- zscp_file = file(os.path.join(local_path, 'ZSCP.cfg'), 'w')
- zscp_file.write(produce(zscp))
- zscp_file.close()
- # Now update that data
- self.update(pkg)
- # Add all files to the repository and check them in
- client.add([os.path.join(local_path, 'ZSCP.cfg'),
- os.path.join(local_path, 'PUBLICATION.cfg'),
- os.path.join(local_path, 'RELEASES.xml'),
- os.path.join(local_path, 'CERTIFICATIONS.xml')])
- client.checkin(local_path, 'Initial addition of package data.')
- # Send out an event notification
- zope.event.notify(interfaces.PackageRegisteredEvent(pkg))
-
- def unregister(self, pkg):
- """See interfaces.IZSCPRepository"""
- client = self._getClient()
- full_url = self.svnRoot + '/' + pkg.name + '/zscp'
- # Remove the directory
- client.remove(full_url)
- # Remove local checkout
- # LAME! Simulate recursive delete!
- def remove(arg, dirname, fnames):
- for fname in fnames:
- path = os.path.join(dirname, fname)
- if os.path.isfile(path):
- os.remove(path)
-
- os.path.walk(os.path.join(self.localRoot, pkg.name), remove, None)
- os.removedirs(os.path.join(self.localRoot, pkg.name))
- # Send out an event notification
- zope.event.notify(interfaces.PackageUnregisteredEvent(pkg))
-
- def update(self, pkg):
- """See interfaces.IZSCPRepository"""
- client = self._getClient()
- local_path = os.path.join(self.localRoot, pkg.name)
- # Do checkout update
- client.update(local_path)
- # Load the ZSCP configuration
- zscp_path = os.path.join(local_path, 'ZSCP.cfg')
- zscp = process(file(zscp_path))
- # Update publication
- pub_file = file(os.path.join(local_path, zscp['publication']), 'w')
- pub_file.write(publication.produce(pkg.publication))
- pub_file.close()
- # Update releases
- rel_file = file(os.path.join(local_path, zscp['releases']), 'w')
- rel_file.write(release.produceXML(pkg.releases))
- rel_file.close()
- # Update certifications
- cert_file = file(os.path.join(local_path, zscp['certifications']), 'w')
- cert_file.write(certification.produceXML(pkg.certifications))
- cert_file.close()
- # Commit the changes
- client.checkin(local_path, 'Update of package data.')
- # Send out an event notification
- zope.event.notify(interfaces.PackageUpdatedEvent(pkg))
-
- def fetch(self, all=False):
- """See interfaces.IZSCPRepository"""
- names = []
- client = self._getClient()
- for entry in client.ls(self.svnRoot):
- name = os.path.split(entry['name'])[-1]
- if all is True:
- names.append(name)
- else:
- path = entry['name'] + '/zscp'
- if path in [e['name'] for e in client.ls(entry['name'])]:
- names.append(name)
- return names
-
- def __getitem__(self, key):
- """See zope.interface.common.mapping.IItemMapping"""
- if key not in os.listdir(self.localRoot):
- raise KeyError, key
-
- local_path = os.path.join(self.localRoot, key)
- # Load the ZSCP configuration
- zscp_path = os.path.join(local_path, 'ZSCP.cfg')
- zscp = process(file(zscp_path))
- # Create the package
- pkg = package.Package(key)
- # Add publication
- pub_file = file(os.path.join(local_path, zscp['publication']), 'r')
- pkg.publication = publication.process(pub_file)
- pub_file.close()
- # Add releases
- rel_file = file(os.path.join(local_path, zscp['releases']), 'r')
- pkg.releases = release.processXML(rel_file)
- rel_file.close()
- # Add certifications
- cert_file = file(os.path.join(local_path, zscp['certifications']), 'r')
- pkg.certifications = certification.processXML(cert_file)
- cert_file.close()
-
- return pkg
-
- def keys(self):
- """See zope.interface.common.mapping.IEnumerableMapping"""
- return os.listdir(self.localRoot)
-
- def get(self, key, default=None):
- """See zope.interface.common.mapping.IReadMapping"""
- try:
- return self[key]
- except KeyError:
- return default
-
- def __contains__(self, key):
- """See zope.interface.common.mapping.IReadMapping"""
- return key in self.keys()
-
- def __iter__(self):
- """See zope.interface.common.mapping.IEnumerableMapping"""
- return iter(keys)
-
- def values(self):
- """See zope.interface.common.mapping.IEnumerableMapping"""
- return [self[name] for name in self.keys()]
-
- def items(self):
- """See zope.interface.common.mapping.IEnumerableMapping"""
- return [(name, self[name]) for name in self.keys()]
-
- def __len__(self):
- """See zope.interface.common.mapping.IEnumerableMapping"""
- return len(self.keys())
-
-
-def process(file):
- """Process the ZSCP.cfg file content."""
- config = {}
- for line in file.readlines():
- line = line.strip()
- if line.startswith('#') or not line:
- continue
- key, value = line.split(' ')
- config[key] = value
- return config
-
-def produce(zscp):
- """Produce the ZSCP.cfg file content."""
- return '\n'.join(['%s %s' %(key, value) for key, value in zscp.items()])
Deleted: zf.zscp/trunk/src/zf/zscp/zscp.txt
===================================================================
--- zf.zscp/trunk/src/zf/zscp/zscp.txt 2006-04-09 08:25:41 UTC (rev 66704)
+++ zf.zscp/trunk/src/zf/zscp/zscp.txt 2006-04-09 08:39:05 UTC (rev 66705)
@@ -1,203 +0,0 @@
-=====================
-A ZSCP Implementation
-=====================
-
-The zscp module,
-
- >>> from zf.zscp import zscp
-
-implements the process for an SVN repository. It is controoled by the ZSCP
-repository object:
-
- >>> import tempfile
- >>> localRoot = tempfile.mkdtemp()
- >>> repos = zscp.ZSCPRepository(
- ... 'svn+ssh://svn.zope.org/repos/main', localRoot, 'mypass')
-
-The first argument of the constructor is the SVN URL to the repository, the
-second is the directory that will be used to checkout the ``zscp`` directories
-and the final argument is the passphrase for the SSL authentication.
-
-For the purpose of this test, we register a stub pysvn client:
-
- >>> svnClient.root = 'svn+ssh://svn.zope.org/repos/main'
- >>> repos._getClient = lambda : svnClient
-
-The initial test SVN repository looks as follows::
-
- root/
- zope.sample/
- zscp/
- ZSCP.cfg
- PUBLICATION.cfg
- RELEASES.xml
- CERTIFICATIONS.xml
- zope.sample1/
- zope.sample2/
-
-With the setup all done, let's see how the ZSCP is realized. The first step is
-to initialize the repository, which means that all available package ``zscp``
-directories are checked out from the repository. In the local copy, those
-``zscp`` directories will be known by their package name:
-
- >>> repos.initialize()
-
- >>> import os
- >>> os.listdir(localRoot)
- ['zope.sample']
-
-Since only the ``zope.sample`` package has a ``zscp`` directory, it is the
-only one checked out. You can also use the ``fetch()`` method to get a list of
-all ZSCP packages in the repository:
-
- >>> repos.fetch()
- ['zope.sample']
-
-When you pass ``all=True`` to the method, then all packages in the repository
-will be returned:
-
- >>> sorted(repos.fetch(all=True))
- ['zope.sample', 'zope.sample1', 'zope.sample2']
-
-Once the repository is initialized, you can use the mapping interface to
-discover the content:
-
- >>> len(repos)
- 1
-
- >>> 'zope.sample' in repos
- True
- >>> 'zope.sample1' in repos
- False
-
- >>> repos['zope.sample']
- <Package 'zope.sample'>
- >>> repos.get('zope.sample')
- <Package 'zope.sample'>
- >>> repos.get('zope.sample1') is None
- True
-
- >>> repos.keys()
- ['zope.sample']
- >>> repos.items()
- [('zope.sample', <Package 'zope.sample'>)]
- >>> repos.values()
- [<Package 'zope.sample'>]
-
-Now we would like to register a new package with the ZSCP process. This is
-done by first creating a package ...
-
- >>> from zf.zscp import package, publication
- >>> sample1 = package.Package('zope.sample1')
-
- >>> sample1.publication = publication.Publication()
- >>> sample1.publication.packageName = 'zope.sample1'
- >>> sample1.publication.name = u'Sample Package 1'
- >>> sample1.publication.summary = u'This is the Sample Package 1.'
- >>> sample1.publication.author = [u'Jane Doe']
- >>> sample1.publication.authorEmail = [u'jane at doe.com']
- >>> sample1.publication.license = [u'GPL 2.0']
- >>> sample1.publication.metadataVersion = u'1.0'
-
- >>> sample1.certifications = []
- >>> sample1.releases = []
-
-and then registering it:
-
- >>> repos.register(sample1)
-
-Let's make sure all the data was really stored in the SVN repository:
-
- >>> sorted(repos.items())
- [('zope.sample', <Package 'zope.sample'>),
- ('zope.sample1', <Package 'zope.sample1'>)]
-
- >>> svnClient.dir['zope.sample1']['zscp'].keys()
- ['PUBLICATION.cfg', 'CERTIFICATIONS.xml', 'RELEASES.xml', 'ZSCP.cfg']
-
-At the beginning there are no certifications:
-
- >>> sample1.certifications
- []
- >>> print svnClient.dir['zope.sample1']['zscp']['CERTIFICATIONS.xml'].read()
- <certifications>
- </certifications>
-
-Let's now add a certification:
-
- >>> import datetime
- >>> from zf.zscp import certification, contact
- >>> listed = certification.Certification()
- >>> listed.action = u'grant'
- >>> listed.sourceLevel = u'none'
- >>> listed.targetLevel = u'listed'
- >>> listed.date = datetime.date(2006, 1, 1)
- >>> listed.certificationManager = contact.Contact()
- >>> listed.certificationManager.name = 'John Doe'
- >>> listed.certificationManager.email = 'john at doe.com'
- >>> sample1.certifications.append(listed)
-
-To update the checkout and the repository, we can do the following:
-
- >>> repos.update(sample1)
-
-So now we should have an entry:
-
- >>> sample1.certifications
- [<Certification action=u'grant', source=u'none', target=u'listed'>]
- >>> svnClient.dir['zope.sample1']['zscp']['CERTIFICATIONS.xml'].seek(0)
- >>> print svnClient.dir['zope.sample1']['zscp']['CERTIFICATIONS.xml'].read()
- <certifications>
- <certification>
- <action>grant</action>
- <source-level>none</source-level>
- <target-level>listed</target-level>
- <date>2006-01-01</date>
- <certification-manager>
- <name>John Doe</name>
- <email>john at doe.com</email>
- </certification-manager>
- </certification>
- </certifications>
-
-In case a project wants to be removed from the ZSCP process, you simply
-unregister it:
-
- >>> repos.unregister(sample1)
-
-It should be gone in the SVN repository and the local checkout:
-
-
- >>> print svnClient.dir['zope.sample1'].keys()
- []
- >>> os.listdir(localRoot)
- ['zope.sample']
-
-And that's it.
-
-
-Parsing and writing the ``ZSCP.cfg`` file
------------------------------------------
-
-It is necessary to parse the ``ZSCP.cfg`` file in order to determine the
-locations of the other data files.
-
- >>> import StringIO
- >>> config = StringIO.StringIO(u'''
- ... publication PUBLICATION.cfg
- ... releases RELEASES.xml
- ... certifications CERTIFICATIONS.xml
- ... ''')
-
- >>> zscp_data = zscp.process(config)
- >>> pprint(zscp_data)
- {u'certifications': u'CERTIFICATIONS.xml',
- u'publication': u'PUBLICATION.cfg',
- u'releases': u'RELEASES.xml'}
-
-On the other hand, we also need to be able create the contents of the file:
-
- >>> print zscp.produce(zscp_data)
- certifications CERTIFICATIONS.xml
- publication PUBLICATION.cfg
- releases RELEASES.xml
More information about the Checkins
mailing list