mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-04 17:21:39 +09:00
200 lines
5.1 KiB
PHP
Executable file
200 lines
5.1 KiB
PHP
Executable file
<?php
|
|
/* Copyright (C) NAVER <http://www.navercorp.com> */
|
|
/**
|
|
* Minify
|
|
* This script comnbines multiple JavaScript or CSS files with minifying.
|
|
* PHP 5.3.0 or above version is required.
|
|
*
|
|
* Usage : php minify.php [TARGET_DIR ...]
|
|
* TARGET_DIR use the current working directory as a default path.
|
|
*
|
|
* @author NAVER(developer@xpressengine.com)
|
|
*/
|
|
|
|
if(version_compare(PHP_VERSION, '5.3.0', '<')) {
|
|
echo "PHP 5.3.0 or above version is required.";
|
|
exit(1);
|
|
}
|
|
|
|
function main() {
|
|
$argv = $_SERVER['argv'];
|
|
$argc = $_SERVER['argc'];
|
|
|
|
// get target directories
|
|
if($argc < 1) exit;
|
|
elseif($argc < 2) $dirs = array($_SERVER['PWD']);
|
|
else $dirs = array_slice($argv, 1);
|
|
|
|
$dirs = array_map('realpath', $dirs);
|
|
$dirs = array_map('add_dirsep', $dirs);
|
|
|
|
array_walk($dirs, 'execute');
|
|
}
|
|
|
|
// add directory separator
|
|
function add_dirsep($path) {
|
|
if(substr($path,-1) != DIRECTORY_SEPARATOR) $path .= DIRECTORY_SEPARATOR;
|
|
return $path;
|
|
}
|
|
|
|
function execute($dir) {
|
|
echo "Processing : {$dir}\n";
|
|
|
|
// parse config file if it exists
|
|
echo " Finding predefined configuration file...";
|
|
$config = read_config($dir);
|
|
echo " Done\n";
|
|
|
|
// merge
|
|
foreach($config['merge'] as $target=>$files) {
|
|
merge($files, $target, $dir);
|
|
}
|
|
|
|
// files to skip
|
|
$files_to_skip = $config['skip'];
|
|
foreach($files_to_skip as $idx=>$file) {
|
|
if($file) $files_to_skip[$idx] = realpath($dir.trim($file));
|
|
}
|
|
|
|
echo " Minifying JavaScript files...";
|
|
$js_files = get_target_files('js', $dir, $files_to_skip);
|
|
|
|
if(count($js_files) && !class_exists('JSMinPlus')) {
|
|
require dirname(__FILE__).'/jsminplus/jsminplus.php';
|
|
}
|
|
foreach($js_files as $file) {
|
|
if(!is_readable($file)) continue;
|
|
|
|
$target = preg_replace('@\.js$@', '.min.js', $file);
|
|
$content = file_get_contents($file);
|
|
|
|
// save copyright to preserve it
|
|
if(preg_match('@^[ \t]*(/\*\*.+?\*/)@s', $content, $matches)) {
|
|
$copyright = $matches[1]."\n";
|
|
} else {
|
|
$copyright = '';
|
|
}
|
|
|
|
if($config['use_closure_compiler']) {
|
|
$content = closure_compile($content);
|
|
if(!$content) {
|
|
echo " CANNOT compile the js file with closure compiler.\n";
|
|
echo " Trying again with JSMinPlus.\n";
|
|
$content = JSMinPlus::minify($content);
|
|
}
|
|
} else {
|
|
$content = JSMinPlus::minify($content);
|
|
}
|
|
|
|
file_put_contents($target, $copyright.$content, LOCK_EX);
|
|
|
|
echo '.';
|
|
}
|
|
echo " Done\n";
|
|
|
|
echo " Minifying CSS files...";
|
|
$css_files = get_target_files('css', $dir, $files_to_skip);
|
|
|
|
if(count($css_files) && !class_exists('CSSmin')) {
|
|
require dirname(__FILE__).'/cssmin/CSSmin.php';
|
|
}
|
|
|
|
$oCSSmin = new CSSmin();
|
|
|
|
foreach($css_files as $file) {
|
|
if(!is_readable($file)) continue;
|
|
|
|
$target = preg_replace('@\.css$@', '.min.css', $file);
|
|
$content = file_get_contents($file);
|
|
|
|
file_put_contents($target, $copyright.$oCSSmin->run($content), LOCK_EX);
|
|
echo '.';
|
|
}
|
|
echo " Done\n";
|
|
}
|
|
|
|
function read_config($dir) {
|
|
$default = array('option'=>array(), 'skip'=>array(), 'merge'=>array());
|
|
$file = $dir.'minify.ini';
|
|
|
|
if(!is_readable($file)) return $default;
|
|
|
|
$config_str = file_get_contents($file);
|
|
$config_str = preg_replace_callback('/(\[(?:skip|merge *>> *.+?)\])([\s\S]+?)(?=\[|$)/', 'transform_config_str', $config_str);
|
|
|
|
$config = parse_ini_string($config_str, 1);
|
|
if($config === false) return $default;
|
|
|
|
if(is_array($config['skip'])) $config['skip'] = array_keys($config['skip']);
|
|
|
|
foreach($config as $section=>$value) {
|
|
if(preg_match('/merge *>> *(.+)/', $section, $match)) {
|
|
if(!is_array($config['merge'])) $config['merge'] = array();
|
|
$config['merge'][trim($match[1])] = array_keys($value);
|
|
|
|
unset($config[$section]);
|
|
}
|
|
}
|
|
|
|
if(is_array($config['option'])) $config = array_merge($config['option'], $config);
|
|
$config = array_merge($default, $config);
|
|
|
|
return $config;
|
|
}
|
|
|
|
function transform_config_str($matches) {
|
|
if(!$matches[2]) return $matches[0];
|
|
$values = preg_replace('/$/m', '=', trim($matches[2]));
|
|
|
|
return "{$matches[1]}\n{$values}\n\n";
|
|
}
|
|
|
|
function merge($files, $target, $base_dir) {
|
|
if(!is_array($files)) return false;
|
|
|
|
$body = '';
|
|
$is_css = !!preg_match('/\.css$/', $target);
|
|
|
|
foreach($files as $file) {
|
|
$file = $base_dir.trim($file);
|
|
if(!is_readable($file)) continue;
|
|
|
|
$content = trim(file_get_contents($file));
|
|
if($is_css && $body) $content = preg_replace('/^@.+?;/m', '', $content);
|
|
if($content) $body .= $content."\n";
|
|
}
|
|
|
|
if ($body) {
|
|
$file_count = count($files);
|
|
echo " Merging {$file_count} files to create {$target} file...";
|
|
file_put_contents($base_dir.$target, $body, LOCK_EX);
|
|
echo " Done\n";
|
|
}
|
|
}
|
|
|
|
function get_target_files($ext, $dir, $files_to_skip) {
|
|
$files = glob("{$dir}*.{$ext}");
|
|
$skips = glob("{$dir}*.min.{$ext}");
|
|
$skips = array_merge($skips, $files_to_skip);
|
|
$files = array_diff($files, $skips);
|
|
|
|
return $files;
|
|
}
|
|
|
|
function closure_compile($content) {
|
|
require_once dirname(__FILE__).'/../../classes/httprequest/XEHttpRequest.class.php';
|
|
|
|
$req = new XEHttpRequest('closure-compiler.appspot.com', 80);
|
|
$ret = $req->send('/compile', 'POST', 5, array(
|
|
'output_info' => 'compiled_code',
|
|
'output_format' => 'text',
|
|
'compilation_level' => 'SIMPLE_OPTIMIZATIONS',
|
|
'js_code' => $content
|
|
));
|
|
|
|
return $ret->body;
|
|
}
|
|
|
|
// run main function
|
|
error_reporting(E_ALL & ~E_NOTICE);
|
|
main();
|