public function run(string $task, $ostr = STDERR)
    {
        // CLI uses : because \ is used as escape character, so that
        // awkward syntax is required.
        $task = str_replace(":", "\\", $task);

        $log = Logger::getLogger('');
        $log->addLogWriter(new StreamWriter(STDOUT));

        if (!class_exists($task))
        {
            fprintf($ostr, "Error: task does not exist: {$task}\n");
            return false;
        }

        try
        {
            if (!is_subclass_of($task, TaskInterface::class))
            {
                fprintf($ostr, "Error: invalid task: {$task}\n");
                return false;
            }
            $taskrunner = new $task;
            $taskrunner->execute();
        }
        catch (\Throwable $e)
        {
            fprintf($ostr, "Error: error while running task: %s\n", $task);
            fprintf($ostr, "Exception: %s\n", get_class($e));
            fprintf($ostr, "Message: %s\n", $e->getMessage());
            if (method_exists($e, "getLine"))
                fprintf($ostr, "On: %s (line %d)\n", $e->getFile(), $e->getLine());
            fprintf($ostr, $e->getTraceAsString() . "\n");
            return false;
        }
        return true;
    }