From 54cd3576d70f6a550d2607786212ff5d85432d01 Mon Sep 17 00:00:00 2001 From: Pavel Shevaev Date: Mon, 28 Apr 2025 14:24:43 +0300 Subject: [PATCH] Adding initial support for tasks bench times; A bit improving similar tasks logic in case of task was not found; A bit cleaning internals; --- internal.inc.php | 50 +++++++++++++++++++++++++++++----------- taskman.inc.php | 60 +++++++++++++++++++++++++----------------------- 2 files changed, 68 insertions(+), 42 deletions(-) diff --git a/internal.inc.php b/internal.inc.php index c651dc5..fb56fa1 100644 --- a/internal.inc.php +++ b/internal.inc.php @@ -18,7 +18,7 @@ function _default_usage($script_name = "") 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); @@ -290,3 +289,28 @@ function _extract_lines_from_file(string $file_path) : array return $lines; } +function _show_bench(array $tasks, int $limit = 5) +{ + $times = array(); + + foreach($tasks as $name => $task) + { + if($task->hasRun()) + $times[$name] = round($task->getRunTime(), 2); + } + + uasort($times, fn($a, $b) => $b <=> $a); + array_splice($times, $limit); + + if(!$times) + return; + + \taskman\log(2, "Top ".count($times)." time consuming tasks:\n"); + $n = 0; + foreach($times as $name => $time) + { + ++$n; + \taskman\log(2, "$n) Task '$name': $time sec\n"); + } +} + diff --git a/taskman.inc.php b/taskman.inc.php index f331723..60dc735 100644 --- a/taskman.inc.php +++ b/taskman.inc.php @@ -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(); @@ -39,7 +40,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 +156,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 +173,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 +189,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 +222,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 +483,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 +511,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 +525,8 @@ function main( else if($default_task) run($default_task, $argv); + internal\_show_bench($task_objs); + log(0, "***** All done (".round(microtime(true)-$GLOBALS['TASKMAN_START_TIME'],2)." sec.) *****\n"); }