Author: hwright
Date: Wed Jul 28 22:04:23 2010
New Revision: 980249
URL: http://svn.apache.org/viewvc?rev=980249&view=rev
Log:
More the item-fetching code to its own module, and update the tests.
Added:
labs/mouse/sources.py
- copied, changed from r979938, labs/mouse/mouse.py
Modified:
labs/mouse/mouse.py
labs/mouse/tests/test_mouse.py
Modified: labs/mouse/mouse.py
URL:
http://svn.apache.org/viewvc/labs/mouse/mouse.py?rev=980249&r1=980248&r2=980249&view=diff
==============================================================================
--- labs/mouse/mouse.py (original)
+++ labs/mouse/mouse.py Wed Jul 28 22:04:23 2010
@@ -34,12 +34,12 @@ For information about how to use mouse,
import os
import sys
-import tarfile
-import zipfile
import optparse
import xml.etree.cElementTree as ElementTree
+import sources
+
# Some constants
VERSION = '0.1'
@@ -47,35 +47,6 @@ VERSION = '0.1'
resources_path = os.path.join(sys.path[0], 'resources')
-class _UnknownArchiveError(Exception):
- '''An exception to communicate we've discovered a type of archive we can't
- handle.'''
-
- def __init__(self, target):
- self.target = target
-
- def __str__(self):
- return "Unable to read archive '%s'" % self.target
-
-
-class Item(object):
- '''An item which needs to be matched.'''
-
- def __init__(self, name, file):
- '''NAME is a label for the object. FILE is a file-like object from which
- the file contents will be grabbed. It does not need to be seekable,
- and its file pointer may not be preserved.'''
- self.name = name
- self.file = file
- self._content = None
-
- def get_content(self):
- '''Return the contents of this item.'''
- if not self._content:
- self._content = self.file.read()
- return self._content
-
-
class Result(object):
def __init__(self):
@@ -184,53 +155,6 @@ def filter_excludes(items, excludes):
return filter_generator
-def get_items(target):
- '''Using TARGET as the source, return a generator or iterable suitable for
- use as input to generate_report().'''
-
- # is the thing a directory?
- if os.path.isdir(target):
- def dir_gen_func():
- for (dirpath, dirnames, filenames) in os.walk(target):
- # ignore .svn directories, if in a working copy
- if '.svn' in dirnames:
- dirnames.remove('.svn')
-
- for filename in filenames:
- name = os.path.join(dirpath, filename)
- yield Item(name, open(name))
-
- return dir_gen_func
-
- # is the thing a tarfile?
- if tarfile.is_tarfile(target):
- tar = tarfile.open(target, 'r')
-
- def tar_gen_func():
- for info in tar.getmembers():
- if info.isdir():
- continue
- yield Item(info.name, tar.extractfile(info))
-
- return tar_gen_func
-
- # is the thing a zipfile?
- if zipfile.is_zipfile(target):
- zip = zipfile.ZipFile(target, 'r')
-
- def zip_gen_func():
- for info in zip.infolist():
- if info.filename[-1] == '/':
- continue
- yield Item(info.filename, zip.open(info))
-
- return zip_gen_func
-
- # if we get to this point, we've no idea what the user gave us, so throw
- # an appropriate exception
- raise _UnknownArchiveError(target)
-
-
def main():
'Parse the command line arguments, and use them to generate a mouse report.'
@@ -269,7 +193,7 @@ def main():
parser.error('mouse only supports one tarball or directory per run')
try:
- items = get_items(args[0])
+ items = sources.get_items(args[0])
except IOError:
parser.error('error reading \'%s\'' % args[0])
except _UnknownArchiveError as ex:
Copied: labs/mouse/sources.py (from r979938, labs/mouse/mouse.py)
URL:
http://svn.apache.org/viewvc/labs/mouse/sources.py?p2=labs/mouse/sources.py&p1=labs/mouse/mouse.py&r1=979938&r2=980249&rev=980249&view=diff
==============================================================================
--- labs/mouse/mouse.py (original)
+++ labs/mouse/sources.py Wed Jul 28 22:04:23 2010
@@ -33,18 +33,8 @@ For information about how to use mouse,
import os
-import sys
import tarfile
import zipfile
-import optparse
-
-import xml.etree.cElementTree as ElementTree
-
-
-# Some constants
-VERSION = '0.1'
-
-resources_path = os.path.join(sys.path[0], 'resources')
class _UnknownArchiveError(Exception):
@@ -76,114 +66,6 @@ class Item(object):
return self._content
-class Result(object):
-
- def __init__(self):
- self.header_name = '?????'
- self.license_family = '?????'
- self.license_approved = False
- self.type_name = 'standard'
-
-
-class Resource(object):
-
- def __init__(self, item, result):
- self._item = item
- self._result = result
-
- def to_element(self):
- elem = ElementTree.Element('resource')
- elem.set('name', self._item.name)
-
- child = ElementTree.SubElement(elem, 'header-sample')
- child.text = self._item.get_content()
-
- child = ElementTree.SubElement(elem, 'header-type')
- child.set('name', self._result.header_name)
-
- child = ElementTree.SubElement(elem, 'license-family')
- child.set('name', self._result.license_family)
-
- child = ElementTree.SubElement(elem, 'license-approval')
- if self._result.license_approved:
- child.set('name', 'true')
- else:
- child.set('name', 'false')
-
- child = ElementTree.SubElement(elem, 'type')
- child.set('name', self._result.type_name)
-
- return elem
-
-
-def generate_report(items):
- '''Return a generator which will produce Resource objects for each item
- in ITEMS.
-
- ITEMS is a generator (or other callable which will produce an iterable)
- which returns objects which mouse is to process. ITEMS should return
- objects of type Item (which see for details).'''
-
- def report_generator():
- for item in items():
- yield Resource(item, Result())
-
- return report_generator
-
-
-def process_report(report):
- '''Given REPORT, generate xml output representing its results.'''
-
- root = ElementTree.Element('rat-report')
-
- for resource in report():
- root.append(resource.to_element())
-
- return ElementTree.tostring(root)
-
-
-def transform_xslt(input_xml, stylesheet):
- '''Transform OUTPUT_XML, which should be valid xml (usually the result of
- calling process_report_xml()), according to the rules given in STYLESHEET.'''
-
- # Do the import here so that if people don't want to do xslt transforms,
- # they aren't required too
- import libxml2
- import libxslt
-
- styledoc = libxml2.parseFile(stylesheet)
- style = libxslt.parseStylesheetDoc(styledoc)
- doc = libxml2.parseMemory(input_xml, len(input_xml))
- result = style.applyStylesheet(doc, None)
- output_xml = style.saveResultToString(result)
-
- style.freeStylesheet()
- doc.freeDoc()
- result.freeDoc()
-
- return output_xml
-
-
-def filter_excludes(items, excludes):
- '''Return a filtered version of ITEMS, according to EXCLUDES.
-
- EXCLUDES should be a list of regular expression objects.'''
-
- def filter_generator():
- for item in items():
- matched = False
- for exclude in excludes:
- if exclude.match(item.name):
- matched = True
- break
- if matched:
- continue
- else:
- yield item
-
- return filter_generator
-
-
def get_items(target):
'''Using TARGET as the source, return a generator or iterable suitable for
use as input to generate_report().'''
@@ -229,67 +111,3 @@ def get_items(target):
# if we get to this point, we've no idea what the user gave us, so throw
# an appropriate exception
raise _UnknownArchiveError(target)
-
-
-def main():
- 'Parse the command line arguments, and use them to generate a mouse report.'
-
- # set up the option parser
- usage = 'usage: %prog [options] <DIR|TARBALL>'
- version = '%prog ' + VERSION
- parser = optparse.OptionParser(usage=usage, version=version)
- parser.add_option('-d', '--dir', action='store_true',
- help='Used to indicate source when using --exclude')
- parser.add_option('-e', '--exclude', action='store', metavar='expression',
- help='Excludes files matching <expression>. Note that ' +
- '--dir is required when using this parameter. ' +
- 'Allows multiple arguments.')
- parser.add_option('-s', '--stylesheet', action='store', metavar='arg',
- help='XSLT stylesheet to use when creating the report. ' +
- 'Not compatible with -x')
- parser.add_option('-x', '--xml', action='store_true',
- help='Output the report in raw XML format. Not '
- 'compatible with -s')
-
- (options, args) = parser.parse_args()
-
- # detect required argument bogosity
- if options.exclude and not options.dir:
- parser.error('--dir required when using --exclude')
- if options.stylesheet and options.xml:
- parser.error('--stylesheet and --xml are mutually exclusive')
- if options.stylesheet:
- try:
- import libxslt
- except:
- parser.error('cannot find python xslt module, needed for --stylesheet')
- if len(args) < 1:
- parser.error('no tarball or directory given')
- if len(args) > 1:
- parser.error('mouse only supports one tarball or directory per run')
-
- try:
- items = get_items(args[0])
- except IOError:
- parser.error('error reading \'%s\'' % args[0])
- except _UnknownArchiveError as ex:
- parser.error(str(ex))
-
- if options.exclude:
- items = filter_excludes(get_items(args[0]),
- open(options.exclude).read().split())
-
- report = generate_report(items)
-
- output = process_report(report)
- if options.stylesheet:
- output = transform_xslt(report, options.stylesheet)
- elif not options.xml:
- output = transform_xslt(report, os.path.join(resources_path,
- 'plain-rat.xsl'))
-
- print output
-
-
-if __name__ == '__main__':
- main()
Modified: labs/mouse/tests/test_mouse.py
URL:
http://svn.apache.org/viewvc/labs/mouse/tests/test_mouse.py?rev=980249&r1=980248&r2=980249&view=diff
==============================================================================
--- labs/mouse/tests/test_mouse.py (original)
+++ labs/mouse/tests/test_mouse.py Wed Jul 28 22:04:23 2010
@@ -31,6 +31,7 @@ import xml.etree.cElementTree as Element
sys.path.append(os.path.dirname(sys.path[0]))
import mouse
+import sources
data_path = 'data'
resources_path = os.path.join(os.path.dirname(sys.path[0]), 'resources')
@@ -92,7 +93,7 @@ class TestReport(unittest.TestCase):
'Test generating reports'
def test_greek_vanilla_xml(self):
- items = mouse.get_items(os.path.join(data_path, 'greek'))
+ items = sources.get_items(os.path.join(data_path, 'greek'))
report = mouse.generate_report(items)
output = mouse.process_report(report)
output_element = ElementTree.XML(output)
@@ -102,7 +103,7 @@ class TestReport(unittest.TestCase):
self.assertTrue(elements_are_same(output_element, target_element))
def test_greek_vanilla(self):
- items = mouse.get_items(os.path.join(data_path, 'greek'))
+ items = sources.get_items(os.path.join(data_path, 'greek'))
report = mouse.generate_report(items)
output = mouse.process_report(report)
output = mouse.transform_xslt(output, os.path.join(resources_path,
@@ -117,7 +118,7 @@ class TestFilters(unittest.TestCase):
'Test filtering various files and patterns'
def test_single_exclude(self):
- items = mouse.get_items(os.path.join(data_path, 'greek'))
+ items = sources.get_items(os.path.join(data_path, 'greek'))
self.assertEqual(12, _count_items(items))
items = mouse.filter_excludes(items, (re.compile('.*greek\/iota$'), ))
self.assertEqual(11, _count_items(items))
@@ -134,7 +135,7 @@ class TestSources(unittest.TestCase):
latin_path = os.path.join(data_path, 'latin')
def _assert_items(self, path):
- items = mouse.get_items(path)
+ items = sources.get_items(path)
self.assertEqual(12, _count_items(items))
def test_dir(self):
@@ -150,10 +151,10 @@ class TestSources(unittest.TestCase):
self._assert_items(self.zip_path)
def test_archive_error(self):
- self.assertRaises(IOError, mouse.get_items, self.latin_path)
+ self.assertRaises(IOError, sources.get_items, self.latin_path)
def test_bogus_filetype(self):
- self.assertRaises(mouse._UnknownArchiveError, mouse.get_items,
+ self.assertRaises(sources._UnknownArchiveError, sources.get_items,
self.iota_path)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]