<commit_before><?php namespace Aedart\Scaffold\Console;

use Aedart\Config\Loader\Traits\ConfigLoaderTrait;
use Aedart\Scaffold\Tasks\CopyFiles;
use Aedart\Scaffold\Tasks\CreateDirectories;
use Illuminate\Config\Repository;
use Illuminate\Contracts\Config\Repository as RepositoryInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\StyleInterface;

/**
 * Build Command
 *
 * Builds folders and files, based on the given configuration
 *
 * @author <NAME> <<EMAIL>>
 * @package Aedart\Scaffold\Console
 */
class BuildCommand extends BaseCommand
{
    use ConfigLoaderTrait;

    /**
     * List of console tasks (paths) that this command
     * must perform / execute.
     *
     * NB: The list is ordered !
     *
     * @var string[]
     */
    protected $tasks = [
        CreateDirectories::class,
        CopyFiles::class,
    ];

    protected function configure()
    {
        $this
            ->setName('build')
            ->setDescription('Creates folders, copies and generate files into the given output path')
            ->addArgument('config', InputArgument::REQUIRED, 'Path to the scaffold configuration file')
            ->addOption('output', null, InputOption::VALUE_OPTIONAL, 'Path where to build the scaffold folders and files', getcwd())
            ->setHelp($this->formatHelp());
    }

    /**
     * Execute the command
     *
     * @return int|null
     */
    public function runCommand()
    {
        // Load and resolve the configuration
        $config = $this->loadAndResolveConfiguration($this->input->getArgument('config'), $this->input->getOption('output'));

        // Execute builder's tasks
        $this->executeTasks($this->tasks, $this->input, $this->output, $config);

        // Output done msg
        $this->output->newLine();
        $this->output->success(sprintf('%s completed', $config->get('name')));
    }

    /**
     * Execute the given tasks
     *
     * @param string[] $tasks Class paths to the tasks that must be executed
     * @param InputInterface $input
     * @param OutputInterface $output
     * @param RepositoryInterface $config Configuration to be passed to each task
     */
    protected function executeTasks(array $tasks, InputInterface $input, OutputInterface $output, RepositoryInterface $config)
    {
        $i = 1;
        $total = count($tasks);

        foreach($tasks as $task){
            // Create new task instance
            /** @var \Aedart\Scaffold\Contracts\Tasks\ConsoleTask $taskToExecute */
            $taskToExecute = (new $task);

            // Output task info
            if($output instanceof StyleInterface){
                $output->section($taskToExecute->getName());
                $output->text("Task ({$i}/{$total})");
                $output->newLine();
            }

            // Execute the task
            $taskToExecute->execute($input, $output, $config);
            $i++;
        }
    }

    /**
     * Loads and resolves the scaffold configuration
     *
     * @param string $pathToConfig
     * @param string $outputPath
     *
     * @return Repository|RepositoryInterface
     */
    protected function loadAndResolveConfiguration($pathToConfig, $outputPath)
    {<commit_msg>Use task runner trait<commit_after><?php namespace Aedart\Scaffold\Console;

use Aedart\Config\Loader\Traits\ConfigLoaderTrait;
use Aedart\Scaffold\Tasks\CopyFiles;
use Aedart\Scaffold\Tasks\CreateDirectories;
use Aedart\Scaffold\Traits\TaskRunner;
use Illuminate\Config\Repository;
use Illuminate\Contracts\Config\Repository as RepositoryInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\StyleInterface;

/**
 * Build Command
 *
 * Builds folders and files, based on the given configuration
 *
 * @author <NAME> <<EMAIL>>
 * @package Aedart\Scaffold\Console
 */
class BuildCommand extends BaseCommand
{
    use ConfigLoaderTrait;
    use TaskRunner;

    /**
     * List of console tasks (paths) that this command
     * must perform / execute.
     *
     * NB: The list is ordered !
     *
     * @var string[]
     */
    protected $tasks = [
        CreateDirectories::class,
        CopyFiles::class,
    ];

    protected function configure()
    {
        $this
            ->setName('build')
            ->setDescription('Creates folders, copies and generate files into the given output path')
            ->addArgument('config', InputArgument::REQUIRED, 'Path to the scaffold configuration file')
            ->addOption('output', null, InputOption::VALUE_OPTIONAL, 'Path where to build the scaffold folders and files', getcwd())
            ->setHelp($this->formatHelp());
    }

    /**
     * Execute the command
     *
     * @return int|null
     */
    public function runCommand()
    {
        // Load and resolve the configuration
        $config = $this->loadAndResolveConfiguration($this->input->getArgument('config'), $this->input->getOption('output'));

        // Execute builder's tasks
        $this->getTaskRunner()->execute($this->tasks, $this->input, $this->output, $config);

        // Output done msg
        $this->output->newLine();
        $this->output->success(sprintf('%s completed', $config->get('name')));
    }

    /**
     * Loads and resolves the scaffold configuration
     *
     * @param string $pathToConfig
     * @param string $outputPath
     *
     * @return Repository|RepositoryInterface
     */
    protected function loadAndResolveConfiguration($pathToConfig, $outputPath)
    {
{'fraction_non_alphanumeric': 0.11976047904191617, 'fraction_numerical': 0.00017108639863130882, 'mean_word_length': 2.835958005249344, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 55, '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': '95754', 'n_tokens_mistral': 1603, 'n_tokens_neox': 1580, 'n_words': 393}