Initial commit: apps.prometeysev.ru
This commit is contained in:
commit
96ccabcd8b
6561 files changed
+1270349
No files matched your search
@@ -0,0 +1,473 @@
|
||||
<?php
|
||||
namespace Cake\Composer\Installer;
|
||||
|
||||
use Composer\Composer;
|
||||
use Composer\Installer\LibraryInstaller;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Repository\InstalledRepositoryInterface;
|
||||
use Composer\Script\Event;
|
||||
use Composer\Util\Filesystem;
|
||||
use RuntimeException;
|
||||
|
||||
class PluginInstaller extends LibraryInstaller
|
||||
{
|
||||
/**
|
||||
* A flag to check usage - once
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected static $checkUsage = true;
|
||||
|
||||
/**
|
||||
* Check usage upon construction
|
||||
*
|
||||
* @param IOInterface $io composer object
|
||||
* @param Composer $composer composer object
|
||||
* @param string $type what are we loading
|
||||
* @param Filesystem $filesystem composer object
|
||||
*/
|
||||
public function __construct(IOInterface $io, Composer $composer, $type = 'library', Filesystem $filesystem = null)
|
||||
{
|
||||
parent::__construct($io, $composer, $type, $filesystem);
|
||||
$this->checkUsage($composer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the root composer.json file use the post-autoload-dump hook
|
||||
*
|
||||
* If not, warn the user they need to update their application's composer file.
|
||||
* Do nothing if the main project is not a project (if it's a plugin in development).
|
||||
*
|
||||
* @param Composer $composer object
|
||||
* @return void
|
||||
*/
|
||||
public function checkUsage(Composer $composer)
|
||||
{
|
||||
if (static::$checkUsage === false) {
|
||||
return;
|
||||
}
|
||||
static::$checkUsage = false;
|
||||
|
||||
$package = $composer->getPackage();
|
||||
|
||||
if (!$package || $package->getType() !== 'project') {
|
||||
return;
|
||||
}
|
||||
|
||||
$scripts = $composer->getPackage()->getScripts();
|
||||
$postAutoloadDump = 'Cake\Composer\Installer\PluginInstaller::postAutoloadDump';
|
||||
if (!isset($scripts['post-autoload-dump']) ||
|
||||
!in_array($postAutoloadDump, $scripts['post-autoload-dump'])
|
||||
) {
|
||||
$this->warnUser(
|
||||
'Action required!',
|
||||
'The CakePHP plugin installer has been changed, please update your' .
|
||||
' application composer.json file to add the post-autoload-dump hook.' .
|
||||
' See the changes in https://github.com/cakephp/app/pull/216 for more' .
|
||||
' info.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Warn the developer of action they need to take
|
||||
*
|
||||
* @param string $title Warning title
|
||||
* @param string $text warning text
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function warnUser($title, $text)
|
||||
{
|
||||
$wrap = function ($text, $width = 75) {
|
||||
return '<error> ' . str_pad($text, $width) . '</error>';
|
||||
};
|
||||
|
||||
$messages = [
|
||||
'',
|
||||
'',
|
||||
$wrap(''),
|
||||
$wrap($title),
|
||||
$wrap(''),
|
||||
];
|
||||
|
||||
$lines = explode("\n", wordwrap($text, 68));
|
||||
foreach ($lines as $line) {
|
||||
$messages[] = $wrap($line);
|
||||
}
|
||||
|
||||
$messages = array_merge($messages, [$wrap(''), '', '']);
|
||||
|
||||
$this->io->write($messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever composer (re)generates the autoloader
|
||||
*
|
||||
* Recreates CakePHP's plugin path map, based on composer information
|
||||
* and available app-plugins.
|
||||
*
|
||||
* @param Event $event the composer event object
|
||||
* @return void
|
||||
*/
|
||||
public static function postAutoloadDump(Event $event)
|
||||
{
|
||||
$composer = $event->getComposer();
|
||||
$config = $composer->getConfig();
|
||||
|
||||
$vendorDir = realpath($config->get('vendor-dir'));
|
||||
|
||||
$packages = $composer->getRepositoryManager()->getLocalRepository()->getPackages();
|
||||
$extra = $event->getComposer()->getPackage()->getExtra();
|
||||
if (empty($extra['plugin-paths'])) {
|
||||
$pluginsDir = dirname($vendorDir) . DIRECTORY_SEPARATOR . 'plugins';
|
||||
} else {
|
||||
$pluginsDir = $extra['plugin-paths'];
|
||||
}
|
||||
|
||||
$plugins = static::determinePlugins($packages, $pluginsDir, $vendorDir);
|
||||
|
||||
$configFile = static::_configFile($vendorDir);
|
||||
static::writeConfigFile($configFile, $plugins);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all plugins available
|
||||
*
|
||||
* Add all composer packages of type cakephp-plugin, and all plugins located
|
||||
* in the plugins directory to a plugin-name indexed array of paths
|
||||
*
|
||||
* @param array $packages an array of \Composer\Package\PackageInterface objects
|
||||
* @param string|array $pluginsDir the path to the plugins dir
|
||||
* @param string $vendorDir the path to the vendor dir
|
||||
* @return array plugin-name indexed paths to plugins
|
||||
*/
|
||||
public static function determinePlugins($packages, $pluginsDir = 'plugins', $vendorDir = 'vendor')
|
||||
{
|
||||
$plugins = [];
|
||||
|
||||
foreach ($packages as $package) {
|
||||
if ($package->getType() !== 'cakephp-plugin') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ns = static::primaryNamespace($package);
|
||||
$path = $vendorDir . DIRECTORY_SEPARATOR . $package->getPrettyName();
|
||||
$plugins[$ns] = $path;
|
||||
}
|
||||
|
||||
foreach ((array)$pluginsDir as $path) {
|
||||
$path = static::fullpath($path, $vendorDir);
|
||||
if (is_dir($path)) {
|
||||
$dir = new \DirectoryIterator($path);
|
||||
foreach ($dir as $info) {
|
||||
if (!$info->isDir() || $info->isDot()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = $info->getFilename();
|
||||
if ($name[0] === '.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$plugins[$name] = $path . DIRECTORY_SEPARATOR . $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ksort($plugins);
|
||||
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns relative paths in full paths.
|
||||
*
|
||||
* @param string $path Path
|
||||
* @param string $vendorDir The path to the vendor dir
|
||||
* @return string
|
||||
*/
|
||||
protected static function fullpath($path, $vendorDir)
|
||||
{
|
||||
if (preg_match('{^(?:/|[a-z]:|[a-z0-9.]+://)}i', $path)) {
|
||||
return rtrim($path, '/');
|
||||
}
|
||||
|
||||
if (substr($path, 0, 2) === './') {
|
||||
$path = substr($path, 2);
|
||||
}
|
||||
|
||||
return rtrim(dirname($vendorDir) . DIRECTORY_SEPARATOR . $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrite the config file with a complete list of plugins
|
||||
*
|
||||
* @param string $configFile the path to the config file
|
||||
* @param array $plugins of plugins
|
||||
* @param string|null $root The root directory. Defaults to a value generated from $configFile
|
||||
* @return void
|
||||
*/
|
||||
public static function writeConfigFile($configFile, $plugins, $root = null)
|
||||
{
|
||||
$root = $root ?: dirname(dirname($configFile));
|
||||
|
||||
$data = [];
|
||||
foreach ($plugins as $name => $pluginPath) {
|
||||
// Normalize to *nix paths.
|
||||
$pluginPath = str_replace('\\', '/', $pluginPath);
|
||||
$pluginPath .= '/';
|
||||
|
||||
$pluginPath = str_replace(
|
||||
DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR,
|
||||
DIRECTORY_SEPARATOR,
|
||||
$pluginPath
|
||||
);
|
||||
|
||||
// Namespaced plugins should use /
|
||||
$name = str_replace('\\', '/', $name);
|
||||
|
||||
$data[] = sprintf(" '%s' => '%s'", $name, $pluginPath);
|
||||
}
|
||||
|
||||
$data = implode(",\n", $data);
|
||||
|
||||
$contents = <<<'PHP'
|
||||
<?php
|
||||
$baseDir = dirname(dirname(__file__));
|
||||
return [
|
||||
'plugins' => [
|
||||
%s
|
||||
]
|
||||
];
|
||||
PHP;
|
||||
$contents = sprintf($contents, $data);
|
||||
|
||||
// Gross hacks to work around composer smashing `__FILE__` in this
|
||||
// PHP file when it runs the code through eval()
|
||||
$uppercase = function ($matches) {
|
||||
return strtoupper($matches[0]);
|
||||
};
|
||||
$contents = preg_replace_callback('/__file__/', $uppercase, $contents);
|
||||
|
||||
$root = str_replace(
|
||||
DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR,
|
||||
DIRECTORY_SEPARATOR,
|
||||
$root
|
||||
);
|
||||
|
||||
// Normalize to *nix paths.
|
||||
$root = str_replace('\\', '/', $root);
|
||||
$contents = str_replace('\'' . $root, '$baseDir . \'', $contents);
|
||||
|
||||
file_put_contents($configFile, $contents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Path to the plugin config file
|
||||
*
|
||||
* @param string $vendorDir path to composer-vendor dir
|
||||
* @return string absolute file path
|
||||
*/
|
||||
protected static function _configFile($vendorDir)
|
||||
{
|
||||
return $vendorDir . DIRECTORY_SEPARATOR . 'cakephp-plugins.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the primary namespace for a plugin package.
|
||||
*
|
||||
* @param \Composer\Package\PackageInterface $package composer object
|
||||
* @return string The package's primary namespace.
|
||||
* @throws \RuntimeException When the package's primary namespace cannot be determined.
|
||||
*/
|
||||
public static function primaryNamespace($package)
|
||||
{
|
||||
$primaryNs = null;
|
||||
$autoLoad = $package->getAutoload();
|
||||
foreach ($autoLoad as $type => $pathMap) {
|
||||
if ($type !== 'psr-4') {
|
||||
continue;
|
||||
}
|
||||
$count = count($pathMap);
|
||||
|
||||
if ($count === 1) {
|
||||
$primaryNs = key($pathMap);
|
||||
break;
|
||||
}
|
||||
|
||||
$matches = preg_grep('#^(\./)?src/?$#', $pathMap);
|
||||
if ($matches) {
|
||||
$primaryNs = key($matches);
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (['', '.'] as $path) {
|
||||
$key = array_search($path, $pathMap, true);
|
||||
if ($key !== false) {
|
||||
$primaryNs = $key;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$primaryNs) {
|
||||
throw new RuntimeException(
|
||||
sprintf(
|
||||
"Unable to get primary namespace for package %s." .
|
||||
"\nEnsure you have added proper 'autoload' section to your plugin's config" .
|
||||
" as stated in README on https://github.com/cakephp/plugin-installer",
|
||||
$package->getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return trim($primaryNs, '\\');
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides if the installer supports the given type.
|
||||
*
|
||||
* This installer only supports package of type 'cakephp-plugin'.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supports($packageType)
|
||||
{
|
||||
return 'cakephp-plugin' === $packageType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs specific plugin.
|
||||
*
|
||||
* After the plugin is installed, app's `cakephp-plugins.php` config file is updated with
|
||||
* plugin namespace to path mapping.
|
||||
*
|
||||
* @param \Composer\Repository\InstalledRepositoryInterface $repo Repository in which to check.
|
||||
* @param \Composer\Package\PackageInterface $package Package instance.
|
||||
* @deprecated superceeded by the post-autoload-dump hook
|
||||
*/
|
||||
public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
|
||||
{
|
||||
parent::install($repo, $package);
|
||||
$path = $this->getInstallPath($package);
|
||||
$ns = static::primaryNamespace($package);
|
||||
$this->updateConfig($ns, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates specific plugin.
|
||||
*
|
||||
* After the plugin is installed, app's `cakephp-plugins.php` config file is updated with
|
||||
* plugin namespace to path mapping.
|
||||
*
|
||||
* @param \Composer\Repository\InstalledRepositoryInterface $repo Repository in which to check.
|
||||
* @param \Composer\Package\PackageInterface $initial Already installed package version.
|
||||
* @param \Composer\Package\PackageInterface $target Updated version.
|
||||
* @deprecated superceeded by the post-autoload-dump hook
|
||||
*
|
||||
* @throws \InvalidArgumentException if $initial package is not installed
|
||||
*/
|
||||
public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
|
||||
{
|
||||
parent::update($repo, $initial, $target);
|
||||
|
||||
$ns = static::primaryNamespace($initial);
|
||||
$this->updateConfig($ns, null);
|
||||
|
||||
$path = $this->getInstallPath($target);
|
||||
$ns = static::primaryNamespace($target);
|
||||
$this->updateConfig($ns, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstalls specific package.
|
||||
*
|
||||
* @param \Composer\Repository\InstalledRepositoryInterface $repo Repository in which to check.
|
||||
* @param \Composer\Package\PackageInterface $package Package instance.
|
||||
* @deprecated superceeded by the post-autoload-dump hook
|
||||
*/
|
||||
public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
|
||||
{
|
||||
parent::uninstall($repo, $package);
|
||||
$path = $this->getInstallPath($package);
|
||||
$ns = static::primaryNamespace($package);
|
||||
$this->updateConfig($ns, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the plugin path for a given package.
|
||||
*
|
||||
* @param string $name The plugin name being installed.
|
||||
* @param string $path The path, the plugin is being installed into.
|
||||
*/
|
||||
public function updateConfig($name, $path)
|
||||
{
|
||||
$name = str_replace('\\', '/', $name);
|
||||
$configFile = static::_configFile($this->vendorDir);
|
||||
$this->_ensureConfigFile($configFile);
|
||||
|
||||
$return = include $configFile;
|
||||
if (is_array($return) && empty($config)) {
|
||||
$config = $return;
|
||||
}
|
||||
if (!isset($config)) {
|
||||
$this->io->write(
|
||||
'ERROR - `vendor/cakephp-plugins.php` file is invalid. ' .
|
||||
'Plugin path configuration not updated.'
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
if (!isset($config['plugins'])) {
|
||||
$config['plugins'] = [];
|
||||
}
|
||||
if ($path == null) {
|
||||
unset($config['plugins'][$name]);
|
||||
} else {
|
||||
$config['plugins'][$name] = $path;
|
||||
}
|
||||
$root = dirname($this->vendorDir);
|
||||
static::writeConfigFile($configFile, $config['plugins'], $root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the vendor/cakephp-plugins.php file exists.
|
||||
*
|
||||
* If config/plugins.php is found - copy it to the vendor folder
|
||||
*
|
||||
* @param string $path the config file path.
|
||||
* @return void
|
||||
*/
|
||||
protected function _ensureConfigFile($path)
|
||||
{
|
||||
if (file_exists($path)) {
|
||||
if ($this->io->isVerbose()) {
|
||||
$this->io->write('vendor/cakephp-plugins.php exists.');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$oldPath = dirname(dirname($path)) . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'plugins.php';
|
||||
if (file_exists($oldPath)) {
|
||||
copy($oldPath, $path);
|
||||
if ($this->io->isVerbose()) {
|
||||
$this->io->write('config/plugins.php found and copied to vendor/cakephp-plugins.php.');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_dir(dirname($path))) {
|
||||
mkdir(dirname($path));
|
||||
}
|
||||
$root = dirname($this->vendorDir);
|
||||
static::writeConfigFile($path, [], $root);
|
||||
|
||||
if ($this->io->isVerbose()) {
|
||||
$this->io->write('Created vendor/cakephp-plugins.php');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user