<commit_before><?php
namespace Sitegeist\MagicWand\Command;

/*                                                                        *
 * This script belongs to the TYPO3 Flow package "Sitegeist.MagicWand".   *
 *                                                                        *
 *                                                                        */

use TYPO3\Flow\Annotations as Flow;
use TYPO3\Flow\Utility\Files as FileUtils;
use TYPO3\Flow\Core\Bootstrap;

/**
 * @Flow\Scope("singleton")
 */
class StashCommandController extends AbstractCommandController
{



    /**
     * Creates a new stash entry.
     *
     * If you provide this command with a name, you can reference the new entry via stash:restore. Otherwise the new
     * entry can be restored with stash:pop, while multiple entries are handled LIFO-wise.
     *
     * @param string $name The name for the new stash entry
     * @return void
     */
    public function pushCommand($name = '')
    {
        #######################
        #     Build Paths     #
        #######################

        $identifier = $name ? $name : md5(time());

        $basePath = sprintf(FLOW_PATH_ROOT . 'Data/MagicWandStash/%s/%s',
            $name ? 'named' : 'anonymous',
            $identifier
        );

        $databaseDestination = $basePath . '/database.sql';
        $persistentDestination = $basePath . '/persistent/';

        FileUtils::createDirectoryRecursively($basePath);

        #######################
        # Check Configuration #
        #######################

        $this->checkConfiguration();

        ##################
        # Define Secrets #
        ##################

        $this->addSecret($this->databaseConfiguration['user']);
        $this->addSecret($this->databaseConfiguration['password']);

        ######################
        #  Backup Database   #
        ######################

        $this->outputHeadLine('Backup Database');
        $this->executeLocalShellCommand(
            'mysqldump --add-drop-table --host="%s" --user="%s" --password="%s" %s > %s',
            [
                $this->databaseConfiguration['host'],
                $this->databaseConfiguration['user'],
                $this->databaseConfiguration['password'],
                $this->databaseConfiguration['dbname'],
                $databaseDestination
            ]
        );

        ###############################
        # Backup Persistent Resources #
        ###############################

        $this->outputHeadLine('Backup Persistent Resources');
        $this->executeLocalShellCommand(
            'cp -al %s %s',
            [
                FLOW_PATH_ROOT . 'Data/Persistent',
                $persistentDestination
            ]
        );

        $this->outputLine('<b>Done!</b> Successfuly stashed %s', [$identifier]);
    }

    /**
     * Restores the last anonymous stash entry
     *
     * @param boolean $yes confirm execution without further input
     * @param boolean $keepDb skip dropping of database during sync
     * @return void
     */
    public function popCommand($yes = false, $keepDb = false)
    {
        $basePath = sprintf(FLOW_PATH_ROOT . 'Data/MagicWandStash/anonymous');

        if (!is_dir($basePath)) {
            $this->outputLine('Stash is empty.');
            $this->quit(1);
        }

        $entries = [];
        $baseDir = new \DirectoryIterator($basePath);

        foreach ($baseDir as $entry) {
            if (!in_array($entry, ['.', '..'])) {
                $entries[] = $entry->getPathname();
            }
        }

        uasort($entries, function ($a, $b) {
            return filemtime($b) - filemtime($a);
        });

        $this->restoreStashEntry($entries[0], basename($entries[0]), $yes, false, $keepDb);
    }

    /**
     * Shows the number of anonymous entries in the stash
     *
     * @return void
     */
    public function countCommand()
    {
        $basePath = sprintf(FLOW_PATH_ROOT . 'Data/MagicWandStash/anonymous');

        if (!is_dir($basePath)) {
            $this->outputLine('Stash is empty.');
            $this->quit(1);
        }

        $count = 0;
        $baseDir = new \DirectoryIterator($basePath);

        foreach ($baseDir as $entry) {
            if (!in_array($entry, ['.', '..'])) {
                $count++;
            }
        }

        $this->outputLine('<b>%d</b> anonymous %s.', [$count, $count === 1 ? 'entry' : 'entries']);
    }

