<commit_before><?php declare(strict_types=1);
/*
 * This file is part of the ************************ package.
 * _____________                           _______________
 *  ______/     \__  _____  ____  ______  / /_  _________
 *   ____/ __   / / / / _ \/ __`\/ / __ \/ __ \/ __ \___
 *    __/ / /  / /_/ /  __/ /  \  / /_/ / / / / /_/ /__
 *      \_\ \_/\____/\___/_/   / / .___/_/ /_/ .___/
 *         \_\                /_/_/         /_/
 *
 * The PHP Framework For Code Poem As Free As Wind. <Query Yet Simple>
 * (c) 2010-2018 http://queryphp.com All rights reserved.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace Leevel\Option;

use Exception;
use Dotenv\Dotenv;
use RuntimeException;
use Leevel\Kernel\IProject;
use Dotenv\Exception\InvalidFileException;
use Dotenv\Exception\InvalidPathException;

/**
 * 配置工具类
 *
 * @author <NAME> <<EMAIL>>
 * @package $$
 * @since 2017.05.18
 * @version 1.0
 */
class Load
{
    /**
     * 配置路径
     *
     * @var string
     */
    protected $dir = [];

    /**
     * 已经载入数据
     *
     * @var array
     */
    protected $loaded = [];

    /**
     * 构造函数
     *
     * @param string $dir
     * @return void
     */
    public function __construct(string $dir)
    {
        if (! is_string($dir)) {
            throw new RuntimeException('Option load dir is not exits.');
        }

        $this->dir = $dir;
    }

    /**
     * 载入配置数据
     *
     * @param \Leevel\Kernel\IProject $project
     * @return array
     */
    public function loadData(IProject $project): array
    {
        if ($this->loaded) {
            return $this->loaded;
        }

        $env = $this->loadEnvData($project);

        $composer = $this->loadComposerOption($project->path());

        $data = $this->loadOptionData();

        // 读取额外的配置
        if ($composer['options']) {
            $data = $this->mergeComposerOption($data, $project, $composer['options']);
        }

        // 环境变量
        $data['app']['_env'] = $env;

        // composer 配置
        $data['app']['_composer'] = $composer;

        // 延迟服务提供者
        $providers = $this->loadDeferredProviderData(array_diff($composer['providers'], $composer['ignores']));
        $data['app']['_deferred_poviders'] = $providers;

        return $this->loaded = $data;
    }

    /**
     * 载入环境变量数据
     * 
     * @param \Leevel\Kernel\IProject $project
     * @return array
     */
    protected function loadEnvData(IProject $project): array
    {
        try {
            (new Dotenv($project->pathEnv(), $project->envFile()))->load();
        } catch (InvalidPathException $e) {
            exit($e->getMessage());
        } catch (InvalidFileException $e) {
            exit($e->getMessage());
        }

        return $_ENV;
    }

    /**
     * 分析延迟加载服务提供者
     * 
     * @param array $providers
     * @return array
     */
    protected function loadDeferredProviderData(array $providers): array
    {
       $deferredProviders = $deferredAlias = [];

       foreach ($providers as $provider) {
            if (! class_exists($provider)) {
                continue;
            }

            if ($provider::isDeferred()) {
                $providers = $provider::providers();
                foreach ($providers as $key => $alias) {
                    if (is_int($key)) {
                        $key = $alias;
                    }

                    $deferredProviders[$key] = $provider;
                }

                $deferredAlias[$provider] = $providers;
            }
        }

        return [
            $deferredProviders,
            $deferredAlias
        ];
    }

    /**
     * 载入 Composer 配置数据
     * 
     * @param string $path
     * @return array
     */
    protected function loadComposerOption(string $path): array
    {
        return (new ComposerOption($path))->loadData();
    }

