class DependencyResolver(object):
    def __init__(self, path, options):
        logging.debug("Creating DependencyResolver")
        self.graph  = DAG()
        self.root   = path
        self.opts   = options

    def scan(self):
        for root, dirs, files in os.walk(self.root):
            for name in files:
                (base, ext) = os.path.splitext(name)
                if ext in ['.css', '.js']:
                    data = self.scanfile(os.path.join(root, name))
                    for module in data[ 'module' ]:
                        self.graph.addNode(
                            Module(
                                module=module,
                                filename=data['filename'],
                                package=data['package'],
                                requires=data['requires']
                            )
                        )
        for module in self.graph.nodes():
            self.graph.addEdgesFromNode(module.id(), module.requirements())

        

    def scanfile(self, path):
        logging.debug( "Scanning file: %s" % path )
        metadata    = {
            "filename": path,
            "package":  [],
            "module":   [],
            "requires": []
        }

        with open( path, 'r' ) as f:
            in_comment  = False
            for line in f:
                if in_comment:
                    if re.search( "\*\/", line ):
                        in_comment = False
                    else:
                        tags = re.search( "@(?P<name>\w+)\s+(?P<value>.+)\s*$", line )
                        if tags:
                            (name, value) = (tags.group( 'name' ), re.split( '\s*,\s*', tags.group( 'value' )))
                            if metadata.has_key( name ):
                                metadata[ name ].extend(value)
                else:
                    if re.match( "\s*\/\*\*", line ):
                        in_comment = True
        logging.debug( "   - Result: %s" % metadata )
        return metadata
Example #2
0
class TestDAG(unittest.TestCase):
    def setUp(self):
        self.graph = DAG()
#
#   Insertion
#
    def test_insertion(self):
        self.assertEqual( len(self.graph.nodes()), 0 )
        self.graph.addNode(MockNode('id1'))
        self.assertTrue( self.graph.contains( 'id1' ) )
        self.assertRaises(DuplicateInsertionError, lambda: self.graph.addNode(MockNode('id1')))

    def test_edgeinsertion(self):
        self.graph.addNode(MockNode('id1'))
        self.graph.addNode(MockNode('id2'))
        self.assertRaises(NodeNotExists, lambda: self.graph.addEdge('id1', 'id3'))
        self.assertRaises(NodeNotExists, lambda: self.graph.addEdge('id3', 'id1'))

        self.graph.addEdge('id1', 'id2')
        self.assertEquals(self.graph.neighbors('id1'), [ 'id2' ])
        self.assertEquals(self.graph.neighbors('id2'), [])
#
#   Cycle Detection
#
    def test_cycledetection_simple(self):
        self.graph.addNode(MockNode('id1'))
        self.graph.addNode(MockNode('id2'))
        self.graph.addEdge('id1','id2')
        self.assertRaises(CyclicInsertionError, lambda: self.graph.addEdge('id2','id1'))
    
    def test_cycledetection_complex(self):
        prev = None
        for x in range( 100 ):
            self.graph.addNode(MockNode(x))
            if prev is not None:
                self.graph.addEdge(prev, x)
            prev = x
        self.assertRaises(CyclicInsertionError, lambda: self.graph.addEdge(99, 0))
#
#   Topological Sort
#
    def test_topologicalsort_empty(self):
        self.assertEquals( [], self.graph.topologicalSort(self.graph.nodes()))

    def test_topologicalsort_one(self):
        self.graph.addNode(MockNode('id1'))
        self.assertEquals( ['id1'], self.graph.topologicalSort(self.graph.nodes()))

    def test_topologicalsort_two(self):
        self.graph.addNode(MockNode('id1'))
        self.graph.addNode(MockNode('id2'))
        self.graph.addEdge('id1','id2')
        self.assertEquals( ['id2', 'id1'], self.graph.topologicalSort(self.graph.nodes()))

    def test_topologicalsort_many(self):
        prev = None
        list = []
        for x in range( 100 ):
            self.graph.addNode(MockNode(x))
            if prev is not None:
                self.graph.addEdge(prev, x)
            prev = x
            list.append( x )
        list.reverse()
        self.assertEquals( list, self.graph.topologicalSort(self.graph.nodes()))