<commit_before><?php

namespace Qobo\Robo;

use \Robo\Result;
use \Robo\Exception\TaskException;
use \Qobo\Utility\Template;

/**
 * Qobo base command task.
 */
abstract class AbstractCmdTask extends AbstractTask
{
    /**
     * {@inheritdoc}
     */
    protected $data = [
        // command to run
        'cmd'   => null,

        // array of paths agains which to run a command. If empty, command will not run (use './')
        'path'  => [],

        // whether to run a command agains each path separatly or in batch (path will be joined with ' ')
        'batch' => false,

        // path for any logs to be written to
        'logs'  => null,

        // path for any output files to be written to
        'out'   => null,
    ];

    /**
     * {@inhericdoc}
     */
    protected $requiredData = [
        'cmd',
        'path',
        'batch'
    ];

    /**
     * @var array $tokenKeys data keys to use as tokens in cmd
     */
    protected $tokenKeys = [
        'out',
        'logs'
    ];

    /**
     * {@inheritdoc}
     */
    public function run()
    {
        $result = parent::run();
        if (!$result->wasSuccessful()) {
            return $result;
        }

		if (!is_array($this->data['path'])) {
			$this->data['path'] = [ $this->data['path'] ];
		}
        // validate our cmd and paths
        try {
            static::checkCmd($this->data['cmd']);
            foreach ($this->data['path'] as $path) {
                static::checkPath($path);
            }
        } catch (\Exception $e) {
            return Result::fromException($this, $e);
        }

        // get a list of commands to run
        $cmds = $this->getCommands();

        $this->data['data'] = [];
        foreach ($cmds as $cmd) {
            $this->printInfo("Running {cmd}", ['cmd' => $cmd]);
            $data = $this->runCmd($cmd);
            $this->data['data'] []= $data;

            // POSIX commands will exit with 1 on success
            // and 0 on failure
            if (!$data['status'] && $this->stopOnFail) {
                return Result::error($this, "Last command failed to run", $this->data);
            }

        }
        return Result::success($this, "Commands run successfully", $this->data);
    }

    /**
     * Check if path is readable
     */
    public static function checkPath($path)
    {
        if (!is_string($path)) {
            throw new \InvalidArgumentException(sprintf("String expected as path, got '%s' instead", gettype($path)));
        }<commit_msg>Fixed POSIX exit code for abstract command class (task #4292)<commit_after><?php

namespace Qobo\Robo;

use \Robo\Result;
use \Robo\Exception\TaskException;
use \Qobo\Utility\Template;

/**
 * Qobo base command task.
 */
abstract class AbstractCmdTask extends AbstractTask
{
    /**
     * {@inheritdoc}
     */
    protected $data = [
        // command to run
        'cmd'   => null,

        // array of paths agains which to run a command. If empty, command will not run (use './')
        'path'  => [],

        // whether to run a command agains each path separatly or in batch (path will be joined with ' ')
        'batch' => false,

        // path for any logs to be written to
        'logs'  => null,

        // path for any output files to be written to
        'out'   => null,
    ];

    /**
     * {@inhericdoc}
     */
    protected $requiredData = [
        'cmd',
        'path',
        'batch'
    ];

    /**
     * @var array $tokenKeys data keys to use as tokens in cmd
     */
    protected $tokenKeys = [
        'out',
        'logs'
    ];

    /**
     * {@inheritdoc}
     */
    public function run()
    {
        $result = parent::run();
        if (!$result->wasSuccessful()) {
            return $result;
        }

		if (!is_array($this->data['path'])) {
			$this->data['path'] = [ $this->data['path'] ];
		}
        // validate our cmd and paths
        try {
            static::checkCmd($this->data['cmd']);
            foreach ($this->data['path'] as $path) {
                static::checkPath($path);
            }
        } catch (\Exception $e) {
            return Result::fromException($this, $e);
        }

        // get a list of commands to run
        $cmds = $this->getCommands();

        $this->data['data'] = [];
        foreach ($cmds as $cmd) {
            $this->printInfo("Running {cmd}", ['cmd' => $cmd]);
            $data = $this->runCmd($cmd);
            $this->data['data'] []= $data;

            // POSIX commands will exit with 0 on success
            // and 1 on failure
            if ($data['status'] && $this->stopOnFail) {
                return Result::error($this, "Last command failed to run", $this->data);
            }

        }

        return ($data['status'])
            ? Result::error($this, "Last command failed to run", $this->data)
            : Result::success($this, "Commands run successfully", $this->data);
    }

    /**
     * Check if path is readable
     */
    public static function checkPath($path)
    {
        if (!is_string($path)) {
            throw new \InvalidArgumentException(sprintf("String expected as path, got '%s' instead", gettype($path)));
        }
{'fraction_non_alphanumeric': 0.15323824209714726, 'fraction_numerical': 0.0015420200462606013, 'mean_word_length': 1.7659914712153517, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 44, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6934707', 'n_tokens_mistral': 1522, 'n_tokens_neox': 1474, 'n_words': 433}