    /**
     * Lists all named stash entries
     *
     * @return void
     */
    public function listCommand()
    {
        $basePath = sprintf(FLOW_PATH_ROOT . 'Data/MagicWandStash/named');

        if (!is_dir($basePath)) {
            $this->outputLine('Stash is empty.');
            $this->quit(1);
        }

        $baseDir = new \DirectoryIterator($basePath);
        $anyEntry = false;

        foreach ($baseDir as $entry) {
            if (!in_array($entry, ['.', '..'])) {
                $this->outputLine(' • %s', [$entry->getFilename()]);
                $anyEntry = true;
            }
        }

        if (!$anyEntry) {
            $this->outputLine('Stash is empty.');
            $this->quit(1);
        }
    }

    /**
     * Clear the stash
     *
     * If provided with the optional parameter $type, this command will remove only anonymous entries ($type=anonymous),
     * named entries ($type=named), or by default all (or $type=all)
     *
     * @param string $type
     * @return void
     */
    public function clearCommand($type = 'all')
    {
        switch ($type) {
            case 'all':
                $path = FLOW_PATH_ROOT . 'Data/MagicWandStash';
                break;

            case 'anonymous':
            case 'named':
                $path = FLOW_PATH_ROOT . 'Data/MagicWandStash/' . $type;
                break;

            default:
                $this->outputLine('<error>You have to provide a correct type (all|anonymous|named)</error>');
                $this->quit(1);

        }

        FileUtils::removeDirectoryRecursively($path);

        $this->outputLine('<b>Done!</b> Cleanup successful.');
    }

    /**
     * Restores named stash entries
     *
     * @param string $name The name of the stash entry that will be restored
     * @param boolean $yes confirm execution without further input
     * @param boolean $keepDb skip dropping of database during sync
     * @return void
     */
    public function restoreCommand($name, $yes = false, $keepDb = false)
    {
        $basePath = sprintf(FLOW_PATH_ROOT . 'Data/MagicWandStash/named/%s', $name);
        $this->restoreStashEntry($basePath, $name, $yes, true, $keepDb);
    }

    /**
     * Remove a named stash entry
     *
     * @param string $name The name of the stash entry that will be removed
     * @param boolean $yes confirm execution without further input
     * @return void
     */
    public function removeCommand($name, $yes = false)
    {
        $directory = FLOW_PATH_ROOT . 'Data/MagicWandStash/named/' . $name;

        if (!is_dir($directory)) {
            $this->outputLine('<error>%s does not exist</error>', [$name]);
            $this->quit(1);
        }

        if (!$yes) {
            $this->outputLine("Are you sure you want to do this?  Type 'yes' to continue: ");
            $handle = fopen("php://stdin", "r");
            $line = fgets($handle);

            if (trim($line) != 'yes') {
                $this->outputLine('exit');
                $this->quit(1);
            } else {
                $this->outputLine();
                $this->outputLine();
            }
        }

        FileUtils::removeDirectoryRecursively($directory);

        $this->outputLine('<b>Done!</b> Successfuly removed %s', [$name]);
    }

