Merge remote-tracking branch 'kocsismate/feature-bin-compat'
commit
c9b51a5751
|
@ -102,6 +102,15 @@ downloads. When the garbage collection is periodically ran, this is the maximum
|
|||
size the cache will be able to use. Older (less used) files will be removed
|
||||
first until the cache fits.
|
||||
|
||||
## bin-compat
|
||||
|
||||
Defaults to `auto`. Determines the compatibility of the binaries to be installed.
|
||||
If it is `auto` then Composer tries to automatically guess which compatibility mode
|
||||
to use. If it is `nosymlink` then the binaries will be compatible with Unix-based
|
||||
operating systems (useful for cases when symlinks are not available).
|
||||
If its value is `full` then both .bat files for Windows and scripts for Unix-based
|
||||
operating systems will be installed for each binary.
|
||||
|
||||
## prepend-autoloader
|
||||
|
||||
Defaults to `true`. If `false`, the Composer autoloader will not be prepended to
|
||||
|
|
|
@ -186,6 +186,10 @@
|
|||
"type": ["string", "integer"],
|
||||
"description": "The cache max size for the files cache, defaults to \"300MiB\"."
|
||||
},
|
||||
"bin-compat": {
|
||||
"enum": ["auto", "nosymlink", "full"],
|
||||
"description": "The compatibility of the binaries, defaults to \"auto\" (automatically guessed) and can be \"nosymlink\" (compatible with Unix-based systems) or \"full\" (compatible with both Windows and Unix-based systems)."
|
||||
},
|
||||
"discard-changes": {
|
||||
"type": ["string", "boolean"],
|
||||
"description": "The default style of handling dirty updates, defaults to false and can be any of true, false or \"stash\"."
|
||||
|
|
|
@ -307,6 +307,10 @@ EOT
|
|||
function ($val) { return preg_match('/^\s*([0-9.]+)\s*(?:([kmg])(?:i?b)?)?\s*$/i', $val) > 0; },
|
||||
function ($val) { return $val; },
|
||||
),
|
||||
'bin-compat' => array(
|
||||
function ($val) { return in_array($val, array('auto', 'nosymlink', 'full')); },
|
||||
function ($val) { return $val; }
|
||||
),
|
||||
'discard-changes' => array(
|
||||
function ($val) { return in_array($val, array('stash', 'true', 'false', '1', '0'), true); },
|
||||
function ($val) {
|
||||
|
|
|
@ -36,6 +36,7 @@ class Config
|
|||
'cache-ttl' => 15552000, // 6 months
|
||||
'cache-files-ttl' => null, // fallback to cache-ttl
|
||||
'cache-files-maxsize' => '300MiB',
|
||||
'bin-compat' => 'auto',
|
||||
'discard-changes' => false,
|
||||
'autoloader-suffix' => null,
|
||||
'optimize-autoloader' => false,
|
||||
|
@ -218,6 +219,17 @@ class Config
|
|||
case 'home':
|
||||
return rtrim($this->process($this->config[$key], $flags), '/\\');
|
||||
|
||||
case 'bin-compat':
|
||||
$value = $this->getComposerEnv('COMPOSER_BIN_COMPAT') ?: $this->config[$key];
|
||||
|
||||
if (!in_array($value, array('auto', 'nosymlink', 'full'))) {
|
||||
throw new \RuntimeException(
|
||||
"Invalid value for 'bin-compat': {$value}. Expected auto, nosymlink, full"
|
||||
);
|
||||
}
|
||||
|
||||
return $value;
|
||||
|
||||
case 'discard-changes':
|
||||
if ($env = $this->getComposerEnv('COMPOSER_DISCARD_CHANGES')) {
|
||||
if (!in_array($env, array('stash', 'true', 'false', '1', '0'), true)) {
|
||||
|
|
|
@ -18,6 +18,7 @@ use Composer\Repository\InstalledRepositoryInterface;
|
|||
use Composer\Package\PackageInterface;
|
||||
use Composer\Util\Filesystem;
|
||||
use Composer\Util\ProcessExecutor;
|
||||
use Composer\Util\Symlink;
|
||||
|
||||
/**
|
||||
* Package installation manager.
|
||||
|
@ -34,6 +35,7 @@ class LibraryInstaller implements InstallerInterface
|
|||
protected $io;
|
||||
protected $type;
|
||||
protected $filesystem;
|
||||
protected $binCompat;
|
||||
|
||||
/**
|
||||
* Initializes library installer.
|
||||
|
@ -53,6 +55,7 @@ class LibraryInstaller implements InstallerInterface
|
|||
$this->filesystem = $filesystem ?: new Filesystem();
|
||||
$this->vendorDir = rtrim($composer->getConfig()->get('vendor-dir'), '/');
|
||||
$this->binDir = rtrim($composer->getConfig()->get('bin-dir'), '/');
|
||||
$this->binCompat = $composer->getConfig()->get('bin-compat');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -219,10 +222,27 @@ class LibraryInstaller implements InstallerInterface
|
|||
$this->io->writeError(' Skipped installation of bin '.$bin.' for package '.$package->getName().': name conflicts with an existing file');
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->binCompat === "auto") {
|
||||
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||
$this->installFullBinaries($binPath, $link, $bin, $package);
|
||||
} else {
|
||||
$this->installSymlinkBinaries($binPath, $link);
|
||||
}
|
||||
} elseif ($this->binCompat === "nosymlink") {
|
||||
$this->installUnixyProxyBinaries($binPath, $link);
|
||||
} elseif ($this->binCompat === "full") {
|
||||
$this->installFullBinaries($binPath, $link, $bin, $package);
|
||||
}
|
||||
@chmod($link, 0777 & ~umask());
|
||||
}
|
||||
}
|
||||
|
||||
protected function installFullBinaries($binPath, $link, $bin, PackageInterface $package)
|
||||
{
|
||||
// add unixy support for cygwin and similar environments
|
||||
if ('.bat' !== substr($binPath, -4)) {
|
||||
file_put_contents($link, $this->generateUnixyProxyCode($binPath, $link));
|
||||
$this->installUnixyProxyBinaries($binPath, $link);
|
||||
@chmod($link, 0777 & ~umask());
|
||||
$link .= '.bat';
|
||||
if (file_exists($link)) {
|
||||
|
@ -232,24 +252,22 @@ class LibraryInstaller implements InstallerInterface
|
|||
if (!file_exists($link)) {
|
||||
file_put_contents($link, $this->generateWindowsProxyCode($binPath, $link));
|
||||
}
|
||||
} else {
|
||||
$cwd = getcwd();
|
||||
}
|
||||
|
||||
protected function installSymlinkBinaries($binPath, $link)
|
||||
{
|
||||
try {
|
||||
// under linux symlinks are not always supported for example
|
||||
// when using it in smbfs mounted folder
|
||||
$relativeBin = $this->filesystem->findShortestPath($link, $binPath);
|
||||
chdir(dirname($link));
|
||||
if (false === @symlink($relativeBin, $link)) {
|
||||
throw new \ErrorException();
|
||||
}
|
||||
$symlink = new Symlink($this->filesystem);
|
||||
$symlink->symlinkBin($binPath, $link);
|
||||
} catch (\ErrorException $e) {
|
||||
$this->installUnixyProxyBinaries($binPath, $link);
|
||||
}
|
||||
}
|
||||
|
||||
protected function installUnixyProxyBinaries($binPath, $link)
|
||||
{
|
||||
file_put_contents($link, $this->generateUnixyProxyCode($binPath, $link));
|
||||
}
|
||||
chdir($cwd);
|
||||
}
|
||||
@chmod($link, 0777 & ~umask());
|
||||
}
|
||||
}
|
||||
|
||||
protected function removeBinaries(PackageInterface $package)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Util;
|
||||
|
||||
use Composer\Config;
|
||||
|
||||
/**
|
||||
* @author Kocsis Máté <kocsismate@woohoolabs.com>
|
||||
*/
|
||||
class Symlink
|
||||
{
|
||||
protected $filesystem;
|
||||
|
||||
/**
|
||||
* Initializes the symlinking utility.
|
||||
*
|
||||
* @param Filesystem $filesystem
|
||||
*/
|
||||
public function __construct(Filesystem $filesystem = null)
|
||||
{
|
||||
$this->filesystem = $filesystem ?: new Filesystem();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a symlink for a binary file at a given path.
|
||||
*
|
||||
* @param string $binPath The path of the binary file to be symlinked
|
||||
* @param string $link The path where the symlink should be created
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
public function symlinkBin($binPath, $link)
|
||||
{
|
||||
$cwd = getcwd();
|
||||
|
||||
$relativeBin = $this->filesystem->findShortestPath($link, $binPath);
|
||||
chdir(dirname($link));
|
||||
$result = @symlink($relativeBin, $link);
|
||||
|
||||
chdir($cwd);
|
||||
if ($result === false) {
|
||||
throw new \ErrorException();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue