<commit_before><?php declare(strict_types=1);

namespace EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\PostProcessor;

/**
 * This class provides the necessary functionality to allow you to maintain a set of file overrides and to safely apply
 * them as part of a post process to your main build process
 */
class FileOverrider
{
    /**
     * The default path to the overrides folder, relative to the project root
     */
    public const OVERRIDES_PATH = '/build/overrides';

    private const EXTENSION_LENGTH_NO_HASH_IN_PROJECT     = 4;
    private const EXTENSION_LENGTH_WITH_HASH_IN_OVERRIDES = 46;
    private const OVERRIDE_EXTENSION                      = 'override';

    /**
     * @var string
     */
    private $pathToProjectRoot;

    /**
     * @var string
     */
    private $pathToOverridesDirectory;

    public function __construct(
        string $pathToProjectRoot = null,
        string $relativePathToOverridesDirectory = self::OVERRIDES_PATH
    ) {
        if (null !== $pathToProjectRoot) {
            $this->setPathToProjectRoot($pathToProjectRoot);
            $this->setPathToOverridesDirectory($this->pathToProjectRoot . '/' . $relativePathToOverridesDirectory);
        }
    }

    /**
     * @param string $pathToProjectRoot
     *
     * @return $this
     * @throws \RuntimeException
     */
    public function setPathToProjectRoot(string $pathToProjectRoot): self
    {
        $this->pathToProjectRoot = $this->getRealPath($pathToProjectRoot);
        $this->setPathToOverridesDirectory($this->pathToProjectRoot . self::OVERRIDES_PATH);

        return $this;
    }

    private function getRealPath(string $path): string
    {
        $realPath = \realpath($path);
        if (false === $realPath) {
            if (!mkdir($path, 0777, true) && !is_dir($path)) {
                throw new \RuntimeException(sprintf('Directory "%s" was not created', $path));
            }
            $realPath = realpath($path);
        }

        return $realPath;
    }

    /**
     * Create a new Override File by copying the file from the project into the project's overrides directory
     *
     * @param string $pathToFileInProject
     *
     * @return string
     */
    public function createNewOverride(string $pathToFileInProject): string
    {
        $relativePathToFileInProject = $this->getRelativePathToFile($pathToFileInProject);
        if (null !== $this->getOverrideForPath($relativePathToFileInProject)) {
            throw new \RuntimeException('Override already exists for path ' . $relativePathToFileInProject);
        }
        $overridePath        =
            $this->getOverrideDirectoryForFile($relativePathToFileInProject) .
            '/' . $this->getFileNameNoExtensionForPathInProject($relativePathToFileInProject) .
            '.' . $this->getProjectFileHash($relativePathToFileInProject) .
            '.php.override';
        $pathToFileInProject = $this->pathToProjectRoot . '/' . $relativePathToFileInProject;
        if (false === is_file($pathToFileInProject)) {
            throw new \RuntimeException('path ' . $pathToFileInProject . ' is not a file');
        }
        copy($pathToFileInProject, $overridePath);

        return $this->getRelativePathToFile($overridePath);
    }

    private function getRelativePathToFile(string $pathToFileInProject): string
    {
        return str_replace($this->pathToProjectRoot, '', $this->getRealPath($pathToFileInProject));
    }

    private function getOverrideForPath(string $relativePathToFileInProject): ?string
    {
        $fileDirectory       = $this->getOverrideDirectoryForFile($relativePathToFileInProject);
        $fileNameNoExtension = $this->getFileNameNoExtensionForPathInProject($relativePathToFileInProject);
        $filesInDirectory    = glob("$fileDirectory/$fileNameNoExtension*");
        if ([] === $filesInDirectory) {
            return null;
        }
        if (1 === count($filesInDirectory)) {
            return $fileDirectory . '/' . current($filesInDirectory);
        }
        throw new \RuntimeException(
            'Found more than one override in path ' . $fileDirectory . ': '
            . print_r($filesInDirectory, true)
        );
    }

    private function getOverrideDirectoryForFile(string $relativePathToFileInProject): string
    {
        $path = $this->getPathToOverridesDirectory() . \dirname($relativePathToFileInProject);
        if (!is_dir($path) && !(mkdir($path, 0777, true) && is_dir($path))) {
            throw new \RuntimeException('Failed making override directory path ' . $path);
        }

        return $this->getRealPath($path);
    }