    /**
     * Actual resore logic
     *
     * @param string $source
     * @param string $identifier
     * @param boolean $force
     * @param boolean $keepDb
     * @return void
     */
    protected function restoreStashEntry($source, $identifier, $force = false, $preserve = true, $keepDb = false)
    {
        if (!is_dir($source)) {
            $this->outputLine('<error>%s does not exist</error>', [$identifier]);
            $this->quit(1);
        }
<commit_msg>[TASK] Remove the unnamed stashes entirely<commit_after><?php
namespace Sitegeist\MagicWand\Command;

/*                                                                        *
 * This script belongs to the TYPO3 Flow package "Sitegeist.MagicWand".   *
 *                                                                        *
 *                                                                        */

use TYPO3\Flow\Annotations as Flow;
use TYPO3\Flow\Utility\Files as FileUtils;
use TYPO3\Flow\Core\Bootstrap;

/**
 * @Flow\Scope("singleton")
 */
class StashCommandController extends AbstractCommandController
{



    /**
     * Creates a new stash entry with the given name.
     *
     * @param string $name The name for the new stash entry
     * @return void
     */
    public function createCommand($name)
    {
        #######################
        #     Build Paths     #
        #######################

        $identifier = $name ? $name : md5(time());

        $basePath = sprintf(FLOW_PATH_ROOT . 'Data/MagicWandStash/%s',
            $identifier
        );

        $databaseDestination = $basePath . '/database.sql';
        $persistentDestination = $basePath . '/persistent/';

        FileUtils::createDirectoryRecursively($basePath);

        #######################
        # Check Configuration #
        #######################

        $this->checkConfiguration();

        ##################
        # Define Secrets #
        ##################

        $this->addSecret($this->databaseConfiguration['user']);
        $this->addSecret($this->databaseConfiguration['password']);

        ######################
        #  Backup Database   #
        ######################

        $this->outputHeadLine('Backup Database');
        $this->executeLocalShellCommand(
            'mysqldump --add-drop-table --host="%s" --user="%s" --password="%s" %s > %s',
            [
                $this->databaseConfiguration['host'],
                $this->databaseConfiguration['user'],
                $this->databaseConfiguration['password'],
                $this->databaseConfiguration['dbname'],
                $databaseDestination
            ]
        );

        ###############################
        # Backup Persistent Resources #
        ###############################

        $this->outputHeadLine('Backup Persistent Resources');
        $this->executeLocalShellCommand(
            'cp -al %s %s',
            [
                FLOW_PATH_ROOT . 'Data/Persistent',
                $persistentDestination
            ]
        );

        $this->outputLine('<b>Done!</b> Successfuly stashed %s', [$identifier]);
    }

    /**
     * Lists all entries
     *
     * @return void
     */
    public function listCommand()
    {
        $basePath = sprintf(FLOW_PATH_ROOT . 'Data/MagicWandStash');

        if (!is_dir($basePath)) {
            $this->outputLine('Stash is empty.');
            $this->quit(1);
        }

        $baseDir = new \DirectoryIterator($basePath);
        $anyEntry = false;

        foreach ($baseDir as $entry) {
            if (!in_array($entry, ['.', '..'])) {
                $this->outputLine(' • %s', [$entry->getFilename()]);
                $anyEntry = true;
            }
        }

        if (!$anyEntry) {
            $this->outputLine('Stash is empty.');
            $this->quit(1);
        }
    }

    /**
     * Clear the whole stash
     *
     * @return void
     */
    public function clearCommand()
    {
        $path = FLOW_PATH_ROOT . 'Data/MagicWandStash';
        FileUtils::removeDirectoryRecursively($path);
        $this->outputLine('<b>Done!</b> Cleanup successful.');
    }

    /**
     * Restores stash entries
     *
     * @param string $name The name of the stash entry that will be restored
     * @param boolean $yes confirm execution without further input
     * @param boolean $keepDb skip dropping of database during sync
     * @return void
     */
    public function restoreCommand($name, $yes = false, $keepDb = false)
    {
        $basePath = sprintf(FLOW_PATH_ROOT . 'Data/MagicWandStash/%s', $name);
        $this->restoreStashEntry($basePath, $name, $yes, true, $keepDb);
    }

    /**
     * Remove a named stash entry
     *
     * @param string $name The name of the stash entry that will be removed
     * @param boolean $yes confirm execution without further input
     * @return void
     */
    public function removeCommand($name, $yes = false)
    {
        $directory = FLOW_PATH_ROOT . 'Data/MagicWandStash/' . $name;

        if (!is_dir($directory)) {
            $this->outputLine('<error>%s does not exist</error>', [$name]);
            $this->quit(1);
        }

        if (!$yes) {
            $this->outputLine("Are you sure you want to do this?  Type 'yes' to continue: ");
            $handle = fopen("php://stdin", "r");
            $line = fgets($handle);

            if (trim($line) != 'yes') {
                $this->outputLine('exit');
                $this->quit(1);
            } else {
                $this->outputLine();
                $this->outputLine();
            }
        }

        FileUtils::removeDirectoryRecursively($directory);

        $this->outputLine('<b>Done!</b> Successfuly removed %s', [$name]);
    }

    /**
     * Actual restore logic
     *
     * @param string $source
     * @param string $identifier
     * @param boolean $force
     * @param boolean $keepDb
     * @return void
     */
    protected function restoreStashEntry($source, $identifier, $force = false, $preserve = true, $keepDb = false)
    {
        if (!is_dir($source)) {
            $this->outputLine('<error>%s does not exist</error>', [$identifier]);
            $this->quit(1);
        }

{'fraction_non_alphanumeric': 0.1640328923846979, 'fraction_numerical': 0.0019306399713979263, 'mean_word_length': 1.830601092896175, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 102, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1086655', 'n_tokens_mistral': 3881, 'n_tokens_neox': 3760, 'n_words': 858}