Compare commits

..

4 Commits

Author SHA1 Message Date
Pavel Shevaev 97e948d132 Artefact is considered stale if passed changed files match the spec (without additional stale check)
Publish PHP Package / docker (push) Successful in 3m28s Details
2025-04-29 14:11:51 +03:00
Pavel Shevaev ade0ef5373 Adding --bench option to show basic tasks bench info
Publish PHP Package / docker (push) Successful in 7s Details
2025-04-28 14:38:13 +03:00
Pavel Shevaev 058ab92420 array_splice possible fix
Publish PHP Package / docker (push) Successful in 6s Details
2025-04-28 14:28:29 +03:00
Pavel Shevaev 54cd3576d7 Adding initial support for tasks bench times; A bit improving similar tasks logic in case of task was not found; A bit cleaning internals;
Publish PHP Package / docker (push) Successful in 6s Details
2025-04-28 14:24:44 +03:00
3 changed files with 95 additions and 51 deletions

View File

@ -89,11 +89,19 @@ class TaskmanArtefact
{
if(!isset($this->sources_affected[$idx]))
{
$sources = $this->task->getFileChanges() != null ?
//tries to match changed files with sources spec
$this->getChangedSources($idx) :
$this->getSources($idx);
$this->sources_affected[$idx] = is_stale($this->getPath(), $sources);
//NOTE: more conservative implementation which always checks for staleness
//$sources = $this->task->getFileChanges() != null ?
// //tries to match changed files with sources spec
// $this->getChangedSources($idx) :
// $this->getSources($idx);
//$this->sources_affected[$idx] = is_stale($this->getPath(), $sources);
//NOTE: if there any file changes we simply check if there are any changed sources,
// and if yes then we mark the artefact as affected
if($this->task->getFileChanges() != null)
$this->sources_affected[$idx] = count($this->getChangedSources($idx)) > 0;
else
$this->sources_affected[$idx] = is_stale($this->getPath(), $this->getSources($idx));
}
return $this->sources_affected[$idx];

View File

@ -18,7 +18,7 @@ function _default_usage($script_name = "<taskman-script>")
echo " -- pass all options verbatim after this mark\n";
}
function _collect_tasks()
function _collect_tasks() : array
{
global $TASKMAN_TASKS;
global $TASKMAN_TASK_ALIASES;
@ -59,14 +59,14 @@ function _collect_tasks()
}
}
_validate_tasks();
_validate_tasks($TASKMAN_TASKS);
return $TASKMAN_TASKS;
}
function _validate_tasks()
function _validate_tasks(array $tasks)
{
global $TASKMAN_TASKS;
foreach($TASKMAN_TASKS as $task)
foreach($tasks as $task)
{
try
{
@ -88,7 +88,7 @@ function _validate_tasks()
}
}
function _get_task_candidates()
function _get_task_candidates() : array
{
global $TASKMAN_CLOSURES;
@ -105,7 +105,7 @@ function _get_task_candidates()
return $cands;
}
function _resolve_callable_prop($name)
function _resolve_callable_prop(string $name)
{
$prop = $GLOBALS['TASKMAN_PROP_' . $name];
if(!($prop instanceof \Closure))
@ -114,25 +114,24 @@ function _resolve_callable_prop($name)
$GLOBALS['TASKMAN_PROP_' . $name] = $value;
}
function _isset_task($task)
function _isset_task(string $task) : bool
{
global $TASKMAN_TASKS;
global $TASKMAN_TASK_ALIASES;
return isset($TASKMAN_TASKS[$task]) || isset($TASKMAN_TASK_ALIASES[$task]);
}
function _get_hints($task)
function _get_hints(string $task) : array
{
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; }));
$found = array_filter($tasks, function($v) use($task) { similar_text($v, $task, $p); return $p > 70; });
return $found;
}
//e.g: run,build,zip
function _parse_taskstr($str)
function _parse_taskstr(string $str) : array
{
$task_spec = array();
$items = explode(',', $str);
@ -172,6 +171,7 @@ function _process_argv(array &$argv)
global $TASKMAN_BATCH;
global $TASKMAN_NO_DEPS;
global $TASKMAN_FILE_CHANGES;
global $TASKMAN_SHOW_BENCH;
$filtered = array();
$process_defs = false;
@ -186,10 +186,6 @@ function _process_argv(array &$argv)
$filtered[] = $argv[$j];
break;
}
else if($v == '-D')
{
$process_defs = true;
}
else if($v == '-V')
{
$TASKMAN_LOG_LEVEL = 2;
@ -214,6 +210,10 @@ function _process_argv(array &$argv)
{
$TASKMAN_NO_DEPS = true;
}
else if($v == '--bench')
{
$TASKMAN_SHOW_BENCH = true;
}
else if($v == '-c')
{
if(!isset($argv[$i+1]))
@ -230,6 +230,10 @@ function _process_argv(array &$argv)
++$i;
}
else if($v == '-D')
{
$process_defs = true;
}
else if($process_defs)
{
$eq_pos = strpos($v, '=');
@ -290,3 +294,31 @@ function _extract_lines_from_file(string $file_path) : array
return $lines;
}
function _show_bench(array $tasks, int $limit = 5)
{
if(!$tasks)
return;
$times = array();
foreach($tasks as $name => $task)
{
if($task->hasRun())
$times[$name] = round($task->getRunTime(), 2);
}
uasort($times, fn($a, $b) => $b <=> $a);
if(count($times) > $limit)
array_splice($times, $limit);
if(!$times)
return;
\taskman\log(1, "Top ".count($times)." time consuming tasks:\n");
$n = 0;
foreach($times as $name => $time)
{
++$n;
\taskman\log(1, "$n) Task '$name': $time sec\n");
}
}

View File

@ -2,6 +2,7 @@
namespace taskman;
use Exception;
//TODO: get rid of global variables
$GLOBALS['TASKMAN_TASKS'] = array();
$GLOBALS['TASKMAN_CLOSURES'] = array();
$GLOBALS['TASKMAN_STACK'] = array();
@ -15,6 +16,7 @@ $GLOBALS['TASKMAN_LOGGER'] = '\taskman\internal\_default_logger';
$GLOBALS['TASKMAN_ERROR_HANDLER'] = null;
$GLOBALS['TASKMAN_START_TIME'] = 0;
$GLOBALS['TASKMAN_FILES_CHANGES'] = null;
$GLOBALS['TASKMAN_SHOW_BENCH'] = false;
include_once(__DIR__ . '/internal.inc.php');
include_once(__DIR__ . '/util.inc.php');
@ -39,7 +41,11 @@ class TaskmanTask
private $props = array();
private bool $is_running = false;
//contains statuses of runs in the following format:
// serialized_args => 1|2
// 1 - artefacts are not stale, 2 - full run
private array $has_run = array();
private float $run_time = 0;
private ?array $deps = null;
private array $before_deps = array();
@ -151,6 +157,16 @@ class TaskmanTask
return $this->file_changes != null;
}
function hasRun() : bool
{
return count($this->has_run) > 0;
}
function getRunTime() : float
{
return $this->run_time;
}
function run($args = array())
{
global $TASKMAN_CURRENT_TASK;
@ -158,9 +174,9 @@ class TaskmanTask
global $TASKMAN_NO_DEPS;
global $TASKMAN_START_TIME;
$args_str = serialize($args);
$args_hash = serialize($args);
if((isset($this->has_run[$args_str]) && $this->has_run[$args_str]) ||
if((isset($this->has_run[$args_hash]) && $this->has_run[$args_hash]) ||
$this->is_running)
return;
@ -174,11 +190,12 @@ class TaskmanTask
{
$bench = microtime(true);
$stale_found = $this->_checkIfArtefactsStale();
$this->run_time += (microtime(true) - $bench);
log(0, "***** ".str_repeat('-', $level)."task '" . $this->getName() . "' artefacts check done(" .
round(microtime(true)-$bench,2) . '/' .round(microtime(true)-$TASKMAN_START_TIME,2) . " sec.) *****\n");
round($this->run_time,2) . '/' .round(microtime(true)-$TASKMAN_START_TIME,2) . " sec.) *****\n");
if(!$stale_found)
{
$this->has_run[$args_str] = true;
$this->has_run[$args_hash] = 1;
return;
}
}
@ -206,10 +223,11 @@ class TaskmanTask
if(!$TASKMAN_NO_DEPS)
run_many($this->after_deps);
$this->run_time += (microtime(true) - $bench);
log(0, "***** ".str_repeat('-', $level)."task '" . $this->getName() . "' done(" .
round(microtime(true)-$bench,2) . '/' .round(microtime(true)-$TASKMAN_START_TIME,2) . " sec.) *****\n");
round($this->run_time,2) . '/' .round(microtime(true)-$TASKMAN_START_TIME,2) . " sec.) *****\n");
$this->has_run[$args_str] = true;
$this->has_run[$args_hash] = 2;
$this->is_running = false;
}
catch(Exception $e)
@ -466,11 +484,11 @@ function main(
$GLOBALS['TASKMAN_SCRIPT'] = array_shift($argv);
internal\_collect_tasks();
$task_objs = internal\_collect_tasks();
$always_tasks = array();
$default_task = null;
foreach(get_tasks() as $task_obj)
foreach($task_objs as $task_obj)
{
if($task_obj->hasProp('always'))
array_unshift($always_tasks, $task_obj);
@ -494,30 +512,13 @@ function main(
if(count($tasks) == 1 && !internal\_isset_task($tasks[0]))
{
$pattern = $tasks[0];
if($pattern[0] == '~')
{
$pattern = substr($pattern, 1, strlen($pattern) - 1);
$is_similar = true;
}
elseif(substr($pattern, -1, 1) == '~')
{
$pattern = substr($pattern, 0, strlen($pattern) - 1);
$is_similar = true;
}
else
$is_similar = false;
$hints = internal\_get_hints($pattern);
if($is_similar && count($hints) == 1)
$tasks = $hints;
else
{
$similars = '';
if($hints)
$similars .= "\nSimilar tasks: " . implode(', ', $hints) . ".";
$similars = '';
if($hints)
$similars .= "\nSimilar tasks: " . implode(', ', $hints) . ".";
throw new Exception("Task '{$tasks[0]}' not found. $similars");
}
throw new Exception("Task '{$tasks[0]}' not found. $similars");
}
run_many($tasks, $argv);
@ -525,6 +526,9 @@ function main(
else if($default_task)
run($default_task, $argv);
if($GLOBALS['TASKMAN_SHOW_BENCH'])
internal\_show_bench($task_objs);
log(0, "***** All done (".round(microtime(true)-$GLOBALS['TASKMAN_START_TIME'],2)." sec.) *****\n");
}