    /**
     * @return string<commit_msg>another tweak to ignore files that are not overrides<commit_after><?php declare(strict_types=1);

namespace EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\PostProcessor;

/**
 * This class provides the necessary functionality to allow you to maintain a set of file overrides and to safely apply
 * them as part of a post process to your main build process
 */
class FileOverrider
{
    /**
     * The default path to the overrides folder, relative to the project root
     */
    public const OVERRIDES_PATH = '/build/overrides';

    private const EXTENSION_LENGTH_NO_HASH_IN_PROJECT     = 4;
    private const EXTENSION_LENGTH_WITH_HASH_IN_OVERRIDES = 46;
    private const OVERRIDE_EXTENSION                      = 'override';

    /**
     * @var string
     */
    private $pathToProjectRoot;

    /**
     * @var string
     */
    private $pathToOverridesDirectory;

    public function __construct(
        string $pathToProjectRoot = null,
        string $relativePathToOverridesDirectory = self::OVERRIDES_PATH
    ) {
        if (null !== $pathToProjectRoot) {
            $this->setPathToProjectRoot($pathToProjectRoot);
            $this->setPathToOverridesDirectory($this->pathToProjectRoot . '/' . $relativePathToOverridesDirectory);
        }
    }

    /**
     * @param string $pathToProjectRoot
     *
     * @return $this
     * @throws \RuntimeException
     */
    public function setPathToProjectRoot(string $pathToProjectRoot): self
    {
        $this->pathToProjectRoot = $this->getRealPath($pathToProjectRoot);
        $this->setPathToOverridesDirectory($this->pathToProjectRoot . self::OVERRIDES_PATH);

        return $this;
    }

    private function getRealPath(string $path): string
    {
        $realPath = \realpath($path);
        if (false === $realPath) {
            if (!mkdir($path, 0777, true) && !is_dir($path)) {
                throw new \RuntimeException(sprintf('Directory "%s" was not created', $path));
            }
            $realPath = realpath($path);
        }

        return $realPath;
    }

    /**
     * Create a new Override File by copying the file from the project into the project's overrides directory
     *
     * @param string $pathToFileInProject
     *
     * @return string
     */
    public function createNewOverride(string $pathToFileInProject): string
    {
        $relativePathToFileInProject = $this->getRelativePathToFile($pathToFileInProject);
        if (null !== $this->getOverrideForPath($relativePathToFileInProject)) {
            throw new \RuntimeException('Override already exists for path ' . $relativePathToFileInProject);
        }
        $overridePath        =
            $this->getOverrideDirectoryForFile($relativePathToFileInProject) .
            '/' . $this->getFileNameNoExtensionForPathInProject($relativePathToFileInProject) .
            '.' . $this->getProjectFileHash($relativePathToFileInProject) .
            '.php.override';
        $pathToFileInProject = $this->pathToProjectRoot . '/' . $relativePathToFileInProject;
        if (false === is_file($pathToFileInProject)) {
            throw new \RuntimeException('path ' . $pathToFileInProject . ' is not a file');
        }
        copy($pathToFileInProject, $overridePath);

        return $this->getRelativePathToFile($overridePath);
    }

    private function getRelativePathToFile(string $pathToFileInProject): string
    {
        return str_replace($this->pathToProjectRoot, '', $this->getRealPath($pathToFileInProject));
    }

    private function getOverrideForPath(string $relativePathToFileInProject): ?string
    {
        $fileDirectory       = $this->getOverrideDirectoryForFile($relativePathToFileInProject);
        $fileNameNoExtension = $this->getFileNameNoExtensionForPathInProject($relativePathToFileInProject);
        $filesInDirectory    = glob("$fileDirectory/$fileNameNoExtension*" . self::OVERRIDE_EXTENSION);
        if ([] === $filesInDirectory) {
            return null;
        }
        if (1 === count($filesInDirectory)) {
            return $fileDirectory . '/' . current($filesInDirectory);
        }
        throw new \RuntimeException(
            'Found more than one override in path ' . $fileDirectory . ': '
            . print_r($filesInDirectory, true)
        );
    }

    private function getOverrideDirectoryForFile(string $relativePathToFileInProject): string
    {
        $path = $this->getPathToOverridesDirectory() . \dirname($relativePathToFileInProject);
        if (!is_dir($path) && !(mkdir($path, 0777, true) && is_dir($path))) {
            throw new \RuntimeException('Failed making override directory path ' . $path);
        }

        return $this->getRealPath($path);
    }

    /**
     * @return string
{'fraction_non_alphanumeric': 0.10767431972789115, 'fraction_numerical': 0.0027636054421768708, 'mean_word_length': 2.834148329258354, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 43, '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': '6339630', 'n_tokens_mistral': 2611, 'n_tokens_neox': 2559, 'n_words': 538}