diff --git a/lib/Minify/NailgunClosureCompiler.php b/lib/Minify/NailgunClosureCompiler.php new file mode 100644 index 0000000..6634bd4 --- /dev/null +++ b/lib/Minify/NailgunClosureCompiler.php @@ -0,0 +1,104 @@ + + * @link https://github.com/martylamb/nailgun + */ +class Minify_NailgunClosureCompiler extends Minify_ClosureCompiler +{ + const NG_SERVER = 'com.martiansoftware.nailgun.NGServer'; + const CC_MAIN = 'com.google.javascript.jscomp.CommandLineRunner'; + + // exit code that ng gives + // FIXME: figure out the meaning of the value + const NG_EXIT_CODE = 227; + + /** + * Filepath of "ng" executable (from Nailgun package) + * + * @var string + */ + public static $ngExecutable = 'ng'; + + /** + * Filepath of the Nailgun jar file. + * + * @var string + */ + public static $ngJarFile; + + /** + * Get command to launch NailGun server. + * + * @return array + */ + protected function getServerCommandLine() + { + $this->checkJar(self::$ngJarFile); + $this->checkJar(self::$jarFile); + + $classPath = array( + self::$ngJarFile, + self::$jarFile, + ); + + // The command for the server that should show up in the process list + $server = array( + self::$javaExecutable, + '-server', + '-cp', join(':', $classPath), + self::NG_SERVER, + ); + + return $server; + } + + /** + * @return array + * @throws Minify_ClosureCompiler_Exception + */ + protected function getCompilerCommandLine() + { + $server = array( + self::$ngExecutable, + escapeshellarg(self::CC_MAIN) + ); + + return $server; + } + + /** + * @param string $tmpFile + * @param array $options + * @return string + * @throws Minify_ClosureCompiler_Exception + */ + protected function compile($tmpFile, $options) + { + $this->startServer(); + + $command = $this->getCommand($options, $tmpFile); + + return implode("\n", $this->shell($command, array(self::NG_EXIT_CODE))); + } + + private function startServer() + { + $serverCommand = join(' ', $this->getServerCommandLine()); + $psCommand = $this->shell("ps -o cmd= -C " . self::$javaExecutable); + if (array_search($serverCommand, $psCommand) !== false) { + // already started! + return; + } + + $this->shell("$serverCommand /dev/null 2>/dev/null & sleep 10"); + } +} \ No newline at end of file diff --git a/tests/MinifyNailgunClosureCompilerTest.php b/tests/MinifyNailgunClosureCompilerTest.php new file mode 100644 index 0000000..caeeb70 --- /dev/null +++ b/tests/MinifyNailgunClosureCompilerTest.php @@ -0,0 +1,49 @@ +assertHasJar(); + $src = " + (function (window, undefined){ + function addOne(input) { + return 1 + input; + } + window.addOne = addOne; + window.undefined = undefined; + })(window); + "; + $minExpected = "(function(a,b){a.addOne=function(a){return 1+a};a.undefined=b})(window);"; + $minOutput = Minify_NailgunClosureCompiler::minify($src); + $this->assertSame($minExpected, $minOutput, 'minimum necessary settings'); + } + + protected function assertHasJar() + { + $this->assertNotEmpty(Minify_ClosureCompiler::$jarFile); + try { + $this->assertFileExists(Minify_ClosureCompiler::$jarFile, "Have closure compiler compiler.jar"); + } catch (Exception $e) { + $this->markTestSkipped($e->getMessage()); + } + } +} \ No newline at end of file