MediaWiki REL1_34
makeRepo.php
Go to the documentation of this file.
1<?php
2
4
5require __DIR__ . '/../Maintenance.php';
6
7class HHVMMakeRepo extends Maintenance {
8 function __construct() {
9 parent::__construct();
10 $this->addDescription( 'Compile PHP sources for this MediaWiki instance, ' .
11 'and generate an HHVM bytecode file to be used with HHVM\'s ' .
12 'RepoAuthoritative mode. The MediaWiki core installation path and ' .
13 'all registered extensions are automatically searched for the file ' .
14 'extensions *.php, *.inc, *.php5 and *.phtml.' );
15 $this->addOption( 'output', 'Output filename', true, true, 'o' );
16 $this->addOption( 'input-dir', 'Add an input directory. ' .
17 'This can be specified multiple times.', false, true, 'd', true );
18 $this->addOption( 'exclude-dir', 'Directory to exclude. ' .
19 'This can be specified multiple times.', false, true, false, true );
20 $this->addOption( 'extension', 'Extra file extension', false, true, false, true );
21 $this->addOption( 'hhvm', 'Location of HHVM binary', false, true );
22 $this->addOption( 'base-dir', 'The root of all source files. ' .
23 'This must match hhvm.server.source_root in the server\'s configuration file. ' .
24 'By default, the MW core install path will be used.',
25 false, true );
26 $this->addOption( 'verbose', 'Log level 0-3', false, true, 'v' );
27 }
28
29 private static function startsWith( $subject, $search ) {
30 return substr( $subject, 0, strlen( $search ) === $search );
31 }
32
33 function execute() {
35
36 $dirs = [ $IP ];
37
38 foreach ( $wgExtensionCredits as $type => $extensions ) {
39 foreach ( $extensions as $extension ) {
40 if ( isset( $extension['path'] )
41 && !self::startsWith( $extension['path'], $IP )
42 ) {
43 $dirs[] = dirname( $extension['path'] );
44 }
45 }
46 }
47
48 $dirs = array_merge( $dirs, $this->getOption( 'input-dir', [] ) );
49 $fileExts =
50 [
51 'php' => true,
52 'inc' => true,
53 'php5' => true,
54 'phtml' => true
55 ] +
56 array_flip( $this->getOption( 'extension', [] ) );
57
58 $dirs = array_unique( $dirs );
59
60 $baseDir = $this->getOption( 'base-dir', $IP );
61 $excludeDirs = array_map( 'realpath', $this->getOption( 'exclude-dir', [] ) );
62
63 if ( $baseDir !== '' && substr( $baseDir, -1 ) !== '/' ) {
64 $baseDir .= '/';
65 }
66
67 $unfilteredFiles = [ "$IP/LocalSettings.php" ];
68 foreach ( $dirs as $dir ) {
69 $this->appendDir( $unfilteredFiles, $dir );
70 }
71
72 $files = [];
73 foreach ( $unfilteredFiles as $file ) {
74 $dotPos = strrpos( $file, '.' );
75 $slashPos = strrpos( $file, '/' );
76 if ( $dotPos === false || $slashPos === false || $dotPos < $slashPos ) {
77 continue;
78 }
79 $extension = substr( $file, $dotPos + 1 );
80 if ( !isset( $fileExts[$extension] ) ) {
81 continue;
82 }
83 $canonical = realpath( $file );
84 foreach ( $excludeDirs as $excluded ) {
85 if ( self::startsWith( $canonical, $excluded ) ) {
86 continue 2;
87 }
88 }
89 if ( self::startsWith( $file, $baseDir ) ) {
90 $file = substr( $file, strlen( $baseDir ) );
91 }
92 $files[] = $file;
93 }
94
95 $files = array_unique( $files );
96
97 print "Found " . count( $files ) . " files in " .
98 count( $dirs ) . " directories\n";
99
100 $tmpDir = wfTempDir() . '/mw-make-repo' . mt_rand( 0, 1 << 31 );
101 if ( !mkdir( $tmpDir ) ) {
102 $this->fatalError( 'Unable to create temporary directory' );
103 }
104 file_put_contents( "$tmpDir/file-list", implode( "\n", $files ) );
105
106 $hhvm = $this->getOption( 'hhvm', 'hhvm' );
107 $verbose = $this->getOption( 'verbose', 3 );
108 $cmd = Shell::escape(
109 $hhvm,
110 '--hphp',
111 '--target', 'hhbc',
112 '--format', 'binary',
113 '--force', '1',
114 '--keep-tempdir', '1',
115 '--log', $verbose,
116 '-v', 'AllVolatile=true',
117 '--input-dir', $baseDir,
118 '--input-list', "$tmpDir/file-list",
119 '--output-dir', $tmpDir );
120 print "$cmd\n";
121 passthru( $cmd, $ret );
122 if ( $ret ) {
123 $this->cleanupTemp( $tmpDir );
124 $this->fatalError( "Error: HHVM returned error code $ret" );
125 }
126 if ( !rename( "$tmpDir/hhvm.hhbc", $this->getOption( 'output' ) ) ) {
127 $this->cleanupTemp( $tmpDir );
128 $this->fatalError( "Error: unable to rename output file" );
129 }
130 $this->cleanupTemp( $tmpDir );
131 return 0;
132 }
133
134 private function cleanupTemp( $tmpDir ) {
135 if ( file_exists( "$tmpDir/hhvm.hhbc" ) ) {
136 unlink( "$tmpDir/hhvm.hhbc" );
137 }
138 if ( file_exists( "$tmpDir/Stats.js" ) ) {
139 unlink( "$tmpDir/Stats.js" );
140 }
141
142 unlink( "$tmpDir/file-list" );
143 rmdir( $tmpDir );
144 }
145
146 private function appendDir( &$files, $dir ) {
147 $iter = new RecursiveIteratorIterator(
148 new RecursiveDirectoryIterator(
149 $dir,
150 FilesystemIterator::UNIX_PATHS
151 ),
152 RecursiveIteratorIterator::LEAVES_ONLY
153 );
155 foreach ( $iter as $file => $fileInfo ) {
156 if ( $fileInfo->isFile() ) {
157 $files[] = $file;
158 }
159 }
160 }
161}
162
163$maintClass = HHVMMakeRepo::class;
$wgExtensionCredits
An array of information about installed extensions keyed by their type.
wfTempDir()
Tries to get the system directory for temporary files.
const RUN_MAINTENANCE_IF_MAIN
$IP
Definition WebStart.php:41
__construct()
Default constructor.
Definition makeRepo.php:8
execute()
Do the actual work.
Definition makeRepo.php:33
static startsWith( $subject, $search)
Definition makeRepo.php:29
appendDir(&$files, $dir)
Definition makeRepo.php:146
cleanupTemp( $tmpDir)
Definition makeRepo.php:134
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
addDescription( $text)
Set the description text.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
getOption( $name, $default=null)
Get an option, or return the default.
fatalError( $msg, $exitCode=1)
Output a message and terminate the current script.
Executes shell commands.
Definition Shell.php:44
while(( $__line=Maintenance::readconsole()) !==false) print
Definition eval.php:64
$maintClass
Definition makeRepo.php:163
return true
Definition router.php:94
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition router.php:42