| 
									
										
										
										
											2011-01-25 09:59:31 -08:00
										 |  |  | #!/usr/bin/env php
 | 
					
						
							|  |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-29 16:10:05 -08:00
										 |  |  | $package_spec = array( | 
					
						
							|  |  |  |   'core.pkg.css' => array( | 
					
						
							|  |  |  |     'phabricator-core-css', | 
					
						
							|  |  |  |     'phabricator-core-buttons-css', | 
					
						
							|  |  |  |     'phabricator-standard-page-view', | 
					
						
							|  |  |  |     'aphront-dialog-view-css', | 
					
						
							|  |  |  |     'aphront-form-view-css', | 
					
						
							|  |  |  |     'aphront-panel-view-css', | 
					
						
							|  |  |  |     'aphront-side-nav-view-css', | 
					
						
							|  |  |  |     'aphront-table-view-css', | 
					
						
							|  |  |  |     'aphront-tokenizer-control-css', | 
					
						
							|  |  |  |     'aphront-typeahead-control-css', | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     'phabricator-directory-css', | 
					
						
							|  |  |  |   ), | 
					
						
							|  |  |  |   'differential.pkg.css' => array( | 
					
						
							|  |  |  |     'differential-core-view-css', | 
					
						
							|  |  |  |     'differential-changeset-view-css', | 
					
						
							|  |  |  |     'differential-revision-detail-css', | 
					
						
							|  |  |  |     'differential-revision-history-css', | 
					
						
							|  |  |  |     'differential-table-of-contents-css', | 
					
						
							|  |  |  |   ), | 
					
						
							|  |  |  | ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-25 09:59:31 -08:00
										 |  |  | require_once dirname(__FILE__).'/__init_script__.php'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if ($argc != 2) { | 
					
						
							|  |  |  |   $self = basename($argv[0]); | 
					
						
							|  |  |  |   echo "usage: {$self} <webroot>\n"; | 
					
						
							|  |  |  |   exit(1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | phutil_require_module('phutil', 'filesystem'); | 
					
						
							|  |  |  | phutil_require_module('phutil', 'filesystem/filefinder'); | 
					
						
							|  |  |  | phutil_require_module('phutil', 'future/exec'); | 
					
						
							|  |  |  | phutil_require_module('phutil', 'parser/docblock'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $root = Filesystem::resolvePath($argv[1]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | echo "Finding static resources...\n"; | 
					
						
							|  |  |  | $files = id(new FileFinder($root)) | 
					
						
							|  |  |  |   ->withType('f') | 
					
						
							|  |  |  |   ->withSuffix('js') | 
					
						
							|  |  |  |   ->withSuffix('css') | 
					
						
							|  |  |  |   ->setGenerateChecksums(true) | 
					
						
							|  |  |  |   ->find(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | echo "Processing ".count($files)." files"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $file_map = array(); | 
					
						
							|  |  |  | foreach ($files as $path => $hash) { | 
					
						
							|  |  |  |   echo "."; | 
					
						
							|  |  |  |   $name = '/'.Filesystem::readablePath($path, $root); | 
					
						
							|  |  |  |   $file_map[$name] = array( | 
					
						
							|  |  |  |     'hash' => $hash, | 
					
						
							|  |  |  |     'disk' => $path, | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | echo "\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $runtime_map = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-29 16:10:05 -08:00
										 |  |  | $hash_map = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-25 09:59:31 -08:00
										 |  |  | $parser = new PhutilDocblockParser(); | 
					
						
							|  |  |  | foreach ($file_map as $path => $info) { | 
					
						
							|  |  |  |   $data = Filesystem::readFile($info['disk']); | 
					
						
							|  |  |  |   $matches = array(); | 
					
						
							|  |  |  |   $ok = preg_match('@/[*][*].*?[*]/@s', $data, $matches); | 
					
						
							|  |  |  |   if (!$ok) { | 
					
						
							|  |  |  |     throw new Exception( | 
					
						
							|  |  |  |       "File {$path} does not have a header doc comment. Encode dependency ". | 
					
						
							|  |  |  |       "data in a header docblock."); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   list($description, $metadata) = $parser->parse($matches[0]); | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   $provides = preg_split('/\s+/', trim(idx($metadata, 'provides'))); | 
					
						
							|  |  |  |   $requires = preg_split('/\s+/', trim(idx($metadata, 'requires'))); | 
					
						
							|  |  |  |   $provides = array_filter($provides); | 
					
						
							|  |  |  |   $requires = array_filter($requires); | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   if (count($provides) !== 1) { | 
					
						
							|  |  |  |     throw new Exception( | 
					
						
							|  |  |  |       "File {$path} must @provide exactly one Celerity target."); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   $provides = reset($provides); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   $type = 'js'; | 
					
						
							|  |  |  |   if (preg_match('/\.css$/', $path)) { | 
					
						
							|  |  |  |     $type = 'css'; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2011-01-29 16:10:05 -08:00
										 |  |  |   $uri = '/res/'.substr($info['hash'], 0, 8).$path; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   $hash_map[$provides] = $info['hash']; | 
					
						
							| 
									
										
										
										
											2011-01-25 09:59:31 -08:00
										 |  |  |    | 
					
						
							|  |  |  |   $runtime_map[$provides] = array( | 
					
						
							| 
									
										
										
										
											2011-01-29 16:10:05 -08:00
										 |  |  |     'uri'       => $uri, | 
					
						
							| 
									
										
										
										
											2011-01-25 09:59:31 -08:00
										 |  |  |     'type'      => $type, | 
					
						
							|  |  |  |     'requires'  => $requires, | 
					
						
							| 
									
										
										
										
											2011-01-29 16:10:05 -08:00
										 |  |  |     'disk'      => $path, | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $package_map = array(); | 
					
						
							|  |  |  | foreach ($package_spec as $name => $package) { | 
					
						
							|  |  |  |   $hashes = array(); | 
					
						
							| 
									
										
										
										
											2011-01-29 16:16:09 -08:00
										 |  |  |   $type = null; | 
					
						
							| 
									
										
										
										
											2011-01-29 16:10:05 -08:00
										 |  |  |   foreach ($package as $symbol) { | 
					
						
							|  |  |  |     if (empty($hash_map[$symbol])) { | 
					
						
							|  |  |  |       throw new Exception( | 
					
						
							|  |  |  |         "Package specification for '{$name}' includes '{$symbol}', but that ". | 
					
						
							|  |  |  |         "symbol is not defined anywhere."); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-01-29 16:16:09 -08:00
										 |  |  |     if ($type === null) { | 
					
						
							|  |  |  |       $type = $runtime_map[$symbol]['type']; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       $ntype = $runtime_map[$symbol]['type']; | 
					
						
							|  |  |  |       if ($type !== $ntype) { | 
					
						
							|  |  |  |         throw new Exception( | 
					
						
							|  |  |  |           "Package specification for '{$name}' mixes resources of type ". | 
					
						
							|  |  |  |           "'{$type}' with resources of type '{$ntype}'. Each package may only ". | 
					
						
							|  |  |  |           "contain one type of resource."); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-01-29 16:10:05 -08:00
										 |  |  |     $hashes[] = $symbol.':'.$hash_map[$symbol]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   $key = substr(md5(implode("\n", $hashes)), 0, 8); | 
					
						
							|  |  |  |   $package_map['packages'][$key] = array( | 
					
						
							|  |  |  |     'name'    => $name, | 
					
						
							|  |  |  |     'symbols' => $package, | 
					
						
							|  |  |  |     'uri'     => '/res/pkg/'.$key.'/'.$name, | 
					
						
							| 
									
										
										
										
											2011-01-29 16:16:09 -08:00
										 |  |  |     'type'    => $type, | 
					
						
							| 
									
										
										
										
											2011-01-25 09:59:31 -08:00
										 |  |  |   ); | 
					
						
							| 
									
										
										
										
											2011-01-29 16:10:05 -08:00
										 |  |  |   foreach ($package as $symbol) { | 
					
						
							|  |  |  |     $package_map['reverse'][$symbol] = $key; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-01-25 09:59:31 -08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2011-01-29 16:10:05 -08:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2011-01-25 09:59:31 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | $runtime_map = var_export($runtime_map, true); | 
					
						
							|  |  |  | $runtime_map = preg_replace('/\s+$/m', '', $runtime_map); | 
					
						
							|  |  |  | $runtime_map = preg_replace('/array \(/', 'array(', $runtime_map); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-29 16:10:05 -08:00
										 |  |  | $package_map = var_export($package_map, true); | 
					
						
							|  |  |  | $pacakge_map = preg_replace('/\s+$/m', '', $package_map); | 
					
						
							|  |  |  | $package_map = preg_replace('/array \(/', 'array(', $package_map); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-25 09:59:31 -08:00
										 |  |  | $resource_map = <<<EOFILE | 
					
						
							|  |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * This file is automatically generated. Use 'celerity_mapper.php' to rebuild | 
					
						
							|  |  |  |  * it. | 
					
						
							|  |  |  |  * @generated | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-29 16:10:05 -08:00
										 |  |  | celerity_register_resource_map({$runtime_map}, {$pacakge_map}); | 
					
						
							| 
									
										
										
										
											2011-01-25 09:59:31 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | EOFILE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | echo "Writing map...\n"; | 
					
						
							|  |  |  | Filesystem::writeFile( | 
					
						
							|  |  |  |   $root.'/../src/__celerity_resource_map__.php', | 
					
						
							|  |  |  |   $resource_map); | 
					
						
							|  |  |  | echo "Done.\n";   |