taskman/internal.inc.php

285 lines
6.1 KiB
PHP

<?php
namespace taskman\internal;
use Exception;
function _default_logger($msg)
{
echo $msg;
}
function _default_usage($script_name = "<taskman-script>")
{
echo "\nUsage:\n $script_name [OPTIONS] <task-name1>[,<task-name2>,..] [-D PROP1=value [-D PROP2]]\n\n";
echo "Available options:\n";
echo " -c specify PHP script to be included (handy for setting props,config options,etc)\n";
echo " -V be super verbose\n";
echo " -q be quite, only system messages\n";
echo " -b batch mode: be super quite, don't even output any system messages\n";
echo " -- pass all options verbatim after this mark\n";
}
function _collect_tasks()
{
global $TASKMAN_TASKS;
global $TASKMAN_TASK_ALIASES;
global $TASKMAN_FILE_CHANGES;
$TASKMAN_TASKS = array();
$TASKMAN_TASK_ALIASES = array();
$cands = _get_task_candidates();
foreach($cands as $name => $args)
{
if(isset($TASKMAN_TASKS[$name]))
throw new \taskman\TaskmanException("Task '$name' is already defined");
if(is_array($args))
{
$props = array();
if(sizeof($args) > 2)
{
$props = $args[1];
$func = $args[2];
}
else
$func = $args[1];
$task = new \taskman\TaskmanTask($func, $name, $props, $TASKMAN_FILE_CHANGES);
}
else
throw new Exception("Task '$name' is invalid");
$TASKMAN_TASKS[$name] = $task;
foreach($task->getAliases() as $alias)
{
if(isset($TASKMAN_TASKS[$alias]) || isset($TASKMAN_TASK_ALIASES[$alias]))
throw new \taskman\TaskmanException("Alias '$alias' is already defined for task '$name'");
$TASKMAN_TASK_ALIASES[$alias] = $task;
}
}
_validate_tasks();
}
function _validate_tasks()
{
global $TASKMAN_TASKS;
foreach($TASKMAN_TASKS as $task)
{
try
{
$before = $task->getPropOr("before", "");
if($before)
\taskman\get_task($before)->addBeforeDep($task);
$after = $task->getPropOr("after", "");
if($after)
\taskman\get_task($after)->addAfterDep($task);
foreach($task->getDeps() as $dep_task)
\taskman\get_task($dep_task);
}
catch(Exception $e)
{
throw new Exception("Task '{$task->getName()}' validation error: " . $e->getMessage());
}
}
}
function _get_task_candidates()
{
global $TASKMAN_CLOSURES;
$cands = array();
//get tasks defined as closures
foreach($TASKMAN_CLOSURES as $name => $args)
{
$cands[$name] = $args;
}
ksort($cands);
return $cands;
}
function _resolve_callable_prop($name)
{
$prop = $GLOBALS['TASKMAN_PROP_' . $name];
if(!($prop instanceof \Closure))
return;
$value = $prop();
$GLOBALS['TASKMAN_PROP_' . $name] = $value;
}
function _isset_task($task)
{
global $TASKMAN_TASKS;
global $TASKMAN_TASK_ALIASES;
return isset($TASKMAN_TASKS[$task]) || isset($TASKMAN_TASK_ALIASES[$task]);
}
function _get_hints($task)
{
global $TASKMAN_TASKS;
global $TASKMAN_TASK_ALIASES;
$tasks = array_merge(array_keys($TASKMAN_TASKS), array_keys($TASKMAN_TASK_ALIASES));
$found = array_filter($tasks, function($v) use($task) { return strpos($v, $task) === 0; });
$found = array_merge($found, array_filter($tasks, function($v) use($task) { $pos = strpos($v, $task); return $pos !== false && $pos > 0; }));
return $found;
}
//e.g: run,build,zip
function _parse_taskstr($str)
{
$task_spec = array();
$items = explode(',', $str);
foreach($items as $item)
{
$args = null;
$task = $item;
if(strpos($item, ' ') !== false)
@list($task, $args) = explode(' ', $item, 2);
if($args)
$task_spec[] = array($task, explode(' ', $args));
else
$task_spec[] = $task;
}
return $task_spec;
}
function _read_env_vars()
{
$envs = getenv();
foreach($envs as $k => $v)
{
if(strpos($k, 'TASKMAN_SET_') === 0)
{
$prop_name = substr($k, 12);
\taskman\log(0, "Setting prop '$prop_name' (with env '$k')\n");
\taskman\set($prop_name, $v);
}
}
}
function _process_argv(array &$argv)
{
global $TASKMAN_LOG_LEVEL;
global $TASKMAN_BATCH;
global $TASKMAN_NO_DEPS;
global $TASKMAN_FILE_CHANGES;
$filtered = array();
$process_defs = false;
for($i=0;$i<sizeof($argv);++$i)
{
$v = $argv[$i];
if($v == '--')
{
for($j=$i+1;$j<sizeof($argv);++$j)
$filtered[] = $argv[$j];
break;
}
else if($v == '-D')
{
$process_defs = true;
}
else if($v == '-V')
{
$TASKMAN_LOG_LEVEL = 2;
}
else if($v == '-q')
{
$TASKMAN_LOG_LEVEL = 0;
}
else if($v == '-b')
{
$TASKMAN_LOG_LEVEL = -1;
}
else if($v == '-O')
{
$TASKMAN_NO_DEPS = true;
}
else if($v == '-c')
{
if(!isset($argv[$i+1]))
throw new \taskman\TaskmanException("Configuration file(-c option) is missing");
require_once($argv[$i+1]);
++$i;
}
else if($v == '-F')
{
if(!isset($argv[$i+1]))
throw new \taskman\TaskmanException("Argument(-F option) is missing");
$TASKMAN_FILE_CHANGES = \taskman\TaskmanFileChanges::parse($argv[$i+1]);
++$i;
}
else if($process_defs)
{
$eq_pos = strpos($v, '=');
if($eq_pos !== false)
{
$def_name = substr($v, 0, $eq_pos);
$def_value = substr($v, $eq_pos+1);
//TODO: this code must be more robust
if(strtolower($def_value) === 'true')
$def_value = true;
else if(strtolower($def_value) === 'false')
$def_value = false;
}
else
{
$def_name = $v;
$def_value = 1;
}
\taskman\log(0, "Setting prop '$def_name'=" . var_export($def_value, true) . "\n");
\taskman\set($def_name, $def_value);
$process_defs = false;
}
else
$filtered[] = $v;
}
$argv = $filtered;
}
function _extract_lines_from_file(string $file_path) : array
{
$lines = array();
$fh = fopen($file_path, 'r+');
if($fh === false)
return $lines;
try
{
if(flock($fh, LOCK_EX))
{
while(($line = fgets($fh)) !== false)
$lines[] = $line;
ftruncate($fh, 0);
flock($fh, LOCK_UN);
}
}
finally
{
fclose($fh);
}
return $lines;
}