From 0795cd4baa889e4ce7b4d77c20d9413e52b35fe6 Mon Sep 17 00:00:00 2001 From: Bob Trahan Date: Tue, 22 Nov 2011 11:36:57 -0800 Subject: [PATCH] Add cycle detection to celerity mapper Summary: create CelerityResourceGraph, which extends AbstractDirectedGraph. since we've done a bunch of work already to load the resource graph into memory CelerityResourceGraph simply stores a copy and makes loadEdges work off that stored copy. Test Plan: made phabricator-prefab require herald-rule-editor ~/code/phabricator> ./scripts/celerity_mapper.php webroot Finding static resources... Processing 154 files.......................................................................................................................................................... [2011-11-22 11:28:29] EXCEPTION: (Exception) Cycle detected in resource graph: phabricator-prefab => herald-rule-editor => phabricator-prefab at [/Users/btrahan/Dropbox/code/phabricator/scripts/celerity_mapper.php:173] fixed phabricator-prefab requiring herald-rule-editor. re-ran celerity_mapper and no errors! Reviewers: epriestley Reviewed By: epriestley CC: aran, btrahan, epriestley Differential Revision: 1132 --- scripts/celerity_mapper.php | 18 ++++++- src/__phutil_library_map__.php | 2 + .../celerity/graph/CelerityResourceGraph.php | 47 +++++++++++++++++++ .../celerity/graph/__init__.php | 13 +++++ 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/infrastructure/celerity/graph/CelerityResourceGraph.php create mode 100644 src/infrastructure/celerity/graph/__init__.php diff --git a/scripts/celerity_mapper.php b/scripts/celerity_mapper.php index 11bde8d467..373fe46ee4 100755 --- a/scripts/celerity_mapper.php +++ b/scripts/celerity_mapper.php @@ -130,7 +130,7 @@ foreach ($files as $path => $hash) { echo "\n"; $runtime_map = array(); - +$resource_graph = array(); $hash_map = array(); $parser = new PhutilDocblockParser(); @@ -168,6 +168,8 @@ foreach ($file_map as $path => $info) { $hash_map[$provides] = $info['hash']; + $resource_graph[$provides] = $requires; + $runtime_map[$provides] = array( 'uri' => $uri, 'type' => $type, @@ -176,6 +178,20 @@ foreach ($file_map as $path => $info) { ); } +$celerity_resource_graph = new CelerityResourceGraph(); +$celerity_resource_graph->addNodes($resource_graph); +$celerity_resource_graph->setResourceGraph($resource_graph); +$celerity_resource_graph->loadGraph(); + +foreach ($resource_graph as $provides => $requires) { + $cycle = $celerity_resource_graph->detectCycles($provides); + if ($cycle) { + throw new Exception( + "Cycle detected in resource graph: ". implode($cycle, " => ") + ); + } +} + $package_map = array(); foreach ($package_spec as $name => $package) { $hashes = array(); diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index a164adf5aa..67960fead6 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -83,6 +83,7 @@ phutil_register_library_map(array( 'AphrontWriteGuard' => 'aphront/writeguard', 'CelerityAPI' => 'infrastructure/celerity/api', 'CelerityResourceController' => 'infrastructure/celerity/controller', + 'CelerityResourceGraph' => 'infrastructure/celerity/graph', 'CelerityResourceMap' => 'infrastructure/celerity/map', 'CelerityStaticResourceResponse' => 'infrastructure/celerity/response', 'ConduitAPIMethod' => 'applications/conduit/method/base', @@ -813,6 +814,7 @@ phutil_register_library_map(array( 'AphrontTypeaheadTemplateView' => 'AphrontView', 'AphrontWebpageResponse' => 'AphrontResponse', 'CelerityResourceController' => 'AphrontController', + 'CelerityResourceGraph' => 'AbstractDirectedGraph', 'ConduitAPI_arcanist_Method' => 'ConduitAPIMethod', 'ConduitAPI_arcanist_projectinfo_Method' => 'ConduitAPI_arcanist_Method', 'ConduitAPI_conduit_connect_Method' => 'ConduitAPIMethod', diff --git a/src/infrastructure/celerity/graph/CelerityResourceGraph.php b/src/infrastructure/celerity/graph/CelerityResourceGraph.php new file mode 100644 index 0000000000..81b2dfbae8 --- /dev/null +++ b/src/infrastructure/celerity/graph/CelerityResourceGraph.php @@ -0,0 +1,47 @@ +graphSet) { + throw new Exception( + "Call setResourceGraph before loading the graph!" + ); + } + + $graph = $this->getResourceGraph(); + $edges = array(); + foreach ($nodes as $node) { + $edges[$node] = idx($graph, $node, array()); + } + return $edges; + } + + final public function setResourceGraph(array $graph) { + $this->resourceGraph = $graph; + $this->graphSet = true; + } + + private function getResourceGraph() { + return $this->resourceGraph; + } +} diff --git a/src/infrastructure/celerity/graph/__init__.php b/src/infrastructure/celerity/graph/__init__.php new file mode 100644 index 0000000000..ab99a26952 --- /dev/null +++ b/src/infrastructure/celerity/graph/__init__.php @@ -0,0 +1,13 @@ +