    /**
     * 载入配置数据
     *
     * @return array
     */
    protected function loadOptionData(): array
    {
        $data = [];

        $files = glob($this->dir . '/*.php');

        $findApp = false;

        foreach ($files as $file) {
            $type = substr(basename($file), 0, -4);

            if ($type == 'app') {
                $findApp = true;
            }

            $data[$type] = (array) include $file;
        }


        if ($findApp === false) {
            throw new Exception('Unable to load the app option file.');
        }

        return $data;
    }
<commit_msg>the compute providers is wrong<commit_after><?php declare(strict_types=1);
/*
 * This file is part of the ************************ package.
 * _____________                           _______________
 *  ______/     \__  _____  ____  ______  / /_  _________
 *   ____/ __   / / / / _ \/ __`\/ / __ \/ __ \/ __ \___
 *    __/ / /  / /_/ /  __/ /  \  / /_/ / / / / /_/ /__
 *      \_\ \_/\____/\___/_/   / / .___/_/ /_/ .___/
 *         \_\                /_/_/         /_/
 *
 * The PHP Framework For Code Poem As Free As Wind. <Query Yet Simple>
 * (c) 2010-2018 http://queryphp.com All rights reserved.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace Leevel\Option;

use Exception;
use Dotenv\Dotenv;
use RuntimeException;
use Leevel\Kernel\IProject;
use Dotenv\Exception\InvalidFileException;
use Dotenv\Exception\InvalidPathException;

/**
 * 配置工具类
 *
 * @author <NAME> <<EMAIL>>
 * @package $$
 * @since 2017.05.18
 * @version 1.0
 */
class Load
{
    /**
     * 配置路径
     *
     * @var string
     */
    protected $dir = [];

    /**
     * 已经载入数据
     *
     * @var array
     */
    protected $loaded = [];

    /**
     * 构造函数
     *
     * @param string $dir
     * @return void
     */
    public function __construct(string $dir)
    {
        if (! is_string($dir)) {
            throw new RuntimeException('Option load dir is not exits.');
        }

        $this->dir = $dir;
    }

    /**
     * 载入配置数据
     *
     * @param \Leevel\Kernel\IProject $project
     * @return array
     */
    public function loadData(IProject $project): array
    {
        if ($this->loaded) {
            return $this->loaded;
        }

        $env = $this->loadEnvData($project);

        $composer = $this->loadComposerOption($project->path());

        $data = $this->loadOptionData();

        // 读取额外的配置
        if ($composer['options']) {
            $data = $this->mergeComposerOption($data, $project, $composer['options']);
        }

        // 环境变量
        $data['app']['_env'] = $env;

        // 延迟服务提供者
        $composer['providers'] = array_diff($composer['providers'], $composer['ignores']);
        $providers = $this->loadDeferredProviderData($composer['providers']);
        $data['app']['_deferred_providers'] = $providers;

        // composer 配置
        $data['app']['_composer'] = $composer;

        return $this->loaded = $data;
    }

    /**
     * 载入环境变量数据
     * 
     * @param \Leevel\Kernel\IProject $project
     * @return array
     */
    protected function loadEnvData(IProject $project): array
    {
        try {
            (new Dotenv($project->pathEnv(), $project->envFile()))->load();
        } catch (InvalidPathException $e) {
            exit($e->getMessage());
        } catch (InvalidFileException $e) {
            exit($e->getMessage());
        }

        return $_ENV;
    }

    /**
     * 分析延迟加载服务提供者
     * 
     * @param array $providers
     * @return array
     */
    protected function loadDeferredProviderData(array &$providers): array
    {
       $deferredProviders = $deferredAlias = [];

       foreach ($providers as $k => $provider) {
            if (! class_exists($provider)) {
                unset($providers[$key]);
                continue;
            }

            if ($provider::isDeferred()) {
                $providerAlias = $provider::providers();

                foreach ($providerAlias as $key => $alias) {
                    if (is_int($key)) {
                        $key = $alias;
                    }

                    $deferredProviders[$key] = $provider;
                }

                $deferredAlias[$provider] = $providerAlias;

                unset($providers[$k]);
            }
        }

        $providers = array_values($providers);

        return [
            $deferredProviders,
            $deferredAlias
        ];
    }

    /**
     * 载入 Composer 配置数据
     * 
     * @param string $path
     * @return array
     */
    protected function loadComposerOption(string $path): array
    {
        return (new ComposerOption($path))->loadData();
    }

    /**
     * 载入配置数据
     *
     * @return array
     */
    protected function loadOptionData(): array
    {
        $data = [];

        $files = glob($this->dir . '/*.php');

        $findApp = false;

        foreach ($files as $file) {
            $type = substr(basename($file), 0, -4);

            if ($type == 'app') {
                $findApp = true;
            }

            $data[$type] = (array)include $file;
        }


        if ($findApp === false) {
            throw new Exception('Unable to load the app option file.');
        }

        return $data;
    }

{'fraction_non_alphanumeric': 0.1509230270970528, 'fraction_numerical': 0.004534168196048796, 'mean_word_length': 1.6117846067098958, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, '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': '1801704', 'n_tokens_mistral': 2939, 'n_tokens_neox': 2842, 'n_words': 556}