|
|
|
@ -2,53 +2,51 @@
|
|
|
|
|
namespace taskman;
|
|
|
|
|
use Exception;
|
|
|
|
|
|
|
|
|
|
function is_release()
|
|
|
|
|
function is_release() : bool
|
|
|
|
|
{
|
|
|
|
|
return get("GAME_IS_DEV") == 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function is_dev()
|
|
|
|
|
function is_dev() : bool
|
|
|
|
|
{
|
|
|
|
|
return !is_release();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function is_dev_no_env()
|
|
|
|
|
function is_dev_no_env() : bool
|
|
|
|
|
{
|
|
|
|
|
return is_dev() && !getenv("GAME_ENV");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function is_win()
|
|
|
|
|
function is_win() : bool
|
|
|
|
|
{
|
|
|
|
|
return !(DIRECTORY_SEPARATOR == '/');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function is_linux()
|
|
|
|
|
function is_linux() : bool
|
|
|
|
|
{
|
|
|
|
|
return PHP_OS == 'Linux';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function stderr($msg)
|
|
|
|
|
function stderr(string $msg)
|
|
|
|
|
{
|
|
|
|
|
fwrite(STDERR, $msg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function fatal($msg)
|
|
|
|
|
function fatal(string $msg)
|
|
|
|
|
{
|
|
|
|
|
fwrite(STDERR, $msg);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function make_tmp_file_name($file_name)
|
|
|
|
|
function make_tmp_file_name(string $file_name) : string
|
|
|
|
|
{
|
|
|
|
|
$meta = stream_get_meta_data(tmpfile());
|
|
|
|
|
if(!isset($meta['uri']))
|
|
|
|
|
throw new Exception("Could not get temp directory name");
|
|
|
|
|
$tmp_dir = dirname($meta['uri']);
|
|
|
|
|
$tmp_file = "$tmp_dir/$file_name";
|
|
|
|
|
return $tmp_file;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function get_tmp_build_path($file)
|
|
|
|
|
function get_tmp_build_path(string $file) : string
|
|
|
|
|
{
|
|
|
|
|
global $GAME_ROOT;
|
|
|
|
|
|
|
|
|
@ -57,7 +55,7 @@ function get_tmp_build_path($file)
|
|
|
|
|
return normalize_path("$GAME_ROOT/build/tmp/$name");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function find_recursive($dir, $ext)
|
|
|
|
|
function find_recursive(string $dir, string $ext) : array
|
|
|
|
|
{
|
|
|
|
|
if(is_win())
|
|
|
|
|
$cmd = "dir /s /b " . normalize_path("$dir/*$ext");
|
|
|
|
@ -67,7 +65,7 @@ function find_recursive($dir, $ext)
|
|
|
|
|
return $out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function find_files($dir, array $fnmatch_patterns = array())
|
|
|
|
|
function find_files(string $dir, array $fnmatch_patterns = []) : array
|
|
|
|
|
{
|
|
|
|
|
$results = array();
|
|
|
|
|
$files = scandir($dir);
|
|
|
|
@ -89,9 +87,7 @@ function find_files($dir, array $fnmatch_patterns = array())
|
|
|
|
|
return $results;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//obsolete, use find_files instead
|
|
|
|
|
function scan_files_rec(array $dirs, array $only_extensions = array(), $mode = 1)
|
|
|
|
|
function scan_files_rec(array $dirs, array $only_extensions = [], int $mode = 1) : array
|
|
|
|
|
{
|
|
|
|
|
$files = array();
|
|
|
|
|
foreach($dirs as $dir)
|
|
|
|
@ -126,7 +122,7 @@ function scan_files_rec(array $dirs, array $only_extensions = array(), $mode = 1
|
|
|
|
|
return $files;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function normalize_path($path, $unix=null/*null means try to guess*/)
|
|
|
|
|
function normalize_path(string $path, ?bool $unix = null/*null means try to guess*/) : string
|
|
|
|
|
{
|
|
|
|
|
if(is_null($unix))
|
|
|
|
|
$unix = !is_win();
|
|
|
|
@ -149,7 +145,7 @@ function normalize_path($path, $unix=null/*null means try to guess*/)
|
|
|
|
|
return $res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function normalize_sed_path($path)
|
|
|
|
|
function normalize_sed_path(string $path) : string
|
|
|
|
|
{
|
|
|
|
|
$path = normalize_path($path);
|
|
|
|
|
if(is_win())
|
|
|
|
@ -159,18 +155,18 @@ function normalize_sed_path($path)
|
|
|
|
|
|
|
|
|
|
//NOTE: Escaping multibyte unicode chars as \uXXXX impacts decoding performance drastically
|
|
|
|
|
//so we unescape them while encoding json
|
|
|
|
|
function json_encode_unescaped($arr)
|
|
|
|
|
function json_encode_unescaped(array $arr) : string
|
|
|
|
|
{
|
|
|
|
|
array_walk_recursive($arr, function (&$item, $key) { if (is_string($item)) $item = mb_encode_numericentity($item, array (0x80, 0xffff, 0, 0xffff), 'UTF-8'); });
|
|
|
|
|
return mb_decode_numericentity(json_encode($arr), array (0x80, 0xffff, 0, 0xffff), 'UTF-8');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function json_make_pretty($json)
|
|
|
|
|
function json_make_pretty(string $json) : string
|
|
|
|
|
{
|
|
|
|
|
return prettyJSON($json);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function need_to_regen($file, array $deps, $debug = false)
|
|
|
|
|
function need_to_regen(string $file, iterable $deps, bool $debug = false) : bool
|
|
|
|
|
{
|
|
|
|
|
if(!is_file($file))
|
|
|
|
|
{
|
|
|
|
@ -180,9 +176,10 @@ function need_to_regen($file, array $deps, $debug = false)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$fmtime = filemtime($file);
|
|
|
|
|
|
|
|
|
|
foreach($deps as $dep)
|
|
|
|
|
{
|
|
|
|
|
if(is_file($dep) && (filemtime($dep) > $fmtime))
|
|
|
|
|
if($dep && is_file($dep) && (filemtime($dep) > $fmtime))
|
|
|
|
|
{
|
|
|
|
|
if($debug)
|
|
|
|
|
echo "$dep > $file\n";
|
|
|
|
@ -193,7 +190,7 @@ function need_to_regen($file, array $deps, $debug = false)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function need_to_regen_any(array $files, array $deps, $debug = false)
|
|
|
|
|
function need_to_regen_any(array $files, array $deps, bool $debug = false) : bool
|
|
|
|
|
{
|
|
|
|
|
$earliest_file = null;
|
|
|
|
|
$earliest_time = 2e32;
|
|
|
|
@ -217,10 +214,13 @@ function need_to_regen_any(array $files, array $deps, $debug = false)
|
|
|
|
|
echo "need_to_regen_any, earliest file: $earliest_file ($date)\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if($earliest_file === null)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return need_to_regen($earliest_file, $deps, $debug);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function fnmatch_patterns($file, array $fnmatch_patterns)
|
|
|
|
|
function fnmatch_patterns(string $file, array $fnmatch_patterns) : bool
|
|
|
|
|
{
|
|
|
|
|
foreach($fnmatch_patterns as $pattern)
|
|
|
|
|
{
|
|
|
|
@ -238,10 +238,8 @@ function fnmatch_patterns($file, array $fnmatch_patterns)
|
|
|
|
|
//1 - force write always,
|
|
|
|
|
//2 - write only if content differs
|
|
|
|
|
//3 - write only if content differs, don't even touch if they are same
|
|
|
|
|
function gen_file($tpl_file, $result_file, $deps = array(), $force = 0, $perms = 0640)
|
|
|
|
|
function gen_file(string $tpl_file, string $result_file, $deps = array(), $force = 0, int $perms = 0640)
|
|
|
|
|
{
|
|
|
|
|
global $GAME_ROOT;
|
|
|
|
|
|
|
|
|
|
$deps[] = $tpl_file;
|
|
|
|
|
if($force > 0 || need_to_regen($result_file, $deps))
|
|
|
|
|
{
|
|
|
|
@ -304,33 +302,43 @@ const COPY_MODE_BUILTIN = 1;
|
|
|
|
|
const COPY_MODE_SYSTEM = 2;
|
|
|
|
|
const COPY_MODE_HARDLINK = 3;
|
|
|
|
|
|
|
|
|
|
function ensure_copy($src, $dst, $dir_perms = 0777, $excludes = array())
|
|
|
|
|
function ensure_copy(string $src, string $dst, int $dir_perms = 0777, array $excludes = array(), array $fnmatches = array())
|
|
|
|
|
{
|
|
|
|
|
recurse_copy($src, $dst, $dir_perms, COPY_MODE_BUILTIN, false, $excludes);
|
|
|
|
|
recurse_copy($src, $dst, $dir_perms, COPY_MODE_BUILTIN, false, $excludes, $fnmatches);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ensure_copy_file_if_differs($src_file, $dst_file, $dir_perms = 0777)
|
|
|
|
|
function ensure_copy_file_if_differs(string $src_file, string $dst_file, $dir_perms = 0777)
|
|
|
|
|
{
|
|
|
|
|
if(!is_file($dst_file) || filesize($src_file) != filesize($dst_file) || crc32_file($src_file) !== crc32_file($dst_file))
|
|
|
|
|
ensure_copy($src_file, $dst_file, $dir_perms);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ensure_sync($src, $dst, $dir_perms = 0777, $excludes = array())
|
|
|
|
|
function ensure_sync(string $src, string $dst, int $dir_perms = 0777, array $excludes = array(), array $fnmatches = array())
|
|
|
|
|
{
|
|
|
|
|
recurse_copy($src, $dst, $dir_perms, COPY_MODE_BUILTIN, true, $excludes);
|
|
|
|
|
recurse_copy($src, $dst, $dir_perms, COPY_MODE_BUILTIN, true, $excludes, $fnmatches);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ensure_hardlink($src, $dst, $dir_perms = 0777, $excludes = array())
|
|
|
|
|
function ensure_hardlink(string $src, string $dst, int $dir_perms = 0777, array $excludes = array(), array $fnmatches = array())
|
|
|
|
|
{
|
|
|
|
|
recurse_copy($src, $dst, $dir_perms, COPY_MODE_HARDLINK, true, $excludes);
|
|
|
|
|
recurse_copy($src, $dst, $dir_perms, COPY_MODE_HARDLINK, true, $excludes, $fnmatches);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ensure_duplicate($src, $dst, $dir_perms = 0777)
|
|
|
|
|
function ensure_duplicate(string $src, string $dst, int $dir_perms = 0777)
|
|
|
|
|
{
|
|
|
|
|
recurse_copy($src, $dst, $dir_perms, COPY_MODE_SYSTEM);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function recurse_copy($src, $dst, $dir_perms = 0777, $copy_mode = COPY_MODE_BUILTIN, $mtime_check = false, $excludes = array())
|
|
|
|
|
function recurse_copy(
|
|
|
|
|
string $src,
|
|
|
|
|
string $dst,
|
|
|
|
|
int $dir_perms = 0777,
|
|
|
|
|
int $copy_mode = COPY_MODE_BUILTIN,
|
|
|
|
|
bool $mtime_check = false,
|
|
|
|
|
//regex expressions which check full paths
|
|
|
|
|
array $excludes = array(),
|
|
|
|
|
//fnmatch expressions which check file names only
|
|
|
|
|
array $fnmatches = array()
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
msg_dbg("copying $src => $dst ...\n");
|
|
|
|
|
|
|
|
|
@ -356,14 +364,27 @@ function recurse_copy($src, $dst, $dir_perms = 0777, $copy_mode = COPY_MODE_BUIL
|
|
|
|
|
if(($file != '.' ) && ($file != '..'))
|
|
|
|
|
{
|
|
|
|
|
if(is_dir($src . '/' . $file))
|
|
|
|
|
recurse_copy($src . '/' . $file, $dst . '/' . $file, $dir_perms, $copy_mode, $mtime_check, $excludes);
|
|
|
|
|
{
|
|
|
|
|
recurse_copy(
|
|
|
|
|
$src . '/' . $file,
|
|
|
|
|
$dst . '/' . $file,
|
|
|
|
|
$dir_perms,
|
|
|
|
|
$copy_mode,
|
|
|
|
|
$mtime_check,
|
|
|
|
|
$excludes,
|
|
|
|
|
$fnmatches
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
$excluded = false;
|
|
|
|
|
foreach($excludes as $exclude_pattern)
|
|
|
|
|
$excluded = $excluded || (bool)preg_match("~$exclude_pattern~", $src . '/' . $file);
|
|
|
|
|
$fnmatched = sizeof($fnmatches) == 0;
|
|
|
|
|
foreach($fnmatches as $fnmatch)
|
|
|
|
|
$fnmatched = $fnmatched || fnmatch($fnmatch, $file);
|
|
|
|
|
|
|
|
|
|
if($excluded)
|
|
|
|
|
if($excluded || !$fnmatched)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
_ensure_copy_file($src . '/' . $file, $dst . '/' . $file, $copy_mode, $mtime_check);
|
|
|
|
@ -373,7 +394,56 @@ function recurse_copy($src, $dst, $dir_perms = 0777, $copy_mode = COPY_MODE_BUIL
|
|
|
|
|
closedir($dir);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function _ensure_copy_file($src, $dst, $copy_mode = COPY_MODE_BUILTIN, $mtime_check = false)
|
|
|
|
|
function shell(string $cmd, &$out = null)
|
|
|
|
|
{
|
|
|
|
|
shell_try($cmd, $ret, $out);
|
|
|
|
|
if($ret != 0)
|
|
|
|
|
throw new Exception("Shell execution error(exit code $ret)");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function shell_try(string $cmd, &$ret = null, &$out = null)
|
|
|
|
|
{
|
|
|
|
|
msg(" shell: $cmd\n");
|
|
|
|
|
msg(" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
|
|
|
|
|
|
|
|
|
|
if(func_num_args() < 3)
|
|
|
|
|
system($cmd, $ret);
|
|
|
|
|
else
|
|
|
|
|
_execute_proc_cmd($cmd, $ret, $out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function shell_get(string $cmd, bool $as_string = true)
|
|
|
|
|
{
|
|
|
|
|
exec($cmd, $out, $code);
|
|
|
|
|
if($code !== 0)
|
|
|
|
|
throw new Exception("Error($code) executing shell cmd '$cmd'");
|
|
|
|
|
return $as_string ? implode("", $out) : $out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function _execute_proc_cmd(string $cmd, &$ret, &$out)
|
|
|
|
|
{
|
|
|
|
|
//TODO: do we really need to redirect error stream?
|
|
|
|
|
$proc = popen("$cmd 2>&1", 'r');
|
|
|
|
|
|
|
|
|
|
$log = '';
|
|
|
|
|
if(!is_resource($proc))
|
|
|
|
|
{
|
|
|
|
|
$log = "";
|
|
|
|
|
_log($log, 1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
while($logline = fgets($proc))
|
|
|
|
|
{
|
|
|
|
|
$log .= $logline;
|
|
|
|
|
_log($logline, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$out = explode("\n", $log);
|
|
|
|
|
$ret = pclose($proc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function _ensure_copy_file(string $src, string $dst, int $copy_mode = COPY_MODE_BUILTIN, bool $mtime_check = false)
|
|
|
|
|
{
|
|
|
|
|
if($mtime_check && file_exists($dst) && filemtime($src) <= filemtime($dst))
|
|
|
|
|
return;
|
|
|
|
@ -398,7 +468,7 @@ function _ensure_copy_file($src, $dst, $copy_mode = COPY_MODE_BUILTIN, $mtime_ch
|
|
|
|
|
throw new Exception("Unrecognized copy mode $copy_mode");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ensure_identical($src, $dst, $excludes = array())
|
|
|
|
|
function ensure_identical(string $src, string $dst, $excludes = array())
|
|
|
|
|
{
|
|
|
|
|
msg_dbg("deleting files missing in $src from $dst ...\n");
|
|
|
|
|
|
|
|
|
@ -440,7 +510,7 @@ function ensure_identical($src, $dst, $excludes = array())
|
|
|
|
|
closedir($dir);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ensure_symlink($src, $dst, $dir_perms = 0777)
|
|
|
|
|
function ensure_symlink(string $src, string $dst, int $dir_perms = 0777)
|
|
|
|
|
{
|
|
|
|
|
if(!is_file($src) && !is_dir($src))
|
|
|
|
|
throw new Exception("Bad file or dir '$src'");
|
|
|
|
@ -456,7 +526,7 @@ function ensure_symlink($src, $dst, $dir_perms = 0777)
|
|
|
|
|
throw new Exception("Could not create symlink");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ensure_rm($what)
|
|
|
|
|
function ensure_rm(string $what)
|
|
|
|
|
{
|
|
|
|
|
if(is_dir($what) && !is_link($what))
|
|
|
|
|
rrmdir($what);
|
|
|
|
@ -464,7 +534,7 @@ function ensure_rm($what)
|
|
|
|
|
unlink($what);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ensure_mkdir($dir, $perms = 0775)
|
|
|
|
|
function ensure_mkdir(string $dir, int $perms = 0775)
|
|
|
|
|
{
|
|
|
|
|
if(is_dir($dir))
|
|
|
|
|
return;
|
|
|
|
@ -478,7 +548,7 @@ function ensure_mkdir($dir, $perms = 0775)
|
|
|
|
|
throw new Exception("Could not chmod " . decoct($perms) . " dir '$dir'");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ensure_var_dir($dir)
|
|
|
|
|
function ensure_var_dir(string $dir)
|
|
|
|
|
{
|
|
|
|
|
ensure_mkdir($dir, 0777);
|
|
|
|
|
$items = fmatch("$dir/*");
|
|
|
|
@ -492,7 +562,7 @@ function ensure_var_dir($dir)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function compare_files_timestamp($file_a, $file_b)
|
|
|
|
|
function compare_files_timestamp(string $file_a, string $file_b) : int
|
|
|
|
|
{
|
|
|
|
|
$file_a_timestamp = file_exists($file_a) ? filemtime($file_a) : 0;
|
|
|
|
|
$file_b_timestamp = file_exists($file_b) ? filemtime($file_b) : 0;
|
|
|
|
@ -502,15 +572,15 @@ function compare_files_timestamp($file_a, $file_b)
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function fmatch($pat)
|
|
|
|
|
function fmatch(string $path) : array
|
|
|
|
|
{
|
|
|
|
|
$res = glob($pat);
|
|
|
|
|
$res = glob($path);
|
|
|
|
|
if(!is_array($res))
|
|
|
|
|
return array();
|
|
|
|
|
return $res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function rrmdir($dir, $remove_top_dir = true)
|
|
|
|
|
function rrmdir(string $dir, bool $remove_top_dir = true)
|
|
|
|
|
{
|
|
|
|
|
if(is_dir($dir))
|
|
|
|
|
{
|
|
|
|
@ -519,7 +589,7 @@ function rrmdir($dir, $remove_top_dir = true)
|
|
|
|
|
{
|
|
|
|
|
if($object != "." && $object != "..")
|
|
|
|
|
{
|
|
|
|
|
if(filetype($dir."/".$object) == "dir")
|
|
|
|
|
if(is_dir($dir."/".$object))
|
|
|
|
|
rrmdir($dir."/".$object);
|
|
|
|
|
else
|
|
|
|
|
unlink($dir."/".$object);
|
|
|
|
@ -536,88 +606,74 @@ function rrmdir($dir, $remove_top_dir = true)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function run_apple_script($script)
|
|
|
|
|
{
|
|
|
|
|
$vm = popen("osascript", "w");
|
|
|
|
|
fwrite($vm, $script);
|
|
|
|
|
// run script will always exit with status 1
|
|
|
|
|
pclose($vm);
|
|
|
|
|
}
|
|
|
|
|
define("GIT_INFO_REV_HASH" , 1 << 0);
|
|
|
|
|
define("GIT_INFO_BRANCH" , 1 << 1);
|
|
|
|
|
define("GIT_INFO_REV_NUMBER", 1 << 2);
|
|
|
|
|
define("GIT_INFO_ALL" , ~0);
|
|
|
|
|
|
|
|
|
|
function client_xcode_build($scheme, $config = 'Debug', $sdk = 'iphonesimulator4.3')
|
|
|
|
|
{
|
|
|
|
|
global $GAME_ROOT;
|
|
|
|
|
|
|
|
|
|
$xcode_filter = ". $GAME_ROOT/utils/xcodefilter.sh";
|
|
|
|
|
|
|
|
|
|
ensure_mkdir("$GAME_ROOT/build/client");
|
|
|
|
|
shell(_(
|
|
|
|
|
"cd $GAME_ROOT/client && " .
|
|
|
|
|
"$xcode_filter xcodebuild -workspace %XCODE_WKSPACE% -scheme $scheme -configuration $config -sdk $sdk SYMROOT=$GAME_ROOT/build/client"
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function task_git_info()
|
|
|
|
|
{
|
|
|
|
|
list($rev_hash, $branch, $revision_number) = git_get_info();
|
|
|
|
|
$info = "==============GIT INFO==============\n"
|
|
|
|
|
. "$rev_hash - hash\n"
|
|
|
|
|
. "$branch - branch\n"
|
|
|
|
|
. "$revision_number - revision\n";
|
|
|
|
|
echo $info;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function git_get_info()
|
|
|
|
|
function git_get_info($info = GIT_INFO_ALL) : array
|
|
|
|
|
{
|
|
|
|
|
global $GAME_ROOT;
|
|
|
|
|
$rev_hash = "";
|
|
|
|
|
$branch = "";
|
|
|
|
|
$revision_number = 0;
|
|
|
|
|
|
|
|
|
|
if(!is_dir("$GAME_ROOT/.git"))
|
|
|
|
|
throw new Exception("Not a Git repository");
|
|
|
|
|
|
|
|
|
|
$out = array();
|
|
|
|
|
exec("git rev-parse HEAD", $out);
|
|
|
|
|
$rev_hash = trim($out[0]);
|
|
|
|
|
if(!$rev_hash)
|
|
|
|
|
throw new Exception("Error getting git revision hash");
|
|
|
|
|
if($info & GIT_INFO_REV_HASH)
|
|
|
|
|
{
|
|
|
|
|
$out = array();
|
|
|
|
|
exec("git rev-parse HEAD", $out);
|
|
|
|
|
$rev_hash = trim($out[0]);
|
|
|
|
|
if(!$rev_hash)
|
|
|
|
|
throw new Exception("Error getting git revision hash");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$out = array();
|
|
|
|
|
exec("git rev-parse --abbrev-ref HEAD", $out);
|
|
|
|
|
$branch = trim($out[0]);
|
|
|
|
|
if(!$branch)
|
|
|
|
|
throw new Exception("Error getting git branch");
|
|
|
|
|
if($info & GIT_INFO_BRANCH)
|
|
|
|
|
{
|
|
|
|
|
$out = array();
|
|
|
|
|
exec("git rev-parse --abbrev-ref HEAD", $out);
|
|
|
|
|
$branch = trim($out[0]);
|
|
|
|
|
if(!$branch)
|
|
|
|
|
throw new Exception("Error getting git branch");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$out = array();
|
|
|
|
|
exec("git rev-list HEAD --count", $out);
|
|
|
|
|
$revision_number = (int)$out[0];
|
|
|
|
|
if(!$revision_number)
|
|
|
|
|
throw new Exception("Error getting git revision number");
|
|
|
|
|
if($info & GIT_INFO_REV_NUMBER)
|
|
|
|
|
{
|
|
|
|
|
$out = array();
|
|
|
|
|
exec("git rev-list HEAD --count", $out);
|
|
|
|
|
$revision_number = (int)$out[0];
|
|
|
|
|
if(!$revision_number)
|
|
|
|
|
throw new Exception("Error getting git revision number");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return array($rev_hash, $branch, $revision_number);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function git_get_rev_hash()
|
|
|
|
|
function git_get_rev_hash() : string
|
|
|
|
|
{
|
|
|
|
|
list($rev_hash, $_, $__) = git_get_info();
|
|
|
|
|
list($rev_hash, $_, $__) = git_get_info(GIT_INFO_REV_HASH);
|
|
|
|
|
return $rev_hash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function git_get_branch()
|
|
|
|
|
function git_get_branch() : string
|
|
|
|
|
{
|
|
|
|
|
list($_, $branch, $__) = git_get_info();
|
|
|
|
|
list($_, $branch, $__) = git_get_info(GIT_INFO_BRANCH);
|
|
|
|
|
return $branch;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function git_get_rev_number()
|
|
|
|
|
function git_get_rev_number() : string
|
|
|
|
|
{
|
|
|
|
|
list($_, $__, $rev_number) = git_get_info();
|
|
|
|
|
list($_, $__, $rev_number) = git_get_info(GIT_INFO_REV_NUMBER);
|
|
|
|
|
return $rev_number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function git_try_commit($files, $msg)
|
|
|
|
|
function git_try_commit(string $paths, string $msg)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
exec("git add $files && git commit -m \"$msg\" && git pull && git push");
|
|
|
|
|
exec("git add $paths && git commit -m \"$msg\" && git pull && git push");
|
|
|
|
|
}
|
|
|
|
|
catch(Exception $e)
|
|
|
|
|
{
|
|
|
|
@ -625,46 +681,7 @@ function git_try_commit($files, $msg)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function decode_json_ensure($json, $assoc = false)
|
|
|
|
|
{
|
|
|
|
|
$res = json_decode($json, $assoc);
|
|
|
|
|
if($res === null)
|
|
|
|
|
{
|
|
|
|
|
$parser = new JsonParser();
|
|
|
|
|
$err = $parser->lint($json);
|
|
|
|
|
echo $json;
|
|
|
|
|
throw $err;
|
|
|
|
|
}
|
|
|
|
|
return $res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function convert_js_to_msgpack($file, $bin_file)
|
|
|
|
|
{
|
|
|
|
|
$bin_file = "$file.lib";
|
|
|
|
|
if(need_to_regen($bin_file, array($file)))
|
|
|
|
|
{
|
|
|
|
|
echo "Converting $file -> $bin_file...\n";
|
|
|
|
|
$data = decode_json_ensure(file_get_contents($file));
|
|
|
|
|
$msg = config_msgpack_pack($data);
|
|
|
|
|
ensure_write($bin_file, $msg);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function check_and_decode_json($json)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
$arr = decode_json_ensure($json, true);
|
|
|
|
|
return array(0, "", $arr);
|
|
|
|
|
}
|
|
|
|
|
catch(Exception $e)
|
|
|
|
|
{
|
|
|
|
|
return array(1, $e->getMessage(), array());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function check_and_decode_jzon($json)
|
|
|
|
|
function check_and_decode_jzon(string $json) : array
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
@ -703,7 +720,7 @@ function make_dir_md5($dir, $md5_file)
|
|
|
|
|
ensure_write($md5_file, $md5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function file_put_contents_atomic($filename, $content, $mode = 0644)
|
|
|
|
|
function file_put_contents_atomic(string $filename, string $content, int $mode = 0644)
|
|
|
|
|
{
|
|
|
|
|
$temp = tempnam(dirname($filename), 'atomic');
|
|
|
|
|
if(!($f = @fopen($temp, 'wb')))
|
|
|
|
@ -720,15 +737,15 @@ function file_put_contents_atomic($filename, $content, $mode = 0644)
|
|
|
|
|
chmod($filename, $mode);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function gmgetdate($ts = null)
|
|
|
|
|
function gmgetdate($ts = null) : array
|
|
|
|
|
{
|
|
|
|
|
$k = array('seconds','minutes','hours','mday',
|
|
|
|
|
'wday','mon','year','yday','weekday','month',0);
|
|
|
|
|
return(array_combine($k, explode(":",
|
|
|
|
|
gmdate('s:i:G:j:w:n:Y:z:l:F:U',is_null($ts)?time():$ts))));
|
|
|
|
|
return array_combine($k, explode(":",
|
|
|
|
|
gmdate('s:i:G:j:w:n:Y:z:l:F:U',is_null($ts)?time():$ts)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function prettyJSON($json)
|
|
|
|
|
function prettyJSON(string $json) : string
|
|
|
|
|
{
|
|
|
|
|
$result = '';
|
|
|
|
|
$level = 0;
|
|
|
|
@ -809,12 +826,12 @@ function run_shell_in_project_dir($cmd)
|
|
|
|
|
return $out[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function boolstr($b)
|
|
|
|
|
function boolstr(bool $b) : string
|
|
|
|
|
{
|
|
|
|
|
return $b ? 'true' : 'false';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function create_js_template_literal($str)
|
|
|
|
|
function create_js_template_literal(string $str) : string
|
|
|
|
|
{
|
|
|
|
|
$result = str_replace('\\', '\\\\', $str); // replace \ -> \\
|
|
|
|
|
$result = str_replace('`', '\\`', $result); // replace ` -> \`
|
|
|
|
@ -822,7 +839,7 @@ function create_js_template_literal($str)
|
|
|
|
|
return "`$result`";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function create_go_string_literal($str)
|
|
|
|
|
function create_go_string_literal(string $str) : string
|
|
|
|
|
{
|
|
|
|
|
$result = str_replace('\\', '\\\\', $str); // replace \ -> \\
|
|
|
|
|
$result = str_replace('"', '\\"', $result); // replace " -> \"
|
|
|
|
@ -830,7 +847,7 @@ function create_go_string_literal($str)
|
|
|
|
|
return '"' . $result . '"';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function convertFileFromDos2UnixFormat($file)
|
|
|
|
|
function convertFileFromDos2UnixFormat(string $file)
|
|
|
|
|
{
|
|
|
|
|
$file_tmp = $file.".tmp";
|
|
|
|
|
|
|
|
|
@ -843,7 +860,7 @@ function convertFileFromDos2UnixFormat($file)
|
|
|
|
|
ensure_rm($file_tmp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function removeCarriageReturn($file)
|
|
|
|
|
function removeCarriageReturn(string $file)
|
|
|
|
|
{
|
|
|
|
|
$file_tmp = $file.".tmp";
|
|
|
|
|
|
|
|
|
@ -856,19 +873,19 @@ function removeCarriageReturn($file)
|
|
|
|
|
ensure_rm($file_tmp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function replace_text_in_file($search_pattern, $replace_pattern, $from_file, $to_file)
|
|
|
|
|
function replace_text_in_file(string $search_pattern, string $replace_pattern, string $from_file, string $to_file)
|
|
|
|
|
{
|
|
|
|
|
$file_content = ensure_read($from_file);
|
|
|
|
|
$res = str_replace($search_pattern, $replace_pattern, $file_content);
|
|
|
|
|
ensure_write($to_file, $res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function gamectl_get_props_as_php_code()
|
|
|
|
|
function gamectl_get_props_as_php_code() : string
|
|
|
|
|
{
|
|
|
|
|
$props = props();
|
|
|
|
|
$props_str = "<?php\n";
|
|
|
|
|
$props_str = "<?php\nnamespace taskman;\n";
|
|
|
|
|
foreach($props as $k => $v)
|
|
|
|
|
$props_str .= "taskman_propset('$k', " . var_export($v, true). ");\n";
|
|
|
|
|
$props_str .= "set('$k', " . var_export($v, true). ");\n";
|
|
|
|
|
return $props_str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -907,7 +924,7 @@ function run_background_proc($bin, array $args = array(), $redirect_out = '', $r
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function run_background_gamectl_workers($task, array $worker_args)
|
|
|
|
|
function run_background_gamectl_workers(string $task, array $worker_args) : array
|
|
|
|
|
{
|
|
|
|
|
global $GAME_ROOT;
|
|
|
|
|
|
|
|
|
@ -977,7 +994,7 @@ function run_background_gamectl_workers($task, array $worker_args)
|
|
|
|
|
{
|
|
|
|
|
foreach($workers as $item)
|
|
|
|
|
{
|
|
|
|
|
list($in_file, $log_file, $err_file) = $item;
|
|
|
|
|
list($in_file, $out_file, $log_file, $err_file) = $item;
|
|
|
|
|
@ensure_rm($in_file);
|
|
|
|
|
@ensure_rm($out_file);
|
|
|
|
|
@ensure_rm($log_file);
|
|
|
|
@ -988,17 +1005,17 @@ function run_background_gamectl_workers($task, array $worker_args)
|
|
|
|
|
return $results;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function kb($str)
|
|
|
|
|
function kb(string $data) : string
|
|
|
|
|
{
|
|
|
|
|
return kb_len(strlen($str));
|
|
|
|
|
return kb_len(strlen($data));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function kb_len($len)
|
|
|
|
|
function kb_len(int $len) : string
|
|
|
|
|
{
|
|
|
|
|
return round($len/1024,2) . "kb";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function gen_uuid_v4()
|
|
|
|
|
function gen_uuid_v4() : string
|
|
|
|
|
{
|
|
|
|
|
$UUID_LENGTH_BYTES = 16;
|
|
|
|
|
$data = random_bytes($UUID_LENGTH_BYTES);
|
|
|
|
@ -1009,14 +1026,15 @@ function gen_uuid_v4()
|
|
|
|
|
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function watch_running_process($pid, $log_file, $exit_matches = array(), $error_matches = array(), $verbose = true, $break_after_sec = -1, $ignored_errors = array(), $noted_warnings = array())
|
|
|
|
|
function watch_running_process($pid, string $log_file, $exit_matches = array(), $error_matches = array(), bool $verbose = true, $break_after_sec = -1, $ignored_errors = array(), $noted_warnings = array())
|
|
|
|
|
{
|
|
|
|
|
$matches_any_fn = function($buffer, array $matches)
|
|
|
|
|
{
|
|
|
|
|
foreach($matches as $match)
|
|
|
|
|
{
|
|
|
|
|
if(strpos($buffer, $match) !== false)
|
|
|
|
|
return true;
|
|
|
|
|
$match_idx = strpos($buffer, $match);
|
|
|
|
|
if($match_idx !== false)
|
|
|
|
|
return $match_idx;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
@ -1027,7 +1045,7 @@ function watch_running_process($pid, $log_file, $exit_matches = array(), $error_
|
|
|
|
|
|
|
|
|
|
$throw_fn = function($msg) use (&$warnings_list)
|
|
|
|
|
{
|
|
|
|
|
if(count($warnings_list) > 0)
|
|
|
|
|
if(count($warnings_list) > 0) // @phpstan-ignore-line
|
|
|
|
|
$msg .= "\n\nPossible causes:\n" . implode("\n", $warnings_list) . "\n";
|
|
|
|
|
throw new Exception($msg);
|
|
|
|
|
};
|
|
|
|
@ -1044,18 +1062,22 @@ function watch_running_process($pid, $log_file, $exit_matches = array(), $error_
|
|
|
|
|
echo $buffer;
|
|
|
|
|
|
|
|
|
|
//log success condition
|
|
|
|
|
if($matches_any_fn($buffer, $exit_matches))
|
|
|
|
|
if($matches_any_fn($buffer, $exit_matches) !== false)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if($matches_any_fn($buffer, $noted_warnings))
|
|
|
|
|
if($matches_any_fn($buffer, $noted_warnings) !== false)
|
|
|
|
|
$warnings_list[] = $buffer;
|
|
|
|
|
|
|
|
|
|
if($matches_any_fn($buffer, $error_matches))
|
|
|
|
|
$buffer_error_idx = $matches_any_fn($buffer, $error_matches);
|
|
|
|
|
if($buffer_error_idx !== false)
|
|
|
|
|
{
|
|
|
|
|
if($matches_any_fn($buffer, $ignored_errors))
|
|
|
|
|
if($matches_any_fn($buffer, $ignored_errors) !== false)
|
|
|
|
|
echo "Error in log file IGNORED\n";
|
|
|
|
|
else
|
|
|
|
|
$throw_fn("Error condition in log file detected");
|
|
|
|
|
$throw_fn("Error condition in log file '$log_file' detected:\n****\n" .
|
|
|
|
|
trim(substr($buffer, $buffer_error_idx, 300))
|
|
|
|
|
. "\n****\n"
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if($process_gone)
|
|
|
|
@ -1083,7 +1105,7 @@ function watch_running_process($pid, $log_file, $exit_matches = array(), $error_
|
|
|
|
|
fclose($h);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function check_process($pid)
|
|
|
|
|
function check_process($pid) : int
|
|
|
|
|
{
|
|
|
|
|
if(is_win())
|
|
|
|
|
{
|
|
|
|
@ -1098,12 +1120,12 @@ function check_process($pid)
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function which_dir($bin)
|
|
|
|
|
function which_dir(string $bin) : string
|
|
|
|
|
{
|
|
|
|
|
return dirname(which_path($bin));
|
|
|
|
|
return realpath(dirname(which_path($bin)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function which_path($bin)
|
|
|
|
|
function which_path(string $bin) : string
|
|
|
|
|
{
|
|
|
|
|
if(is_win())
|
|
|
|
|
{
|
|
|
|
@ -1117,9 +1139,86 @@ function which_path($bin)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function arg_exists($args, $needle)
|
|
|
|
|
function arg_exists(array $args, string $needle) : bool
|
|
|
|
|
{
|
|
|
|
|
$strict = true;
|
|
|
|
|
return in_array($needle, $args, $strict);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!function_exists('str_ends_with'))
|
|
|
|
|
{
|
|
|
|
|
function str_ends_with($haystack, $needle)
|
|
|
|
|
{
|
|
|
|
|
// search forward starting from end minus needle length characters
|
|
|
|
|
return $needle === "" || (($temp = strlen($haystack) - strlen($needle)) >= 0 && strpos($haystack, $needle, $temp) !== false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function arg_opt(array &$args, $opt, $default, $conv_fn = null)
|
|
|
|
|
{
|
|
|
|
|
foreach($args as $idx => $arg)
|
|
|
|
|
{
|
|
|
|
|
if(strpos($arg, $opt) === 0)
|
|
|
|
|
{
|
|
|
|
|
$arg = substr($arg, strlen($opt));
|
|
|
|
|
unset($args[$idx]);
|
|
|
|
|
return $conv_fn === null ? $arg : $conv_fn($arg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $default;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function arg_opt_check_no_trailing(array $args)
|
|
|
|
|
{
|
|
|
|
|
foreach($args as $arg)
|
|
|
|
|
{
|
|
|
|
|
if(preg_match('~(--\w+)=.*~', $arg, $m))
|
|
|
|
|
throw new Exception("Unknown option '{$m[1]}'");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function are_you_sure()
|
|
|
|
|
{
|
|
|
|
|
if(!are_you_sure_ask())
|
|
|
|
|
{
|
|
|
|
|
echo "exiting then\n";
|
|
|
|
|
exit();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function are_you_sure_ask() : bool
|
|
|
|
|
{
|
|
|
|
|
echo "Are you sure you want to proceed?(type YES): ";
|
|
|
|
|
$resp = trim(fread(STDIN, 10));
|
|
|
|
|
return $resp == "YES";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function names_hash_changed(string $crc_file, iterable $names) : bool
|
|
|
|
|
{
|
|
|
|
|
$ctx = hash_init('crc32');
|
|
|
|
|
foreach($names as $name)
|
|
|
|
|
hash_update($ctx, $name);
|
|
|
|
|
$names_crc = hash_final($ctx, false);
|
|
|
|
|
$changed = !file_exists($crc_file) || ensure_read($crc_file) != $names_crc;
|
|
|
|
|
ensure_write($crc_file, $names_crc);
|
|
|
|
|
return $changed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function is_apple_silicon()
|
|
|
|
|
{
|
|
|
|
|
$arch = php_uname('m');
|
|
|
|
|
|
|
|
|
|
// Check if the machine type contains 'arm' (ARM architecture)
|
|
|
|
|
if (strpos($arch, 'arm') !== false) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If running on x86_64, check for Apple Silicon using sysctl
|
|
|
|
|
// (because we might get 'x86_64' when running under Rosetta)
|
|
|
|
|
if ($arch === 'x86_64') {
|
|
|
|
|
$sysctl = shell_exec('sysctl -n machdep.cpu.brand_string');
|
|
|
|
|
return strpos($sysctl, 'Apple') !== false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|