[advancedcontentfilter] Remove yet more Composer dependencies files
- Remove missing fxp/composer-asset-plugin files
This commit is contained in:
parent
cefb58374e
commit
1e77af90ad
77 changed files with 0 additions and 12423 deletions
|
@ -1,133 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Composer;
|
||||
|
||||
use Composer\DependencyResolver\Operation\InstallOperation;
|
||||
use Composer\DependencyResolver\Operation\OperationInterface;
|
||||
use Composer\DependencyResolver\Operation\UpdateOperation;
|
||||
use Composer\Installer\PackageEvent;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Fxp\Composer\AssetPlugin\Assets;
|
||||
use Fxp\Composer\AssetPlugin\Config\Config;
|
||||
use Fxp\Composer\AssetPlugin\FxpAssetPlugin;
|
||||
use Fxp\Composer\AssetPlugin\Installer\IgnoreFactory;
|
||||
|
||||
/**
|
||||
* Composer script handler.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class ScriptHandler
|
||||
{
|
||||
/**
|
||||
* Remove ignored files of the installed package defined in the root
|
||||
* package config section.
|
||||
*
|
||||
* @param PackageEvent $event
|
||||
*/
|
||||
public static function deleteIgnoredFiles(PackageEvent $event)
|
||||
{
|
||||
if (null === $package = static::getLibraryPackage($event->getOperation())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$section = static::getIgnoreConfigSection();
|
||||
$manager = IgnoreFactory::create(static::getConfig($event), $event->getComposer(), $package, null, $section);
|
||||
$manager->cleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin config.
|
||||
*
|
||||
* @param PackageEvent $event
|
||||
*
|
||||
* @return Config
|
||||
*/
|
||||
public static function getConfig(PackageEvent $event)
|
||||
{
|
||||
foreach ($event->getComposer()->getPluginManager()->getPlugins() as $plugin) {
|
||||
if ($plugin instanceof FxpAssetPlugin) {
|
||||
return $plugin->getConfig();
|
||||
}
|
||||
}
|
||||
|
||||
throw new \RuntimeException('The fxp composer asset plugin is not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the root config section of igore file patterns for each package.
|
||||
*
|
||||
* @return string The config section name
|
||||
*/
|
||||
protected static function getIgnoreConfigSection()
|
||||
{
|
||||
return 'ignore-files';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the library package (not asset package).
|
||||
*
|
||||
* @param OperationInterface $operation The operation
|
||||
*
|
||||
* @return PackageInterface|null Return NULL if the package is an asset
|
||||
*/
|
||||
protected static function getLibraryPackage(OperationInterface $operation)
|
||||
{
|
||||
$package = static::getOperationPackage($operation);
|
||||
$data = null;
|
||||
|
||||
if ($package && !static::isAsset($package)) {
|
||||
$data = $package;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the package defined in the composer operation.
|
||||
*
|
||||
* @param OperationInterface $operation The operation
|
||||
*
|
||||
* @return PackageInterface|null Return NULL if the operation is not INSTALL or UPDATE
|
||||
*/
|
||||
protected static function getOperationPackage(OperationInterface $operation)
|
||||
{
|
||||
$data = null;
|
||||
if ($operation instanceof UpdateOperation) {
|
||||
$data = $operation->getTargetPackage();
|
||||
} elseif ($operation instanceof InstallOperation) {
|
||||
$data = $operation->getPackage();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the package is a asset package.
|
||||
*
|
||||
* @param PackageInterface $package The package instance
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected static function isAsset(PackageInterface $package)
|
||||
{
|
||||
foreach (Assets::getTypes() as $type) {
|
||||
$type = Assets::createType($type);
|
||||
|
||||
if ($package->getType() === $type->getComposerType()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,197 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Config;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Helper of package config.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
final class Config
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $cacheEnv = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $config The config
|
||||
*/
|
||||
public function __construct(array $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array config value.
|
||||
*
|
||||
* @param string $key The config key
|
||||
* @param array $default The default value
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getArray($key, array $default = array())
|
||||
{
|
||||
return $this->get($key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the config value.
|
||||
*
|
||||
* @param string $key The config key
|
||||
* @param mixed|null $default The default value
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
if (array_key_exists($key, $this->cacheEnv)) {
|
||||
return $this->cacheEnv[$key];
|
||||
} else {
|
||||
$envKey = $this->convertEnvKey($key);
|
||||
$envValue = getenv($envKey);
|
||||
|
||||
if (false !== $envValue) {
|
||||
return $this->cacheEnv[$key] = $this->convertEnvValue($envValue, $envKey);
|
||||
}
|
||||
}
|
||||
|
||||
return array_key_exists($key, $this->config)
|
||||
? $this->config[$key]
|
||||
: $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the config key into environment variable.
|
||||
*
|
||||
* @param string $key The config key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function convertEnvKey($key)
|
||||
{
|
||||
return 'FXP_ASSET__'.strtoupper(str_replace('-', '_', $key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the value of environment variable into php variable.
|
||||
*
|
||||
* @param string $value The value of environment variable
|
||||
* @param string $environmentVariable The environment variable name
|
||||
*
|
||||
* @return string|bool|int|array
|
||||
*/
|
||||
private function convertEnvValue($value, $environmentVariable)
|
||||
{
|
||||
$value = trim(trim(trim($value, '\''), '"'));
|
||||
|
||||
if ($this->isBoolean($value)) {
|
||||
$value = $this->convertBoolean($value);
|
||||
} elseif ($this->isInteger($value)) {
|
||||
$value = $this->convertInteger($value);
|
||||
} elseif ($this->isJson($value)) {
|
||||
$value = $this->convertJson($value, $environmentVariable);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the value of environment variable is a boolean.
|
||||
*
|
||||
* @param string $value The value of environment variable
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isBoolean($value)
|
||||
{
|
||||
$value = strtolower($value);
|
||||
|
||||
return in_array($value, array('true', 'false', '1', '0', 'yes', 'no', 'y', 'n'), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the value of environment variable into a boolean.
|
||||
*
|
||||
* @param string $value The value of environment variable
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function convertBoolean($value)
|
||||
{
|
||||
return in_array($value, array('true', '1', 'yes', 'y'), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the value of environment variable is a integer.
|
||||
*
|
||||
* @param string $value The value of environment variable
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isInteger($value)
|
||||
{
|
||||
return ctype_digit(trim($value, '-'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the value of environment variable into a integer.
|
||||
*
|
||||
* @param string $value The value of environment variable
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function convertInteger($value)
|
||||
{
|
||||
return (int) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the value of environment variable is a string JSON.
|
||||
*
|
||||
* @param string $value The value of environment variable
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isJson($value)
|
||||
{
|
||||
return 0 === strpos($value, '{') || 0 === strpos($value, '[');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the value of environment variable into a json array.
|
||||
*
|
||||
* @param string $value The value of environment variable
|
||||
* @param string $environmentVariable The environment variable name
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function convertJson($value, $environmentVariable)
|
||||
{
|
||||
$value = json_decode($value, true);
|
||||
|
||||
if (json_last_error()) {
|
||||
throw new InvalidArgumentException(sprintf('The "%s" environment variable isn\'t a valid JSON', $environmentVariable));
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
|
@ -1,162 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Config;
|
||||
|
||||
use Composer\Composer;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Json\JsonFile;
|
||||
use Composer\Package\RootPackageInterface;
|
||||
|
||||
/**
|
||||
* Plugin Config builder.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
abstract class ConfigBuilder
|
||||
{
|
||||
/**
|
||||
* List of the deprecated options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $deprecatedOptions = array(
|
||||
'installer-paths' => 'asset-installer-paths',
|
||||
'ignore-files' => 'asset-ignore-files',
|
||||
'private-bower-registries' => 'asset-private-bower-registries',
|
||||
'pattern-skip-version' => 'asset-pattern-skip-version',
|
||||
'optimize-with-installed-packages' => 'asset-optimize-with-installed-packages',
|
||||
'optimize-with-conjunctive' => 'asset-optimize-with-conjunctive',
|
||||
'repositories' => 'asset-repositories',
|
||||
'registry-options' => 'asset-registry-options',
|
||||
'vcs-driver-options' => 'asset-vcs-driver-options',
|
||||
'main-files' => 'asset-main-files',
|
||||
);
|
||||
|
||||
/**
|
||||
* Validate the config of root package.
|
||||
*
|
||||
* @param IOInterface $io The composer input/output
|
||||
* @param RootPackageInterface $package The root package
|
||||
* @param string $commandName The command name
|
||||
*/
|
||||
public static function validate(IOInterface $io, RootPackageInterface $package, $commandName = null)
|
||||
{
|
||||
if (null === $commandName || in_array($commandName, array('install', 'update', 'validate', 'require', 'remove'))) {
|
||||
$extra = (array) $package->getExtra();
|
||||
|
||||
foreach (self::$deprecatedOptions as $new => $old) {
|
||||
if (array_key_exists($old, $extra)) {
|
||||
$io->write(sprintf('<warning>The "extra.%s" option is deprecated, use the "config.fxp-asset.%s" option</warning>', $old, $new));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the config of plugin.
|
||||
*
|
||||
* @param Composer $composer The composer
|
||||
* @param IOInterface|null $io The composer input/output
|
||||
*
|
||||
* @return Config
|
||||
*/
|
||||
public static function build(Composer $composer, $io = null)
|
||||
{
|
||||
$config = self::getConfigBase($composer, $io);
|
||||
$config = self::injectDeprecatedConfig($config, (array) $composer->getPackage()->getExtra());
|
||||
|
||||
return new Config($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject the deprecated keys in config if the config keys are not present.
|
||||
*
|
||||
* @param array $config The config
|
||||
* @param array $extra The root package extra section
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function injectDeprecatedConfig(array $config, array $extra)
|
||||
{
|
||||
foreach (self::$deprecatedOptions as $key => $deprecatedKey) {
|
||||
if (array_key_exists($deprecatedKey, $extra) && !array_key_exists($key, $config)) {
|
||||
$config[$key] = $extra[$deprecatedKey];
|
||||
}
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base of data.
|
||||
*
|
||||
* @param Composer $composer The composer
|
||||
* @param IOInterface|null $io The composer input/output
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function getConfigBase(Composer $composer, $io = null)
|
||||
{
|
||||
$globalPackageConfig = self::getGlobalConfig($composer, 'composer', $io);
|
||||
$globalConfig = self::getGlobalConfig($composer, 'config', $io);
|
||||
$packageConfig = $composer->getPackage()->getConfig();
|
||||
$packageConfig = isset($packageConfig['fxp-asset']) && is_array($packageConfig['fxp-asset'])
|
||||
? $packageConfig['fxp-asset']
|
||||
: array();
|
||||
|
||||
return array_merge($globalPackageConfig, $globalConfig, $packageConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data of the global config.
|
||||
*
|
||||
* @param Composer $composer The composer
|
||||
* @param string $filename The filename
|
||||
* @param IOInterface|null $io The composer input/output
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function getGlobalConfig(Composer $composer, $filename, $io = null)
|
||||
{
|
||||
$home = self::getComposerHome($composer);
|
||||
$file = new JsonFile($home.'/'.$filename.'.json');
|
||||
$config = array();
|
||||
|
||||
if ($file->exists()) {
|
||||
$data = $file->read();
|
||||
|
||||
if (isset($data['config']['fxp-asset']) && is_array($data['config']['fxp-asset'])) {
|
||||
$config = $data['config']['fxp-asset'];
|
||||
|
||||
if ($io instanceof IOInterface && $io->isDebug()) {
|
||||
$io->writeError('Loading fxp-asset config in file '.$file->getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the home directory of composer.
|
||||
*
|
||||
* @param Composer $composer The composer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function getComposerHome(Composer $composer)
|
||||
{
|
||||
return null !== $composer->getConfig() && $composer->getConfig()->has('home')
|
||||
? $composer->getConfig()->get('home')
|
||||
: '';
|
||||
}
|
||||
}
|
|
@ -1,193 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Converter;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Exception\InvalidArgumentException;
|
||||
use Fxp\Composer\AssetPlugin\Type\AssetTypeInterface;
|
||||
|
||||
/**
|
||||
* Abstract class for converter for asset package to composer package.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
abstract class AbstractPackageConverter implements PackageConverterInterface
|
||||
{
|
||||
/**
|
||||
* @var AssetTypeInterface
|
||||
*/
|
||||
protected $assetType;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param AssetTypeInterface $assetType
|
||||
*/
|
||||
public function __construct(AssetTypeInterface $assetType)
|
||||
{
|
||||
$this->assetType = $assetType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function convert(array $data, array &$vcsRepos = array())
|
||||
{
|
||||
$keys = $this->getMapKeys();
|
||||
$dependencies = $this->getMapDependencies();
|
||||
$extras = $this->getMapExtras();
|
||||
|
||||
return $this->convertData($data, $keys, $dependencies, $extras, $vcsRepos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the all keys (keys, dependencies and extra keys).
|
||||
*
|
||||
* @param array $asset The asset data
|
||||
* @param array $keys The map of asset key and composer key
|
||||
* @param array $dependencies The map of asset dependency key and composer dependency key
|
||||
* @param array $extras The map of asset key and composer extra key
|
||||
* @param array $vcsRepos The list of new vcs configs
|
||||
*
|
||||
* @return array The composer package converted
|
||||
*/
|
||||
protected function convertData(array $asset, array $keys, array $dependencies, array $extras, array &$vcsRepos = array())
|
||||
{
|
||||
$composer = array();
|
||||
|
||||
foreach ($keys as $assetKey => $composerKey) {
|
||||
$this->convertKey($asset, $assetKey, $composer, $composerKey);
|
||||
}
|
||||
|
||||
foreach ($dependencies as $assetKey => $composerKey) {
|
||||
$this->convertDependencies($asset, $assetKey, $composer, $composerKey, $vcsRepos);
|
||||
}
|
||||
|
||||
foreach ($extras as $assetKey => $composerKey) {
|
||||
$this->convertExtraKey($asset, $assetKey, $composer, $composerKey);
|
||||
}
|
||||
|
||||
return $composer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the simple key of package.
|
||||
*
|
||||
* @param array $asset The asset data
|
||||
* @param string $assetKey The asset key
|
||||
* @param array $composer The composer data
|
||||
* @param string|array $composerKey The composer key or array with composer key name and closure
|
||||
*
|
||||
* @throws InvalidArgumentException When the 'composerKey' argument of asset packager converter is not an string or an array with the composer key and closure
|
||||
*/
|
||||
protected function convertKey(array $asset, $assetKey, array &$composer, $composerKey)
|
||||
{
|
||||
if (is_array($composerKey)) {
|
||||
PackageUtil::convertArrayKey($asset, $assetKey, $composer, $composerKey);
|
||||
} else {
|
||||
PackageUtil::convertStringKey($asset, $assetKey, $composer, $composerKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the extra key of package.
|
||||
*
|
||||
* @param array $asset The asset data
|
||||
* @param string $assetKey The asset extra key
|
||||
* @param array $composer The composer data
|
||||
* @param string|array $composerKey The composer extra key or array with composer extra key name and closure
|
||||
* @param string $extraKey The extra key name
|
||||
*/
|
||||
protected function convertExtraKey(array $asset, $assetKey, array &$composer, $composerKey, $extraKey = 'extra')
|
||||
{
|
||||
$extra = isset($composer[$extraKey]) ? $composer[$extraKey] : array();
|
||||
|
||||
$this->convertKey($asset, $assetKey, $extra, $composerKey);
|
||||
|
||||
if (count($extra) > 0) {
|
||||
$composer[$extraKey] = $extra;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts simple key of package.
|
||||
*
|
||||
* @param array $asset The asset data
|
||||
* @param string $assetKey The asset key of dependencies
|
||||
* @param array $composer The composer data
|
||||
* @param string $composerKey The composer key of dependencies
|
||||
* @param array $vcsRepos The list of new vcs configs
|
||||
*/
|
||||
protected function convertDependencies(array $asset, $assetKey, array &$composer, $composerKey, array &$vcsRepos = array())
|
||||
{
|
||||
if (isset($asset[$assetKey]) && is_array($asset[$assetKey])) {
|
||||
$newDependencies = array();
|
||||
|
||||
foreach ($asset[$assetKey] as $dependency => $version) {
|
||||
list($dependency, $version) = $this->convertDependency($dependency, $version, $vcsRepos, $composer);
|
||||
$version = $this->assetType->getVersionConverter()->convertRange($version);
|
||||
if (0 !== strpos($version, $dependency)) {
|
||||
$newDependencies[$this->assetType->getComposerVendorName().'/'.$dependency] = $version;
|
||||
}
|
||||
}
|
||||
|
||||
$composer[$composerKey] = $newDependencies;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the .
|
||||
*
|
||||
* @param string $dependency The dependency
|
||||
* @param string $version The version
|
||||
* @param array $vcsRepos The list of new vcs configs
|
||||
* @param array $composer The partial composer data
|
||||
*
|
||||
* @return string[] The new dependency and the new version
|
||||
*/
|
||||
protected function convertDependency($dependency, $version, array &$vcsRepos, array $composer)
|
||||
{
|
||||
list($dependency, $version) = PackageUtil::checkUrlVersion($this->assetType, $dependency, $version, $vcsRepos, $composer);
|
||||
list($dependency, $version) = PackageUtil::checkAliasVersion($this->assetType, $dependency, $version);
|
||||
list($dependency, $version) = PackageUtil::convertDependencyVersion($this->assetType, $dependency, $version);
|
||||
|
||||
return array($dependency, $version);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getMapKeys()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the map conversion of dependencies.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getMapDependencies()
|
||||
{
|
||||
return array(
|
||||
'dependencies' => 'require',
|
||||
'devDependencies' => 'require-dev',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getMapExtras()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Converter;
|
||||
|
||||
/**
|
||||
* Converter for bower package to composer package.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class BowerPackageConverter extends AbstractPackageConverter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getMapKeys()
|
||||
{
|
||||
$assetType = $this->assetType;
|
||||
|
||||
return array(
|
||||
'name' => array('name', function ($value) use ($assetType) {
|
||||
return $assetType->formatComposerName($value);
|
||||
}),
|
||||
'type' => array('type', function () use ($assetType) {
|
||||
return $assetType->getComposerType();
|
||||
}),
|
||||
'version' => array('version', function ($value) use ($assetType) {
|
||||
return $assetType->getVersionConverter()->convertVersion($value);
|
||||
}),
|
||||
'version_normalized' => 'version_normalized',
|
||||
'description' => 'description',
|
||||
'keywords' => 'keywords',
|
||||
'license' => 'license',
|
||||
'time' => 'time',
|
||||
'bin' => 'bin',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getMapExtras()
|
||||
{
|
||||
return array(
|
||||
'main' => 'bower-asset-main',
|
||||
'ignore' => 'bower-asset-ignore',
|
||||
'private' => 'bower-asset-private',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function convertDependency($dependency, $version, array &$vcsRepos, array $composer)
|
||||
{
|
||||
list($dependency, $version) = $this->checkGithubRepositoryVersion($dependency, $version);
|
||||
|
||||
return parent::convertDependency($dependency, $version, $vcsRepos, $composer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the version is a Github alias version of repository.
|
||||
*
|
||||
* @param string $dependency The dependency
|
||||
* @param string $version The version
|
||||
*
|
||||
* @return string[] The new dependency and the new version
|
||||
*/
|
||||
protected function checkGithubRepositoryVersion($dependency, $version)
|
||||
{
|
||||
if (preg_match('/^[A-Za-z0-9\-_]+\/[A-Za-z0-9\-_.]+/', $version)) {
|
||||
$pos = strpos($version, '#');
|
||||
$pos = false === $pos ? strlen($version) : $pos;
|
||||
$realVersion = substr($version, $pos);
|
||||
$version = 'git://github.com/'.substr($version, 0, $pos).'.git'.$realVersion;
|
||||
}
|
||||
|
||||
return array($dependency, $version);
|
||||
}
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Converter;
|
||||
|
||||
/**
|
||||
* Converter for NPM package to composer package.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class NpmPackageConverter extends AbstractPackageConverter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getMapKeys()
|
||||
{
|
||||
$assetType = $this->assetType;
|
||||
|
||||
return array(
|
||||
'name' => array('name', function ($value) use ($assetType) {
|
||||
return $assetType->formatComposerName(NpmPackageUtil::convertName($value));
|
||||
}),
|
||||
'type' => array('type', function () use ($assetType) {
|
||||
return $assetType->getComposerType();
|
||||
}),
|
||||
'version' => array('version', function ($value) use ($assetType) {
|
||||
return $assetType->getVersionConverter()->convertVersion($value);
|
||||
}),
|
||||
'version_normalized' => 'version_normalized',
|
||||
'description' => 'description',
|
||||
'keywords' => 'keywords',
|
||||
'homepage' => 'homepage',
|
||||
'license' => 'license',
|
||||
'time' => 'time',
|
||||
'author' => array('authors', function ($value) {
|
||||
return NpmPackageUtil::convertAuthor($value);
|
||||
}),
|
||||
'contributors' => array('authors', function ($value, $prevValue) {
|
||||
return NpmPackageUtil::convertContributors($value, $prevValue);
|
||||
}),
|
||||
'bin' => array('bin', function ($value) {
|
||||
return (array) $value;
|
||||
}),
|
||||
'dist' => array('dist', function ($value) {
|
||||
return NpmPackageUtil::convertDist($value);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getMapExtras()
|
||||
{
|
||||
return array(
|
||||
'bugs' => 'npm-asset-bugs',
|
||||
'files' => 'npm-asset-files',
|
||||
'main' => 'npm-asset-main',
|
||||
'man' => 'npm-asset-man',
|
||||
'directories' => 'npm-asset-directories',
|
||||
'repository' => 'npm-asset-repository',
|
||||
'scripts' => 'npm-asset-scripts',
|
||||
'config' => 'npm-asset-config',
|
||||
'bundledDependencies' => 'npm-asset-bundled-dependencies',
|
||||
'optionalDependencies' => 'npm-asset-optional-dependencies',
|
||||
'engines' => 'npm-asset-engines',
|
||||
'engineStrict' => 'npm-asset-engine-strict',
|
||||
'os' => 'npm-asset-os',
|
||||
'cpu' => 'npm-asset-cpu',
|
||||
'preferGlobal' => 'npm-asset-prefer-global',
|
||||
'private' => 'npm-asset-private',
|
||||
'publishConfig' => 'npm-asset-publish-config',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function convertDependency($dependency, $version, array &$vcsRepos, array $composer)
|
||||
{
|
||||
$dependency = NpmPackageUtil::convertName($dependency);
|
||||
|
||||
return parent::convertDependency($dependency, $version, $vcsRepos, $composer);
|
||||
}
|
||||
}
|
|
@ -1,134 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Converter;
|
||||
|
||||
/**
|
||||
* Utils for NPM package converter.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
abstract class NpmPackageUtil
|
||||
{
|
||||
/**
|
||||
* Convert the npm package name.
|
||||
*
|
||||
* @param string $name The npm package name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function convertName($name)
|
||||
{
|
||||
if (0 === strpos($name, '@') && false !== strpos($name, '/')) {
|
||||
$name = ltrim(str_replace('/', '--', $name), '@');
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Revert the npm package name from composer package name.
|
||||
*
|
||||
* @param string $name The npm package name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function revertName($name)
|
||||
{
|
||||
if (false !== strpos($name, '--')) {
|
||||
$name = '@'.str_replace('--', '/', $name);
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the author section.
|
||||
*
|
||||
* @param string|null $value The current value
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function convertAuthor($value)
|
||||
{
|
||||
if (null !== $value) {
|
||||
$value = array($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the contributors section.
|
||||
*
|
||||
* @param string|null $value The current value
|
||||
* @param string|null $prevValue The previous value
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function convertContributors($value, $prevValue)
|
||||
{
|
||||
$mergeValue = is_array($prevValue) ? $prevValue : array();
|
||||
$mergeValue = array_merge($mergeValue, is_array($value) ? $value : array());
|
||||
|
||||
if (count($mergeValue) > 0) {
|
||||
$value = $mergeValue;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the dist section.
|
||||
*
|
||||
* @param string|null $value The current value
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function convertDist($value)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
$data = (array) $value;
|
||||
$value = array();
|
||||
|
||||
foreach ($data as $type => $url) {
|
||||
if (is_string($url)) {
|
||||
self::convertDistEntry($value, $type, $url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the each entry of dist section.
|
||||
*
|
||||
* @param array $value The result
|
||||
* @param string $type The dist type
|
||||
* @param string $url The dist url
|
||||
*/
|
||||
private static function convertDistEntry(array &$value, $type, $url)
|
||||
{
|
||||
$httpPrefix = 'http://';
|
||||
|
||||
if (0 === strpos($url, $httpPrefix)) {
|
||||
$url = 'https://'.substr($url, strlen($httpPrefix));
|
||||
}
|
||||
|
||||
if ('shasum' === $type) {
|
||||
$value[$type] = $url;
|
||||
} else {
|
||||
$value['type'] = 'tarball' === $type ? 'tar' : $type;
|
||||
$value['url'] = $url;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Converter;
|
||||
|
||||
/**
|
||||
* Interface for the converter for asset package to composer package.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
interface PackageConverterInterface
|
||||
{
|
||||
/**
|
||||
* Converts the asset data package to composer data package.
|
||||
*
|
||||
* @param array $data The asset data package
|
||||
* @param array $vcsRepos The vcs repositories created
|
||||
*
|
||||
* @return array The composer data package
|
||||
*/
|
||||
public function convert(array $data, array &$vcsRepos = array());
|
||||
}
|
|
@ -1,321 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Converter;
|
||||
|
||||
use Composer\Config;
|
||||
use Composer\IO\NullIO;
|
||||
use Composer\Repository\Vcs\VcsDriverInterface;
|
||||
use Fxp\Composer\AssetPlugin\Assets;
|
||||
use Fxp\Composer\AssetPlugin\Exception\InvalidArgumentException;
|
||||
use Fxp\Composer\AssetPlugin\Type\AssetTypeInterface;
|
||||
use Fxp\Composer\AssetPlugin\Util\Validator;
|
||||
|
||||
/**
|
||||
* Utils for package converter.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
abstract class PackageUtil
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private static $extensions = array(
|
||||
'.zip',
|
||||
'.tar',
|
||||
'.tar.gz',
|
||||
'.tar.bz2',
|
||||
'.tar.Z',
|
||||
'.tar.xz',
|
||||
'.bz2',
|
||||
'.gz',
|
||||
);
|
||||
|
||||
/**
|
||||
* Checks if the version is a URL version.
|
||||
*
|
||||
* @param AssetTypeInterface $assetType The asset type
|
||||
* @param string $dependency The dependency
|
||||
* @param string $version The version
|
||||
* @param array $vcsRepos The list of new vcs configs
|
||||
* @param array $composer The partial composer data
|
||||
*
|
||||
* @return string[] The new dependency and the new version
|
||||
*/
|
||||
public static function checkUrlVersion(AssetTypeInterface $assetType, $dependency, $version, array &$vcsRepos, array $composer)
|
||||
{
|
||||
if (preg_match('/(\:\/\/)|\@/', $version)) {
|
||||
list($url, $version) = static::splitUrlVersion($version);
|
||||
|
||||
if (!static::isUrlArchive($url) && static::hasUrlDependencySupported($url)) {
|
||||
$vcsRepos[] = array(
|
||||
'type' => sprintf('%s-vcs', $assetType->getName()),
|
||||
'url' => $url,
|
||||
'name' => $assetType->formatComposerName($dependency),
|
||||
);
|
||||
} else {
|
||||
$dependency = static::getUrlFileDependencyName($assetType, $composer, $dependency);
|
||||
$vcsRepos[] = array(
|
||||
'type' => 'package',
|
||||
'package' => array(
|
||||
'name' => $assetType->formatComposerName($dependency),
|
||||
'type' => $assetType->getComposerType(),
|
||||
'version' => static::getUrlFileDependencyVersion($assetType, $url, $version),
|
||||
'dist' => array(
|
||||
'url' => $url,
|
||||
'type' => 'file',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return array($dependency, $version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the url is a url of a archive file.
|
||||
*
|
||||
* @param string $url The url
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isUrlArchive($url)
|
||||
{
|
||||
if (0 === strpos($url, 'http')) {
|
||||
foreach (self::$extensions as $extension) {
|
||||
if (substr($url, -strlen($extension)) === $extension) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the version is a alias version.
|
||||
*
|
||||
* @param AssetTypeInterface $assetType The asset type
|
||||
* @param string $dependency The dependency
|
||||
* @param string $version The version
|
||||
*
|
||||
* @return string[] The new dependency and the new version
|
||||
*/
|
||||
public static function checkAliasVersion(AssetTypeInterface $assetType, $dependency, $version)
|
||||
{
|
||||
$pos = strpos($version, '#');
|
||||
|
||||
if ($pos > 0 && !preg_match('{[0-9a-f]{40}$}', $version)) {
|
||||
$dependency = substr($version, 0, $pos);
|
||||
$version = substr($version, $pos);
|
||||
$searchVerion = substr($version, 1);
|
||||
|
||||
if (false === strpos($version, '*') && Validator::validateTag($searchVerion, $assetType)) {
|
||||
$dependency .= '-'.str_replace('#', '', $version);
|
||||
}
|
||||
}
|
||||
|
||||
return array($dependency, $version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the dependency version.
|
||||
*
|
||||
* @param AssetTypeInterface $assetType The asset type
|
||||
* @param string $dependency The dependency
|
||||
* @param string $version The version
|
||||
*
|
||||
* @return string[] The new dependency and the new version
|
||||
*/
|
||||
public static function convertDependencyVersion(AssetTypeInterface $assetType, $dependency, $version)
|
||||
{
|
||||
$containsHash = false !== strpos($version, '#');
|
||||
$version = str_replace('#', '', $version);
|
||||
$version = empty($version) ? '*' : trim($version);
|
||||
$searchVersion = str_replace(array(' ', '<', '>', '=', '^', '~'), '', $version);
|
||||
|
||||
// sha version or branch version
|
||||
// sha size: 4-40. See https://git-scm.com/book/tr/v2/Git-Tools-Revision-Selection#_short_sha_1
|
||||
if ($containsHash && preg_match('{^[0-9a-f]{4,40}$}', $version)) {
|
||||
$version = 'dev-default#'.$version;
|
||||
} elseif ('*' !== $version && !Validator::validateTag($searchVersion, $assetType) && !static::depIsRange($version)) {
|
||||
$version = static::convertBrachVersion($assetType, $version);
|
||||
}
|
||||
|
||||
return array($dependency, $version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the simple key of package.
|
||||
*
|
||||
* @param array $asset The asset data
|
||||
* @param string $assetKey The asset key
|
||||
* @param array $composer The composer data
|
||||
* @param string $composerKey The composer key
|
||||
*/
|
||||
public static function convertStringKey(array $asset, $assetKey, array &$composer, $composerKey)
|
||||
{
|
||||
if (isset($asset[$assetKey])) {
|
||||
$composer[$composerKey] = $asset[$assetKey];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the simple key of package.
|
||||
*
|
||||
* @param array $asset The asset data
|
||||
* @param string $assetKey The asset key
|
||||
* @param array $composer The composer data
|
||||
* @param array $composerKey The array with composer key name and closure
|
||||
*
|
||||
* @throws InvalidArgumentException When the 'composerKey' argument of asset packager converter is not an string or an array with the composer key and closure
|
||||
*/
|
||||
public static function convertArrayKey(array $asset, $assetKey, array &$composer, $composerKey)
|
||||
{
|
||||
if (2 !== count($composerKey)
|
||||
|| !is_string($composerKey[0]) || !$composerKey[1] instanceof \Closure) {
|
||||
throw new InvalidArgumentException('The "composerKey" argument of asset packager converter must be an string or an array with the composer key and closure');
|
||||
}
|
||||
|
||||
$closure = $composerKey[1];
|
||||
$composerKey = $composerKey[0];
|
||||
$data = isset($asset[$assetKey]) ? $asset[$assetKey] : null;
|
||||
$previousData = isset($composer[$composerKey]) ? $composer[$composerKey] : null;
|
||||
$data = $closure($data, $previousData);
|
||||
|
||||
if (null !== $data) {
|
||||
$composer[$composerKey] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Split the URL and version.
|
||||
*
|
||||
* @param string $version The url and version (in the same string)
|
||||
*
|
||||
* @return string[] The url and version
|
||||
*/
|
||||
protected static function splitUrlVersion($version)
|
||||
{
|
||||
$pos = strpos($version, '#');
|
||||
|
||||
// number version or empty version
|
||||
if (false !== $pos) {
|
||||
$url = substr($version, 0, $pos);
|
||||
$version = substr($version, $pos);
|
||||
} else {
|
||||
$url = $version;
|
||||
$version = '#';
|
||||
}
|
||||
|
||||
return array($url, $version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of url file dependency.
|
||||
*
|
||||
* @param AssetTypeInterface $assetType The asset type
|
||||
* @param array $composer The partial composer
|
||||
* @param string $dependency The dependency name
|
||||
*
|
||||
* @return string The dependency name
|
||||
*/
|
||||
protected static function getUrlFileDependencyName(AssetTypeInterface $assetType, array $composer, $dependency)
|
||||
{
|
||||
$prefix = isset($composer['name'])
|
||||
? substr($composer['name'], strlen($assetType->getComposerVendorName()) + 1).'-'
|
||||
: '';
|
||||
|
||||
return $prefix.$dependency.'-file';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version of url file dependency.
|
||||
*
|
||||
* @param AssetTypeInterface $assetType The asset type
|
||||
* @param string $url The url
|
||||
* @param string $version The version
|
||||
*
|
||||
* @return string The version
|
||||
*/
|
||||
protected static function getUrlFileDependencyVersion(AssetTypeInterface $assetType, $url, $version)
|
||||
{
|
||||
if ('#' !== $version) {
|
||||
return substr($version, 1);
|
||||
}
|
||||
|
||||
if (preg_match('/(\d+)(\.\d+)(\.\d+)?(\.\d+)?/', $url, $match)) {
|
||||
return $assetType->getVersionConverter()->convertVersion($match[0]);
|
||||
}
|
||||
|
||||
return '0.0.0.0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if url is supported by vcs drivers.
|
||||
*
|
||||
* @param string $url The url
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected static function hasUrlDependencySupported($url)
|
||||
{
|
||||
$io = new NullIO();
|
||||
$config = new Config();
|
||||
|
||||
/* @var VcsDriverInterface $driver */
|
||||
foreach (Assets::getVcsDrivers() as $driver) {
|
||||
$supported = $driver::supports($io, $config, $url);
|
||||
|
||||
if ($supported) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the version of dependency is a range version.
|
||||
*
|
||||
* @param string $version
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected static function depIsRange($version)
|
||||
{
|
||||
$version = trim($version);
|
||||
|
||||
return (bool) preg_match('/[\<\>\=\^\~\ ]/', $version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the dependency branch version.
|
||||
*
|
||||
* @param AssetTypeInterface $assetType The asset type
|
||||
* @param string $version The version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function convertBrachVersion(AssetTypeInterface $assetType, $version)
|
||||
{
|
||||
$oldVersion = $version;
|
||||
$version = 'dev-'.$assetType->getVersionConverter()->convertVersion($version);
|
||||
|
||||
if (!Validator::validateBranch($oldVersion)) {
|
||||
$version .= ' || '.$oldVersion;
|
||||
}
|
||||
|
||||
return $version;
|
||||
}
|
||||
}
|
|
@ -1,219 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Converter;
|
||||
|
||||
/**
|
||||
* Converter for Semver syntax version to composer syntax version.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class SemverConverter implements VersionConverterInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function convertVersion($version)
|
||||
{
|
||||
if (in_array($version, array(null, '', 'latest'))) {
|
||||
return ('latest' === $version ? 'default || ' : '').'*';
|
||||
}
|
||||
|
||||
$version = str_replace('–', '-', $version);
|
||||
$prefix = preg_match('/^[a-z]/', $version) && 0 !== strpos($version, 'dev-') ? substr($version, 0, 1) : '';
|
||||
$version = substr($version, strlen($prefix));
|
||||
$version = SemverUtil::convertVersionMetadata($version);
|
||||
$version = SemverUtil::convertDateVersion($version);
|
||||
|
||||
return $prefix.$version;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function convertRange($range)
|
||||
{
|
||||
$range = $this->cleanRange(strtolower($range));
|
||||
|
||||
return $this->matchRange($range);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean the raw range.
|
||||
*
|
||||
* @param string $range
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function cleanRange($range)
|
||||
{
|
||||
foreach (array('<', '>', '=', '~', '^', '||', '&&') as $character) {
|
||||
$range = str_replace($character.' ', $character, $range);
|
||||
}
|
||||
|
||||
$range = preg_replace('/(?:[vV])(\d+)/', '${1}', $range);
|
||||
$range = str_replace(' ||', '||', $range);
|
||||
$range = str_replace(array(' &&', '&&'), ',', $range);
|
||||
|
||||
return $range;
|
||||
}
|
||||
|
||||
/**
|
||||
* Match the range.
|
||||
*
|
||||
* @param string $range The range cleaned
|
||||
*
|
||||
* @return string The range
|
||||
*/
|
||||
protected function matchRange($range)
|
||||
{
|
||||
$pattern = '/(\ -\ )|(<)|(>)|(=)|(\|\|)|(\ )|(,)|(\~)|(\^)/';
|
||||
$matches = preg_split($pattern, $range, -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
$special = null;
|
||||
$replace = null;
|
||||
$first = true;
|
||||
|
||||
foreach ($matches as $i => $match) {
|
||||
if ($first && '' !== $match) {
|
||||
$first = false;
|
||||
$match = '=' === $match ? 'EQUAL' : $match;
|
||||
}
|
||||
|
||||
$this->matchRangeToken($i, $match, $matches, $special, $replace);
|
||||
}
|
||||
|
||||
return implode('', $matches);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the token of the matched range.
|
||||
*
|
||||
* @param int $i
|
||||
* @param string $match
|
||||
* @param array $matches
|
||||
* @param string|null $special
|
||||
* @param string|null $replace
|
||||
*/
|
||||
protected function matchRangeToken($i, $match, array &$matches, &$special, &$replace)
|
||||
{
|
||||
if (' - ' === $match) {
|
||||
$matches[$i - 1] = '>='.str_replace(array('*', 'x', 'X'), '0', $matches[$i - 1]);
|
||||
|
||||
if (false !== strpos($matches[$i + 1], '.') && strpos($matches[$i + 1], '*') === false
|
||||
&& strpos($matches[$i + 1], 'x') === false && strpos($matches[$i + 1], 'X') === false) {
|
||||
$matches[$i] = ',<=';
|
||||
} else {
|
||||
$matches[$i] = ',<';
|
||||
$special = ',<~';
|
||||
}
|
||||
} else {
|
||||
$this->matchRangeTokenStep2($i, $match, $matches, $special, $replace);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Step2: Converts the token of the matched range.
|
||||
*
|
||||
* @param int $i
|
||||
* @param string $match
|
||||
* @param array $matches
|
||||
* @param string|null $special
|
||||
* @param string|null $replace
|
||||
*/
|
||||
protected function matchRangeTokenStep2($i, $match, array &$matches, &$special, &$replace)
|
||||
{
|
||||
if (in_array($match, array('', '<', '>', '=', ','))) {
|
||||
$replace = in_array($match, array('<', '>')) ? $match : $replace;
|
||||
$matches[$i] = '~' === $special && in_array($replace, array('<', '>')) ? '' : $matches[$i];
|
||||
} elseif ('~' === $match) {
|
||||
$special = $match;
|
||||
} elseif (in_array($match, array('EQUAL', '^'))) {
|
||||
$special = $match;
|
||||
$matches[$i] = '';
|
||||
} else {
|
||||
$this->matchRangeTokenStep3($i, $match, $matches, $special, $replace);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Step3: Converts the token of the matched range.
|
||||
*
|
||||
* @param int $i
|
||||
* @param string $match
|
||||
* @param array $matches
|
||||
* @param string|null $special
|
||||
* @param string|null $replace
|
||||
*/
|
||||
protected function matchRangeTokenStep3($i, $match, array &$matches, &$special, &$replace)
|
||||
{
|
||||
if (' ' === $match) {
|
||||
$matches[$i] = ',';
|
||||
} elseif ('||' === $match) {
|
||||
$matches[$i] = '|';
|
||||
} elseif (in_array($special, array('^'))) {
|
||||
$matches[$i] = SemverRangeUtil::replaceSpecialRange($this, $match);
|
||||
$special = null;
|
||||
} else {
|
||||
$this->matchRangeTokenStep4($i, $match, $matches, $special, $replace);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Step4: Converts the token of the matched range.
|
||||
*
|
||||
* @param int $i
|
||||
* @param string $match
|
||||
* @param array $matches
|
||||
* @param string|null $special
|
||||
* @param string|null $replace
|
||||
*/
|
||||
protected function matchRangeTokenStep4($i, $match, array &$matches, &$special, &$replace)
|
||||
{
|
||||
if ($special === ',<~') {
|
||||
// Version range contains x in last place.
|
||||
$match .= (false === strpos($match, '.') ? '.x' : '');
|
||||
$version = explode('.', $match);
|
||||
$change = count($version) - 2;
|
||||
$version[$change] = (int) ($version[$change]) + 1;
|
||||
$match = str_replace(array('*', 'x', 'X'), '0', implode('.', $version));
|
||||
} elseif (null === $special && $i === 0 && false === strpos($match, '.') && is_numeric($match)) {
|
||||
$match = isset($matches[$i + 1]) && (' - ' === $matches[$i + 1] || '-' === $matches[$i + 1])
|
||||
? $match
|
||||
: '~'.$match;
|
||||
} else {
|
||||
$match = '~' === $special ? str_replace(array('*', 'x', 'X'), '0', $match) : $match;
|
||||
}
|
||||
|
||||
$this->matchRangeTokenStep5($i, $match, $matches, $special, $replace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Step5: Converts the token of the matched range.
|
||||
*
|
||||
* @param int $i
|
||||
* @param string $match
|
||||
* @param array $matches
|
||||
* @param string|null $special
|
||||
* @param string|null $replace
|
||||
*/
|
||||
protected function matchRangeTokenStep5($i, $match, array &$matches, &$special, &$replace)
|
||||
{
|
||||
$matches[$i] = $this->convertVersion($match);
|
||||
$matches[$i] = $replace
|
||||
? SemverUtil::replaceAlias($matches[$i], $replace)
|
||||
: $matches[$i];
|
||||
$matches[$i] .= '~' === $special && in_array($replace, array('<', '>'))
|
||||
? ','.$replace.$matches[$i]
|
||||
: '';
|
||||
$special = null;
|
||||
$replace = null;
|
||||
}
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Converter;
|
||||
|
||||
/**
|
||||
* Utils for semver range converter.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
abstract class SemverRangeUtil
|
||||
{
|
||||
/**
|
||||
* Replaces the special range "^".
|
||||
*
|
||||
* @param SemverConverter $converter The semver converter
|
||||
* @param string $match The match version
|
||||
*
|
||||
* @return string the new match version
|
||||
*/
|
||||
public static function replaceSpecialRange(SemverConverter $converter, $match)
|
||||
{
|
||||
$newMatch = $converter->convertVersion($match);
|
||||
$newMatch = '>='.static::standardizeVersion(SemverUtil::replaceAlias($newMatch, '>')).',<';
|
||||
$exp = static::getSplittedVersion($match);
|
||||
$increase = false;
|
||||
|
||||
foreach ($exp as $i => $sub) {
|
||||
if (static::analyzeSubVersion($i, $exp, $increase)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
static::increaseSubVersion($i, $exp, $increase);
|
||||
}
|
||||
|
||||
$newMatch .= $converter->convertVersion(static::standardizeVersion($exp));
|
||||
|
||||
return $newMatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze the sub version of splitted version.
|
||||
*
|
||||
* @param int $i The position in splitted version
|
||||
* @param array $exp The splitted version
|
||||
* @param bool $increase Check if the next sub version must be increased
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected static function analyzeSubVersion($i, array &$exp, &$increase)
|
||||
{
|
||||
$analyzed = false;
|
||||
|
||||
if ($increase) {
|
||||
$exp[$i] = 0;
|
||||
$analyzed = true;
|
||||
}
|
||||
|
||||
if (0 === $i && (int) $exp[$i] > 0) {
|
||||
$increase = true;
|
||||
$exp[$i] = (int) $exp[$i] + 1;
|
||||
$analyzed = true;
|
||||
}
|
||||
|
||||
return $analyzed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase the sub version of splitted version.
|
||||
*
|
||||
* @param int $i The position in splitted version
|
||||
* @param array $exp The splitted version
|
||||
* @param bool $increase Check if the next sub version must be increased
|
||||
*/
|
||||
protected static function increaseSubVersion($i, array &$exp, &$increase)
|
||||
{
|
||||
$iNext = min(min($i + 1, 3), count($exp) - 1);
|
||||
|
||||
if (($iNext !== $i && ($exp[$i] > 0 || (int) $exp[$iNext] > 9999998)) || $iNext === $i) {
|
||||
$exp[$i] = (int) $exp[$i] + 1;
|
||||
$increase = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Standardize the version.
|
||||
*
|
||||
* @param string|array $version The version or the splitted version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function standardizeVersion($version)
|
||||
{
|
||||
if (is_string($version)) {
|
||||
$version = explode('.', $version);
|
||||
}
|
||||
|
||||
while (count($version) < 3) {
|
||||
$version[] = '0';
|
||||
}
|
||||
|
||||
return implode('.', $version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Split the version.
|
||||
*
|
||||
* @param string $version
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function getSplittedVersion($version)
|
||||
{
|
||||
$version = static::cleanExtraVersion($version);
|
||||
$version = str_replace(array('*', 'x', 'X'), '9999999', $version);
|
||||
$exp = explode('.', $version);
|
||||
|
||||
return $exp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the extra informations of the version (info after "-").
|
||||
*
|
||||
* @param string $version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function cleanExtraVersion($version)
|
||||
{
|
||||
$pos = strpos($version, '-');
|
||||
|
||||
if (false !== $pos) {
|
||||
$version = substr($version, 0, $pos);
|
||||
}
|
||||
|
||||
return $version;
|
||||
}
|
||||
}
|
|
@ -1,192 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Converter;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Package\Version\VersionParser;
|
||||
|
||||
/**
|
||||
* Utils for semver converter.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
abstract class SemverUtil
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private static $cleanPatterns = array(
|
||||
'-npm-packages',
|
||||
'-bower-packages',
|
||||
);
|
||||
|
||||
/**
|
||||
* Replace the alias version (x or *) by integer.
|
||||
*
|
||||
* @param string $version
|
||||
* @param string $type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function replaceAlias($version, $type)
|
||||
{
|
||||
$value = '>' === $type ? '0' : '9999999';
|
||||
|
||||
return str_replace(array('x', '*'), $value, $version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the date or datetime version.
|
||||
*
|
||||
* @param string $version The version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function convertDateVersion($version)
|
||||
{
|
||||
if (preg_match('/^\d{7,}\./', $version)) {
|
||||
$pos = strpos($version, '.');
|
||||
$version = substr($version, 0, $pos).self::convertDateMinorVersion(substr($version, $pos + 1));
|
||||
}
|
||||
|
||||
return $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the version metadata.
|
||||
*
|
||||
* @param string $version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function convertVersionMetadata($version)
|
||||
{
|
||||
$version = str_replace(self::$cleanPatterns, '', $version);
|
||||
|
||||
if (preg_match_all(self::createPattern('([a-zA-Z]+|(\-|\+)[a-zA-Z]+|(\-|\+)[0-9]+)'),
|
||||
$version, $matches, PREG_OFFSET_CAPTURE)) {
|
||||
list($type, $version, $end) = self::cleanVersion(strtolower($version), $matches);
|
||||
list($version, $patchVersion) = self::matchVersion($version, $type);
|
||||
|
||||
$matches = array();
|
||||
$hasPatchNumber = preg_match('/[0-9]+\.[0-9]+|[0-9]+|\.[0-9]+$/', $end, $matches);
|
||||
$end = $hasPatchNumber ? $matches[0] : '1';
|
||||
|
||||
if ($patchVersion) {
|
||||
$version .= $end;
|
||||
}
|
||||
}
|
||||
|
||||
return static::cleanWildcard($version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a pattern with the version prefix pattern.
|
||||
*
|
||||
* @param string $pattern The pattern without '/'
|
||||
*
|
||||
* @return string The full pattern with '/'
|
||||
*/
|
||||
public static function createPattern($pattern)
|
||||
{
|
||||
$numVer = '([0-9]+|x|\*)';
|
||||
$numVer2 = '('.$numVer.'\.'.$numVer.')';
|
||||
$numVer3 = '('.$numVer.'\.'.$numVer.'\.'.$numVer.')';
|
||||
|
||||
return '/^'.'('.$numVer.'|'.$numVer2.'|'.$numVer3.')'.$pattern.'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean the wildcard in version.
|
||||
*
|
||||
* @param string $version The version
|
||||
*
|
||||
* @return string The cleaned version
|
||||
*/
|
||||
protected static function cleanWildcard($version)
|
||||
{
|
||||
while (false !== strpos($version, '.x.x')) {
|
||||
$version = str_replace('.x.x', '.x', $version);
|
||||
}
|
||||
|
||||
return $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean the raw version.
|
||||
*
|
||||
* @param string $version The version
|
||||
* @param array $matches The match of pattern asset version
|
||||
*
|
||||
* @return array The list of $type, $version and $end
|
||||
*/
|
||||
protected static function cleanVersion($version, array $matches)
|
||||
{
|
||||
$end = substr($version, strlen($matches[1][0][0]));
|
||||
$version = $matches[1][0][0].'-';
|
||||
|
||||
$matches = array();
|
||||
if (preg_match('/^(\-|\+)/', $end, $matches)) {
|
||||
$end = substr($end, 1);
|
||||
}
|
||||
|
||||
$matches = array();
|
||||
preg_match('/^[a-z]+/', $end, $matches);
|
||||
$type = isset($matches[0]) ? VersionParser::normalizeStability($matches[0]) : null;
|
||||
$end = substr($end, strlen($type));
|
||||
|
||||
return array($type, $version, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Match the version.
|
||||
*
|
||||
* @param string $version
|
||||
* @param string $type
|
||||
*
|
||||
* @return array The list of $version and $patchVersion
|
||||
*/
|
||||
protected static function matchVersion($version, $type)
|
||||
{
|
||||
$patchVersion = true;
|
||||
|
||||
if (in_array($type, array('dev', 'snapshot'))) {
|
||||
$type = 'dev';
|
||||
$patchVersion = false;
|
||||
} elseif ('a' === $type) {
|
||||
$type = 'alpha';
|
||||
} elseif (in_array($type, array('b', 'pre'))) {
|
||||
$type = 'beta';
|
||||
} elseif (!in_array($type, array('alpha', 'beta', 'RC'))) {
|
||||
$type = 'patch';
|
||||
}
|
||||
|
||||
$version .= $type;
|
||||
|
||||
return array($version, $patchVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the minor version of date.
|
||||
*
|
||||
* @param string $minor The minor version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function convertDateMinorVersion($minor)
|
||||
{
|
||||
$split = explode('.', $minor);
|
||||
$minor = (int) $split[0];
|
||||
$revision = isset($split[1]) ? (int) $split[1] : 0;
|
||||
|
||||
return '.'.sprintf('%03d', $minor).sprintf('%03d', $revision);
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Converter;
|
||||
|
||||
/**
|
||||
* Interface for the converter for asset syntax version to composer syntax version.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
interface VersionConverterInterface
|
||||
{
|
||||
/**
|
||||
* Converts the asset version to composer version.
|
||||
*
|
||||
* @param string $version The asset version
|
||||
*
|
||||
* @return string The composer version
|
||||
*/
|
||||
public function convertVersion($version);
|
||||
|
||||
/**
|
||||
* Converts the range asset version to range composer version.
|
||||
*
|
||||
* @param string $range The range asset version
|
||||
*
|
||||
* @return string The range composer version
|
||||
*/
|
||||
public function convertRange($range);
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Exception;
|
||||
|
||||
/**
|
||||
* The interface of exception.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
interface ExceptionInterface
|
||||
{
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Exception;
|
||||
|
||||
/**
|
||||
* The Invalid Argument Exception.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Exception;
|
||||
|
||||
/**
|
||||
* The Invalid Create Asset Repository Exception.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class InvalidCreateRepositoryException extends \Exception implements ExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $data = array();
|
||||
|
||||
/**
|
||||
* Set the data of asset package config defined by the registry.
|
||||
*
|
||||
* @param array $data The data
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setData(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data of asset package config defined by the registry.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Installer;
|
||||
|
||||
use Composer\Composer;
|
||||
use Composer\Installer\LibraryInstaller;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Util\Filesystem;
|
||||
use Fxp\Composer\AssetPlugin\Config\Config;
|
||||
use Fxp\Composer\AssetPlugin\Type\AssetTypeInterface;
|
||||
use Fxp\Composer\AssetPlugin\Util\AssetPlugin;
|
||||
|
||||
/**
|
||||
* Installer for asset packages.
|
||||
*
|
||||
* @author Martin Hasoň <martin.hason@gmail.com>
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class AssetInstaller extends LibraryInstaller
|
||||
{
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Config $config
|
||||
* @param IOInterface $io
|
||||
* @param Composer $composer
|
||||
* @param AssetTypeInterface $assetType
|
||||
* @param Filesystem $filesystem
|
||||
*/
|
||||
public function __construct(Config $config, IOInterface $io, Composer $composer, AssetTypeInterface $assetType, Filesystem $filesystem = null)
|
||||
{
|
||||
parent::__construct($io, $composer, $assetType->getComposerType(), $filesystem);
|
||||
|
||||
$this->config = $config;
|
||||
$paths = $this->config->getArray('installer-paths');
|
||||
|
||||
if (!empty($paths[$this->type])) {
|
||||
$this->vendorDir = rtrim($paths[$this->type], '/');
|
||||
} else {
|
||||
$this->vendorDir = rtrim($this->vendorDir.'/'.$assetType->getComposerVendorName(), '/');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports($packageType)
|
||||
{
|
||||
return $packageType === $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getInstallPath(PackageInterface $package)
|
||||
{
|
||||
$this->initializeVendorDir();
|
||||
|
||||
$targetDir = $package->getTargetDir();
|
||||
|
||||
list(, $name) = explode('/', $package->getPrettyName(), 2);
|
||||
|
||||
return ($this->vendorDir ? $this->vendorDir.'/' : '').$name.($targetDir ? '/'.$targetDir : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getPackageBasePath(PackageInterface $package)
|
||||
{
|
||||
return $this->getInstallPath($package);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function installCode(PackageInterface $package)
|
||||
{
|
||||
$package = AssetPlugin::addMainFiles($this->config, $package);
|
||||
|
||||
parent::installCode($package);
|
||||
|
||||
$this->deleteIgnoredFiles($package);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function updateCode(PackageInterface $initial, PackageInterface $target)
|
||||
{
|
||||
$target = AssetPlugin::addMainFiles($this->config, $target);
|
||||
|
||||
parent::updateCode($initial, $target);
|
||||
|
||||
$this->deleteIgnoredFiles($target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes files defined in bower.json in section "ignore".
|
||||
*
|
||||
* @param PackageInterface $package
|
||||
*/
|
||||
protected function deleteIgnoredFiles(PackageInterface $package)
|
||||
{
|
||||
$manager = IgnoreFactory::create($this->config, $this->composer, $package, $this->getInstallPath($package));
|
||||
|
||||
if ($manager->isEnabled() && !$manager->hasPattern()) {
|
||||
$this->addIgnorePatterns($manager, $package);
|
||||
}
|
||||
|
||||
$manager->cleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add ignore patterns in the manager.
|
||||
*
|
||||
* @param IgnoreManager $manager The ignore manager instance
|
||||
* @param PackageInterface $package The package instance
|
||||
*/
|
||||
protected function addIgnorePatterns(IgnoreManager $manager, PackageInterface $package)
|
||||
{
|
||||
// override this method
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Installer;
|
||||
|
||||
use Composer\Package\PackageInterface;
|
||||
|
||||
/**
|
||||
* Installer for bower packages.
|
||||
*
|
||||
* @author Martin Hasoň <martin.hason@gmail.com>
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class BowerInstaller extends AssetInstaller
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function addIgnorePatterns(IgnoreManager $manager, PackageInterface $package)
|
||||
{
|
||||
$extra = $package->getExtra();
|
||||
|
||||
if (!empty($extra['bower-asset-ignore'])) {
|
||||
$manager->doAddPattern('!bower.json');
|
||||
|
||||
foreach ($extra['bower-asset-ignore'] as $pattern) {
|
||||
$manager->addPattern($pattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Installer;
|
||||
|
||||
use Composer\Composer;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Fxp\Composer\AssetPlugin\Config\Config;
|
||||
|
||||
/**
|
||||
* Factory of ignore manager patterns.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class IgnoreFactory
|
||||
{
|
||||
/**
|
||||
* Create a ignore manager.
|
||||
*
|
||||
* @param Config $config The plugin config
|
||||
* @param Composer $composer The composer instance
|
||||
* @param PackageInterface $package The package instance
|
||||
* @param string|null $installDir The custom installation directory
|
||||
* @param string|null $section The config section of ignore patterns
|
||||
*
|
||||
* @return IgnoreManager
|
||||
*/
|
||||
public static function create(Config $config, Composer $composer, PackageInterface $package, $installDir = null, $section = 'ignore-files')
|
||||
{
|
||||
$installDir = static::getInstallDir($composer, $package, $installDir);
|
||||
$manager = new IgnoreManager($installDir);
|
||||
$config = $config->getArray($section);
|
||||
|
||||
foreach ($config as $packageName => $patterns) {
|
||||
if ($packageName === $package->getName()) {
|
||||
static::addPatterns($manager, $patterns);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the installation directory of the package.
|
||||
*
|
||||
* @param Composer $composer The composer instance
|
||||
* @param PackageInterface $package The package instance
|
||||
* @param string|null $installDir The custom installation directory
|
||||
*
|
||||
* @return string The installation directory
|
||||
*/
|
||||
protected static function getInstallDir(Composer $composer, PackageInterface $package, $installDir = null)
|
||||
{
|
||||
if (null === $installDir) {
|
||||
$installDir = rtrim($composer->getConfig()->get('vendor-dir'), '/').'/'.$package->getName();
|
||||
}
|
||||
|
||||
return rtrim($installDir, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add ignore file patterns in the ignore manager.
|
||||
*
|
||||
* @param IgnoreManager $manager The ignore files manager
|
||||
* @param bool|array $patterns The patterns for ignore files
|
||||
*/
|
||||
protected static function addPatterns(IgnoreManager $manager, $patterns)
|
||||
{
|
||||
$enabled = false === $patterns ? false : true;
|
||||
$manager->setEnabled($enabled);
|
||||
|
||||
if (is_array($patterns)) {
|
||||
foreach ($patterns as $pattern) {
|
||||
$manager->addPattern($pattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,196 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Installer;
|
||||
|
||||
use Composer\Util\Filesystem;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\Finder\Glob;
|
||||
|
||||
/**
|
||||
* Manager of ignore patterns.
|
||||
*
|
||||
* @author Martin Hasoň <martin.hason@gmail.com>
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class IgnoreManager
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $installDir;
|
||||
|
||||
/**
|
||||
* @var Filesystem
|
||||
*/
|
||||
private $filesystem;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $enabled;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $hasPattern;
|
||||
|
||||
/**
|
||||
* @var Finder
|
||||
*/
|
||||
private $finder;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $installDir The install dir
|
||||
* @param Filesystem|null $filesystem The filesystem
|
||||
*/
|
||||
public function __construct($installDir, Filesystem $filesystem = null)
|
||||
{
|
||||
$this->installDir = $installDir;
|
||||
$this->filesystem = $filesystem ?: new Filesystem();
|
||||
$this->enabled = true;
|
||||
$this->hasPattern = false;
|
||||
$this->finder = Finder::create()->ignoreVCS(true)->ignoreDotFiles(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or not this ignore files manager.
|
||||
*
|
||||
* @param bool $enabled
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setEnabled($enabled)
|
||||
{
|
||||
$this->enabled = (bool) $enabled;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this ignore files manager is enabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled()
|
||||
{
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a pattern is added.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasPattern()
|
||||
{
|
||||
return $this->hasPattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an ignore pattern.
|
||||
*
|
||||
* @param string $pattern The pattern
|
||||
*/
|
||||
public function addPattern($pattern)
|
||||
{
|
||||
$this->doAddPattern($this->convertPattern($pattern));
|
||||
$this->hasPattern = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all files and directories that matches patterns.
|
||||
*/
|
||||
public function cleanup()
|
||||
{
|
||||
if ($this->isEnabled() && $this->hasPattern() && realpath($this->installDir)) {
|
||||
$paths = iterator_to_array($this->finder->in($this->installDir));
|
||||
|
||||
/* @var \SplFileInfo $path */
|
||||
foreach ($paths as $path) {
|
||||
$this->filesystem->remove($path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action for Add an ignore pattern.
|
||||
*
|
||||
* @param string $pattern The pattern
|
||||
*/
|
||||
public function doAddPattern($pattern)
|
||||
{
|
||||
if (0 === strpos($pattern, '!')) {
|
||||
$searchPattern = substr($pattern, 1);
|
||||
$this->finder->notPath(Glob::toRegex($searchPattern, true, true));
|
||||
|
||||
$pathComponents = explode('/', $searchPattern);
|
||||
|
||||
if (1 < count($pathComponents)) {
|
||||
$parentDirectories = array_slice($pathComponents, 0, -1);
|
||||
$basePath = '';
|
||||
|
||||
foreach ($parentDirectories as $dir) {
|
||||
$this->finder->notPath('/\b('.preg_quote($basePath.$dir, '/').')(?!\/)\b/');
|
||||
$basePath .= $dir.'/';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->finder->path(Glob::toRegex($pattern, true, true));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converter pattern to glob.
|
||||
*
|
||||
* @param string $pattern The pattern
|
||||
*
|
||||
* @return string The pattern converted
|
||||
*/
|
||||
protected function convertPattern($pattern)
|
||||
{
|
||||
$prefix = 0 === strpos($pattern, '!') ? '!' : '';
|
||||
$searchPattern = trim(ltrim($pattern, '!'), '/');
|
||||
$pattern = $prefix.$searchPattern;
|
||||
|
||||
if (in_array($searchPattern, array('*', '*.*'))) {
|
||||
$this->doAddPattern($prefix.'.*');
|
||||
} elseif (0 === strpos($searchPattern, '**/')) {
|
||||
$this->doAddPattern($prefix.'**/'.$searchPattern);
|
||||
$this->doAddPattern($prefix.substr($searchPattern, 3));
|
||||
} else {
|
||||
$this->convertPatternStep2($prefix, $searchPattern, $pattern);
|
||||
}
|
||||
|
||||
return $pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Step2: Converter pattern to glob.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param string $searchPattern The search pattern
|
||||
* @param string $pattern The pattern
|
||||
*/
|
||||
protected function convertPatternStep2($prefix, $searchPattern, $pattern)
|
||||
{
|
||||
if ('.*' === $searchPattern) {
|
||||
$this->doAddPattern($prefix.'**/.*');
|
||||
} elseif ('**' === $searchPattern) {
|
||||
$this->finder->path('/.*/');
|
||||
$this->finder->notPath('/^\..*(?!\/)/');
|
||||
} elseif (preg_match('/\/\*$|\/\*\*$/', $pattern, $matches)) {
|
||||
$this->doAddPattern(substr($pattern, 0, strlen($pattern) - strlen($matches[0])));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,281 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Package\Loader;
|
||||
|
||||
use Composer\Downloader\TransportException;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Package\CompletePackageInterface;
|
||||
use Composer\Package\Loader\LoaderInterface;
|
||||
use Composer\Repository\Vcs\VcsDriverInterface;
|
||||
use Fxp\Composer\AssetPlugin\Exception\InvalidArgumentException;
|
||||
use Fxp\Composer\AssetPlugin\Package\LazyPackageInterface;
|
||||
use Fxp\Composer\AssetPlugin\Repository\AssetRepositoryManager;
|
||||
use Fxp\Composer\AssetPlugin\Type\AssetTypeInterface;
|
||||
|
||||
/**
|
||||
* Lazy loader for asset package.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class LazyAssetPackageLoader implements LazyLoaderInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $identifier;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $packageData;
|
||||
|
||||
/**
|
||||
* @var AssetTypeInterface
|
||||
*/
|
||||
protected $assetType;
|
||||
|
||||
/**
|
||||
* @var LoaderInterface
|
||||
*/
|
||||
protected $loader;
|
||||
|
||||
/**
|
||||
* @var VcsDriverInterface
|
||||
*/
|
||||
protected $driver;
|
||||
|
||||
/**
|
||||
* @var IOInterface
|
||||
*/
|
||||
protected $io;
|
||||
|
||||
/**
|
||||
* @var AssetRepositoryManager
|
||||
*/
|
||||
protected $assetRepositoryManager;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $verbose;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $identifier
|
||||
* @param string $type
|
||||
* @param array $packageData
|
||||
*/
|
||||
public function __construct($type, $identifier, array $packageData)
|
||||
{
|
||||
$this->identifier = $identifier;
|
||||
$this->type = $type;
|
||||
$this->packageData = $packageData;
|
||||
$this->verbose = false;
|
||||
$this->cache = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the asset type.
|
||||
*
|
||||
* @param AssetTypeInterface $assetType
|
||||
*/
|
||||
public function setAssetType(AssetTypeInterface $assetType)
|
||||
{
|
||||
$this->assetType = $assetType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the laoder.
|
||||
*
|
||||
* @param LoaderInterface $loader
|
||||
*/
|
||||
public function setLoader(LoaderInterface $loader)
|
||||
{
|
||||
$this->loader = $loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the driver.
|
||||
*
|
||||
* @param VcsDriverInterface $driver
|
||||
*/
|
||||
public function setDriver(VcsDriverInterface $driver)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the IO.
|
||||
*
|
||||
* @param IOInterface $io
|
||||
*/
|
||||
public function setIO(IOInterface $io)
|
||||
{
|
||||
$this->io = $io;
|
||||
$this->verbose = $io->isVerbose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the asset repository manager.
|
||||
*
|
||||
* @param AssetRepositoryManager $assetRepositoryManager The asset repository manager
|
||||
*/
|
||||
public function setAssetRepositoryManager(AssetRepositoryManager $assetRepositoryManager)
|
||||
{
|
||||
$this->assetRepositoryManager = $assetRepositoryManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load(LazyPackageInterface $package)
|
||||
{
|
||||
if (isset($this->cache[$package->getUniqueName()])) {
|
||||
return $this->cache[$package->getUniqueName()];
|
||||
}
|
||||
$this->validateConfig();
|
||||
|
||||
$filename = $this->assetType->getFilename();
|
||||
$msg = 'Reading '.$filename.' of <info>'.$package->getName().'</info> (<comment>'.$package->getPrettyVersion().'</comment>)';
|
||||
if ($this->verbose) {
|
||||
$this->io->write($msg);
|
||||
} else {
|
||||
$this->io->overwrite($msg, false);
|
||||
}
|
||||
|
||||
$realPackage = $this->loadRealPackage($package);
|
||||
$this->cache[$package->getUniqueName()] = $realPackage;
|
||||
|
||||
if (!$this->verbose) {
|
||||
$this->io->overwrite('', false);
|
||||
}
|
||||
|
||||
return $realPackage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the class config.
|
||||
*
|
||||
* @throws InvalidArgumentException When the property of this class is not defined
|
||||
*/
|
||||
protected function validateConfig()
|
||||
{
|
||||
foreach (array('assetType', 'loader', 'driver', 'io') as $property) {
|
||||
if (null === $this->$property) {
|
||||
throw new InvalidArgumentException(sprintf('The "%s" property must be defined', $property));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the real package.
|
||||
*
|
||||
* @param LazyPackageInterface $package
|
||||
*
|
||||
* @return CompletePackageInterface|false
|
||||
*/
|
||||
protected function loadRealPackage(LazyPackageInterface $package)
|
||||
{
|
||||
$realPackage = false;
|
||||
|
||||
try {
|
||||
$data = $this->driver->getComposerInformation($this->identifier);
|
||||
$valid = is_array($data);
|
||||
$data = $this->preProcess($this->driver, $this->validateData($data), $this->identifier);
|
||||
|
||||
if ($this->verbose) {
|
||||
$this->io->write('Importing '.($valid ? '' : 'empty ').$this->type.' '.$data['version'].' ('.$data['version_normalized'].')');
|
||||
}
|
||||
|
||||
/* @var CompletePackageInterface $realPackage */
|
||||
$realPackage = $this->loader->load($data);
|
||||
} catch (\Exception $e) {
|
||||
if ($this->verbose) {
|
||||
$filename = $this->assetType->getFilename();
|
||||
$this->io->write('<'.$this->getIoTag().'>Skipped '.$this->type.' '.$package->getPrettyVersion().', '.($e instanceof TransportException ? 'no '.$filename.' file was found' : $e->getMessage()).'</'.$this->getIoTag().'>');
|
||||
}
|
||||
}
|
||||
$this->driver->cleanup();
|
||||
|
||||
return $realPackage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|bool $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function validateData($data)
|
||||
{
|
||||
return is_array($data) ? $data : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tag name for IO.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getIoTag()
|
||||
{
|
||||
return 'branch' === $this->type ? 'error' : 'warning';
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre process the data of package before the conversion to Package instance.
|
||||
*
|
||||
* @param VcsDriverInterface $driver
|
||||
* @param array $data
|
||||
* @param string $identifier
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function preProcess(VcsDriverInterface $driver, array $data, $identifier)
|
||||
{
|
||||
$vcsRepos = array();
|
||||
$data = array_merge($data, $this->packageData);
|
||||
$data = $this->assetType->getPackageConverter()->convert($data, $vcsRepos);
|
||||
|
||||
$this->addRepositories($vcsRepos);
|
||||
|
||||
if (!isset($data['dist'])) {
|
||||
$data['dist'] = $driver->getDist($identifier);
|
||||
}
|
||||
if (!isset($data['source'])) {
|
||||
$data['source'] = $driver->getSource($identifier);
|
||||
}
|
||||
|
||||
return $this->assetRepositoryManager->solveResolutions((array) $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the vcs repositories event.
|
||||
*
|
||||
* @param array $vcsRepositories
|
||||
*/
|
||||
protected function addRepositories(array $vcsRepositories)
|
||||
{
|
||||
if (null !== $this->assetRepositoryManager) {
|
||||
$this->assetRepositoryManager->addRepositories($vcsRepositories);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Package\Loader;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Package\LazyPackageInterface;
|
||||
|
||||
/**
|
||||
* Interface for lazy loader package.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
interface LazyLoaderInterface
|
||||
{
|
||||
/**
|
||||
* Loads the real package.
|
||||
*
|
||||
* @param LazyPackageInterface $package
|
||||
*
|
||||
* @return \Composer\Package\CompletePackageInterface|false
|
||||
*/
|
||||
public function load(LazyPackageInterface $package);
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Package\Version;
|
||||
|
||||
use Composer\Package\Version\VersionParser as BaseVersionParser;
|
||||
|
||||
/**
|
||||
* Lazy loader for asset package.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class VersionParser extends BaseVersionParser
|
||||
{
|
||||
/**
|
||||
* Returns the stability of a version.
|
||||
*
|
||||
* @param string $version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function parseStability($version)
|
||||
{
|
||||
$stability = parent::parseStability($version);
|
||||
|
||||
return false !== strpos($version, '-patch') ? 'dev' : $stability;
|
||||
}
|
||||
}
|
|
@ -1,257 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Repository\Vcs;
|
||||
|
||||
use Composer\Cache;
|
||||
use Composer\Downloader\TransportException;
|
||||
use Composer\Json\JsonFile;
|
||||
use Composer\Repository\Vcs\GitHubDriver as BaseGitHubDriver;
|
||||
use Fxp\Composer\AssetPlugin\Repository\Util as RepoUtil;
|
||||
|
||||
/**
|
||||
* Abstract class for GitHub vcs driver.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
abstract class AbstractGitHubDriver extends BaseGitHubDriver
|
||||
{
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @var string|null|false
|
||||
*/
|
||||
protected $redirectApi;
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
if (!isset($this->repoConfig['no-api'])) {
|
||||
$this->repoConfig['no-api'] = $this->getNoApiOption();
|
||||
}
|
||||
|
||||
parent::initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the no-api repository option.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function getNoApiOption()
|
||||
{
|
||||
$packageName = $this->repoConfig['package-name'];
|
||||
$opts = RepoUtil::getArrayValue($this->repoConfig, 'vcs-driver-options', array());
|
||||
$noApiOpt = RepoUtil::getArrayValue($opts, 'github-no-api', array());
|
||||
$defaultValue = false;
|
||||
|
||||
if (is_bool($noApiOpt)) {
|
||||
$defaultValue = $noApiOpt;
|
||||
$noApiOpt = array();
|
||||
}
|
||||
|
||||
$noApiOpt['default'] = (bool) RepoUtil::getArrayValue($noApiOpt, 'default', $defaultValue);
|
||||
$noApiOpt['packages'] = (array) RepoUtil::getArrayValue($noApiOpt, 'packages', array());
|
||||
|
||||
return (bool) RepoUtil::getArrayValue($noApiOpt['packages'], $packageName, $defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the remote content.
|
||||
*
|
||||
* @param string $url The URL of content
|
||||
* @param bool $fetchingRepoData Fetching the repo data or not
|
||||
*
|
||||
* @return mixed The result
|
||||
*/
|
||||
protected function getContents($url, $fetchingRepoData = false)
|
||||
{
|
||||
$url = $this->getValidContentUrl($url);
|
||||
|
||||
if (null !== $this->redirectApi) {
|
||||
return parent::getContents($url, $fetchingRepoData);
|
||||
}
|
||||
|
||||
try {
|
||||
$contents = $this->getRemoteContents($url);
|
||||
$this->redirectApi = false;
|
||||
|
||||
return $contents;
|
||||
} catch (TransportException $e) {
|
||||
if ($this->hasRedirectUrl($url)) {
|
||||
$url = $this->getValidContentUrl($url);
|
||||
}
|
||||
|
||||
return parent::getContents($url, $fetchingRepoData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url The url
|
||||
*
|
||||
* @return string The url redirected
|
||||
*/
|
||||
protected function getValidContentUrl($url)
|
||||
{
|
||||
if (null === $this->redirectApi && false !== $redirectApi = $this->cache->read('redirect-api')) {
|
||||
$this->redirectApi = $redirectApi;
|
||||
}
|
||||
|
||||
if (is_string($this->redirectApi) && 0 === strpos($url, $this->getRepositoryApiUrl())) {
|
||||
$url = $this->redirectApi.substr($url, strlen($this->getRepositoryApiUrl()));
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the driver must find the new url.
|
||||
*
|
||||
* @param string $url The url
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasRedirectUrl($url)
|
||||
{
|
||||
if (null === $this->redirectApi && 0 === strpos($url, $this->getRepositoryApiUrl())) {
|
||||
$this->redirectApi = $this->getNewRepositoryUrl();
|
||||
|
||||
if (is_string($this->redirectApi)) {
|
||||
$this->cache->write('redirect-api', $this->redirectApi);
|
||||
}
|
||||
}
|
||||
|
||||
return is_string($this->redirectApi);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the new url of repository.
|
||||
*
|
||||
* @return string|false The new url or false if there is not a new url
|
||||
*/
|
||||
protected function getNewRepositoryUrl()
|
||||
{
|
||||
try {
|
||||
$this->getRemoteContents($this->getRepositoryUrl());
|
||||
$headers = $this->remoteFilesystem->getLastHeaders();
|
||||
|
||||
if (!empty($headers[0]) && preg_match('{^HTTP/\S+ (30[1278])}i', $headers[0], $match)) {
|
||||
array_shift($headers);
|
||||
|
||||
return $this->findNewLocationInHeader($headers);
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (\Exception $ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the new url api in the header.
|
||||
*
|
||||
* @param array $headers The http header
|
||||
*
|
||||
* @return string|false
|
||||
*/
|
||||
protected function findNewLocationInHeader(array $headers)
|
||||
{
|
||||
$url = false;
|
||||
|
||||
foreach ($headers as $header) {
|
||||
if (0 === strpos($header, 'Location:')) {
|
||||
$newUrl = trim(substr($header, 9));
|
||||
preg_match('#^(?:(?:https?|git)://([^/]+)/|git@([^:]+):)([^/]+)/(.+?)(?:\.git|/)?$#', $newUrl, $match);
|
||||
$owner = $match[3];
|
||||
$repository = $match[4];
|
||||
$paramPos = strpos($repository, '?');
|
||||
$repository = is_int($paramPos) ? substr($match[4], 0, $paramPos) : $repository;
|
||||
$url = $this->getRepositoryApiUrl($owner, $repository);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the url API of the repository.
|
||||
*
|
||||
* @param string $owner
|
||||
* @param string $repository
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getRepositoryApiUrl($owner = null, $repository = null)
|
||||
{
|
||||
$owner = null !== $owner ? $owner : $this->owner;
|
||||
$repository = null !== $repository ? $repository : $this->repository;
|
||||
|
||||
return $this->getApiUrl().'/repos/'.$owner.'/'.$repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the remote content.
|
||||
*
|
||||
* @param string $url
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
protected function getRemoteContents($url)
|
||||
{
|
||||
return $this->remoteFilesystem->getContents($this->originUrl, $url, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getBranches()
|
||||
{
|
||||
if ($this->gitDriver) {
|
||||
return $this->gitDriver->getBranches();
|
||||
}
|
||||
|
||||
if (null === $this->branches) {
|
||||
$this->branches = array();
|
||||
$resource = $this->getApiUrl().'/repos/'.$this->owner.'/'.$this->repository.'/git/refs/heads?per_page=100';
|
||||
$branchBlacklist = 'gh-pages' === $this->getRootIdentifier() ? array() : array('gh-pages');
|
||||
|
||||
$this->doAddBranches($resource, $branchBlacklist);
|
||||
}
|
||||
|
||||
return $this->branches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Push the list of all branch.
|
||||
*
|
||||
* @param string $resource
|
||||
* @param array $branchBlacklist
|
||||
*/
|
||||
protected function doAddBranches($resource, array $branchBlacklist)
|
||||
{
|
||||
do {
|
||||
$branchData = JsonFile::parseJson((string) $this->getContents($resource), $resource);
|
||||
|
||||
foreach ($branchData as $branch) {
|
||||
$name = substr($branch['ref'], 11);
|
||||
|
||||
if (!in_array($name, $branchBlacklist)) {
|
||||
$this->branches[$name] = $branch['object']['sha'];
|
||||
}
|
||||
}
|
||||
|
||||
$resource = $this->getNextPage();
|
||||
} while ($resource);
|
||||
}
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Repository\Vcs;
|
||||
|
||||
use Composer\Cache;
|
||||
use Composer\Json\JsonFile;
|
||||
use Composer\Repository\Vcs\VcsDriverInterface;
|
||||
|
||||
/**
|
||||
* Helper for bitbucket VCS driver.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class BitbucketUtil
|
||||
{
|
||||
/**
|
||||
* Get composer information.
|
||||
*
|
||||
* @param Cache $cache The cache
|
||||
* @param array $infoCache The code cache
|
||||
* @param string $scheme The scheme
|
||||
* @param array $repoConfig The repository config
|
||||
* @param string $identifier The identifier
|
||||
* @param string $owner The owner of repository
|
||||
* @param string $repository The repository name
|
||||
* @param VcsDriverInterface $driver The vcs driver
|
||||
* @param string $method The method of vcs driver for get contents
|
||||
*
|
||||
* @return array The composer
|
||||
*/
|
||||
public static function getComposerInformation(Cache $cache, array &$infoCache, $scheme,
|
||||
array $repoConfig, $identifier, $owner, $repository, VcsDriverInterface $driver, $method = 'getContents')
|
||||
{
|
||||
$infoCache[$identifier] = Util::readCache($infoCache, $cache, $repoConfig['asset-type'], $identifier);
|
||||
|
||||
if (!isset($infoCache[$identifier])) {
|
||||
$resource = static::getUrlResource($scheme, $repoConfig, $identifier, $owner, $repository, $driver);
|
||||
$composer = static::getComposerContent($resource, $identifier, $scheme, $owner, $repository, $driver, $method);
|
||||
|
||||
Util::writeCache($cache, $repoConfig['asset-type'], $identifier, $composer);
|
||||
$infoCache[$identifier] = $composer;
|
||||
}
|
||||
|
||||
return $infoCache[$identifier];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the url of resource.
|
||||
*
|
||||
* @param string $scheme The scheme
|
||||
* @param array $repoConfig The repository config
|
||||
* @param string $identifier The identifier
|
||||
* @param string $owner The owner of repository
|
||||
* @param string $repository The repository name
|
||||
* @param VcsDriverInterface $driver The vcs driver
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getUrlResource($scheme, array $repoConfig, $identifier, $owner, $repository,
|
||||
VcsDriverInterface $driver)
|
||||
{
|
||||
if (false === strpos(get_class($driver), 'Git')) {
|
||||
return $scheme.'://bitbucket.org/'.$owner.'/'.$repository.'/raw/'.$identifier.'/'.$repoConfig['filename'];
|
||||
}
|
||||
|
||||
return $scheme.'://api.bitbucket.org/1.0/repositories/'.$owner.'/'.$repository.'/src/'.$identifier.'/'.$repoConfig['filename'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets content of composer information.
|
||||
*
|
||||
* @param string $resource The resource
|
||||
* @param string $identifier The identifier
|
||||
* @param string $scheme The scheme
|
||||
* @param string $owner The owner
|
||||
* @param string $repository The repository
|
||||
* @param VcsDriverInterface $driver The vcs driver
|
||||
* @param string $method The method for get content
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function getComposerContent($resource, $identifier, $scheme, $owner, $repository,
|
||||
VcsDriverInterface $driver, $method)
|
||||
{
|
||||
$composer = static::getComposerContentOfFile($resource, $driver, $method);
|
||||
|
||||
if (false !== $composer) {
|
||||
$composer = (array) JsonFile::parseJson((string) $composer, $resource);
|
||||
$composer = static::formatComposerContent($composer, $identifier, $scheme, $owner, $repository, $driver, $method);
|
||||
|
||||
return $composer;
|
||||
}
|
||||
|
||||
return array('_nonexistent_package' => true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parsed content of composer.
|
||||
*
|
||||
* @param string $resource The resource
|
||||
* @param VcsDriverInterface $driver The vcs driver
|
||||
* @param string $method The method for get content
|
||||
*
|
||||
* @return string|false
|
||||
*/
|
||||
protected static function getComposerContentOfFile($resource, VcsDriverInterface $driver, $method)
|
||||
{
|
||||
try {
|
||||
$ref = new \ReflectionClass($driver);
|
||||
$meth = $ref->getMethod($method);
|
||||
$meth->setAccessible(true);
|
||||
$composer = $meth->invoke($driver, $resource);
|
||||
|
||||
if ($method !== 'getContents') {
|
||||
$file = (array) JsonFile::parseJson((string) $composer, $resource);
|
||||
$composer = empty($file) || !array_key_exists('data', $file)
|
||||
? false : $file['data'];
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$composer = false;
|
||||
}
|
||||
|
||||
return $composer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format composer content.
|
||||
*
|
||||
* @param array $composer The composer
|
||||
* @param string $identifier The identifier
|
||||
* @param string $scheme The scheme
|
||||
* @param string $owner The owner
|
||||
* @param string $repository The repository
|
||||
* @param VcsDriverInterface $driver The vcs driver
|
||||
* @param string $method The method for get content
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function formatComposerContent(array $composer, $identifier, $scheme, $owner, $repository, $driver, $method)
|
||||
{
|
||||
$resource = $scheme.'://api.bitbucket.org/1.0/repositories/'.$owner.'/'.$repository.'/changesets/'.$identifier;
|
||||
$composer = Util::addComposerTime($composer, 'timestamp', $resource, $driver, $method);
|
||||
|
||||
return $composer;
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Repository\Vcs;
|
||||
|
||||
use Composer\Cache;
|
||||
use Composer\Repository\Vcs\GitBitbucketDriver as BaseGitBitbucketDriver;
|
||||
|
||||
/**
|
||||
* Git Bitbucket vcs driver.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class GitBitbucketDriver extends BaseGitBitbucketDriver
|
||||
{
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
$this->cache = new Cache($this->io, $this->config->get('cache-repo-dir').'/'.$this->originUrl.'/'.$this->owner.'/'.$this->repository);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getComposerInformation($identifier)
|
||||
{
|
||||
$method = method_exists($this, 'getContentsWithOAuthCredentials') ? 'getContentsWithOAuthCredentials' : 'getContents';
|
||||
|
||||
return BitbucketUtil::getComposerInformation($this->cache, $this->infoCache, $this->getScheme(), $this->repoConfig, $identifier, $this->owner, $this->repository, $this, $method);
|
||||
}
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Repository\Vcs;
|
||||
|
||||
use Composer\Cache;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Repository\Vcs\GitDriver as BaseGitDriver;
|
||||
use Composer\Util\Filesystem;
|
||||
use Composer\Util\Git as GitUtil;
|
||||
use Fxp\Composer\AssetPlugin\Repository\AssetRepositoryManager;
|
||||
|
||||
/**
|
||||
* Git vcs driver.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class GitDriver extends BaseGitDriver
|
||||
{
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getComposerInformation($identifier)
|
||||
{
|
||||
$resource = sprintf('%s:%s', escapeshellarg($identifier), $this->repoConfig['filename']);
|
||||
|
||||
return ProcessUtil::getComposerInformation($this->cache, $this->infoCache, $this->repoConfig['asset-type'], $this->process, $identifier, $resource, sprintf('git show %s', $resource), sprintf('git log -1 --format=%%at %s', escapeshellarg($identifier)), $this->repoDir, '@');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
/* @var AssetRepositoryManager $arm */
|
||||
$arm = $this->repoConfig['asset-repository-manager'];
|
||||
$skipSync = false;
|
||||
|
||||
if (null !== ($skip = $arm->getConfig()->get('git-skip-update'))) {
|
||||
$localUrl = $this->config->get('cache-vcs-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $this->url).'/';
|
||||
// check if local copy exists and if it is a git repository and that modification time is within threshold
|
||||
if (is_dir($localUrl) && is_file($localUrl.'/config') && filemtime($localUrl) > strtotime('-'.$skip)) {
|
||||
$skipSync = true;
|
||||
$this->io->write('(<comment>skip update</comment>) ', false, IOInterface::VERBOSE);
|
||||
}
|
||||
}
|
||||
|
||||
$cacheUrl = Filesystem::isLocalPath($this->url)
|
||||
? $this->initializeLocalPath() : $this->initializeRemotePath($skipSync);
|
||||
$this->getTags();
|
||||
$this->getBranches();
|
||||
$this->cache = new Cache($this->io, $this->config->get('cache-repo-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $cacheUrl));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the local path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function initializeLocalPath()
|
||||
{
|
||||
$this->url = preg_replace('{[\\/]\.git/?$}', '', $this->url);
|
||||
$this->repoDir = $this->url;
|
||||
|
||||
return realpath($this->url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the remote path.
|
||||
*
|
||||
* @param bool $skipSync Check if sync must be skipped
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function initializeRemotePath($skipSync)
|
||||
{
|
||||
$this->repoDir = $this->config->get('cache-vcs-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $this->url).'/';
|
||||
|
||||
GitUtil::cleanEnv();
|
||||
|
||||
$fs = new Filesystem();
|
||||
$fs->ensureDirectoryExists(dirname($this->repoDir));
|
||||
|
||||
if (!is_writable(dirname($this->repoDir))) {
|
||||
throw new \RuntimeException('Can not clone '.$this->url.' to access package information. The "'.dirname($this->repoDir).'" directory is not writable by the current user.');
|
||||
}
|
||||
|
||||
if (preg_match('{^ssh://[^@]+@[^:]+:[^0-9]+}', $this->url)) {
|
||||
throw new \InvalidArgumentException('The source URL '.$this->url.' is invalid, ssh URLs should have a port number after ":".'."\n".'Use ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.');
|
||||
}
|
||||
|
||||
$gitUtil = new GitUtil($this->io, $this->config, $this->process, $fs);
|
||||
// patched line, sync from local dir without modifying url
|
||||
if (!$skipSync && !$gitUtil->syncMirror($this->url, $this->repoDir)) {
|
||||
$this->io->writeError('<error>Failed to update '.$this->url.', package information from this repository may be outdated</error>');
|
||||
}
|
||||
|
||||
return $this->url;
|
||||
}
|
||||
}
|
|
@ -1,152 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Repository\Vcs;
|
||||
|
||||
use Composer\Downloader\TransportException;
|
||||
use Composer\Json\JsonFile;
|
||||
|
||||
/**
|
||||
* GitHub vcs driver.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class GitHubDriver extends AbstractGitHubDriver
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getComposerInformation($identifier)
|
||||
{
|
||||
if ($this->gitDriver) {
|
||||
return $this->gitDriver->getComposerInformation($identifier);
|
||||
}
|
||||
|
||||
$this->infoCache[$identifier] = Util::readCache($this->infoCache, $this->cache, $this->repoConfig['asset-type'], $identifier);
|
||||
|
||||
if (!isset($this->infoCache[$identifier])) {
|
||||
$resource = $this->getApiUrl().'/repos/'.$this->owner.'/'.$this->repository.'/contents/'.$this->repoConfig['filename'].'?ref='.urlencode($identifier);
|
||||
$composer = $this->getComposerContent($resource);
|
||||
|
||||
if ($composer) {
|
||||
$composer = $this->convertComposerContent($composer, $resource, $identifier);
|
||||
} else {
|
||||
$composer = array('_nonexistent_package' => true);
|
||||
}
|
||||
|
||||
Util::writeCache($this->cache, $this->repoConfig['asset-type'], $identifier, $composer);
|
||||
$this->infoCache[$identifier] = $composer;
|
||||
}
|
||||
|
||||
return $this->infoCache[$identifier];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets content of composer information.
|
||||
*
|
||||
* @param string $resource
|
||||
*
|
||||
* @return null|false|array
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @throws \Composer\Downloader\TransportException
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function getComposerContent($resource)
|
||||
{
|
||||
$notFoundRetries = 2;
|
||||
$composer = null;
|
||||
|
||||
while ($notFoundRetries) {
|
||||
try {
|
||||
$composer = $this->parseComposerContent($resource);
|
||||
break;
|
||||
} catch (TransportException $e) {
|
||||
if (404 !== $e->getCode()) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
// retry fetching if github returns a 404 since they happen randomly
|
||||
--$notFoundRetries;
|
||||
$composer = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $composer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the composer content.
|
||||
*
|
||||
* @param string $resource
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \RuntimeException When the resource could not be retrieved
|
||||
*/
|
||||
protected function parseComposerContent($resource)
|
||||
{
|
||||
$composer = (array) JsonFile::parseJson($this->getContents($resource));
|
||||
if (empty($composer['content']) || $composer['encoding'] !== 'base64' || !($composer = base64_decode($composer['content']))) {
|
||||
throw new \RuntimeException('Could not retrieve '.$this->repoConfig['filename'].' from '.$resource);
|
||||
}
|
||||
|
||||
return $composer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts json composer file to array.
|
||||
*
|
||||
* @param string $composer
|
||||
* @param string $resource
|
||||
* @param string $identifier
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function convertComposerContent($composer, $resource, $identifier)
|
||||
{
|
||||
$composer = JsonFile::parseJson($composer, $resource);
|
||||
$resource = $this->getApiUrl().'/repos/'.$this->owner.'/'.$this->repository.'/commits/'.urlencode($identifier);
|
||||
$composer = Util::addComposerTime($composer, 'commit.committer.date', $resource, $this);
|
||||
|
||||
if (!isset($composer['support']['source'])) {
|
||||
$label = array_search($identifier, $this->getTags()) ?: array_search($identifier, $this->getBranches()) ?: $identifier;
|
||||
$composer['support']['source'] = sprintf('https://%s/%s/%s/tree/%s', $this->originUrl, $this->owner, $this->repository, $label);
|
||||
}
|
||||
if (!isset($composer['support']['issues']) && $this->hasIssues) {
|
||||
$composer['support']['issues'] = sprintf('https://%s/%s/%s/issues', $this->originUrl, $this->owner, $this->repository);
|
||||
}
|
||||
|
||||
return $composer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup git driver.
|
||||
*
|
||||
* @param string $url
|
||||
*/
|
||||
protected function setupGitDriver($url)
|
||||
{
|
||||
$this->gitDriver = new GitDriver(
|
||||
array(
|
||||
'url' => $url,
|
||||
'asset-type' => $this->repoConfig['asset-type'],
|
||||
'filename' => $this->repoConfig['filename'],
|
||||
'asset-repository-manager' => $this->repoConfig['asset-repository-manager'],
|
||||
),
|
||||
$this->io,
|
||||
$this->config,
|
||||
$this->process,
|
||||
$this->remoteFilesystem
|
||||
);
|
||||
$this->gitDriver->initialize();
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Repository\Vcs;
|
||||
|
||||
use Composer\Cache;
|
||||
use Composer\Repository\Vcs\HgBitbucketDriver as BaseHgBitbucketDriver;
|
||||
|
||||
/**
|
||||
* Mercurial Bitbucket Bitbucket vcs driver.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class HgBitbucketDriver extends BaseHgBitbucketDriver
|
||||
{
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
$this->cache = new Cache($this->io, $this->config->get('cache-repo-dir').'/'.$this->originUrl.'/'.$this->owner.'/'.$this->repository);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getComposerInformation($identifier)
|
||||
{
|
||||
return BitbucketUtil::getComposerInformation($this->cache, $this->infoCache, $this->getScheme(), $this->repoConfig, $identifier, $this->owner, $this->repository, $this, 'getContents');
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Repository\Vcs;
|
||||
|
||||
use Composer\Cache;
|
||||
use Composer\Repository\Vcs\HgDriver as BaseHgDriver;
|
||||
use Composer\Util\Filesystem;
|
||||
use Composer\Util\ProcessExecutor;
|
||||
|
||||
/**
|
||||
* Mercurial vcs driver.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class HgDriver extends BaseHgDriver
|
||||
{
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
$cacheUrl = Filesystem::isLocalPath($this->url)
|
||||
? realpath($this->url) : $this->url;
|
||||
|
||||
$this->cache = new Cache($this->io, $this->config->get('cache-repo-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $cacheUrl));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getComposerInformation($identifier)
|
||||
{
|
||||
$resource = sprintf('%s %s', ProcessExecutor::escape($identifier), $this->repoConfig['filename']);
|
||||
|
||||
return ProcessUtil::getComposerInformation($this->cache, $this->infoCache, $this->repoConfig['asset-type'], $this->process, $identifier, $resource, sprintf('hg cat -r %s', $resource), sprintf('hg log --template "{date|rfc3339date}" -r %s', ProcessExecutor::escape($identifier)), $this->repoDir);
|
||||
}
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Repository\Vcs;
|
||||
|
||||
use Composer\Cache;
|
||||
use Composer\Repository\Vcs\PerforceDriver as BasePerforceDriver;
|
||||
use Fxp\Composer\AssetPlugin\Util\Perforce;
|
||||
|
||||
/**
|
||||
* Perforce vcs driver.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class PerforceDriver extends BasePerforceDriver
|
||||
{
|
||||
/**
|
||||
* @var Perforce
|
||||
*/
|
||||
protected $perforce;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $infoCache = array();
|
||||
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
$this->depot = $this->repoConfig['depot'];
|
||||
$this->branch = '';
|
||||
if (!empty($this->repoConfig['branch'])) {
|
||||
$this->branch = $this->repoConfig['branch'];
|
||||
}
|
||||
|
||||
$this->initAssetPerforce($this->repoConfig);
|
||||
$this->perforce->p4Login();
|
||||
$this->perforce->checkStream();
|
||||
|
||||
$this->perforce->writeP4ClientSpec();
|
||||
$this->perforce->connectClient();
|
||||
|
||||
$this->cache = new Cache($this->io, $this->config->get('cache-repo-dir').'/'.$this->originUrl.'/'.$this->depot);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getComposerInformation($identifier)
|
||||
{
|
||||
$this->infoCache[$identifier] = Util::readCache($this->infoCache, $this->cache, $this->repoConfig['asset-type'], $identifier, true);
|
||||
|
||||
if (!isset($this->infoCache[$identifier])) {
|
||||
$composer = $this->getComposerContent($identifier);
|
||||
|
||||
Util::writeCache($this->cache, $this->repoConfig['asset-type'], $identifier, $composer, true);
|
||||
$this->infoCache[$identifier] = $composer;
|
||||
}
|
||||
|
||||
return $this->infoCache[$identifier];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get composer content.
|
||||
*
|
||||
* @param string $identifier
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getComposerContent($identifier)
|
||||
{
|
||||
$composer = $this->perforce->getComposerInformation($identifier);
|
||||
|
||||
if (empty($composer) || !is_array($composer)) {
|
||||
$composer = array('_nonexistent_package' => true);
|
||||
}
|
||||
|
||||
return $composer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $repoConfig
|
||||
*/
|
||||
private function initAssetPerforce($repoConfig)
|
||||
{
|
||||
if (!empty($this->perforce)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$repoDir = $this->config->get('cache-vcs-dir').'/'.$this->depot;
|
||||
$this->perforce = Perforce::create($repoConfig, $this->getUrl(), $repoDir, $this->process, $this->io);
|
||||
}
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Repository\Vcs;
|
||||
|
||||
use Composer\Cache;
|
||||
use Composer\Json\JsonFile;
|
||||
use Composer\Util\ProcessExecutor;
|
||||
|
||||
/**
|
||||
* Helper for process VCS driver.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class ProcessUtil
|
||||
{
|
||||
/**
|
||||
* Get composer information.
|
||||
*
|
||||
* @param Cache $cache
|
||||
* @param array $infoCache
|
||||
* @param string $assetType
|
||||
* @param ProcessExecutor $process
|
||||
* @param string $identifier
|
||||
* @param string $resource
|
||||
* @param string $cmdGet
|
||||
* @param string $cmdLog
|
||||
* @param string $repoDir
|
||||
* @param string $datetimePrefix
|
||||
*
|
||||
* @return array The composer
|
||||
*/
|
||||
public static function getComposerInformation(Cache $cache, array &$infoCache,
|
||||
$assetType, ProcessExecutor $process, $identifier, $resource, $cmdGet,
|
||||
$cmdLog, $repoDir, $datetimePrefix = '')
|
||||
{
|
||||
$infoCache[$identifier] = Util::readCache($infoCache, $cache, $assetType, $identifier);
|
||||
|
||||
if (!isset($infoCache[$identifier])) {
|
||||
$composer = static::doGetComposerInformation($resource, $process, $cmdGet, $cmdLog, $repoDir, $datetimePrefix);
|
||||
|
||||
Util::writeCache($cache, $assetType, $identifier, $composer);
|
||||
$infoCache[$identifier] = $composer;
|
||||
}
|
||||
|
||||
return $infoCache[$identifier];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get composer information.
|
||||
*
|
||||
* @param string $resource
|
||||
* @param ProcessExecutor $process
|
||||
* @param string $cmdGet
|
||||
* @param string $cmdLog
|
||||
* @param string $repoDir
|
||||
* @param string $datetimePrefix
|
||||
*
|
||||
* @return array The composer
|
||||
*/
|
||||
protected static function doGetComposerInformation($resource, ProcessExecutor $process, $cmdGet, $cmdLog, $repoDir, $datetimePrefix = '')
|
||||
{
|
||||
$process->execute($cmdGet, $composer, $repoDir);
|
||||
|
||||
if (!trim($composer)) {
|
||||
return array('_nonexistent_package' => true);
|
||||
}
|
||||
|
||||
$composer = JsonFile::parseJson($composer, $resource);
|
||||
|
||||
return static::addComposerTime($composer, $process, $cmdLog, $repoDir, $datetimePrefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add time in composer.
|
||||
*
|
||||
* @param array $composer
|
||||
* @param ProcessExecutor $process
|
||||
* @param string $cmd
|
||||
* @param string $repoDir
|
||||
* @param string $datetimePrefix
|
||||
*
|
||||
* @return array The composer
|
||||
*/
|
||||
protected static function addComposerTime(array $composer, ProcessExecutor $process, $cmd, $repoDir, $datetimePrefix = '')
|
||||
{
|
||||
if (!isset($composer['time'])) {
|
||||
$process->execute($cmd, $output, $repoDir);
|
||||
$date = new \DateTime($datetimePrefix.trim($output), new \DateTimeZone('UTC'));
|
||||
$composer['time'] = $date->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
return $composer;
|
||||
}
|
||||
}
|
|
@ -1,188 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Repository\Vcs;
|
||||
|
||||
use Composer\Config;
|
||||
use Composer\Downloader\TransportException;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Json\JsonFile;
|
||||
use Composer\Repository\Vcs\SvnDriver as BaseSvnDriver;
|
||||
|
||||
/**
|
||||
* SVN vcs driver.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class SvnDriver extends BaseSvnDriver
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
$this->url = 0 === strpos($this->url, 'svn+http')
|
||||
? substr($this->url, 4)
|
||||
: $this->url;
|
||||
|
||||
parent::initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getComposerInformation($identifier)
|
||||
{
|
||||
$identifier = '/'.trim($identifier, '/').'/';
|
||||
$this->infoCache[$identifier] = Util::readCache($this->infoCache, $this->cache, $this->repoConfig['asset-type'], trim($identifier, '/'), true);
|
||||
|
||||
if (!isset($this->infoCache[$identifier])) {
|
||||
list($path, $rev) = $this->getPathRev($identifier);
|
||||
$resource = $path.$this->repoConfig['filename'];
|
||||
$output = $this->getComposerContent($resource, $rev);
|
||||
$composer = $this->parseComposerContent($output, $resource, $path, $rev);
|
||||
|
||||
Util::writeCache($this->cache, $this->repoConfig['asset-type'], trim($identifier, '/'), $composer, true);
|
||||
$this->infoCache[$identifier] = $composer;
|
||||
}
|
||||
|
||||
return $this->infoCache[$identifier];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get path and rev.
|
||||
*
|
||||
* @param string $identifier The identifier
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getPathRev($identifier)
|
||||
{
|
||||
$path = $identifier;
|
||||
$rev = '';
|
||||
|
||||
preg_match('{^(.+?)(@\d+)?/$}', $identifier, $match);
|
||||
|
||||
if (!empty($match[2])) {
|
||||
$path = $match[1];
|
||||
$rev = $match[2];
|
||||
}
|
||||
|
||||
return array($path, $rev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the composer content.
|
||||
*
|
||||
* @param string $resource The resource
|
||||
* @param string $rev The rev
|
||||
*
|
||||
* @return null|string The composer content
|
||||
*
|
||||
* @throws TransportException
|
||||
*/
|
||||
protected function getComposerContent($resource, $rev)
|
||||
{
|
||||
$output = null;
|
||||
|
||||
try {
|
||||
$output = $this->execute($this->getSvnCredetials('svn cat'), $this->baseUrl.$resource.$rev);
|
||||
} catch (\RuntimeException $e) {
|
||||
throw new TransportException($e->getMessage());
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the content of composer.
|
||||
*
|
||||
* @param string|null $output The output of process executor
|
||||
* @param string $resource The resouce
|
||||
* @param string $path The path
|
||||
* @param string $rev The rev
|
||||
*
|
||||
* @return array The composer
|
||||
*/
|
||||
protected function parseComposerContent($output, $resource, $path, $rev)
|
||||
{
|
||||
if (!trim($output)) {
|
||||
return array('_nonexistent_package' => true);
|
||||
}
|
||||
|
||||
$composer = (array) JsonFile::parseJson($output, $this->baseUrl.$resource.$rev);
|
||||
|
||||
return $this->addComposerTime($composer, $path, $rev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add time in composer.
|
||||
*
|
||||
* @param array $composer The composer
|
||||
* @param string $path The path
|
||||
* @param string $rev The rev
|
||||
*
|
||||
* @return array The composer
|
||||
*/
|
||||
protected function addComposerTime(array $composer, $path, $rev)
|
||||
{
|
||||
if (!isset($composer['time'])) {
|
||||
$output = $this->execute($this->getSvnCredetials('svn info'), $this->baseUrl.$path.$rev);
|
||||
|
||||
foreach ($this->process->splitLines($output) as $line) {
|
||||
if ($line && preg_match('{^Last Changed Date: ([^(]+)}', $line, $match)) {
|
||||
$date = new \DateTime($match[1], new \DateTimeZone('UTC'));
|
||||
$composer['time'] = $date->format('Y-m-d H:i:s');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $composer;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function supports(IOInterface $io, Config $config, $url, $deep = false)
|
||||
{
|
||||
if (0 === strpos($url, 'http') && preg_match('/\/svn|svn\//i', $url)) {
|
||||
$url = 'svn'.substr($url, strpos($url, '://'));
|
||||
}
|
||||
|
||||
return parent::supports($io, $config, $url, $deep);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the credentials of SVN.
|
||||
*
|
||||
* @param string $command The command
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getSvnCredetials($command)
|
||||
{
|
||||
$httpBasic = $this->config->get('http-basic');
|
||||
$parsedUrl = parse_url($this->baseUrl);
|
||||
$svnCommand = $command;
|
||||
|
||||
if ($parsedUrl && isset($httpBasic[$parsedUrl['host']])) {
|
||||
if ($httpBasic[$parsedUrl['host']]['username'] && $httpBasic[$parsedUrl['host']]['password']) {
|
||||
$uname = $httpBasic[$parsedUrl['host']]['username'];
|
||||
$pw = $httpBasic[$parsedUrl['host']]['password'];
|
||||
|
||||
$svnCommand = $command.sprintf(' --username %s --password %s --no-auth-cache', $uname, $pw);
|
||||
}
|
||||
}
|
||||
|
||||
return $svnCommand;
|
||||
}
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Repository\Vcs;
|
||||
|
||||
use Composer\Cache;
|
||||
use Composer\Json\JsonFile;
|
||||
use Composer\Repository\Vcs\VcsDriverInterface;
|
||||
|
||||
/**
|
||||
* Helper for VCS driver.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class Util
|
||||
{
|
||||
/**
|
||||
* Check if the identifier is an SHA.
|
||||
*
|
||||
* @param string $identifier The identifier
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isSha($identifier)
|
||||
{
|
||||
return (bool) preg_match('{[a-f0-9]{40}}i', $identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $cacheCode The cache code
|
||||
* @param Cache $cache The cache filesystem
|
||||
* @param string $type The asset type
|
||||
* @param string $identifier The identifier
|
||||
* @param bool $force Force the read
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public static function readCache(array $cacheCode, Cache $cache, $type, $identifier, $force = false)
|
||||
{
|
||||
if (array_key_exists($identifier, $cacheCode)) {
|
||||
return $cacheCode[$identifier];
|
||||
}
|
||||
|
||||
$data = null;
|
||||
if (self::isSha($identifier) || $force) {
|
||||
$res = $cache->read($type.'-'.$identifier);
|
||||
|
||||
if ($res) {
|
||||
$data = JsonFile::parseJson($res);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Cache $cache The cache
|
||||
* @param string $type The asset type
|
||||
* @param string $identifier The identifier
|
||||
* @param array $composer The data composer
|
||||
* @param bool $force Force the write
|
||||
*/
|
||||
public static function writeCache(Cache $cache, $type, $identifier, array $composer, $force = false)
|
||||
{
|
||||
if (self::isSha($identifier) || $force) {
|
||||
$cache->write($type.'-'.$identifier, json_encode($composer));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add time in composer.
|
||||
*
|
||||
* @param array $composer The composer
|
||||
* @param string $resourceKey The composer key
|
||||
* @param string $resource The resource url
|
||||
* @param VcsDriverInterface $driver The vcs driver
|
||||
* @param string $method The method for get content
|
||||
*
|
||||
* @return array The composer
|
||||
*/
|
||||
public static function addComposerTime(array $composer, $resourceKey, $resource, VcsDriverInterface $driver, $method = 'getContents')
|
||||
{
|
||||
if (!isset($composer['time'])) {
|
||||
$ref = new \ReflectionClass($driver);
|
||||
$meth = $ref->getMethod($method);
|
||||
$meth->setAccessible(true);
|
||||
|
||||
$commit = JsonFile::parseJson($meth->invoke($driver, $resource), $resource);
|
||||
$keys = explode('.', $resourceKey);
|
||||
|
||||
while (!empty($keys)) {
|
||||
$commit = $commit[$keys[0]];
|
||||
array_shift($keys);
|
||||
}
|
||||
|
||||
$composer['time'] = $commit;
|
||||
}
|
||||
|
||||
return $composer;
|
||||
}
|
||||
}
|
|
@ -1,164 +0,0 @@
|
|||
FAQs
|
||||
====
|
||||
|
||||
What version required of Composer?
|
||||
----------------------------------
|
||||
|
||||
See the documentation: [Installation](index.md#installation).
|
||||
|
||||
How does the plugin work?
|
||||
-------------------------
|
||||
|
||||
To add dependencies of asset in Composer, the plugin uses the VCS repositories to add
|
||||
each repository of a required asset.
|
||||
|
||||
However, to retrieve the repository of an asset automatically, the plugin needs to add
|
||||
a Composer 'Repository' operating in the same way than the 'Packagist' registry, but
|
||||
dedicated to the NPM and Bower registries. Of course, it’s still possible to
|
||||
add an asset’s VCS repository manually.
|
||||
|
||||
Once the VCS repository is selected, Composer downloads the package definition of the
|
||||
main branch, together with the list of branches and tags. Of course, a conversion of
|
||||
NPM or Bower package definitions is made. Note that the definitions of each package will
|
||||
be taken at the time Composer needs it (in the Solver).
|
||||
|
||||
This way, the plugin makes it possible to add a VCS repository by simulating the presence
|
||||
of the `composer.json` file, and there is no need to add this file manually if the
|
||||
package is registered in the registry of NPM or Bower, and if the file `bower.json` or
|
||||
`package.json` is present in the repository.
|
||||
|
||||
Why does the plugin use the VCS repository?
|
||||
-------------------------------------------
|
||||
|
||||
There are already several possibilities for managing assets in a PHP project:
|
||||
|
||||
1. Install Node.js and use NPM or Bower command line in addition to Composer command line
|
||||
2. Do #1, but add Composer scripts to automate the process
|
||||
3. Include assets directly in the project (not recommended)
|
||||
4. Create a repository with all assets and include the `composer.json` file (and use
|
||||
Packagist or an VCS repository)
|
||||
5. Add a package repository in `composer.json` with a direct download link
|
||||
6. Create a Satis or Packagist server
|
||||
7. And possibly other creative options
|
||||
|
||||
In the case of a complete project in PHP, it shouldn't be necessary to use several tools
|
||||
(PHP, Nodejs, Composer, NPM, Bower, Grunt, etc.) to simply install these assets in your
|
||||
project. This eliminates the possibilities 1, 2 and 3.
|
||||
|
||||
Solution 6 is unfortunately not feasible, because it would regularly collect all
|
||||
packages in the registries of NPM and Bower, then analyze each and every branch and
|
||||
every tag of each package. The packages would not be updated immediately, and the
|
||||
requests limit of API would be reached very quickly.
|
||||
|
||||
The solutions 4 and 5 are standard in Composer, but they are very onerous to manage. The
|
||||
plugin allows exactly opting for this solution, while sorely simplifying these solutions.
|
||||
|
||||
Why is Composer slow when the plugin retrieves the package definitions?
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
For the VCS repositories, the native system of Composer retrieves the package definitions
|
||||
for all branches and all tags. If these are numerous, it may become very slow. However,
|
||||
the plugin uses a caching system, allowing to not make new requests to retrieve the
|
||||
definitions of packages. The next commands install/update will be much faster.
|
||||
|
||||
The performance to get the new package definitions could be even higher, but this requires
|
||||
a change directly into Composer ([see composer/composer#3282](https://github.com/composer/composer/issues/3282)).
|
||||
|
||||
Why are the definitions from multiple versions of package retrieved to install?
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
For the `install`, the Solver must verify that each version available answer all project
|
||||
constraints.
|
||||
|
||||
Therefore, if constraints of version are 'flexible', then the Solver must retrieve the
|
||||
definitions of package for each version who answer the constraint.
|
||||
|
||||
So, more you specify the version, less Composer will try to retrieve the definitions
|
||||
of package.
|
||||
|
||||
Why are all the versions definitions retrieved for all packages to update?
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
For the `update`, The Solver must obtain all of the definitions for each package and for
|
||||
all available versions.
|
||||
|
||||
The plugin uses the system of VCS repository, and this can significantly slow the
|
||||
retrieving of the definitions of packages. Fortunately, a caching system avoids to
|
||||
download every time all versions.
|
||||
|
||||
With the version `>1.0.0-beta3` of the plugin, a new import filter lets you import only
|
||||
package definitions greater than or equal to the installed versions. In this way, the
|
||||
performances are dramatically improved.
|
||||
|
||||
Composer throws an exception stating that the version does not exist
|
||||
--------------------------------------------------------------------
|
||||
|
||||
If Composer throws an exception stating that the version does not exist, whereas the
|
||||
version exists, but it isn't imported, it means that this new package version is lesser than
|
||||
the installed version.
|
||||
|
||||
Of course, 3 solutions can work around the problem:
|
||||
|
||||
1. delete the `vendor` directory, do the `update`
|
||||
2. disable temporarily the import filter in the `config` section
|
||||
3. add the dependency in the root Composer package:
|
||||
- add the dependency in the root Composer package with the required version (the version not found)
|
||||
- put the option `config.fxp-asset.optimize-with-conjunctive` to `false`,
|
||||
- do the `update`,
|
||||
- remove the dependency in the root Composer package
|
||||
- remove the option `config.fxp-asset.optimize-with-conjunctive`
|
||||
- do the `update` to sync the lock file,
|
||||
|
||||
> The solution 1 is the easiest and fastest.
|
||||
|
||||
See the documentation: [Disable the import filter using the installed packages](index.md#disable-the-import-filter-using-the-installed-packages)
|
||||
|
||||
How to reduce the number of requests for getting the package definitions?
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
For the `install`, the more you specify the versions in your dependencies, less Composer will
|
||||
try to retrieve the definitions of the packages.
|
||||
|
||||
For the `update`, in contrast, this is unfortunately not the case, because Composer must
|
||||
retrieve all the definitions of the packages.
|
||||
|
||||
But a trick allows to filter the import of package definitions to the `install`, but also
|
||||
for the `update`:
|
||||
|
||||
Add directly to your root Composer package, the dependencies that you want to filter. Of
|
||||
course, all constraints of versions are functional (exact version, range, wildcard, tilde
|
||||
operator). In this way, all versions are not accepted by the constraint of version and
|
||||
they will be skipped to the importation, and will not be injected in the `Pool`.
|
||||
|
||||
See the documentation: [Reduce the number of requests for getting the package definitions](index.md#reduce-the-number-of-requests-for-getting-the-package-definitions)
|
||||
|
||||
How to increase the PHP memory limit?
|
||||
-------------------------------------
|
||||
|
||||
See the official documentation of Composer: [Memory limits errors](https://getcomposer.org/doc/articles/troubleshooting.md#memory-limit-errors).
|
||||
|
||||
Why should I create a token for Github?
|
||||
---------------------------------------
|
||||
|
||||
It's a rate limit of Github API. In anonymous access, Github at a greatly reduced limit
|
||||
(60/hr), and you must be logged with a token for have a much higher limit (5 000/hr).
|
||||
|
||||
The problem also exists using Nodejs NPM and Bower.
|
||||
|
||||
If you want more details: [Github Personal API Tokens]
|
||||
(https://github.com/blog/1509-personal-api-tokens)
|
||||
|
||||
See the official documentation of Composer: [API rate limit and OAuth tokens](https://getcomposer.org/doc/articles/troubleshooting.md#api-rate-limit-and-oauth-tokens).
|
||||
|
||||
How to add a Github token in the configuration?
|
||||
-----------------------------------------------
|
||||
|
||||
See the official documentation of Composer: [API rate limit and OAuth tokens](https://getcomposer.org/doc/articles/troubleshooting.md#api-rate-limit-and-oauth-tokens).
|
||||
|
||||
Why the asset VCS repositories are placed in the 'config' section?
|
||||
------------------------------------------------------------------
|
||||
|
||||
Because it's impossible to create the custom VCS repositories: Composer checks the type
|
||||
of VCS repository before the loading of plugins, so, an exception is thrown.
|
||||
|
||||
The only way, is to put the config in `config` section (see the [doc](https://github.com/fxpio/composer-asset-plugin/blob/master/Resources/doc/schema.md#configfxp-assetrepositories-root-only)).
|
|
@ -1,657 +0,0 @@
|
|||
Basic Usage
|
||||
===========
|
||||
|
||||
1. [Installation](index.md)
|
||||
2. [Composer Schema of Asset](schema.md)
|
||||
3. [FAQs](faqs.md)
|
||||
|
||||
## Installation
|
||||
|
||||
See the [Release Notes](https://github.com/fxpio/composer-asset-plugin/releases)
|
||||
to know the Composer version required.
|
||||
|
||||
### Global scope (per user) installation
|
||||
|
||||
```shell
|
||||
$ composer global require "fxp/composer-asset-plugin:~1.3"
|
||||
```
|
||||
|
||||
### Project scope installation
|
||||
|
||||
The installation in the project scope is not supported (see the
|
||||
[issue #7](https://github.com/fxpio/composer-asset-plugin/issues/7)).
|
||||
|
||||
## Usage
|
||||
|
||||
### Usage with asset repository
|
||||
|
||||
Adding a dependency on an asset, you must add the asset to the property
|
||||
`require` of the `composer.json` of your project.
|
||||
|
||||
It must be prefixed with `{asset-type}-asset/`.
|
||||
|
||||
**Example for twitter bootstrap:**
|
||||
|
||||
```json
|
||||
{
|
||||
"require": {
|
||||
"npm-asset/bootstrap": "dev-master"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**or:**
|
||||
|
||||
```json
|
||||
{
|
||||
"require": {
|
||||
"bower-asset/bootstrap": "dev-master"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Usage with Private Bower Registry
|
||||
|
||||
You can work with your private Bower server build with
|
||||
[Hacklone Private Bower](https://github.com/Hacklone/private-bower):
|
||||
|
||||
Adding the URL to your Private Bower Server in the `composer.json` in the section `config`. This
|
||||
Asset Plugin automaticly look if there is a private Bower URL defined and search for your Private
|
||||
Bower Package.
|
||||
|
||||
**Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"private-bower-registries": {
|
||||
"<YourPrivateBowerRegistryServerName>": "https://<YourPrivateBowerRegistryServerURL>/packages"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Usage with VCS repository
|
||||
|
||||
If your asset is not listed on the NPM- or Bower-Repository, or it is a private package, you can
|
||||
create a VCS repository for it. The repository must have an asset package file for NPM (`package.json`)
|
||||
or Bower (`bower.json`).
|
||||
|
||||
In addition, the repository must respect the specifications of [Bower Spec]
|
||||
(https://github.com/bower/bower.json-spec) or [NPM Spec](https://docs.npmjs.com/files/package.json)
|
||||
for the package files. Concerning the version numbers and the tags, they must respect the [Semver 2.0]
|
||||
(http://semver.org/) format.
|
||||
|
||||
If your repository does not contain a tag that repsent the number, you must put the flag `@dev` or directly
|
||||
use the development branch `dev-master`.
|
||||
|
||||
**Example:**
|
||||
|
||||
Add the following to your `composer.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"repositories": [
|
||||
{
|
||||
"type": "bower-vcs",
|
||||
"url": "https://github.com/vendor/exemple-asset-name.git"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Availables drivers:**
|
||||
|
||||
| Drivers | NPM | Bower |
|
||||
|---------------------|---------------------|-----------------------|
|
||||
| **auto** | `npm-vcs` | `bower-vcs` |
|
||||
| Git | `npm-git` | `bower-git` |
|
||||
| GitHub | `npm-github` | `bower-github` |
|
||||
| Git Bitbucket | `npm-git-bitbucket` | `bower-git-bitbucket` |
|
||||
| Mercurial | `npm-hg` | `bower-hg` |
|
||||
| Mercurial Bitbucket | `npm-hg-bitbucket` | `bower-hg-bitbucket` |
|
||||
| SVN | `npm-svn` | `bower-svn` |
|
||||
| Perforce | `npm-perforce` | `bower-perforce` |
|
||||
|
||||
### Overriding the config of a VCS Repository
|
||||
|
||||
If you must use a repository other than that indicated by the registry of NPM or Bower,
|
||||
you must specify the name of the package with the asset prefix in the config of the VCS
|
||||
Repository.
|
||||
|
||||
**Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"repositories": [
|
||||
{
|
||||
"type": "bower-vcs",
|
||||
"url": "https://github.com/vendor/exemple-asset-name.git",
|
||||
"name": "bower-asset/exemple-asset-name"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can also use the standard format of Composer for naming your VCS Repository:
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"repositories": {
|
||||
"bower-asset/exemple-asset-name": {
|
||||
"type": "bower-vcs",
|
||||
"url": "https://github.com/vendor/exemple-asset-name.git"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Usage with multiple versions of the same dependency
|
||||
|
||||
If you need to use multiple versions of the same asset, you can do this by
|
||||
simply adding a version number after the package name, separated with the "-"
|
||||
character.
|
||||
|
||||
**Example with Jquery:**
|
||||
|
||||
```json
|
||||
{
|
||||
"require": {
|
||||
"bower-asset/jquery": "1.11.*",
|
||||
"bower-asset/jquery-2.0.x": "2.0.x",
|
||||
"bower-asset/jquery-2.1.0": "2.1.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The dependencies will then be placed in the following directories:
|
||||
|
||||
- `vendor/bower-asset/jquery` for `1.11.*`
|
||||
- `vendor/bower-asset/jquery-2.0.x` for `2.0.x`
|
||||
- `vendor/bower-asset/jquery-2.1.0` for `2.1.0`
|
||||
|
||||
### Reduce the number of requests for getting the package definitions
|
||||
|
||||
The root Composer package has a feature: all asset dependencies added will have automatically
|
||||
a filter applied, before the importation of the branches and the tags.
|
||||
|
||||
In this way, all versions are not accepted by the constraint of version and they will be
|
||||
skipped to the importation, and will not be injected in the `Pool`. Of course, all constraints
|
||||
of versions are functional (exact version, range, wildcard, tilde operator).
|
||||
|
||||
**For example:**
|
||||
|
||||
The root `composer.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"minimum-stability": "dev",
|
||||
"require": {
|
||||
"npm-asset/example-asset1": ">=1.0@stable",
|
||||
"npm-asset/example-asset2": ">=2.3@RC",
|
||||
"npm-asset/example-asset3": ">=1.3@beta",
|
||||
"npm-asset/example-asset4": "~0.9@alpha",
|
||||
"npm-asset/example-asset4": "2.1.*",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In case you have an dependency that that requires a sub asset dependency, and given that this
|
||||
optimization cannot be performed with the sub dependencies, you can add this asset dependency
|
||||
directly to the root Composer package, in the same way that if you wanted to use a
|
||||
well-defined version of this dependency.
|
||||
|
||||
### Disable the import filter using the installed packages
|
||||
|
||||
By default, and for dramatically optimize performance for the `update`, the plugin filters the
|
||||
imports of definitions packages. In addition to filter with the dependencies in the root
|
||||
Composer package, the plugin filters the imports of packages definitions with the previous
|
||||
versions of the packages installed.
|
||||
|
||||
However it may happen that Composer throws an exception, indicating that it can not find a
|
||||
compatible version. This happens if a dependency uses a new version lower than the installed
|
||||
version.
|
||||
|
||||
Of course, several solutions can work around the problem (see the [FAQs]
|
||||
(faqs.md#composer-throws-an-exception-stating-that-the-version-does-not-exist)), but the
|
||||
solution below may be used in another use case.
|
||||
|
||||
You can disable the import filter using the versions of installed packages with the option
|
||||
`config.fxp-asset.optimize-with-installed-packages` in the root Composer package:
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"optimize-with-installed-packages": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Change/Disable the skip of versions by pattern
|
||||
|
||||
By default, the plugin does not import the `patch` versions for increase dramatically
|
||||
performance. However, it is possible to change the pattern or to disable this feature.
|
||||
|
||||
**Example for change the pattern:**
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"pattern-skip-version": "(-build)"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Example for disable the pattern:**
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"pattern-skip-version": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Disable the conjunctive option of the import filter
|
||||
|
||||
You can disable the `conjunctive` mode of the import filter with the option
|
||||
`config.fxp-asset.optimize-with-conjunctive` in the root Composer package:
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"optimize-with-conjunctive": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **Note:**
|
||||
>
|
||||
> This option is used only if the optimization with the installed packages is enabled
|
||||
|
||||
### Define a custom directory for the assets installation
|
||||
|
||||
By default, the plugin will install all the assets in the directory
|
||||
`vendors/{asset-type}-asset` and packages will be installed in each folder with
|
||||
their asset name.
|
||||
|
||||
But you can change the installation directory of the assets directly in the root
|
||||
`composer.json`-file of your project:
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"installer-paths": {
|
||||
"npm-asset-library": "web/assets/vendor",
|
||||
"bower-asset-library": "web/assets/vendor"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **Note:**
|
||||
>
|
||||
> For Bower, all files defined in the section `ignore` will not be installed
|
||||
|
||||
### Disable or replace the deleting of the ignore files for Bower
|
||||
|
||||
For Bower, all files defined in the section `ignore` will be delete just after the
|
||||
installation of each package. Of course, this behavior can be disabled or replaced.
|
||||
|
||||
**Example for disable the list of ignored files:**
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"ignore-files": {
|
||||
"bower-asset/example-asset1": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Example for replace the list of ignored files:**
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"ignore-files": {
|
||||
"bower-asset/example-asset1": [
|
||||
".*",
|
||||
"*.md",
|
||||
"test"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Enable manually the deleting of the ignore files for NPM
|
||||
|
||||
For NPM, there is no section `ignore`, but you can manually add the patterns for
|
||||
delete the files:
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"ignore-files": {
|
||||
"npm-asset/example-asset1": [
|
||||
".*",
|
||||
"*.md",
|
||||
"test"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Work with the NPM scopes
|
||||
|
||||
NPM can manage the package with the vendor scopes (`@<vendor>/<dependency-name>`),
|
||||
but Composer has already a namespace for vendors, and this plugin create a virtual
|
||||
vendor for the NPM assets (`npm-asset/`). Futhermore, the `@` character is not
|
||||
managed by Composer for the package name.
|
||||
|
||||
For this reason, the NPM scope `@<vendor>/` is converted into `<vendor>--`.
|
||||
|
||||
NPM package name | Composer package name
|
||||
------------------------------|-----------------------------------------
|
||||
`@<vendor>/<dependency-name>` | `npm-asset/<vendor>--<dependency-name>`
|
||||
|
||||
### Use the Ignore Files Manager in the Composer scripts
|
||||
|
||||
Sometimes you need to clean a package that is not considered an NPM/Bower Asset
|
||||
Package. To do this, you can use the script helper
|
||||
`Fxp\Composer\AssetPlugin\Composer\ScriptHandler::deleteIgnoredFiles` for the
|
||||
`post-package-install` or `post-package-update` script events.
|
||||
|
||||
**Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"post-package-install": [
|
||||
"Fxp\\Composer\\AssetPlugin\\Composer\\ScriptHandler::deleteIgnoredFiles"
|
||||
],
|
||||
"post-package-update": [
|
||||
"Fxp\\Composer\\AssetPlugin\\Composer\\ScriptHandler::deleteIgnoredFiles"
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"ignore-files": {
|
||||
"acme/other-asset": [
|
||||
".*",
|
||||
"*.md",
|
||||
"test"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Override the main files for Bower
|
||||
|
||||
The bower.json specification allows packages to define entry-point files
|
||||
which can later be processed with taskrunners or build scripts. Some Bower
|
||||
plugins like main-bower-files, wiredep and asset-builder have a feature to
|
||||
override the package main files in the project configuration file.
|
||||
|
||||
You can do the same with composer-asset-plugin, just add a section
|
||||
`config.fxp-asset.main-files` in the root project `composer.json` file with the package
|
||||
name and the files you want to mark as main files.
|
||||
|
||||
**Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"main-files": {
|
||||
"acme/other-asset": [
|
||||
"other-asset.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Disable the search for an asset registry
|
||||
|
||||
If you want to disable the search for an asset registry, you can add the
|
||||
option `config.fxp-asset.registry-options.{type}-searchable` in the root project
|
||||
`composer.json`-file.
|
||||
|
||||
**Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"registry-options": {
|
||||
"npm-searchable": false,
|
||||
"bower-searchable": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Use no-api option of VCS Githhub driver
|
||||
|
||||
If you want to use the [no-api](https://getcomposer.org/doc/05-repositories.md#git-alternatives) option
|
||||
for your Github assets, you can add the option `config.fxp-asset.vcs-driver-options.github-no-api` in
|
||||
the root project `composer.json` file. By default, this option is to `false`. The option `config.fxp-asset.pattern-skip-version`
|
||||
can be used to exclude tags via a regular expression.
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"vcs-driver-options": {
|
||||
"github-no-api": true
|
||||
},
|
||||
"pattern-skip-version": "(-build|-patch)"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can further define this option for each package:
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"vcs-driver-options": {
|
||||
"github-no-api": {
|
||||
"default": true,
|
||||
"packages": {
|
||||
"bower-asset/example-asset1": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
With this configuration, all your github packages will use the native Git, except for
|
||||
the `bower-asset/example-asset1` package.
|
||||
|
||||
### Solve the conflicts of asset dependencies
|
||||
|
||||
Bower include a [resolution section](https://jaketrent.com/post/bower-resolutions) to
|
||||
solve the conflicts between 2 same dependencies but with different versions.
|
||||
|
||||
As for NPM, it's possible to install several versions of the same dependency by different
|
||||
dependencies, which is not the case for Bower and Composer. Only the installation of a
|
||||
single version compatible for all dependencies is possible.
|
||||
|
||||
The dependency resolution would force (replace) a version or range version directly in the
|
||||
root Composer package.
|
||||
|
||||
**Example:**
|
||||
```json
|
||||
"name": "foo/bar",
|
||||
"require": {
|
||||
"bower-asset/jquery": "^2.2.0"
|
||||
}
|
||||
```
|
||||
```json
|
||||
"name": "bar/baz",
|
||||
"require": {
|
||||
"bower-asset/jquery": "2.0.*"
|
||||
}
|
||||
```
|
||||
```json
|
||||
"name": "root/package",
|
||||
"require": {
|
||||
"foo/bar": "^1.0.0",
|
||||
"bar/baz": "^1.0.0"
|
||||
}
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"resolutions": {
|
||||
"bower-asset/jquery": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Result, all asset packages with the `bower-asset/jquery` dependency will use the `^3.0.0` range version.
|
||||
|
||||
> **Note:**
|
||||
> Be careful when replacing the version, and check the compatibility before.
|
||||
|
||||
### Define the config for all projects
|
||||
|
||||
You can define each option (`config.fxp-asset.*`) in each project in the `composer.json`
|
||||
file of each project, but you can also set an option for all projects.
|
||||
|
||||
To do this, you simply need to add your options in the Composer global configuration,
|
||||
in the file of your choice:
|
||||
|
||||
- `<COMPOSER_HOME>/composer.json` file
|
||||
- `<COMPOSER_HOME>/config.json` file
|
||||
|
||||
> **Note:**
|
||||
> The `composer global config` command cannot be used, bacause Composer does not accept custom options.
|
||||
> But you can use the command `composer global config -e` to edit the global `composer.json`
|
||||
file with your text editor.
|
||||
|
||||
### Define the config in a environment variable
|
||||
|
||||
You can define each option (`config.fxp-asset.*`) directly in the PHP environment variables. For
|
||||
this, all variables will start with `FXP_ASSET__` and uppercased, and each `-` will replaced by `_`.
|
||||
|
||||
The accepted value types are:
|
||||
|
||||
- string
|
||||
- boolean
|
||||
- integer
|
||||
- JSON array or object
|
||||
|
||||
**Example:**
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"pattern-skip-version": "(-patch)"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Can be overridden by `FXP_ASSET__PATTERN_SKIP_VERSION="(-build)"` environment variable.
|
||||
|
||||
**Example:**
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"vcs-driver-options": {
|
||||
"github-no-api": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Can be overridden by `FXP_ASSET__VCS_DRIVER_OPTIONS='{"github-no-api": true}'` environment variable.
|
||||
|
||||
|
||||
### Config priority order
|
||||
|
||||
The config values are retrieved in priority in:
|
||||
|
||||
1. the environment variables starting with `FXP_ASSET__`
|
||||
2. the project `composer.json` file
|
||||
3. the global `<COMPOSER_HOME>/config.json` file
|
||||
4. the global `<COMPOSER_HOME>/composer.json` file
|
||||
5. the deprecated config `extra.asset-*` of the project `composer.json` file
|
||||
|
||||
### Disable the plugin
|
||||
|
||||
When you working on multiple PHP projects, you do not necessarily need to use the plugin. It's
|
||||
possible to disable the plugin with the `config.fxp-asset.enabled` option with the `false` value.
|
||||
|
||||
For example, you can disable the plugin globally (for all your projects), and enable it only
|
||||
for projects requiring the plugin.
|
||||
|
||||
**Example:**
|
||||
```json
|
||||
// The global <COMPOSER_HOME>/config.json file
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"enabled": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
```json
|
||||
// The project composer.json file
|
||||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **Note:**
|
||||
> If you disable the plugin, and your project require this plugin, Composer will throw an exception indicating that the asset dependencies does not exist.
|
|
@ -1,276 +0,0 @@
|
|||
Composer Schema of Asset
|
||||
========================
|
||||
|
||||
### Properties
|
||||
|
||||
##### requires
|
||||
|
||||
Lists packages required by this package. The package will not be installed unless those requirements
|
||||
can be met.
|
||||
|
||||
##### requires-dev (root-only)
|
||||
|
||||
Lists packages required for developing this package, or running tests, etc. The dev requirements
|
||||
of the root package are installed by default. Both `install` or `update` support the `--no-dev`
|
||||
option that prevents dev dependencies from being installed.
|
||||
|
||||
##### config.fxp-asset.repositories (root-only)
|
||||
|
||||
Because the plugin is installed after the analysis of type repositories, the custom types must
|
||||
be included in a special property in `config` composer.
|
||||
|
||||
Custom package repositories to use.
|
||||
|
||||
By default composer just uses the packagist repository. By specifying
|
||||
repositories you can get packages from elsewhere.
|
||||
|
||||
Repositories are not resolved recursively. You only can add them to your
|
||||
main `composer.json`. Repository declarations of dependencies' composer.json are ignored.
|
||||
|
||||
The following repository types are supported:
|
||||
|
||||
- **npm-vcs**: The version control system repository can fetch packages from git with `package.json`
|
||||
file dedicated to NPM. The `url` property of git source code is required.
|
||||
- **bower-vcs**: The version control system repository can fetch packages from git with `bower.json`
|
||||
file dedicated to Bower. The `url` property of git source code is required.
|
||||
|
||||
##### config.fxp-asset.registry-options (root-only)
|
||||
|
||||
Options available for the asset registers:
|
||||
|
||||
- **npm-searchable** (bool): The search in the NPM registry may be disabled with this option
|
||||
for the search command.
|
||||
- **bower-searchable** (bool): The search in the Bower registry may be disabled with this option
|
||||
for the search command.
|
||||
|
||||
##### config.fxp-asset.main-files (root-only)
|
||||
|
||||
The plugin can override the main file definitions of the Bower packages. To override the file
|
||||
definitions specify the packages and their main file array as name/value pairs. For an example
|
||||
see the [usage informations](index.md#override-the-main-files-for-bower).
|
||||
|
||||
##### config.fxp-asset.git-skip-update (root-only)
|
||||
|
||||
The plugin can skip updating meta-data in git repositories for given amount of time, i.e. `6 hours`, `3 days` or `1 week`.
|
||||
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"git-skip-update": "2 days"
|
||||
}
|
||||
}
|
||||
|
||||
### Mapping asset file to composer package
|
||||
|
||||
##### NPM mapping
|
||||
|
||||
The `package.json` of asset repository is automatically converted to a Complete Package instance with:
|
||||
|
||||
| NPM Package | Composer Package |
|
||||
|----------------------|---------------------------------------|
|
||||
| name | name (`npm-asset/{name}`) |
|
||||
| `npm-asset-library` | type |
|
||||
| description | description |
|
||||
| version | version |
|
||||
| keywords | keywords |
|
||||
| homepage | homepage |
|
||||
| license | license |
|
||||
| author | authors [0] |
|
||||
| contributors | authors [n], merging with `author` |
|
||||
| dependencies | require |
|
||||
| devDependencies | require-dev |
|
||||
| bin | bin |
|
||||
| bugs | extra.npm-asset-bugs |
|
||||
| files | extra.npm-asset-files |
|
||||
| main | extra.npm-asset-main |
|
||||
| man | extra.npm-asset-man |
|
||||
| directories | extra.npm-asset-directories |
|
||||
| repository | extra.npm-asset-repository |
|
||||
| scripts | extra.npm-asset-scripts |
|
||||
| config | extra.npm-asset-config |
|
||||
| bundledDependencies | extra.npm-asset-bundled-dependencies |
|
||||
| optionalDependencies | extra.npm-asset-optional-dependencies |
|
||||
| engines | extra.npm-asset-engines |
|
||||
| engineStrict | extra.npm-asset-engine-strict |
|
||||
| os | extra.npm-asset-os |
|
||||
| cpu | extra.npm-asset-cpu |
|
||||
| preferGlobal | extra.npm-asset-prefer-global |
|
||||
| private | extra.npm-asset-private |
|
||||
| publishConfig | extra.npm-asset-publish-config |
|
||||
| `not used` | time |
|
||||
| `not used` | support |
|
||||
| `not used` | conflict |
|
||||
| `not used` | replace |
|
||||
| `not used` | provide |
|
||||
| `not used` | suggest |
|
||||
| `not used` | autoload |
|
||||
| `not used` | autoload-dev |
|
||||
| `not used` | include-path |
|
||||
| `not used` | target-dir |
|
||||
| `not used` | extra |
|
||||
| `not used` | archive |
|
||||
|
||||
##### Bower mapping
|
||||
|
||||
The `bower.json` of asset repository is automatically converted to a Complete Package instance with:
|
||||
|
||||
| Bower Package | Composer Package |
|
||||
|----------------------|---------------------------------------|
|
||||
| name | name (`bower-asset/{name}`) |
|
||||
| `bower-asset-library`| type |
|
||||
| description | description |
|
||||
| version | version |
|
||||
| keywords | keywords |
|
||||
| license | license |
|
||||
| dependencies | require |
|
||||
| devDependencies | require-dev |
|
||||
| bin | bin |
|
||||
| main | extra.bower-asset-main |
|
||||
| ignore | extra.bower-asset-ignore |
|
||||
| private | extra.bower-asset-private |
|
||||
| `not used` | homepage |
|
||||
| `not used` | time |
|
||||
| `not used` | authors |
|
||||
| `not used` | support |
|
||||
| `not used` | conflict |
|
||||
| `not used` | replace |
|
||||
| `not used` | provide |
|
||||
| `not used` | suggest |
|
||||
| `not used` | autoload |
|
||||
| `not used` | autoload-dev |
|
||||
| `not used` | include-path |
|
||||
| `not used` | target-dir |
|
||||
| `not used` | extra |
|
||||
| `not used` | archive |
|
||||
|
||||
##### Verison conversion
|
||||
|
||||
NPM and Bower use [Semver](http://semver.org) for formatting the versions, which is not
|
||||
the case for Composer. It is therefore necessary to perform a conversion, but it's not
|
||||
perfect because of the differences in operation between Semver and Composer.
|
||||
|
||||
Here are the matches currently validated:
|
||||
|
||||
| Semver version | Composer version |
|
||||
| ---------------- | ---------------- |
|
||||
| 1.2.3 | 1.2.3 |
|
||||
| 20170124.0.0 | 20170124.000000 |
|
||||
| 20170124.1.0 | 20170124.001000 |
|
||||
| 20170124.1.1 | 20170124.001001 |
|
||||
| 20170124.0 | 20170124.000000 |
|
||||
| 20170124.1 | 20170124.001000 |
|
||||
| 20170124 | 20170124 |
|
||||
| 1.2.3alpha | 1.2.3-alpha1 |
|
||||
| 1.2.3-alpha | 1.2.3-alpha1 |
|
||||
| 1.2.3a | 1.2.3-alpha1 |
|
||||
| 1.2.3a1 | 1.2.3-alpha1 |
|
||||
| 1.2.3-a | 1.2.3-alpha1 |
|
||||
| 1.2.3-a1 | 1.2.3-alpha1 |
|
||||
| 1.2.3b | 1.2.3-beta1 |
|
||||
| 1.2.3b1 | 1.2.3-beta1 |
|
||||
| 1.2.3-b | 1.2.3-beta1 |
|
||||
| 1.2.3-b1 | 1.2.3-beta1 |
|
||||
| 1.2.3beta | 1.2.3-beta1 |
|
||||
| 1.2.3-beta | 1.2.3-beta1 |
|
||||
| 1.2.3beta1 | 1.2.3-beta1 |
|
||||
| 1.2.3-beta1 | 1.2.3-beta1 |
|
||||
| 1.2.3rc1 | 1.2.3-RC1 |
|
||||
| 1.2.3-rc1 | 1.2.3-RC1 |
|
||||
| 1.2.3rc2 | 1.2.3-RC2 |
|
||||
| 1.2.3-rc2 | 1.2.3-RC2 |
|
||||
| 1.2.3rc.2 | 1.2.3-RC.2 |
|
||||
| 1.2.3-rc.2 | 1.2.3-RC.2 |
|
||||
| 1.2.3+0 | 1.2.3-patch0 |
|
||||
| 1.2.3-0 | 1.2.3-patch0 |
|
||||
| 1.2.3pre | 1.2.3-beta1 |
|
||||
| 1.2.3-pre | 1.2.3-beta1 |
|
||||
| 1.2.3dev | 1.2.3-dev |
|
||||
| 1.2.3-dev | 1.2.3-dev |
|
||||
| 1.2.3+build2012 | 1.2.3-patch2012 |
|
||||
| 1.2.3-build2012 | 1.2.3-patch2012 |
|
||||
| 1.2.3+build.2012 | 1.2.3-patch.2012 |
|
||||
| 1.2.3-build.2012 | 1.2.3-patch.2012 |
|
||||
| 1.2.3-SNAPSHOT | 1.2.3-dev |
|
||||
| 1.2.3-snapshot | 1.2.3-dev |
|
||||
| latest | default |
|
||||
|
||||
##### Range verison conversion
|
||||
|
||||
NPM and Bower use [Semver](http://semver.org) for formatting the range versions, which is not
|
||||
the case for Composer. It is therefore necessary to perform a conversion, but it's not
|
||||
perfect because of the differences in operation between Semver and Composer.
|
||||
|
||||
Here are the matches currently validated:
|
||||
|
||||
| Semver range version | Composer range version |
|
||||
| -------------------- | ---------------------- |
|
||||
| >1.2.3 | >1.2.3 |
|
||||
| > 1.2.3 | >1.2.3 |
|
||||
| <1.2.3 | <1.2.3 |
|
||||
| < 1.2.3 | <1.2.3 |
|
||||
| >=1.2.3 | >=1.2.3 |
|
||||
| >= 1.2.3 | >=1.2.3 |
|
||||
| <=1.2.3 | <=1.2.3 |
|
||||
| <= 1.2.3 | <=1.2.3 |
|
||||
| ~1.2.3 | ~1.2.3 |
|
||||
| ~ 1.2.3 | ~1.2.3 |
|
||||
| ~1 | ~1 |
|
||||
| ~ 1 | ~1.2.3 |
|
||||
| ^1.2.3 | >=1.2.3,<2.0 |
|
||||
| ^ 1.2.3 | >=1.2.3,<2.0 |
|
||||
| >1.2.3 <2.0 | >1.2.3,<2.0 |
|
||||
| >=1.0 <1.1 `¦¦` >=1.2 | >=1.0,<1.1`¦`>=1.2 |
|
||||
| 1.2.3 - 2.3.4 | >=1.2.3,<=2.3.4 |
|
||||
| 1 - 2 | >=1,<3.0 |
|
||||
|
||||
|
||||
##### URL Range verison conversion
|
||||
|
||||
NPM and Bower can use a URL directly as the version of the dependency, which is not the
|
||||
case for Composer. It is therefore necessary to perform a conversion, but it's not perfect
|
||||
because of the differences in operation between NPM/Bower and Composer.
|
||||
|
||||
| Asset URL version | Composer version |
|
||||
| ----------------- | --------------------------------------------------- |
|
||||
| {URL} | dev-default |
|
||||
| {URL}#1.2.3 | dev-1.2.3 <code>|</code> 1.2.3 (branch or tag) |
|
||||
| {URL}#{branch} | dev-{branch} |
|
||||
| {URL}#{sha} | dev-default#{sha} |
|
||||
|
||||
##### Multiple versions of a depdendency in the same project
|
||||
|
||||
NPM and Bower can add multiple versions of the same dependency, which is not the case for Composer.
|
||||
To overcome this limitation, the plugin adds a VCS repository for each required version, with the
|
||||
name including the version number after the character `-`
|
||||
(`{ASSET-TYPE}-asset/{PACKAGE-NAME}-X.Y.Z`).
|
||||
|
||||
A Vcs repository will be created for each version, and the number of requests is proportional to
|
||||
the number of versions required. However, given that each version of the dependency uses the same
|
||||
URL of the VCS repository, subsequent requests will get the package information directly in the cache.
|
||||
However, a cache of files is created for each version (included in require section) of a same dependency.
|
||||
|
||||
## Asset Repository
|
||||
|
||||
The plugin creates `Composer Repositories` to find and create
|
||||
the VCS repository of the asset defined in the `require` and `require-dev` automatically.
|
||||
|
||||
### NPM Composer Repository
|
||||
|
||||
[NPM Package](https://www.npmjs.org) is the main NPM repository. A NPM Composer repository
|
||||
is basically a package source, i.e. a place where you can get packages from. NPM Package aims to
|
||||
be the central repository that everybody uses. This means that you can automatically `require`
|
||||
any package that is available there.
|
||||
|
||||
If you go to the [NPM website](https://www.npmjs.org), you can browse and search for packages.
|
||||
|
||||
All package names are automatically prefixed with `npm-asset/`.
|
||||
|
||||
### Bower Composer Repository
|
||||
|
||||
[Bower Package](http://bower.io) is the main Bower repository. A Bower Composer repository
|
||||
is basically a package source, i.e. a place where you can get packages from. Bower Package aims to
|
||||
be the central repository that everybody uses. This means that you can automatically `require`
|
||||
any package that is available there.
|
||||
|
||||
If you go to the [Bower website](http://bower.io/search/), you can browse and search for packages.
|
||||
|
||||
All package names are automatically prefixed with `bower-asset/`.
|
|
@ -1,237 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Composer;
|
||||
|
||||
use Composer\Composer;
|
||||
use Composer\DependencyResolver\Operation\InstallOperation;
|
||||
use Composer\DependencyResolver\Operation\OperationInterface;
|
||||
use Composer\DependencyResolver\Operation\UpdateOperation;
|
||||
use Composer\DependencyResolver\PolicyInterface;
|
||||
use Composer\DependencyResolver\Pool;
|
||||
use Composer\DependencyResolver\Request;
|
||||
use Composer\Installer\PackageEvent;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Plugin\PluginManager;
|
||||
use Composer\Repository\CompositeRepository;
|
||||
use Fxp\Composer\AssetPlugin\Composer\ScriptHandler;
|
||||
use Fxp\Composer\AssetPlugin\Config\Config;
|
||||
use Fxp\Composer\AssetPlugin\FxpAssetPlugin;
|
||||
|
||||
/**
|
||||
* Tests for the composer script handler.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class ScriptHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var Composer|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $composer;
|
||||
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var IOInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $io;
|
||||
|
||||
/**
|
||||
* @var OperationInterface|InstallOperation|UpdateOperation|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $operation;
|
||||
|
||||
/**
|
||||
* @var PackageInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $package;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->composer = $this->getMockBuilder('Composer\Composer')->getMock();
|
||||
$this->io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
$this->package = $this->getMockBuilder('Composer\Package\PackageInterface')->getMock();
|
||||
|
||||
$this->config = $this->getMockBuilder('Composer\Config')->getMock();
|
||||
$this->config->expects($this->any())
|
||||
->method('get')
|
||||
->will($this->returnCallback(function ($key) {
|
||||
$val = null;
|
||||
|
||||
switch ($key) {
|
||||
case 'cache-repo-dir':
|
||||
return sys_get_temp_dir().'/composer-test-repo-cache';
|
||||
case 'vendor-dir':
|
||||
return sys_get_temp_dir().'/composer-test/vendor';
|
||||
}
|
||||
|
||||
return $val;
|
||||
}));
|
||||
|
||||
$rootPackage = $this->getMockBuilder('Composer\Package\RootPackageInterface')->getMock();
|
||||
|
||||
$this->composer->expects($this->any())
|
||||
->method('getConfig')
|
||||
->will($this->returnValue($this->config));
|
||||
$this->composer->expects($this->any())
|
||||
->method('getPackage')
|
||||
->will($this->returnValue($rootPackage));
|
||||
|
||||
$plugin = $this->getMockBuilder(FxpAssetPlugin::class)->disableOriginalConstructor()->getMock();
|
||||
$plugin->expects($this->any())
|
||||
->method('getConfig')
|
||||
->willReturn(new Config(array()));
|
||||
|
||||
$pm = $this->getMockBuilder(PluginManager::class)->disableOriginalConstructor()->getMock();
|
||||
$pm->expects($this->any())
|
||||
->method('getPlugins')
|
||||
->willReturn(array($plugin));
|
||||
|
||||
$this->composer->expects($this->any())
|
||||
->method('getPluginManager')
|
||||
->will($this->returnValue($pm));
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->composer = null;
|
||||
$this->io = null;
|
||||
$this->operation = null;
|
||||
$this->package = null;
|
||||
}
|
||||
|
||||
public function getPackageComposerTypes()
|
||||
{
|
||||
return array(
|
||||
array('npm-asset-library'),
|
||||
array('bower-asset-library'),
|
||||
array('library'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPackageComposerTypes
|
||||
*
|
||||
* @param string $composerType
|
||||
*/
|
||||
public function testDeleteIgnoreFiles($composerType)
|
||||
{
|
||||
$this->operation = $this->getMockBuilder('Composer\DependencyResolver\Operation\OperationInterface')->getMock();
|
||||
$this->assertInstanceOf('Composer\DependencyResolver\Operation\OperationInterface', $this->operation);
|
||||
|
||||
ScriptHandler::deleteIgnoredFiles($this->createEvent($composerType));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPackageComposerTypes
|
||||
*
|
||||
* @param string $composerType
|
||||
*/
|
||||
public function testDeleteIgnoreFilesWithInstallOperation($composerType)
|
||||
{
|
||||
$this->operation = $this->getMockBuilder('Composer\DependencyResolver\Operation\InstallOperation')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->assertInstanceOf('Composer\DependencyResolver\Operation\OperationInterface', $this->operation);
|
||||
|
||||
ScriptHandler::deleteIgnoredFiles($this->createEvent($composerType));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPackageComposerTypes
|
||||
*
|
||||
* @param string $composerType
|
||||
*/
|
||||
public function testDeleteIgnoreFilesWithUpdateOperation($composerType)
|
||||
{
|
||||
$this->operation = $this->getMockBuilder('Composer\DependencyResolver\Operation\UpdateOperation')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->assertInstanceOf('Composer\DependencyResolver\Operation\OperationInterface', $this->operation);
|
||||
|
||||
ScriptHandler::deleteIgnoredFiles($this->createEvent($composerType));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getPackageComposerTypes
|
||||
*
|
||||
* @param string $composerType
|
||||
*
|
||||
* @expectedException \RuntimeException
|
||||
* @expectedExceptionMessage The fxp composer asset plugin is not found
|
||||
*/
|
||||
public function testGetConfig($composerType)
|
||||
{
|
||||
$rootPackage = $this->getMockBuilder('Composer\Package\RootPackageInterface')->getMock();
|
||||
|
||||
$this->composer = $this->getMockBuilder('Composer\Composer')->getMock();
|
||||
$this->composer->expects($this->any())
|
||||
->method('getConfig')
|
||||
->will($this->returnValue($this->config));
|
||||
$this->composer->expects($this->any())
|
||||
->method('getPackage')
|
||||
->will($this->returnValue($rootPackage));
|
||||
|
||||
$pm = $this->getMockBuilder(PluginManager::class)->disableOriginalConstructor()->getMock();
|
||||
$pm->expects($this->any())
|
||||
->method('getPlugins')
|
||||
->willReturn(array());
|
||||
|
||||
$this->composer->expects($this->any())
|
||||
->method('getPluginManager')
|
||||
->will($this->returnValue($pm));
|
||||
|
||||
$this->operation = $this->getMockBuilder('Composer\DependencyResolver\Operation\OperationInterface')->getMock();
|
||||
|
||||
ScriptHandler::getConfig($this->createEvent($composerType));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $composerType
|
||||
*
|
||||
* @return PackageEvent
|
||||
*/
|
||||
protected function createEvent($composerType)
|
||||
{
|
||||
$this->package->expects($this->any())
|
||||
->method('getType')
|
||||
->will($this->returnValue($composerType));
|
||||
|
||||
if ($this->operation instanceof UpdateOperation) {
|
||||
$this->operation->expects($this->any())
|
||||
->method('getTargetPackage')
|
||||
->will($this->returnValue($this->package));
|
||||
}
|
||||
|
||||
if ($this->operation instanceof InstallOperation) {
|
||||
$this->operation->expects($this->any())
|
||||
->method('getPackage')
|
||||
->will($this->returnValue($this->package));
|
||||
}
|
||||
|
||||
/* @var PolicyInterface $policy */
|
||||
$policy = $this->getMockBuilder('Composer\DependencyResolver\PolicyInterface')->getMock();
|
||||
/* @var Pool $pool */
|
||||
$pool = $this->getMockBuilder('Composer\DependencyResolver\Pool')->disableOriginalConstructor()->getMock();
|
||||
/* @var CompositeRepository $installedRepo */
|
||||
$installedRepo = $this->getMockBuilder('Composer\Repository\CompositeRepository')->disableOriginalConstructor()->getMock();
|
||||
/* @var Request $request */
|
||||
$request = $this->getMockBuilder('Composer\DependencyResolver\Request')->disableOriginalConstructor()->getMock();
|
||||
$operations = array($this->getMockBuilder('Composer\DependencyResolver\Operation\OperationInterface')->getMock());
|
||||
|
||||
return new PackageEvent('foo-event', $this->composer, $this->io, true, $policy, $pool, $installedRepo, $request, $operations, $this->operation);
|
||||
}
|
||||
}
|
|
@ -1,205 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Composer;
|
||||
|
||||
use Composer\Composer;
|
||||
use Composer\Config;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Package\RootPackageInterface;
|
||||
use Fxp\Composer\AssetPlugin\Config\ConfigBuilder;
|
||||
|
||||
/**
|
||||
* Tests for the plugin config.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class ConfigTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var Composer|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $composer;
|
||||
|
||||
/**
|
||||
* @var Config|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $composerConfig;
|
||||
|
||||
/**
|
||||
* @var IOInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $io;
|
||||
|
||||
/**
|
||||
* @var RootPackageInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $package;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->composer = $this->getMockBuilder(Composer::class)->disableOriginalConstructor()->getMock();
|
||||
$this->composerConfig = $this->getMockBuilder(Config::class)->disableOriginalConstructor()->getMock();
|
||||
$this->io = $this->getMockBuilder(IOInterface::class)->getMock();
|
||||
$this->package = $this->getMockBuilder(RootPackageInterface::class)->getMock();
|
||||
|
||||
$this->composer->expects($this->any())
|
||||
->method('getPackage')
|
||||
->willReturn($this->package);
|
||||
|
||||
$this->composer->expects($this->any())
|
||||
->method('getConfig')
|
||||
->willReturn($this->composerConfig);
|
||||
}
|
||||
|
||||
public function getDataForGetConfig()
|
||||
{
|
||||
return array(
|
||||
array('foo', 42, 42),
|
||||
array('bar', 'foo', 'empty'),
|
||||
array('baz', false, true),
|
||||
array('repositories', 42, 0),
|
||||
array('global-composer-foo', 90, 0),
|
||||
array('global-composer-bar', 70, 0),
|
||||
array('global-config-foo', 23, 0),
|
||||
array('env-boolean', false, true, 'FXP_ASSET__ENV_BOOLEAN=false'),
|
||||
array('env-integer', -32, 0, 'FXP_ASSET__ENV_INTEGER=-32'),
|
||||
array('env-json', array('foo' => 'bar'), array(), 'FXP_ASSET__ENV_JSON="{"foo": "bar"}"'),
|
||||
array('env-json-array', array(array('foo' => 'bar')), array(), 'FXP_ASSET__ENV_JSON_ARRAY="[{"foo": "bar"}]"'),
|
||||
array('env-string', 'baz', 'foo', 'FXP_ASSET__ENV_STRING=baz'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getDataForGetConfig
|
||||
*
|
||||
* @param string $key The key
|
||||
* @param mixed $expected The expected value
|
||||
* @param mixed|null $default The default value
|
||||
* @param string|null $env The env variable
|
||||
*/
|
||||
public function testGetConfig($key, $expected, $default = null, $env = null)
|
||||
{
|
||||
// add env variables
|
||||
if (null !== $env) {
|
||||
putenv($env);
|
||||
}
|
||||
|
||||
$globalPath = realpath(__DIR__.'/../Fixtures/package/global');
|
||||
$this->composerConfig->expects($this->any())
|
||||
->method('has')
|
||||
->with('home')
|
||||
->willReturn(true);
|
||||
|
||||
$this->composerConfig->expects($this->any())
|
||||
->method('get')
|
||||
->with('home')
|
||||
->willReturn($globalPath);
|
||||
|
||||
$this->package->expects($this->any())
|
||||
->method('getExtra')
|
||||
->willReturn(array(
|
||||
'asset-baz' => false,
|
||||
'asset-repositories' => 42,
|
||||
));
|
||||
|
||||
$this->package->expects($this->any())
|
||||
->method('getConfig')
|
||||
->willReturn(array(
|
||||
'fxp-asset' => array(
|
||||
'bar' => 'foo',
|
||||
'baz' => false,
|
||||
'env-foo' => 55,
|
||||
),
|
||||
));
|
||||
|
||||
if (0 === strpos($key, 'global-')) {
|
||||
$this->io->expects($this->atLeast(2))
|
||||
->method('isDebug')
|
||||
->willReturn(true);
|
||||
|
||||
$this->io->expects($this->at(1))
|
||||
->method('writeError')
|
||||
->with(sprintf('Loading fxp-asset config in file %s/composer.json', $globalPath));
|
||||
$this->io->expects($this->at(3))
|
||||
->method('writeError')
|
||||
->with(sprintf('Loading fxp-asset config in file %s/config.json', $globalPath));
|
||||
}
|
||||
|
||||
$config = ConfigBuilder::build($this->composer, $this->io);
|
||||
$value = $config->get($key, $default);
|
||||
|
||||
// remove env variables
|
||||
if (null !== $env) {
|
||||
$envKey = substr($env, 0, strpos($env, '='));
|
||||
putenv($envKey);
|
||||
$this->assertFalse(getenv($envKey));
|
||||
}
|
||||
|
||||
$this->assertSame($expected, $value);
|
||||
// test cache
|
||||
$this->assertSame($expected, $config->get($key, $default));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Fxp\Composer\AssetPlugin\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "FXP_ASSET__ENV_JSON" environment variable isn't a valid JSON
|
||||
*/
|
||||
public function testGetEnvConfigWithInvalidJson()
|
||||
{
|
||||
putenv('FXP_ASSET__ENV_JSON="{"foo"}"');
|
||||
$config = ConfigBuilder::build($this->composer, $this->io);
|
||||
$ex = null;
|
||||
|
||||
try {
|
||||
$config->get('env-json');
|
||||
} catch (\Exception $e) {
|
||||
$ex = $e;
|
||||
}
|
||||
|
||||
putenv('FXP_ASSET__ENV_JSON');
|
||||
$this->assertFalse(getenv('FXP_ASSET__ENV_JSON'));
|
||||
|
||||
if (null === $ex) {
|
||||
throw new \Exception('The expected exception was not thrown');
|
||||
}
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
public function testValidateConfig()
|
||||
{
|
||||
$deprecated = array(
|
||||
'asset-installer-paths' => 'deprecated',
|
||||
'asset-ignore-files' => 'deprecated',
|
||||
'asset-private-bower-registries' => 'deprecated',
|
||||
'asset-pattern-skip-version' => 'deprecated',
|
||||
'asset-optimize-with-installed-packages' => 'deprecated',
|
||||
'asset-optimize-with-conjunctive' => 'deprecated',
|
||||
'asset-repositories' => 'deprecated',
|
||||
'asset-registry-options' => 'deprecated',
|
||||
'asset-vcs-driver-options' => 'deprecated',
|
||||
'asset-main-files' => 'deprecated',
|
||||
);
|
||||
|
||||
$this->package->expects($this->any())
|
||||
->method('getExtra')
|
||||
->willReturn($deprecated);
|
||||
|
||||
foreach (array_keys($deprecated) as $i => $option) {
|
||||
$this->io->expects($this->at($i))
|
||||
->method('write')
|
||||
->with('<warning>The "extra.'.$option.'" option is deprecated, use the "config.fxp-asset.'.substr($option, 6).'" option</warning>');
|
||||
}
|
||||
|
||||
ConfigBuilder::validate($this->io, $this->package);
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Converter;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Converter\PackageConverterInterface;
|
||||
use Fxp\Composer\AssetPlugin\Tests\Fixtures\Converter\InvalidPackageConverter;
|
||||
use Fxp\Composer\AssetPlugin\Type\AssetTypeInterface;
|
||||
|
||||
/**
|
||||
* Abstract tests of asset package converter.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
abstract class AbstractPackageConverterTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var AssetTypeInterface
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* @var PackageConverterInterface
|
||||
*/
|
||||
protected $converter;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $asset;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$versionConverter = $this->getMockBuilder('Fxp\Composer\AssetPlugin\Converter\VersionConverterInterface')->getMock();
|
||||
$versionConverter->expects($this->any())
|
||||
->method('convertVersion')
|
||||
->will($this->returnCallback(function ($value) {
|
||||
return $value;
|
||||
}));
|
||||
$versionConverter->expects($this->any())
|
||||
->method('convertRange')
|
||||
->will($this->returnCallback(function ($value) {
|
||||
return $value;
|
||||
}));
|
||||
$type = $this->getMockBuilder('Fxp\Composer\AssetPlugin\Type\AssetTypeInterface')->getMock();
|
||||
$type->expects($this->any())
|
||||
->method('getComposerVendorName')
|
||||
->will($this->returnValue('ASSET'));
|
||||
$type->expects($this->any())
|
||||
->method('getComposerType')
|
||||
->will($this->returnValue('ASSET_TYPE'));
|
||||
$type->expects($this->any())
|
||||
->method('getVersionConverter')
|
||||
->will($this->returnValue($versionConverter));
|
||||
$type->expects($this->any())
|
||||
->method('formatComposerName')
|
||||
->will($this->returnCallback(function ($value) {
|
||||
return 'ASSET/'.$value;
|
||||
}));
|
||||
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$this->type = null;
|
||||
$this->converter = null;
|
||||
$this->asset = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Fxp\Composer\AssetPlugin\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function testConversionWithInvalidKey()
|
||||
{
|
||||
$this->converter = new InvalidPackageConverter($this->type);
|
||||
|
||||
$this->converter->convert(array(
|
||||
'name' => 'foo',
|
||||
));
|
||||
}
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Converter;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Converter\BowerPackageConverter;
|
||||
use Fxp\Composer\AssetPlugin\Type\AssetTypeInterface;
|
||||
|
||||
/**
|
||||
* Tests of bower package converter.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class BowerPackageConverterTest extends AbstractPackageConverterTest
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
/* @var AssetTypeInterface $type */
|
||||
$type = $this->type;
|
||||
$this->converter = new BowerPackageConverter($type);
|
||||
$this->asset = (array) json_decode(file_get_contents(__DIR__.'/../Fixtures/package/bower.json'), true);
|
||||
}
|
||||
|
||||
public function testConvert()
|
||||
{
|
||||
$composer = $this->converter->convert($this->asset);
|
||||
|
||||
$this->assertArrayHasKey('name', $composer);
|
||||
$this->assertSame('ASSET/'.$this->asset['name'], $composer['name']);
|
||||
|
||||
$this->assertArrayHasKey('type', $composer);
|
||||
$this->assertSame('ASSET_TYPE', $composer['type']);
|
||||
|
||||
$this->assertArrayHasKey('description', $composer);
|
||||
$this->assertSame($this->asset['description'], $composer['description']);
|
||||
|
||||
$this->assertArrayHasKey('version', $composer);
|
||||
$this->assertSame('1.0.0-pre', $composer['version']);
|
||||
|
||||
$this->assertArrayHasKey('keywords', $composer);
|
||||
$this->assertSame($this->asset['keywords'], $composer['keywords']);
|
||||
|
||||
$this->assertArrayHasKey('require', $composer);
|
||||
$this->assertSame(array(
|
||||
'ASSET/library1' => '>= 1.0.0',
|
||||
'ASSET/library2' => '>= 1.0.0',
|
||||
'ASSET/library2-0.9.0' => '0.9.0',
|
||||
'ASSET/library3' => '*',
|
||||
'ASSET/library4' => '1.2.3',
|
||||
'ASSET/library5' => 'dev-default#0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b',
|
||||
'ASSET/library6' => 'dev-branch',
|
||||
'ASSET/library7' => 'dev-1.2.* || 1.2.*',
|
||||
'ASSET/library8' => 'dev-1.2.x || 1.2.x',
|
||||
'ASSET/library9' => 'dev-master',
|
||||
'ASSET/library10' => '1.0.0',
|
||||
'ASSET/library11' => '*',
|
||||
'ASSET/library12' => '>=1 <2',
|
||||
'ASSET/library13' => '>=1 <2',
|
||||
'ASSET/library14' => '*',
|
||||
'ASSET/library15' => '*',
|
||||
'ASSET/library16' => '>=1 <2',
|
||||
'ASSET/test-library17-file' => '*',
|
||||
'ASSET/test-library18-file' => '1.2.3',
|
||||
'ASSET/test-library19-file' => '*',
|
||||
'ASSET/test-library20-file' => '*',
|
||||
), $composer['require']);
|
||||
|
||||
$this->assertArrayHasKey('require-dev', $composer);
|
||||
$this->assertSame(array(
|
||||
'ASSET/dev-library1' => '>= 1.0.0',
|
||||
'ASSET/dev-library2' => '>= 1.0.0',
|
||||
'ASSET/dev-library2-0.9.0' => '0.9.0',
|
||||
), $composer['require-dev']);
|
||||
|
||||
$this->assertArrayHasKey('license', $composer);
|
||||
$this->assertSame($this->asset['license'], $composer['license']);
|
||||
|
||||
$this->assertArrayHasKey('bin', $composer);
|
||||
$this->assertSame($this->asset['bin'], $composer['bin']);
|
||||
|
||||
$this->assertArrayHasKey('extra', $composer);
|
||||
|
||||
$this->assertArrayHasKey('bower-asset-main', $composer['extra']);
|
||||
$this->assertSame($this->asset['main'], $composer['extra']['bower-asset-main']);
|
||||
|
||||
$this->assertArrayHasKey('bower-asset-ignore', $composer['extra']);
|
||||
$this->assertSame($this->asset['ignore'], $composer['extra']['bower-asset-ignore']);
|
||||
|
||||
$this->assertArrayHasKey('bower-asset-private', $composer['extra']);
|
||||
$this->assertSame($this->asset['private'], $composer['extra']['bower-asset-private']);
|
||||
|
||||
$this->assertArrayNotHasKey('homepage', $composer);
|
||||
$this->assertArrayNotHasKey('time', $composer);
|
||||
$this->assertArrayNotHasKey('authors', $composer);
|
||||
$this->assertArrayNotHasKey('support', $composer);
|
||||
$this->assertArrayNotHasKey('conflict', $composer);
|
||||
$this->assertArrayNotHasKey('replace', $composer);
|
||||
$this->assertArrayNotHasKey('provide', $composer);
|
||||
$this->assertArrayNotHasKey('suggest', $composer);
|
||||
$this->assertArrayNotHasKey('autoload', $composer);
|
||||
$this->assertArrayNotHasKey('autoload-dev', $composer);
|
||||
$this->assertArrayNotHasKey('include-path', $composer);
|
||||
$this->assertArrayNotHasKey('target-dir', $composer);
|
||||
$this->assertArrayNotHasKey('archive', $composer);
|
||||
}
|
||||
}
|
|
@ -1,220 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Converter;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Converter\NpmPackageConverter;
|
||||
use Fxp\Composer\AssetPlugin\Converter\NpmPackageUtil;
|
||||
use Fxp\Composer\AssetPlugin\Type\AssetTypeInterface;
|
||||
|
||||
/**
|
||||
* Tests of npm package converter.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class NpmPackageConverterTest extends AbstractPackageConverterTest
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
/* @var AssetTypeInterface $type */
|
||||
$type = $this->type;
|
||||
$this->converter = new NpmPackageConverter($type);
|
||||
$this->asset = $this->loadPackage();
|
||||
}
|
||||
|
||||
public function testConvert()
|
||||
{
|
||||
$composer = $this->converter->convert($this->asset);
|
||||
|
||||
$this->assertArrayHasKey('name', $composer);
|
||||
$this->assertSame('ASSET/'.$this->asset['name'], $composer['name']);
|
||||
|
||||
$this->assertArrayHasKey('type', $composer);
|
||||
$this->assertSame('ASSET_TYPE', $composer['type']);
|
||||
|
||||
$this->assertArrayHasKey('description', $composer);
|
||||
$this->assertSame($this->asset['description'], $composer['description']);
|
||||
|
||||
$this->assertArrayHasKey('version', $composer);
|
||||
$this->assertSame('1.0.0-pre', $composer['version']);
|
||||
|
||||
$this->assertArrayHasKey('keywords', $composer);
|
||||
$this->assertSame($this->asset['keywords'], $composer['keywords']);
|
||||
|
||||
$this->assertArrayHasKey('homepage', $composer);
|
||||
$this->assertSame($this->asset['homepage'], $composer['homepage']);
|
||||
|
||||
$this->assertArrayHasKey('license', $composer);
|
||||
$this->assertSame($this->asset['license'], $composer['license']);
|
||||
|
||||
$this->assertArrayHasKey('authors', $composer);
|
||||
$this->assertSame(array_merge(array($this->asset['author']), $this->asset['contributors']), $composer['authors']);
|
||||
|
||||
$this->assertArrayHasKey('require', $composer);
|
||||
$this->assertSame(array(
|
||||
'ASSET/library1' => '>= 1.0.0',
|
||||
'ASSET/library2' => '>= 1.0.0',
|
||||
'ASSET/library2-0.9.0' => '0.9.0',
|
||||
'ASSET/library3' => '*',
|
||||
'ASSET/library4' => '1.2.3',
|
||||
'ASSET/library5' => 'dev-default#0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b',
|
||||
'ASSET/library6' => 'dev-branch',
|
||||
'ASSET/library7' => 'dev-1.2.* || 1.2.*',
|
||||
'ASSET/library8' => 'dev-1.2.x || 1.2.x',
|
||||
'ASSET/library9' => 'dev-master',
|
||||
'ASSET/library10' => '1.0.0',
|
||||
'ASSET/library11' => '*',
|
||||
'ASSET/library12' => '>=1 <2',
|
||||
'ASSET/library13' => '>=1 <2',
|
||||
'ASSET/library14' => '*',
|
||||
'ASSET/library15' => '*',
|
||||
'ASSET/library16' => '>=1 <2',
|
||||
'ASSET/test-library17-file' => '*',
|
||||
'ASSET/test-library18-file' => '1.2.3',
|
||||
'ASSET/test-library19-file' => '*',
|
||||
'ASSET/test-library20-file' => '*',
|
||||
'ASSET/library21' => '1 || 2',
|
||||
), $composer['require']);
|
||||
|
||||
$this->assertArrayHasKey('require-dev', $composer);
|
||||
$validDevRequires = $composer['require-dev'];
|
||||
unset($validDevRequires['ASSET/library3']);
|
||||
$this->assertSame(array(
|
||||
'ASSET/dev-library1' => '>= 1.0.0',
|
||||
'ASSET/dev-library2' => '>= 1.0.0',
|
||||
'ASSET/dev-library2-0.9.0' => '0.9.0',
|
||||
), $validDevRequires);
|
||||
|
||||
$this->assertArrayHasKey('bin', $composer);
|
||||
$this->assertInternalType('array', $composer['bin']);
|
||||
$this->assertSame($this->asset['bin'], $composer['bin'][0]);
|
||||
|
||||
$this->assertArrayHasKey('extra', $composer);
|
||||
|
||||
$this->assertArrayHasKey('npm-asset-bugs', $composer['extra']);
|
||||
$this->assertSame($this->asset['bugs'], $composer['extra']['npm-asset-bugs']);
|
||||
|
||||
$this->assertArrayHasKey('npm-asset-files', $composer['extra']);
|
||||
$this->assertSame($this->asset['files'], $composer['extra']['npm-asset-files']);
|
||||
|
||||
$this->assertArrayHasKey('npm-asset-main', $composer['extra']);
|
||||
$this->assertSame($this->asset['main'], $composer['extra']['npm-asset-main']);
|
||||
|
||||
$this->assertArrayHasKey('npm-asset-man', $composer['extra']);
|
||||
$this->assertSame($this->asset['man'], $composer['extra']['npm-asset-man']);
|
||||
|
||||
$this->assertArrayHasKey('npm-asset-directories', $composer['extra']);
|
||||
$this->assertSame($this->asset['directories'], $composer['extra']['npm-asset-directories']);
|
||||
|
||||
$this->assertArrayHasKey('npm-asset-repository', $composer['extra']);
|
||||
$this->assertSame($this->asset['repository'], $composer['extra']['npm-asset-repository']);
|
||||
|
||||
$this->assertArrayHasKey('npm-asset-scripts', $composer['extra']);
|
||||
$this->assertSame($this->asset['scripts'], $composer['extra']['npm-asset-scripts']);
|
||||
|
||||
$this->assertArrayHasKey('npm-asset-config', $composer['extra']);
|
||||
$this->assertSame($this->asset['config'], $composer['extra']['npm-asset-config']);
|
||||
|
||||
$this->assertArrayHasKey('npm-asset-bundled-dependencies', $composer['extra']);
|
||||
$this->assertSame($this->asset['bundledDependencies'], $composer['extra']['npm-asset-bundled-dependencies']);
|
||||
|
||||
$this->assertArrayHasKey('npm-asset-optional-dependencies', $composer['extra']);
|
||||
$this->assertSame($this->asset['optionalDependencies'], $composer['extra']['npm-asset-optional-dependencies']);
|
||||
|
||||
$this->assertArrayHasKey('npm-asset-engines', $composer['extra']);
|
||||
$this->assertSame($this->asset['engines'], $composer['extra']['npm-asset-engines']);
|
||||
|
||||
$this->assertArrayHasKey('npm-asset-engine-strict', $composer['extra']);
|
||||
$this->assertSame($this->asset['engineStrict'], $composer['extra']['npm-asset-engine-strict']);
|
||||
|
||||
$this->assertArrayHasKey('npm-asset-os', $composer['extra']);
|
||||
$this->assertSame($this->asset['os'], $composer['extra']['npm-asset-os']);
|
||||
|
||||
$this->assertArrayHasKey('npm-asset-cpu', $composer['extra']);
|
||||
$this->assertSame($this->asset['cpu'], $composer['extra']['npm-asset-cpu']);
|
||||
|
||||
$this->assertArrayHasKey('npm-asset-prefer-global', $composer['extra']);
|
||||
$this->assertSame($this->asset['preferGlobal'], $composer['extra']['npm-asset-prefer-global']);
|
||||
|
||||
$this->assertArrayHasKey('npm-asset-private', $composer['extra']);
|
||||
$this->assertSame($this->asset['private'], $composer['extra']['npm-asset-private']);
|
||||
|
||||
$this->assertArrayHasKey('npm-asset-publish-config', $composer['extra']);
|
||||
$this->assertSame($this->asset['publishConfig'], $composer['extra']['npm-asset-publish-config']);
|
||||
|
||||
$this->assertArrayNotHasKey('time', $composer);
|
||||
$this->assertArrayNotHasKey('support', $composer);
|
||||
$this->assertArrayNotHasKey('conflict', $composer);
|
||||
$this->assertArrayNotHasKey('replace', $composer);
|
||||
$this->assertArrayNotHasKey('provide', $composer);
|
||||
$this->assertArrayNotHasKey('suggest', $composer);
|
||||
$this->assertArrayNotHasKey('autoload', $composer);
|
||||
$this->assertArrayNotHasKey('autoload-dev', $composer);
|
||||
$this->assertArrayNotHasKey('include-path', $composer);
|
||||
$this->assertArrayNotHasKey('target-dir', $composer);
|
||||
$this->assertArrayNotHasKey('archive', $composer);
|
||||
}
|
||||
|
||||
public function testConvertWithScope()
|
||||
{
|
||||
$this->asset = $this->loadPackage('npm-scope.json');
|
||||
$composer = $this->converter->convert($this->asset);
|
||||
|
||||
$this->assertArrayHasKey('name', $composer);
|
||||
$this->assertSame('ASSET/scope--test', $composer['name']);
|
||||
|
||||
$this->assertArrayHasKey('require', $composer);
|
||||
$this->assertSame(array(
|
||||
'ASSET/scope--library1' => '>= 1.0.0',
|
||||
'ASSET/scope2--library2' => '>= 1.0.0',
|
||||
), $composer['require']);
|
||||
|
||||
$this->assertArrayHasKey('require-dev', $composer);
|
||||
$this->assertSame(array(
|
||||
'ASSET/scope3--dev-library1' => '>= 1.0.0',
|
||||
), $composer['require-dev']);
|
||||
}
|
||||
|
||||
public function getConvertDistData()
|
||||
{
|
||||
return array(
|
||||
array(array('type' => null), array()),
|
||||
array(array('type' => 'http://example.com'), array('type' => 'type', 'url' => 'https://example.com')),
|
||||
array(array('tarball' => 'http://example.com'), array('type' => 'tar', 'url' => 'https://example.com')),
|
||||
array(array('shasum' => 'abcdef0123456789abcdef0123456789abcdef01'), array('shasum' => 'abcdef0123456789abcdef0123456789abcdef01')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getConvertDistData
|
||||
*
|
||||
* @param array $value The value must be converted
|
||||
* @param array $result The result of convertion
|
||||
*/
|
||||
public function testConvertDist($value, $result)
|
||||
{
|
||||
$this->assertSame($result, NpmPackageUtil::convertDist($value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the package.
|
||||
*
|
||||
* @param string $package The package file name
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function loadPackage($package = 'npm.json')
|
||||
{
|
||||
return (array) json_decode(file_get_contents(__DIR__.'/../Fixtures/package/'.$package), true);
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Converter;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Converter\NpmPackageUtil;
|
||||
|
||||
/**
|
||||
* Tests of npm package util.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class NpmPackageUtilTest extends AbstractPackageConverterTest
|
||||
{
|
||||
public function testConvertName()
|
||||
{
|
||||
$packageName = '@vendor/package';
|
||||
$expected = 'vendor--package';
|
||||
|
||||
$this->assertSame($expected, NpmPackageUtil::convertName($packageName));
|
||||
}
|
||||
|
||||
public function testRevertName()
|
||||
{
|
||||
$packageName = 'vendor--package';
|
||||
$expected = '@vendor/package';
|
||||
|
||||
$this->assertSame($expected, NpmPackageUtil::revertName($packageName));
|
||||
}
|
||||
}
|
|
@ -1,182 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Converter;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Converter\SemverConverter;
|
||||
use Fxp\Composer\AssetPlugin\Converter\VersionConverterInterface;
|
||||
|
||||
/**
|
||||
* Tests for the conversion of Semver syntax to composer syntax.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class SemverConverterTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var VersionConverterInterface
|
||||
*/
|
||||
protected $converter;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->converter = new SemverConverter();
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$this->converter = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getTestVersions
|
||||
*
|
||||
* @param string $semver
|
||||
* @param string $composer
|
||||
*/
|
||||
public function testConverter($semver, $composer)
|
||||
{
|
||||
$this->assertEquals($composer, $this->converter->convertVersion($semver));
|
||||
|
||||
if (!ctype_alpha($semver) && !in_array($semver, array(null, ''))) {
|
||||
$this->assertEquals('v'.$composer, $this->converter->convertVersion('v'.$semver));
|
||||
}
|
||||
}
|
||||
|
||||
public function getTestVersions()
|
||||
{
|
||||
return array(
|
||||
array('1.2.3', '1.2.3'),
|
||||
array('1.2.3alpha', '1.2.3-alpha1'),
|
||||
array('1.2.3-alpha', '1.2.3-alpha1'),
|
||||
array('1.2.3a', '1.2.3-alpha1'),
|
||||
array('1.2.3a1', '1.2.3-alpha1'),
|
||||
array('1.2.3-a', '1.2.3-alpha1'),
|
||||
array('1.2.3-a1', '1.2.3-alpha1'),
|
||||
array('1.2.3b', '1.2.3-beta1'),
|
||||
array('1.2.3b1', '1.2.3-beta1'),
|
||||
array('1.2.3-b', '1.2.3-beta1'),
|
||||
array('1.2.3-b1', '1.2.3-beta1'),
|
||||
array('1.2.3beta', '1.2.3-beta1'),
|
||||
array('1.2.3-beta', '1.2.3-beta1'),
|
||||
array('1.2.3beta1', '1.2.3-beta1'),
|
||||
array('1.2.3-beta1', '1.2.3-beta1'),
|
||||
array('1.2.3rc1', '1.2.3-RC1'),
|
||||
array('1.2.3-rc1', '1.2.3-RC1'),
|
||||
array('1.2.3rc2', '1.2.3-RC2'),
|
||||
array('1.2.3-rc2', '1.2.3-RC2'),
|
||||
array('1.2.3rc.2', '1.2.3-RC.2'),
|
||||
array('1.2.3-rc.2', '1.2.3-RC.2'),
|
||||
array('1.2.3+0', '1.2.3-patch0'),
|
||||
array('1.2.3-0', '1.2.3-patch0'),
|
||||
array('1.2.3pre', '1.2.3-beta1'),
|
||||
array('1.2.3-pre', '1.2.3-beta1'),
|
||||
array('1.2.3dev', '1.2.3-dev'),
|
||||
array('1.2.3-dev', '1.2.3-dev'),
|
||||
array('1.2.3+build2012', '1.2.3-patch2012'),
|
||||
array('1.2.3-build2012', '1.2.3-patch2012'),
|
||||
array('1.2.3+build.2012', '1.2.3-patch.2012'),
|
||||
array('1.2.3-build.2012', '1.2.3-patch.2012'),
|
||||
array('1.3.0–rc30.79', '1.3.0-RC30.79'),
|
||||
array('1.2.3-SNAPSHOT', '1.2.3-dev'),
|
||||
array('1.2.3-npm-packages', '1.2.3'),
|
||||
array('1.2.3-bower-packages', '1.2.3'),
|
||||
array('20170124.0.0', '20170124.000000'),
|
||||
array('20170124.1.0', '20170124.001000'),
|
||||
array('20170124.1.1', '20170124.001001'),
|
||||
array('20170124.100.200', '20170124.100200'),
|
||||
array('20170124.0', '20170124.000000'),
|
||||
array('20170124.1', '20170124.001000'),
|
||||
array('20170124', '20170124'),
|
||||
array('latest', 'default || *'),
|
||||
array(null, '*'),
|
||||
array('', '*'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getTestRanges
|
||||
*
|
||||
* @param string $semver
|
||||
* @param string $composer
|
||||
*/
|
||||
public function testRangeConverter($semver, $composer)
|
||||
{
|
||||
$this->assertEquals($composer, $this->converter->convertRange($semver));
|
||||
}
|
||||
|
||||
public function getTestRanges()
|
||||
{
|
||||
return array(
|
||||
array('>1.2.3', '>1.2.3'),
|
||||
array('<1.2.3', '<1.2.3'),
|
||||
array('>=1.2.3', '>=1.2.3'),
|
||||
array('<=1.2.3', '<=1.2.3'),
|
||||
array('~1.2.3', '~1.2.3'),
|
||||
array('~1', '~1'),
|
||||
array('1', '~1'),
|
||||
array('^1.2.3', '>=1.2.3,<2.0.0'),
|
||||
array('^1.2', '>=1.2.0,<2.0.0'),
|
||||
array('^1.x', '>=1.0.0,<2.0.0'),
|
||||
array('^1', '>=1.0.0,<2.0.0'),
|
||||
array('>1.2.3 <2.0', '>1.2.3,<2.0'),
|
||||
array('>1.2 <2.0', '>1.2,<2.0'),
|
||||
array('>1 <2', '>1,<2'),
|
||||
array('>=1.2.3 <2.0', '>=1.2.3,<2.0'),
|
||||
array('>=1.2 <2.0', '>=1.2,<2.0'),
|
||||
array('>=1 <2', '>=1,<2'),
|
||||
array('>=1.0 <1.1 || >=1.2', '>=1.0,<1.1|>=1.2'),
|
||||
array('>=1.0 && <1.1 || >=1.2', '>=1.0,<1.1|>=1.2'),
|
||||
array('< 1.2.3', '<1.2.3'),
|
||||
array('> 1.2.3', '>1.2.3'),
|
||||
array('<= 1.2.3', '<=1.2.3'),
|
||||
array('>= 1.2.3', '>=1.2.3'),
|
||||
array('~ 1.2.3', '~1.2.3'),
|
||||
array('~1.2.x', '~1.2.0'),
|
||||
array('~ 1.2', '~1.2'),
|
||||
array('~ 1', '~1'),
|
||||
array('^ 1.2.3', '>=1.2.3,<2.0.0'),
|
||||
array('~> 1.2.3', '~1.2.3,>1.2.3'),
|
||||
array('1.2.3 - 2.3.4', '>=1.2.3,<=2.3.4'),
|
||||
array('1.0.0 - 1.3.x', '>=1.0.0,<1.4.0'),
|
||||
array('1.0 - 1.x', '>=1.0,<2.0'),
|
||||
array('1.2.3 - 2', '>=1.2.3,<3.0'),
|
||||
array('1.x - 2.x', '>=1.0,<3.0'),
|
||||
array('2 - 3', '>=2,<4.0'),
|
||||
array('>=0.10.x', '>=0.10.0'),
|
||||
array('>=0.10.*', '>=0.10.0'),
|
||||
array('<=0.10.x', '<=0.10.9999999'),
|
||||
array('<=0.10.*', '<=0.10.9999999'),
|
||||
array('=1.2.x', '1.2.x'),
|
||||
array('1.x.x', '1.x'),
|
||||
array('1.x.x.x', '1.x'),
|
||||
array('2.X.X.X', '2.x'),
|
||||
array('2.X.x.x', '2.x'),
|
||||
array('>=1.2.3 <2.0', '>=1.2.3,<2.0'),
|
||||
array('^1.2.3', '>=1.2.3,<2.0.0'),
|
||||
array('^0.2.3', '>=0.2.3,<0.3.0'),
|
||||
array('^0.0.3', '>=0.0.3,<0.0.4'),
|
||||
array('^1.2.3-beta.2', '>=1.2.3-beta.2,<2.0.0'),
|
||||
array('^0.0.3-beta', '>=0.0.3-beta1,<0.0.4'),
|
||||
array('^1.2.x', '>=1.2.0,<2.0.0'),
|
||||
array('^0.0.x', '>=0.0.0,<0.1.0'),
|
||||
array('^0.0', '>=0.0.0,<0.1.0'),
|
||||
array('^1.x', '>=1.0.0,<2.0.0'),
|
||||
array('^0.x', '>=0.0.0,<1.0.0'),
|
||||
array('~v1', '~1'),
|
||||
array('~v1-beta', '~1-beta1'),
|
||||
array('~v1.2', '~1.2'),
|
||||
array('~v1.2-beta', '~1.2-beta1'),
|
||||
array('~v1.2.3', '~1.2.3'),
|
||||
array('~v1.2.3-beta', '~1.2.3-beta1'),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Fixtures\Converter;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Converter\AbstractPackageConverter;
|
||||
|
||||
/**
|
||||
* Fixture for invalid package converter tests.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class InvalidPackageConverter extends AbstractPackageConverter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getMapKeys()
|
||||
{
|
||||
return array_merge(parent::getMapKeys(), array(
|
||||
'name' => array(null, function ($value) {
|
||||
return $value;
|
||||
}),
|
||||
));
|
||||
}
|
||||
}
|
|
@ -1,173 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Fixtures\IO;
|
||||
|
||||
use Composer\IO\BaseIO;
|
||||
|
||||
/**
|
||||
* Mock of IO.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class MockIO extends BaseIO
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $verbose;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $traces;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param bool $verbose
|
||||
*/
|
||||
public function __construct($verbose)
|
||||
{
|
||||
$this->verbose = $verbose;
|
||||
$this->traces = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isInteractive()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isVerbose()
|
||||
{
|
||||
return $this->verbose;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isVeryVerbose()
|
||||
{
|
||||
return $this->verbose;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isDebug()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isDecorated()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function write($messages, $newline = true, $verbosity = self::NORMAL)
|
||||
{
|
||||
$pos = max(count($this->traces) - 1, 0);
|
||||
if (isset($this->traces[$pos])) {
|
||||
$messages = $this->traces[$pos].$messages;
|
||||
}
|
||||
$this->traces[$pos] = $messages;
|
||||
if ($newline) {
|
||||
$this->traces[] = '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function writeError($messages, $newline = true, $verbosity = self::NORMAL)
|
||||
{
|
||||
$this->write($messages, $newline, $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function overwrite($messages, $newline = true, $size = 80, $verbosity = self::NORMAL)
|
||||
{
|
||||
$pos = max(count($this->traces) - 1, 0);
|
||||
$this->traces[$pos] = $messages;
|
||||
if ($newline) {
|
||||
$this->traces[] = '';
|
||||
}
|
||||
}
|
||||
|
||||
public function overwriteError($messages, $newline = true, $size = null, $verbosity = self::NORMAL)
|
||||
{
|
||||
$this->overwrite($messages, $newline, $size, $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function ask($question, $default = null)
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function askConfirmation($question, $default = true)
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function askAndValidate($question, $validator, $attempts = false, $default = null)
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function askAndHideAnswer($question)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function select($question, $choices, $default, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false)
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the taces.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTraces()
|
||||
{
|
||||
return $this->traces;
|
||||
}
|
||||
}
|
|
@ -1,145 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Fixtures\Repository\Vcs;
|
||||
|
||||
use Composer\Config;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Repository\Vcs\VcsDriverInterface;
|
||||
|
||||
/**
|
||||
* Mock vcs driver.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class MockVcsDriver implements VcsDriverInterface
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public static $supported = true;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
public $contents = null;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
// no action
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getComposerInformation($identifier)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRootIdentifier()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getBranches()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDist($identifier)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSource($identifier)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasComposerFile($identifier)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function cleanup()
|
||||
{
|
||||
// no action
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function supports(IOInterface $io, Config $config, $url, $deep = false)
|
||||
{
|
||||
return static::$supported;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getContents()
|
||||
{
|
||||
return $this->contents;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFileContent($file, $identifier)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getChangeDate($identifier)
|
||||
{
|
||||
return new \DateTime();
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Fixtures\Repository\Vcs;
|
||||
|
||||
/**
|
||||
* Mock vcs driver for skip parsing test.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class MockVcsDriverSkipParsing extends MockVcsDriver
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRootIdentifier()
|
||||
{
|
||||
return 'ROOT';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasComposerFile($identifier)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getComposerInformation($identifier)
|
||||
{
|
||||
throw new \Exception('MESSAGE with '.$identifier);
|
||||
}
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Fixtures\Repository\Vcs;
|
||||
|
||||
/**
|
||||
* Mock vcs driver for packages test.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class MockVcsDriverWithPackages extends MockVcsDriver
|
||||
{
|
||||
protected $composer = array(
|
||||
'branch:master' => array(
|
||||
'name' => 'foobar',
|
||||
'version' => '2.0',
|
||||
),
|
||||
'branch:1.x' => array(
|
||||
'name' => 'foobar',
|
||||
'version' => '1.1',
|
||||
),
|
||||
'tag:v1.0.0' => array(
|
||||
'name' => 'foobar',
|
||||
'version' => '1.0',
|
||||
),
|
||||
'tag:v1.0.1' => array(
|
||||
'name' => 'foobar',
|
||||
),
|
||||
'tag:invalid' => array(
|
||||
'name' => 'foobar',
|
||||
'description' => 'invalid tag name',
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRootIdentifier()
|
||||
{
|
||||
return 'master';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasComposerFile($identifier)
|
||||
{
|
||||
return isset($this->composer['branch:'.$identifier])
|
||||
|| isset($this->composer['tag:'.$identifier]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getComposerInformation($identifier)
|
||||
{
|
||||
$composer = null;
|
||||
|
||||
if ($this->hasComposerFile($identifier)) {
|
||||
if (isset($this->composer['branch:'.$identifier])) {
|
||||
$composer = $this->composer['branch:'.$identifier];
|
||||
} elseif (isset($this->composer['tag:'.$identifier])) {
|
||||
$composer = $this->composer['tag:'.$identifier];
|
||||
}
|
||||
}
|
||||
|
||||
return $composer;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getBranches()
|
||||
{
|
||||
return $this->getDataPackages('branch');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
return $this->getDataPackages('tag');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getDataPackages($type)
|
||||
{
|
||||
$packages = array();
|
||||
|
||||
foreach ($this->composer as $name => $data) {
|
||||
if (0 === strpos($name, $type.':')) {
|
||||
$name = substr($name, strpos($name, ':') + 1);
|
||||
$packages[$name] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
return $packages;
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Fixtures\Repository\Vcs;
|
||||
|
||||
/**
|
||||
* Mock vcs driver for url packages test.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class MockVcsDriverWithUrlPackages extends MockVcsDriverWithPackages
|
||||
{
|
||||
protected $composer = array(
|
||||
'branch:master' => array(
|
||||
'version' => '2.0',
|
||||
),
|
||||
'branch:1.x' => array(
|
||||
'version' => '1.1',
|
||||
),
|
||||
'tag:v1.0.0' => array(
|
||||
'version' => '1.0',
|
||||
),
|
||||
'tag:v1.0.1' => array(
|
||||
),
|
||||
'tag:invalid' => array(
|
||||
'description' => 'invalid tag name',
|
||||
),
|
||||
);
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"global-composer-foo": 70,
|
||||
"global-composer-bar": 70
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"config": {
|
||||
"fxp-asset": {
|
||||
"global-composer-foo": 90,
|
||||
"global-config-foo": 23
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,257 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Installer;
|
||||
|
||||
use Composer\Composer;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Package\RootPackageInterface;
|
||||
use Composer\Repository\InstalledRepositoryInterface;
|
||||
use Composer\Util\Filesystem;
|
||||
use Fxp\Composer\AssetPlugin\Config\ConfigBuilder;
|
||||
use Fxp\Composer\AssetPlugin\Installer\AssetInstaller;
|
||||
use Fxp\Composer\AssetPlugin\Type\AssetTypeInterface;
|
||||
|
||||
/**
|
||||
* Tests of asset installer.
|
||||
*
|
||||
* @author Martin Hasoň <martin.hason@gmail.com>
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class AssetInstallerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var Composer|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $composer;
|
||||
|
||||
/**
|
||||
* @var IOInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $io;
|
||||
|
||||
/**
|
||||
* @var RootPackageInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $package;
|
||||
|
||||
/**
|
||||
* @var AssetTypeInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
$config = $this->getMockBuilder('Composer\Config')->getMock();
|
||||
$config->expects($this->any())
|
||||
->method('get')
|
||||
->will($this->returnCallback(function ($key) {
|
||||
$value = null;
|
||||
|
||||
switch ($key) {
|
||||
case 'cache-repo-dir':
|
||||
$value = sys_get_temp_dir().'/composer-test-repo-cache';
|
||||
break;
|
||||
case 'vendor-dir':
|
||||
$value = sys_get_temp_dir().'/composer-test/vendor';
|
||||
break;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}));
|
||||
|
||||
$this->package = $this->getMockBuilder('Composer\Package\RootPackageInterface')->getMock();
|
||||
|
||||
$this->composer = $this->getMockBuilder('Composer\Composer')->getMock();
|
||||
$this->composer->expects($this->any())
|
||||
->method('getPackage')
|
||||
->will($this->returnValue($this->package));
|
||||
$this->composer->expects($this->any())
|
||||
->method('getConfig')
|
||||
->will($this->returnValue($config));
|
||||
|
||||
$this->type = $this->getMockBuilder('Fxp\Composer\AssetPlugin\Type\AssetTypeInterface')->getMock();
|
||||
$this->type->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo'));
|
||||
$this->type->expects($this->any())
|
||||
->method('getComposerVendorName')
|
||||
->will($this->returnValue('foo-asset'));
|
||||
$this->type->expects($this->any())
|
||||
->method('getComposerType')
|
||||
->will($this->returnValue('foo-asset-library'));
|
||||
$this->type->expects($this->any())
|
||||
->method('getFilename')
|
||||
->will($this->returnValue('foo.json'));
|
||||
$this->type->expects($this->any())
|
||||
->method('getVersionConverter')
|
||||
->will($this->returnValue($this->getMockBuilder('Fxp\Composer\AssetPlugin\Converter\VersionConverterInterface')->getMock()));
|
||||
$this->type->expects($this->any())
|
||||
->method('getPackageConverter')
|
||||
->will($this->returnValue($this->getMockBuilder('Fxp\Composer\AssetPlugin\Converter\PackageConverterInterface')->getMock()));
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$this->package = null;
|
||||
$this->composer = null;
|
||||
$this->io = null;
|
||||
|
||||
$fs = new Filesystem();
|
||||
$fs->remove(sys_get_temp_dir().'/composer-test-repo-cache');
|
||||
$fs->remove(sys_get_temp_dir().'/composer-test/vendor');
|
||||
}
|
||||
|
||||
public function testDefaultVendorDir()
|
||||
{
|
||||
$installer = $this->createInstaller();
|
||||
$vendorDir = realpath(sys_get_temp_dir()).'/composer-test/vendor/'.$this->type->getComposerVendorName();
|
||||
$vendorDir = str_replace('\\', '/', $vendorDir);
|
||||
|
||||
$installerPath = $installer->getInstallPath($this->createPackageMock('foo-asset/foo'));
|
||||
$installerPath = str_replace('\\', '/', $installerPath);
|
||||
$this->assertEquals($vendorDir.'/foo', $installerPath);
|
||||
|
||||
$installerPath2 = $installer->getInstallPath($this->createPackageMock('foo-asset/foo/bar'));
|
||||
$installerPath2 = str_replace('\\', '/', $installerPath2);
|
||||
$this->assertEquals($vendorDir.'/foo/bar', $installerPath2);
|
||||
}
|
||||
|
||||
public function testCustomFooDir()
|
||||
{
|
||||
$vendorDir = realpath(sys_get_temp_dir()).'/composer-test/web';
|
||||
$vendorDir = str_replace('\\', '/', $vendorDir);
|
||||
|
||||
$package = $this->package;
|
||||
$package->expects($this->any())
|
||||
->method('getExtra')
|
||||
->will($this->returnValue(array(
|
||||
'asset-installer-paths' => array(
|
||||
$this->type->getComposerType() => $vendorDir,
|
||||
),
|
||||
)));
|
||||
|
||||
$installer = $this->createInstaller();
|
||||
|
||||
$installerPath = $installer->getInstallPath($this->createPackageMock('foo-asset/foo'));
|
||||
$installerPath = str_replace('\\', '/', $installerPath);
|
||||
$this->assertEquals($vendorDir.'/foo', $installerPath);
|
||||
|
||||
$installerPath2 = $installer->getInstallPath($this->createPackageMock('foo-asset/foo/bar'));
|
||||
$installerPath2 = str_replace('\\', '/', $installerPath2);
|
||||
$this->assertEquals($vendorDir.'/foo/bar', $installerPath2);
|
||||
}
|
||||
|
||||
public function testInstall()
|
||||
{
|
||||
/* @var RootPackageInterface $rootPackage */
|
||||
$rootPackage = $this->createRootPackageMock();
|
||||
/* @var IOInterface $io */
|
||||
$io = $this->io;
|
||||
/* @var AssetTypeInterface $type */
|
||||
$type = $this->type;
|
||||
$vendorDir = realpath(sys_get_temp_dir()).DIRECTORY_SEPARATOR.'composer-test'.DIRECTORY_SEPARATOR.'vendor';
|
||||
|
||||
$this->composer->setPackage($rootPackage);
|
||||
|
||||
$dm = $this->getMockBuilder('Composer\Downloader\DownloadManager')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->composer->expects($this->any())
|
||||
->method('getDownloadManager')
|
||||
->will($this->returnValue($dm));
|
||||
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $package */
|
||||
$package = $this->createPackageMock('foo-asset/package');
|
||||
|
||||
/* @var PackageInterface $package */
|
||||
$packageDir = $vendorDir.'/'.$package->getPrettyName();
|
||||
|
||||
$dm->expects($this->once())
|
||||
->method('download')
|
||||
->with($package, $vendorDir.DIRECTORY_SEPARATOR.'foo-asset/package');
|
||||
|
||||
$repository = $this->getMockBuilder('Composer\Repository\InstalledRepositoryInterface')->getMock();
|
||||
$repository->expects($this->once())
|
||||
->method('addPackage')
|
||||
->with($package);
|
||||
|
||||
$config = ConfigBuilder::build($this->composer);
|
||||
$library = new AssetInstaller($config, $io, $this->composer, $type);
|
||||
|
||||
/* @var InstalledRepositoryInterface $repository */
|
||||
$library->install($repository, $package);
|
||||
$this->assertFileExists($vendorDir, 'Vendor dir should be created');
|
||||
|
||||
$this->ensureDirectoryExistsAndClear($packageDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the asset installer.
|
||||
*
|
||||
* @return AssetInstaller
|
||||
*/
|
||||
protected function createInstaller()
|
||||
{
|
||||
/* @var IOInterface $io */
|
||||
$io = $this->io;
|
||||
/* @var Composer $composer */
|
||||
$composer = $this->composer;
|
||||
/* @var AssetTypeInterface $type */
|
||||
$type = $this->type;
|
||||
$config = ConfigBuilder::build($composer);
|
||||
|
||||
return new AssetInstaller($config, $io, $composer, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the mock package.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return PackageInterface
|
||||
*/
|
||||
private function createPackageMock($name)
|
||||
{
|
||||
return $this->getMockBuilder('Composer\Package\Package')
|
||||
->setConstructorArgs(array($name, '1.0.0.0', '1.0.0'))
|
||||
->enableProxyingToOriginalMethods()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return RootPackageInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected function createRootPackageMock()
|
||||
{
|
||||
$package = $this->getMockBuilder('Composer\Package\RootPackageInterface')
|
||||
->setConstructorArgs(array(md5(mt_rand()), '1.0.0.0', '1.0.0'))
|
||||
->getMock();
|
||||
|
||||
$package->expects($this->any())
|
||||
->method('getConfig')
|
||||
->will($this->returnValue(array()));
|
||||
|
||||
return $package;
|
||||
}
|
||||
|
||||
protected function ensureDirectoryExistsAndClear($directory)
|
||||
{
|
||||
$fs = new Filesystem();
|
||||
if (is_dir($directory)) {
|
||||
$fs->removeDirectory($directory);
|
||||
}
|
||||
mkdir($directory, 0777, true);
|
||||
}
|
||||
}
|
|
@ -1,511 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Installer;
|
||||
|
||||
use Composer\Composer;
|
||||
use Composer\Config;
|
||||
use Composer\Downloader\DownloadManager;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Package\Package;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Package\RootPackageInterface;
|
||||
use Composer\Repository\InstalledRepositoryInterface;
|
||||
use Composer\TestCase;
|
||||
use Composer\Util\Filesystem;
|
||||
use Fxp\Composer\AssetPlugin\Config\ConfigBuilder;
|
||||
use Fxp\Composer\AssetPlugin\Installer\BowerInstaller;
|
||||
use Fxp\Composer\AssetPlugin\Type\AssetTypeInterface;
|
||||
use Fxp\Composer\AssetPlugin\Util\AssetPlugin;
|
||||
|
||||
/**
|
||||
* Tests of bower asset installer.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class BowerInstallerTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var Composer
|
||||
*/
|
||||
protected $composer;
|
||||
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $vendorDir;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $binDir;
|
||||
|
||||
/**
|
||||
* @var DownloadManager|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $dm;
|
||||
|
||||
/**
|
||||
* @var InstalledRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $repository;
|
||||
|
||||
/**
|
||||
* @var IOInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $io;
|
||||
|
||||
/**
|
||||
* @var Filesystem
|
||||
*/
|
||||
protected $fs;
|
||||
|
||||
/**
|
||||
* @var AssetTypeInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->fs = new Filesystem();
|
||||
|
||||
$this->composer = new Composer();
|
||||
$this->config = new Config();
|
||||
$this->composer->setConfig($this->config);
|
||||
|
||||
$this->vendorDir = realpath(sys_get_temp_dir()).DIRECTORY_SEPARATOR.'composer-test-vendor';
|
||||
$this->ensureDirectoryExistsAndClear($this->vendorDir);
|
||||
|
||||
$this->binDir = realpath(sys_get_temp_dir()).DIRECTORY_SEPARATOR.'composer-test-bin';
|
||||
$this->ensureDirectoryExistsAndClear($this->binDir);
|
||||
|
||||
$this->config->merge(array(
|
||||
'config' => array(
|
||||
'vendor-dir' => $this->vendorDir,
|
||||
'bin-dir' => $this->binDir,
|
||||
),
|
||||
));
|
||||
|
||||
$this->dm = $this->getMockBuilder('Composer\Downloader\DownloadManager')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
/* @var DownloadManager $dm */
|
||||
$dm = $this->dm;
|
||||
$this->composer->setDownloadManager($dm);
|
||||
|
||||
$this->repository = $this->getMockBuilder('Composer\Repository\InstalledRepositoryInterface')->getMock();
|
||||
$this->io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
|
||||
$this->type = $this->getMockBuilder('Fxp\Composer\AssetPlugin\Type\AssetTypeInterface')->getMock();
|
||||
$this->type->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo'));
|
||||
$this->type->expects($this->any())
|
||||
->method('getComposerVendorName')
|
||||
->will($this->returnValue('foo-asset'));
|
||||
$this->type->expects($this->any())
|
||||
->method('getComposerType')
|
||||
->will($this->returnValue('foo-asset-library'));
|
||||
$this->type->expects($this->any())
|
||||
->method('getFilename')
|
||||
->will($this->returnValue('foo.json'));
|
||||
$this->type->expects($this->any())
|
||||
->method('getVersionConverter')
|
||||
->will($this->returnValue($this->getMockBuilder('Fxp\Composer\AssetPlugin\Converter\VersionConverterInterface')->getMock()));
|
||||
$this->type->expects($this->any())
|
||||
->method('getPackageConverter')
|
||||
->will($this->returnValue($this->getMockBuilder('Fxp\Composer\AssetPlugin\Converter\PackageConverterInterface')->getMock()));
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$this->fs->removeDirectory($this->vendorDir);
|
||||
$this->fs->removeDirectory($this->binDir);
|
||||
}
|
||||
|
||||
public function testInstallerCreationShouldNotCreateVendorDirectory()
|
||||
{
|
||||
/* @var RootPackageInterface $rootPackage */
|
||||
$rootPackage = $this->createRootPackageMock();
|
||||
/* @var IOInterface $io */
|
||||
$io = $this->io;
|
||||
/* @var AssetTypeInterface $type */
|
||||
$type = $this->type;
|
||||
|
||||
$this->fs->removeDirectory($this->vendorDir);
|
||||
$this->composer->setPackage($rootPackage);
|
||||
|
||||
new BowerInstaller(ConfigBuilder::build($this->composer), $io, $this->composer, $type);
|
||||
$this->assertFileNotExists($this->vendorDir);
|
||||
}
|
||||
|
||||
public function testInstallerCreationShouldNotCreateBinDirectory()
|
||||
{
|
||||
/* @var RootPackageInterface $rootPackage */
|
||||
$rootPackage = $this->createRootPackageMock();
|
||||
/* @var IOInterface $io */
|
||||
$io = $this->io;
|
||||
/* @var AssetTypeInterface $type */
|
||||
$type = $this->type;
|
||||
|
||||
$this->fs->removeDirectory($this->binDir);
|
||||
$this->composer->setPackage($rootPackage);
|
||||
|
||||
new BowerInstaller(ConfigBuilder::build($this->composer), $io, $this->composer, $type);
|
||||
$this->assertFileNotExists($this->binDir);
|
||||
}
|
||||
|
||||
public function testIsInstalled()
|
||||
{
|
||||
/* @var RootPackageInterface $rootPackage */
|
||||
$rootPackage = $this->createRootPackageMock();
|
||||
/* @var IOInterface $io */
|
||||
$io = $this->io;
|
||||
/* @var AssetTypeInterface $type */
|
||||
$type = $this->type;
|
||||
|
||||
$this->composer->setPackage($rootPackage);
|
||||
|
||||
$library = new BowerInstaller(ConfigBuilder::build($this->composer), $io, $this->composer, $type);
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $package */
|
||||
$package = $this->createPackageMock();
|
||||
$package
|
||||
->expects($this->any())
|
||||
->method('getPrettyName')
|
||||
->will($this->returnValue('foo-asset/package'));
|
||||
|
||||
/* @var PackageInterface $package */
|
||||
$packageDir = $this->vendorDir.'/'.$package->getPrettyName();
|
||||
mkdir($packageDir, 0777, true);
|
||||
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $repository */
|
||||
$repository = $this->repository;
|
||||
$repository
|
||||
->expects($this->exactly(2))
|
||||
->method('hasPackage')
|
||||
->with($package)
|
||||
->will($this->onConsecutiveCalls(true, false));
|
||||
|
||||
/* @var InstalledRepositoryInterface $repository */
|
||||
$this->assertTrue($library->isInstalled($repository, $package));
|
||||
$this->assertFalse($library->isInstalled($repository, $package));
|
||||
|
||||
$this->ensureDirectoryExistsAndClear($packageDir);
|
||||
}
|
||||
|
||||
public function getAssetIgnoreFiles()
|
||||
{
|
||||
return array(
|
||||
array(array()),
|
||||
array(array('foo', 'bar')),
|
||||
);
|
||||
}
|
||||
|
||||
public function getAssetMainFiles()
|
||||
{
|
||||
return array(
|
||||
array(array()),
|
||||
array(array(
|
||||
'fxp-asset' => array(
|
||||
'main-files' => array(
|
||||
'foo-asset/bar' => array(
|
||||
'foo',
|
||||
'bar',
|
||||
),
|
||||
),
|
||||
),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetIgnoreFiles
|
||||
*
|
||||
* @param array $ignoreFiles
|
||||
*/
|
||||
public function testInstall(array $ignoreFiles)
|
||||
{
|
||||
/* @var RootPackageInterface $rootPackage */
|
||||
$rootPackage = $this->createRootPackageMock();
|
||||
/* @var IOInterface $io */
|
||||
$io = $this->io;
|
||||
/* @var AssetTypeInterface $type */
|
||||
$type = $this->type;
|
||||
|
||||
$this->composer->setPackage($rootPackage);
|
||||
|
||||
$library = new BowerInstaller(ConfigBuilder::build($this->composer), $io, $this->composer, $type);
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $package */
|
||||
$package = $this->createPackageMock($ignoreFiles);
|
||||
$package
|
||||
->expects($this->any())
|
||||
->method('getPrettyName')
|
||||
->will($this->returnValue('foo-asset/package'));
|
||||
|
||||
/* @var PackageInterface $package */
|
||||
$packageDir = $this->vendorDir.'/'.$package->getPrettyName();
|
||||
mkdir($packageDir, 0777, true);
|
||||
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $dm */
|
||||
$dm = $this->dm;
|
||||
$dm
|
||||
->expects($this->once())
|
||||
->method('download')
|
||||
->with($package, $this->vendorDir.DIRECTORY_SEPARATOR.'foo-asset/package');
|
||||
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $repository */
|
||||
$repository = $this->repository;
|
||||
$repository
|
||||
->expects($this->once())
|
||||
->method('addPackage')
|
||||
->with($package);
|
||||
|
||||
/* @var InstalledRepositoryInterface $repository */
|
||||
$library->install($repository, $package);
|
||||
$this->assertFileExists($this->vendorDir, 'Vendor dir should be created');
|
||||
$this->assertFileExists($this->binDir, 'Bin dir should be created');
|
||||
|
||||
$this->ensureDirectoryExistsAndClear($packageDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetIgnoreFiles
|
||||
*
|
||||
* @param array $ignoreFiles
|
||||
*/
|
||||
public function testUpdate(array $ignoreFiles)
|
||||
{
|
||||
/* @var RootPackageInterface $rootPackage */
|
||||
$rootPackage = $this->createRootPackageMock();
|
||||
/* @var IOInterface $io */
|
||||
$io = $this->io;
|
||||
/* @var AssetTypeInterface $type */
|
||||
$type = $this->type;
|
||||
|
||||
$this->composer->setPackage($rootPackage);
|
||||
|
||||
$library = new BowerInstaller(ConfigBuilder::build($this->composer), $io, $this->composer, $type);
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $package */
|
||||
$package = $this->createPackageMock($ignoreFiles);
|
||||
$package
|
||||
->expects($this->any())
|
||||
->method('getPrettyName')
|
||||
->will($this->returnValue('foo-asset/package'));
|
||||
|
||||
/* @var PackageInterface $package */
|
||||
$packageDir = $this->vendorDir.'/'.$package->getPrettyName();
|
||||
mkdir($packageDir, 0777, true);
|
||||
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $repository */
|
||||
$repository = $this->repository;
|
||||
|
||||
$repository
|
||||
->expects($this->exactly(2))
|
||||
->method('hasPackage')
|
||||
->with($package)
|
||||
->will($this->returnValue(true));
|
||||
|
||||
/* @var InstalledRepositoryInterface $repository */
|
||||
$library->update($repository, $package, $package);
|
||||
$this->assertFileExists($this->vendorDir, 'Vendor dir should be created');
|
||||
$this->assertFileExists($this->binDir, 'Bin dir should be created');
|
||||
|
||||
$this->ensureDirectoryExistsAndClear($packageDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testUninstall()
|
||||
{
|
||||
/* @var RootPackageInterface $rootPackage */
|
||||
$rootPackage = $this->createRootPackageMock();
|
||||
/* @var IOInterface $io */
|
||||
$io = $this->io;
|
||||
/* @var AssetTypeInterface $type */
|
||||
$type = $this->type;
|
||||
|
||||
$this->composer->setPackage($rootPackage);
|
||||
|
||||
$library = new BowerInstaller(ConfigBuilder::build($this->composer), $io, $this->composer, $type);
|
||||
$package = $this->createPackageMock();
|
||||
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $package */
|
||||
$package
|
||||
->expects($this->any())
|
||||
->method('getPrettyName')
|
||||
->will($this->returnValue('foo-asset/pkg'));
|
||||
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $repository */
|
||||
$repository = $this->repository;
|
||||
$repository
|
||||
->expects($this->exactly(2))
|
||||
->method('hasPackage')
|
||||
->with($package)
|
||||
->will($this->onConsecutiveCalls(true, false));
|
||||
|
||||
$repository
|
||||
->expects($this->once())
|
||||
->method('removePackage')
|
||||
->with($package);
|
||||
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $dm */
|
||||
$dm = $this->dm;
|
||||
$dm
|
||||
->expects($this->once())
|
||||
->method('remove')
|
||||
->with($package, $this->vendorDir.DIRECTORY_SEPARATOR.'foo-asset/pkg');
|
||||
|
||||
/* @var InstalledRepositoryInterface $repository */
|
||||
/* @var PackageInterface $package */
|
||||
$library->uninstall($repository, $package);
|
||||
|
||||
$library->uninstall($repository, $package);
|
||||
}
|
||||
|
||||
public function testGetInstallPath()
|
||||
{
|
||||
/* @var RootPackageInterface $rootPackage */
|
||||
$rootPackage = $this->createRootPackageMock();
|
||||
/* @var IOInterface $io */
|
||||
$io = $this->io;
|
||||
/* @var AssetTypeInterface $type */
|
||||
$type = $this->type;
|
||||
|
||||
$this->composer->setPackage($rootPackage);
|
||||
|
||||
$library = new BowerInstaller(ConfigBuilder::build($this->composer), $io, $this->composer, $type);
|
||||
$package = $this->createPackageMock();
|
||||
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $package */
|
||||
$package
|
||||
->expects($this->once())
|
||||
->method('getTargetDir')
|
||||
->will($this->returnValue(null));
|
||||
$package
|
||||
->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo-asset/bar'));
|
||||
$package
|
||||
->expects($this->any())
|
||||
->method('getPrettyName')
|
||||
->will($this->returnValue('foo-asset/bar'));
|
||||
|
||||
/* @var PackageInterface $package */
|
||||
$exceptDir = $this->vendorDir.'/'.$package->getName();
|
||||
$exceptDir = str_replace('\\', '/', $exceptDir);
|
||||
$packageDir = $library->getInstallPath($package);
|
||||
$packageDir = str_replace('\\', '/', $packageDir);
|
||||
|
||||
$this->assertEquals($exceptDir, $packageDir);
|
||||
}
|
||||
|
||||
public function testGetInstallPathWithTargetDir()
|
||||
{
|
||||
/* @var RootPackageInterface $rootPackage */
|
||||
$rootPackage = $this->createRootPackageMock();
|
||||
/* @var IOInterface $io */
|
||||
$io = $this->io;
|
||||
/* @var AssetTypeInterface $type */
|
||||
$type = $this->type;
|
||||
|
||||
$this->composer->setPackage($rootPackage);
|
||||
|
||||
$library = new BowerInstaller(ConfigBuilder::build($this->composer), $io, $this->composer, $type);
|
||||
$package = $this->createPackageMock();
|
||||
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $package */
|
||||
$package
|
||||
->expects($this->once())
|
||||
->method('getTargetDir')
|
||||
->will($this->returnValue('Some/Namespace'));
|
||||
$package
|
||||
->expects($this->any())
|
||||
->method('getPrettyName')
|
||||
->will($this->returnValue('foo-asset/bar'));
|
||||
|
||||
/* @var PackageInterface $package */
|
||||
$exceptDir = $this->vendorDir.'/'.$package->getPrettyName().'/Some/Namespace';
|
||||
$exceptDir = str_replace('\\', '/', $exceptDir);
|
||||
$packageDir = $library->getInstallPath($package);
|
||||
$packageDir = str_replace('\\', '/', $packageDir);
|
||||
|
||||
$this->assertEquals($exceptDir, $packageDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetMainFiles
|
||||
*
|
||||
* @param array $mainFiles
|
||||
*/
|
||||
public function testMainFiles(array $mainFiles)
|
||||
{
|
||||
/* @var RootPackageInterface $rootPackage */
|
||||
$rootPackage = $this->createRootPackageMock($mainFiles);
|
||||
$this->composer->setPackage($rootPackage);
|
||||
$config = ConfigBuilder::build($this->composer);
|
||||
|
||||
$package = new Package('foo-asset/bar', '1.0.0', '1.0.0');
|
||||
$package = AssetPlugin::addMainFiles($config, $package);
|
||||
$extra = $package->getExtra();
|
||||
|
||||
if (isset($mainFiles['fxp-asset']['main-files'])) {
|
||||
$this->assertEquals($extra['bower-asset-main'], $mainFiles['fxp-asset']['main-files']['foo-asset/bar']);
|
||||
} else {
|
||||
$this->assertEquals($extra, array());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $ignoreFiles
|
||||
*
|
||||
* @return PackageInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected function createPackageMock(array $ignoreFiles = array())
|
||||
{
|
||||
$package = $this->getMockBuilder('Composer\Package\Package')
|
||||
->setConstructorArgs(array(md5(mt_rand()), '1.0.0.0', '1.0.0'))
|
||||
->getMock();
|
||||
|
||||
$package
|
||||
->expects($this->any())
|
||||
->method('getExtra')
|
||||
->will($this->returnValue(array(
|
||||
'bower-asset-ignore' => $ignoreFiles,
|
||||
)));
|
||||
|
||||
return $package;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $mainFiles
|
||||
*
|
||||
* @return RootPackageInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected function createRootPackageMock(array $mainFiles = array())
|
||||
{
|
||||
$package = $this->getMockBuilder('Composer\Package\RootPackageInterface')
|
||||
->setConstructorArgs(array(md5(mt_rand()), '1.0.0.0', '1.0.0'))
|
||||
->getMock();
|
||||
|
||||
$package
|
||||
->expects($this->any())
|
||||
->method('getConfig')
|
||||
->will($this->returnValue($mainFiles));
|
||||
|
||||
return $package;
|
||||
}
|
||||
}
|
|
@ -1,221 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Installer;
|
||||
|
||||
use Composer\Composer;
|
||||
use Composer\Config;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Package\RootPackageInterface;
|
||||
use Fxp\Composer\AssetPlugin\Config\ConfigBuilder;
|
||||
use Fxp\Composer\AssetPlugin\Installer\IgnoreFactory;
|
||||
use Fxp\Composer\AssetPlugin\Installer\IgnoreManager;
|
||||
|
||||
/**
|
||||
* Tests of ignore factory.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class IgnoreFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var Composer|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $composer;
|
||||
|
||||
/**
|
||||
* @var Config|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var RootPackageInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $rootPackage;
|
||||
|
||||
/**
|
||||
* @var PackageInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $package;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->config = $this->getMockBuilder('Composer\Config')->getMock();
|
||||
$this->config->expects($this->any())
|
||||
->method('get')
|
||||
->will($this->returnCallback(function ($key) {
|
||||
$value = null;
|
||||
|
||||
switch ($key) {
|
||||
case 'cache-repo-dir':
|
||||
$value = sys_get_temp_dir().'/composer-test-repo-cache';
|
||||
break;
|
||||
case 'vendor-dir':
|
||||
$value = sys_get_temp_dir().'/composer-test/vendor';
|
||||
break;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}));
|
||||
|
||||
$this->rootPackage = $this->getMockBuilder('Composer\Package\RootPackageInterface')->getMock();
|
||||
$this->package = $this->getMockBuilder('Composer\Package\PackageInterface')->getMock();
|
||||
$this->package->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo-asset/foo'));
|
||||
|
||||
$this->composer = $this->getMockBuilder('Composer\Composer')->getMock();
|
||||
$this->composer->expects($this->any())
|
||||
->method('getPackage')
|
||||
->will($this->returnValue($this->rootPackage));
|
||||
$this->composer->expects($this->any())
|
||||
->method('getConfig')
|
||||
->will($this->returnValue($this->config));
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->composer = null;
|
||||
$this->config = null;
|
||||
$this->rootPackage = null;
|
||||
$this->package = null;
|
||||
}
|
||||
|
||||
public function testCreateWithoutIgnoreFiles()
|
||||
{
|
||||
$config = ConfigBuilder::build($this->composer);
|
||||
$manager = IgnoreFactory::create($config, $this->composer, $this->package);
|
||||
|
||||
$this->assertTrue($manager->isEnabled());
|
||||
$this->assertFalse($manager->hasPattern());
|
||||
$this->validateInstallDir($manager, $this->config->get('vendor-dir').'/'.$this->package->getName());
|
||||
}
|
||||
|
||||
public function testCreateWithIgnoreFiles()
|
||||
{
|
||||
$config = array(
|
||||
'fxp-asset' => array(
|
||||
'ignore-files' => array(
|
||||
'foo-asset/foo' => array(
|
||||
'PATTERN',
|
||||
),
|
||||
'foo-asset/bar' => array(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->rootPackage->expects($this->any())
|
||||
->method('getConfig')
|
||||
->will($this->returnValue($config));
|
||||
|
||||
$config = ConfigBuilder::build($this->composer);
|
||||
$manager = IgnoreFactory::create($config, $this->composer, $this->package);
|
||||
|
||||
$this->assertTrue($manager->isEnabled());
|
||||
$this->assertTrue($manager->hasPattern());
|
||||
$this->validateInstallDir($manager, $this->config->get('vendor-dir').'/'.$this->package->getName());
|
||||
}
|
||||
|
||||
public function testCreateWithCustomInstallDir()
|
||||
{
|
||||
$installDir = 'web/assets/';
|
||||
$config = ConfigBuilder::build($this->composer);
|
||||
$manager = IgnoreFactory::create($config, $this->composer, $this->package, $installDir);
|
||||
|
||||
$this->assertTrue($manager->isEnabled());
|
||||
$this->assertFalse($manager->hasPattern());
|
||||
$this->validateInstallDir($manager, rtrim($installDir, '/'));
|
||||
}
|
||||
|
||||
public function testCreateWithEnablingOfIgnoreFiles()
|
||||
{
|
||||
$config = array(
|
||||
'fxp-asset' => array(
|
||||
'ignore-files' => array(
|
||||
'foo-asset/foo' => true,
|
||||
'foo-asset/bar' => array(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->rootPackage->expects($this->any())
|
||||
->method('getConfig')
|
||||
->will($this->returnValue($config));
|
||||
|
||||
$config = ConfigBuilder::build($this->composer);
|
||||
$manager = IgnoreFactory::create($config, $this->composer, $this->package);
|
||||
|
||||
$this->assertTrue($manager->isEnabled());
|
||||
$this->assertFalse($manager->hasPattern());
|
||||
$this->validateInstallDir($manager, $this->config->get('vendor-dir').'/'.$this->package->getName());
|
||||
}
|
||||
|
||||
public function testCreateWithDisablingOfIgnoreFiles()
|
||||
{
|
||||
$config = array(
|
||||
'fxp-asset' => array(
|
||||
'ignore-files' => array(
|
||||
'foo-asset/foo' => false,
|
||||
'foo-asset/bar' => array(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->rootPackage->expects($this->any())
|
||||
->method('getConfig')
|
||||
->will($this->returnValue($config));
|
||||
|
||||
$config = ConfigBuilder::build($this->composer);
|
||||
$manager = IgnoreFactory::create($config, $this->composer, $this->package);
|
||||
|
||||
$this->assertFalse($manager->isEnabled());
|
||||
$this->assertFalse($manager->hasPattern());
|
||||
$this->validateInstallDir($manager, $this->config->get('vendor-dir').'/'.$this->package->getName());
|
||||
}
|
||||
|
||||
public function testCreateWithCustomIgnoreSection()
|
||||
{
|
||||
$config = array(
|
||||
'fxp-asset' => array(
|
||||
'custom-ignore-files' => array(
|
||||
'foo-asset/foo' => array(
|
||||
'PATTERN',
|
||||
),
|
||||
'foo-asset/bar' => array(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->rootPackage->expects($this->any())
|
||||
->method('getConfig')
|
||||
->will($this->returnValue($config));
|
||||
|
||||
$config = ConfigBuilder::build($this->composer);
|
||||
$manager = IgnoreFactory::create($config, $this->composer, $this->package, null, 'custom-ignore-files');
|
||||
|
||||
$this->assertTrue($manager->isEnabled());
|
||||
$this->assertTrue($manager->hasPattern());
|
||||
$this->validateInstallDir($manager, $this->config->get('vendor-dir').'/'.$this->package->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IgnoreManager $manager
|
||||
* @param string $installDir
|
||||
*/
|
||||
protected function validateInstallDir(IgnoreManager $manager, $installDir)
|
||||
{
|
||||
$ref = new \ReflectionClass($manager);
|
||||
$prop = $ref->getProperty('installDir');
|
||||
$prop->setAccessible(true);
|
||||
|
||||
$this->assertSame($installDir, $prop->getValue($manager));
|
||||
}
|
||||
}
|
|
@ -1,250 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Installer;
|
||||
|
||||
use Composer\Util\Filesystem;
|
||||
use Fxp\Composer\AssetPlugin\Installer\IgnoreManager;
|
||||
|
||||
/**
|
||||
* Tests of manager of ignore patterns.
|
||||
*
|
||||
* @author Martin Hasoň <martin.hason@gmail.com>
|
||||
*/
|
||||
class IgnoreManagerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $target;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$fs = new Filesystem();
|
||||
$this->target = sys_get_temp_dir().'/composer-foo';
|
||||
|
||||
foreach ($this->getFixtureFiles() as $filename) {
|
||||
$path = $this->target.'/'.$filename;
|
||||
$fs->ensureDirectoryExists(dirname($path));
|
||||
@file_put_contents($path, '');
|
||||
}
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$fs = new Filesystem();
|
||||
$fs->remove($this->target);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getFixtureFiles()
|
||||
{
|
||||
return array(
|
||||
'.hidden',
|
||||
'CHANGELOG',
|
||||
'README',
|
||||
'lib/autoload.php',
|
||||
'src/.hidden',
|
||||
'src/doc',
|
||||
'src/foo/.hidden',
|
||||
'src/foo/empty.html',
|
||||
'src/foo/empty.md',
|
||||
'src/foo/empty.txt',
|
||||
'src/foo/small.txt',
|
||||
'src/lib/empty.txt',
|
||||
'src/lib/foo/empty.txt',
|
||||
'src/lib/foo/small.txt',
|
||||
'src/tests/empty.html',
|
||||
'tests/bootstrap.php',
|
||||
);
|
||||
}
|
||||
|
||||
public function testDeleteIgnoredFiles()
|
||||
{
|
||||
$ignorer = new IgnoreManager($this->target);
|
||||
$ignorer->addPattern('.*');
|
||||
$ignorer->addPattern('**/.*');
|
||||
$ignorer->addPattern('README');
|
||||
$ignorer->addPattern('**/*.md');
|
||||
$ignorer->addPattern('lib');
|
||||
$ignorer->addPattern('tests');
|
||||
$ignorer->addPattern('**/doc');
|
||||
$ignorer->addPattern('src/foo/*.txt');
|
||||
$ignorer->addPattern('!src/foo/small.txt');
|
||||
|
||||
$ignorer->cleanup();
|
||||
|
||||
$this->assertFileNotExists($this->target.'/.hidden');
|
||||
$this->assertFileExists($this->target.'/CHANGELOG');
|
||||
$this->assertFileNotExists($this->target.'/README');
|
||||
|
||||
$this->assertFileNotExists($this->target.'/lib/autoload.php');
|
||||
$this->assertFileNotExists($this->target.'/lib');
|
||||
|
||||
$this->assertFileNotExists($this->target.'/src/.hidden');
|
||||
$this->assertFileNotExists($this->target.'/src/doc');
|
||||
$this->assertFileExists($this->target.'/src');
|
||||
|
||||
$this->assertFileNotExists($this->target.'/src/foo/.hidden');
|
||||
$this->assertFileExists($this->target.'/src/foo/empty.html');
|
||||
$this->assertFileNotExists($this->target.'/src/foo/empty.md');
|
||||
$this->assertFileNotExists($this->target.'/src/foo/empty.txt');
|
||||
$this->assertFileExists($this->target.'/src/foo/small.txt');
|
||||
$this->assertFileExists($this->target.'/src/foo');
|
||||
|
||||
$this->assertFileExists($this->target.'/src/lib/empty.txt');
|
||||
$this->assertFileExists($this->target.'/src/lib');
|
||||
|
||||
$this->assertFileExists($this->target.'/src/lib/foo/empty.txt');
|
||||
$this->assertFileExists($this->target.'/src/lib/foo/small.txt');
|
||||
$this->assertFileExists($this->target.'/src/lib/foo');
|
||||
|
||||
$this->assertFileExists($this->target.'/src/tests/empty.html');
|
||||
$this->assertFileExists($this->target.'/src/tests');
|
||||
|
||||
$this->assertFileNotExists($this->target.'/tests/bootstrap.php');
|
||||
$this->assertFileNotExists($this->target.'/tests');
|
||||
}
|
||||
|
||||
public function testDeleteIgnoredFilesWithDisabledManager()
|
||||
{
|
||||
$ignorer = new IgnoreManager($this->target);
|
||||
$ignorer->setEnabled(false);
|
||||
$ignorer->addPattern('.*');
|
||||
$ignorer->addPattern('**/.*');
|
||||
$ignorer->addPattern('README');
|
||||
$ignorer->addPattern('**/*.md');
|
||||
$ignorer->addPattern('lib');
|
||||
$ignorer->addPattern('tests');
|
||||
$ignorer->addPattern('**/doc');
|
||||
$ignorer->addPattern('src/foo/*.txt');
|
||||
$ignorer->addPattern('!src/foo/small.txt');
|
||||
|
||||
$ignorer->cleanup();
|
||||
|
||||
$this->assertFileExists($this->target.'/.hidden');
|
||||
$this->assertFileExists($this->target.'/CHANGELOG');
|
||||
$this->assertFileExists($this->target.'/README');
|
||||
|
||||
$this->assertFileExists($this->target.'/lib/autoload.php');
|
||||
$this->assertFileExists($this->target.'/lib');
|
||||
|
||||
$this->assertFileExists($this->target.'/src/.hidden');
|
||||
$this->assertFileExists($this->target.'/src/doc');
|
||||
$this->assertFileExists($this->target.'/src');
|
||||
|
||||
$this->assertFileExists($this->target.'/src/foo/.hidden');
|
||||
$this->assertFileExists($this->target.'/src/foo/empty.html');
|
||||
$this->assertFileExists($this->target.'/src/foo/empty.md');
|
||||
$this->assertFileExists($this->target.'/src/foo/empty.txt');
|
||||
$this->assertFileExists($this->target.'/src/foo/small.txt');
|
||||
$this->assertFileExists($this->target.'/src/foo');
|
||||
|
||||
$this->assertFileExists($this->target.'/src/lib/empty.txt');
|
||||
$this->assertFileExists($this->target.'/src/lib');
|
||||
|
||||
$this->assertFileExists($this->target.'/src/lib/foo/empty.txt');
|
||||
$this->assertFileExists($this->target.'/src/lib/foo/small.txt');
|
||||
$this->assertFileExists($this->target.'/src/lib/foo');
|
||||
|
||||
$this->assertFileExists($this->target.'/src/tests/empty.html');
|
||||
$this->assertFileExists($this->target.'/src/tests');
|
||||
|
||||
$this->assertFileExists($this->target.'/tests/bootstrap.php');
|
||||
$this->assertFileExists($this->target.'/tests');
|
||||
}
|
||||
|
||||
public function testIgnoreAllFilesExceptAFew()
|
||||
{
|
||||
$ignorer = new IgnoreManager($this->target);
|
||||
$ignorer->addPattern('*');
|
||||
$ignorer->addPattern('**/.*');
|
||||
$ignorer->addPattern('!README');
|
||||
$ignorer->addPattern('!lib/*');
|
||||
$ignorer->addPattern('!tests');
|
||||
|
||||
$ignorer->cleanup();
|
||||
|
||||
$this->assertFileNotExists($this->target.'/.hidden');
|
||||
$this->assertFileNotExists($this->target.'/CHANGELOG');
|
||||
$this->assertFileExists($this->target.'/README');
|
||||
|
||||
$this->assertFileExists($this->target.'/lib/autoload.php');
|
||||
$this->assertFileExists($this->target.'/lib');
|
||||
|
||||
$this->assertFileNotExists($this->target.'/src/.hidden');
|
||||
$this->assertFileNotExists($this->target.'/src/doc');
|
||||
$this->assertFileNotExists($this->target.'/src');
|
||||
|
||||
$this->assertFileNotExists($this->target.'/src/foo/.hidden');
|
||||
$this->assertFileNotExists($this->target.'/src/foo/empty.html');
|
||||
$this->assertFileNotExists($this->target.'/src/foo/empty.md');
|
||||
$this->assertFileNotExists($this->target.'/src/foo/empty.txt');
|
||||
$this->assertFileNotExists($this->target.'/src/foo/small.txt');
|
||||
$this->assertFileNotExists($this->target.'/src/foo');
|
||||
|
||||
$this->assertFileNotExists($this->target.'/src/lib/empty.txt');
|
||||
$this->assertFileNotExists($this->target.'/src/lib');
|
||||
|
||||
$this->assertFileNotExists($this->target.'/src/lib/foo/empty.txt');
|
||||
$this->assertFileNotExists($this->target.'/src/lib/foo/small.txt');
|
||||
$this->assertFileNotExists($this->target.'/src/lib/foo');
|
||||
|
||||
$this->assertFileNotExists($this->target.'/src/tests/empty.html');
|
||||
$this->assertFileNotExists($this->target.'/src/tests');
|
||||
|
||||
$this->assertFileExists($this->target.'/tests/bootstrap.php');
|
||||
$this->assertFileExists($this->target.'/tests');
|
||||
}
|
||||
|
||||
public function testIgnoreAllFilesExceptAFewWithDoubleAsterisks()
|
||||
{
|
||||
$ignorer = new IgnoreManager($this->target);
|
||||
|
||||
$ignorer->addPattern('**');
|
||||
$ignorer->addPattern('!/src/foo/*.txt');
|
||||
|
||||
$ignorer->cleanup();
|
||||
|
||||
$this->assertFileExists($this->target.'/.hidden');
|
||||
$this->assertFileNotExists($this->target.'/CHANGELOG');
|
||||
$this->assertFileNotExists($this->target.'/README');
|
||||
|
||||
$this->assertFileNotExists($this->target.'/lib/autoload.php');
|
||||
$this->assertFileNotExists($this->target.'/lib');
|
||||
|
||||
$this->assertFileNotExists($this->target.'/src/.hidden');
|
||||
$this->assertFileNotExists($this->target.'/src/doc');
|
||||
$this->assertFileExists($this->target.'/src');
|
||||
|
||||
$this->assertFileNotExists($this->target.'/src/foo/.hidden');
|
||||
$this->assertFileNotExists($this->target.'/src/foo/empty.html');
|
||||
$this->assertFileNotExists($this->target.'/src/foo/empty.md');
|
||||
$this->assertFileExists($this->target.'/src/foo/empty.txt');
|
||||
$this->assertFileExists($this->target.'/src/foo/small.txt');
|
||||
$this->assertFileExists($this->target.'/src/foo');
|
||||
|
||||
$this->assertFileNotExists($this->target.'/src/lib/empty.txt');
|
||||
$this->assertFileNotExists($this->target.'/src/lib');
|
||||
|
||||
$this->assertFileNotExists($this->target.'/src/lib/foo/empty.txt');
|
||||
$this->assertFileNotExists($this->target.'/src/lib/foo/small.txt');
|
||||
$this->assertFileNotExists($this->target.'/src/lib/foo');
|
||||
|
||||
$this->assertFileNotExists($this->target.'/src/tests/empty.html');
|
||||
$this->assertFileNotExists($this->target.'/src/tests');
|
||||
|
||||
$this->assertFileNotExists($this->target.'/tests/bootstrap.php');
|
||||
$this->assertFileNotExists($this->target.'/tests');
|
||||
}
|
||||
}
|
|
@ -1,438 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Package\Loader;
|
||||
|
||||
use Composer\Downloader\TransportException;
|
||||
use Composer\Package\CompletePackageInterface;
|
||||
use Composer\Package\Loader\LoaderInterface;
|
||||
use Composer\Repository\Vcs\VcsDriverInterface;
|
||||
use Fxp\Composer\AssetPlugin\Converter\PackageConverterInterface;
|
||||
use Fxp\Composer\AssetPlugin\Converter\VersionConverterInterface;
|
||||
use Fxp\Composer\AssetPlugin\Package\LazyPackageInterface;
|
||||
use Fxp\Composer\AssetPlugin\Package\Loader\LazyAssetPackageLoader;
|
||||
use Fxp\Composer\AssetPlugin\Repository\AssetRepositoryManager;
|
||||
use Fxp\Composer\AssetPlugin\Tests\Fixtures\IO\MockIO;
|
||||
use Fxp\Composer\AssetPlugin\Type\AssetTypeInterface;
|
||||
|
||||
/**
|
||||
* Tests of lazy asset package loader.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class LazyAssetPackageLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var LazyAssetPackageLoader
|
||||
*/
|
||||
protected $lazyLoader;
|
||||
|
||||
/**
|
||||
* @var LazyPackageInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $lazyPackage;
|
||||
|
||||
/**
|
||||
* @var AssetTypeInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $assetType;
|
||||
|
||||
/**
|
||||
* @var LoaderInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $loader;
|
||||
|
||||
/**
|
||||
* @var VcsDriverInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $driver;
|
||||
|
||||
/**
|
||||
* @var MockIO
|
||||
*/
|
||||
protected $io;
|
||||
|
||||
/**
|
||||
* @var AssetRepositoryManager|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $assetRepositoryManager;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->lazyPackage = $this->getMockBuilder(LazyPackageInterface::class)->getMock();
|
||||
$this->assetType = $this->getMockBuilder(AssetTypeInterface::class)->getMock();
|
||||
$this->loader = $this->getMockBuilder(LoaderInterface::class)->getMock();
|
||||
$this->driver = $this->getMockBuilder(VcsDriverInterface::class)->getMock();
|
||||
$this->assetRepositoryManager = $this->getMockBuilder(AssetRepositoryManager::class)
|
||||
->disableOriginalConstructor()->getMock();
|
||||
|
||||
$this->assetRepositoryManager->expects($this->any())
|
||||
->method('solveResolutions')
|
||||
->willReturnCallback(function ($value) {
|
||||
return $value;
|
||||
});
|
||||
|
||||
$this->lazyPackage
|
||||
->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('PACKAGE_NAME'));
|
||||
$this->lazyPackage
|
||||
->expects($this->any())
|
||||
->method('getUniqueName')
|
||||
->will($this->returnValue('PACKAGE_NAME-1.0.0.0'));
|
||||
$this->lazyPackage
|
||||
->expects($this->any())
|
||||
->method('getPrettyVersion')
|
||||
->will($this->returnValue('1.0'));
|
||||
$this->lazyPackage
|
||||
->expects($this->any())
|
||||
->method('getVersion')
|
||||
->will($this->returnValue('1.0.0.0'));
|
||||
|
||||
$versionConverter = $this->getMockBuilder(VersionConverterInterface::class)->getMock();
|
||||
$versionConverter->expects($this->any())
|
||||
->method('convertVersion')
|
||||
->will($this->returnValue('VERSION_CONVERTED'));
|
||||
$versionConverter->expects($this->any())
|
||||
->method('convertRange')
|
||||
->will($this->returnCallback(function ($value) {
|
||||
return $value;
|
||||
}));
|
||||
$packageConverter = $this->getMockBuilder(PackageConverterInterface::class)->getMock();
|
||||
/* @var LazyPackageInterface $lasyPackage */
|
||||
$lasyPackage = $this->lazyPackage;
|
||||
$packageConverter->expects($this->any())
|
||||
->method('convert')
|
||||
->will($this->returnCallback(function ($value) use ($lasyPackage) {
|
||||
$value['version'] = $lasyPackage->getPrettyVersion();
|
||||
$value['version_normalized'] = $lasyPackage->getVersion();
|
||||
|
||||
return $value;
|
||||
}));
|
||||
$this->assetType->expects($this->any())
|
||||
->method('getComposerVendorName')
|
||||
->will($this->returnValue('ASSET'));
|
||||
$this->assetType->expects($this->any())
|
||||
->method('getComposerType')
|
||||
->will($this->returnValue('ASSET_TYPE'));
|
||||
$this->assetType->expects($this->any())
|
||||
->method('getFilename')
|
||||
->will($this->returnValue('ASSET.json'));
|
||||
$this->assetType->expects($this->any())
|
||||
->method('getVersionConverter')
|
||||
->will($this->returnValue($versionConverter));
|
||||
$this->assetType->expects($this->any())
|
||||
->method('getPackageConverter')
|
||||
->will($this->returnValue($packageConverter));
|
||||
|
||||
$this->driver
|
||||
->expects($this->any())
|
||||
->method('getDist')
|
||||
->will($this->returnCallback(function ($value) {
|
||||
return array(
|
||||
'type' => 'vcs',
|
||||
'url' => 'http://foobar.tld/dist/'.$value,
|
||||
);
|
||||
}));
|
||||
$this->driver
|
||||
->expects($this->any())
|
||||
->method('getSource')
|
||||
->will($this->returnCallback(function ($value) {
|
||||
return array(
|
||||
'type' => 'vcs',
|
||||
'url' => 'http://foobar.tld/source/'.$value,
|
||||
);
|
||||
}));
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$this->lazyPackage = null;
|
||||
$this->assetType = null;
|
||||
$this->loader = null;
|
||||
$this->driver = null;
|
||||
$this->io = null;
|
||||
$this->assetRepositoryManager = null;
|
||||
$this->lazyLoader = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Fxp\Composer\AssetPlugin\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "assetType" property must be defined
|
||||
*/
|
||||
public function testMissingAssetType()
|
||||
{
|
||||
$loader = $this->createLazyLoader('TYPE');
|
||||
$loader->load($this->lazyPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Fxp\Composer\AssetPlugin\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "loader" property must be defined
|
||||
*/
|
||||
public function testMissingLoader()
|
||||
{
|
||||
/* @var AssetTypeInterface $assetType */
|
||||
$assetType = $this->assetType;
|
||||
$loader = $this->createLazyLoader('TYPE');
|
||||
$loader->setAssetType($assetType);
|
||||
$loader->load($this->lazyPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Fxp\Composer\AssetPlugin\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "driver" property must be defined
|
||||
*/
|
||||
public function testMissingDriver()
|
||||
{
|
||||
/* @var AssetTypeInterface $assetType */
|
||||
$assetType = $this->assetType;
|
||||
/* @var LoaderInterface $cLoader */
|
||||
$cLoader = $this->loader;
|
||||
/* @var LazyPackageInterface $lazyPackage */
|
||||
$lazyPackage = $this->lazyPackage;
|
||||
$loader = $this->createLazyLoader('TYPE');
|
||||
$loader->setAssetType($assetType);
|
||||
$loader->setLoader($cLoader);
|
||||
$loader->load($lazyPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Fxp\Composer\AssetPlugin\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The "io" property must be defined
|
||||
*/
|
||||
public function testMissingIo()
|
||||
{
|
||||
/* @var AssetTypeInterface $assetType */
|
||||
$assetType = $this->assetType;
|
||||
/* @var LoaderInterface $cLoader */
|
||||
$cLoader = $this->loader;
|
||||
/* @var VcsDriverInterface $driver */
|
||||
$driver = $this->driver;
|
||||
$loader = $this->createLazyLoader('TYPE');
|
||||
$loader->setAssetType($assetType);
|
||||
$loader->setLoader($cLoader);
|
||||
$loader->setDriver($driver);
|
||||
$loader->load($this->lazyPackage);
|
||||
}
|
||||
|
||||
public function getConfigIo()
|
||||
{
|
||||
return array(
|
||||
array(false),
|
||||
array(true),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $verbose
|
||||
*
|
||||
* @dataProvider getConfigIo
|
||||
*/
|
||||
public function testWithoutJsonFile($verbose)
|
||||
{
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $driver */
|
||||
$driver = $this->driver;
|
||||
$driver
|
||||
->expects($this->any())
|
||||
->method('getComposerInformation')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $loader */
|
||||
$loader = $this->loader;
|
||||
$loader
|
||||
->expects($this->any())
|
||||
->method('load')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$this->lazyLoader = $this->createLazyLoaderConfigured('TYPE', $verbose);
|
||||
$package = $this->lazyLoader->load($this->lazyPackage);
|
||||
|
||||
$this->assertFalse($package);
|
||||
|
||||
$filename = $this->assetType->getFilename();
|
||||
$validOutput = array('');
|
||||
|
||||
if ($verbose) {
|
||||
$validOutput = array(
|
||||
'Reading '.$filename.' of <info>'.$this->lazyPackage->getName().'</info> (<comment>'.$this->lazyPackage->getPrettyVersion().'</comment>)',
|
||||
'Importing empty TYPE '.$this->lazyPackage->getPrettyVersion().' ('.$this->lazyPackage->getVersion().')',
|
||||
'',
|
||||
);
|
||||
}
|
||||
$this->assertSame($validOutput, $this->io->getTraces());
|
||||
|
||||
$packageCache = $this->lazyLoader->load($this->lazyPackage);
|
||||
$this->assertFalse($packageCache);
|
||||
$this->assertSame($validOutput, $this->io->getTraces());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $verbose
|
||||
*
|
||||
* @dataProvider getConfigIo
|
||||
*/
|
||||
public function testWithJsonFile($verbose)
|
||||
{
|
||||
$arrayPackage = array(
|
||||
'name' => 'PACKAGE_NAME',
|
||||
'version' => '1.0',
|
||||
);
|
||||
|
||||
$realPackage = $this->getMockBuilder(CompletePackageInterface::class)->getMock();
|
||||
$realPackage
|
||||
->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('PACKAGE_NAME'));
|
||||
$realPackage
|
||||
->expects($this->any())
|
||||
->method('getUniqueName')
|
||||
->will($this->returnValue('PACKAGE_NAME-1.0.0.0'));
|
||||
$realPackage
|
||||
->expects($this->any())
|
||||
->method('getPrettyVersion')
|
||||
->will($this->returnValue('1.0'));
|
||||
$realPackage
|
||||
->expects($this->any())
|
||||
->method('getVersion')
|
||||
->will($this->returnValue('1.0.0.0'));
|
||||
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $driver */
|
||||
$driver = $this->driver;
|
||||
$driver
|
||||
->expects($this->any())
|
||||
->method('getComposerInformation')
|
||||
->will($this->returnValue($arrayPackage));
|
||||
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $loader */
|
||||
$loader = $this->loader;
|
||||
$loader
|
||||
->expects($this->any())
|
||||
->method('load')
|
||||
->will($this->returnValue($realPackage));
|
||||
|
||||
$this->lazyLoader = $this->createLazyLoaderConfigured('TYPE', $verbose);
|
||||
$package = $this->lazyLoader->load($this->lazyPackage);
|
||||
|
||||
$filename = $this->assetType->getFilename();
|
||||
$validOutput = array('');
|
||||
|
||||
if ($verbose) {
|
||||
$validOutput = array(
|
||||
'Reading '.$filename.' of <info>'.$this->lazyPackage->getName().'</info> (<comment>'.$this->lazyPackage->getPrettyVersion().'</comment>)',
|
||||
'Importing TYPE'.' '.$this->lazyPackage->getPrettyVersion().' ('.$this->lazyPackage->getVersion().')',
|
||||
'',
|
||||
);
|
||||
}
|
||||
|
||||
$this->assertInstanceOf('Composer\Package\CompletePackageInterface', $package);
|
||||
$this->assertSame($validOutput, $this->io->getTraces());
|
||||
|
||||
$packageCache = $this->lazyLoader->load($this->lazyPackage);
|
||||
$this->assertInstanceOf('Composer\Package\CompletePackageInterface', $packageCache);
|
||||
$this->assertSame($package, $packageCache);
|
||||
$this->assertSame($validOutput, $this->io->getTraces());
|
||||
}
|
||||
|
||||
public function getConfigIoForException()
|
||||
{
|
||||
return array(
|
||||
array('tag', false, 'Exception', '<warning>Skipped tag 1.0, MESSAGE</warning>'),
|
||||
array('tag', true, 'Exception', '<warning>Skipped tag 1.0, MESSAGE</warning>'),
|
||||
array('branch', false, 'Exception', '<error>Skipped branch 1.0, MESSAGE</error>'),
|
||||
array('branch', true, 'Exception', '<error>Skipped branch 1.0, MESSAGE</error>'),
|
||||
array('tag', false, TransportException::class, '<warning>Skipped tag 1.0, no ASSET.json file was found</warning>'),
|
||||
array('tag', true, TransportException::class, '<warning>Skipped tag 1.0, no ASSET.json file was found</warning>'),
|
||||
array('branch', false, TransportException::class, '<error>Skipped branch 1.0, no ASSET.json file was found</error>'),
|
||||
array('branch', true, TransportException::class, '<error>Skipped branch 1.0, no ASSET.json file was found</error>'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param bool $verbose
|
||||
* @param string $exceptionClass
|
||||
* @param string $validTrace
|
||||
*
|
||||
* @dataProvider getConfigIoForException
|
||||
*/
|
||||
public function testTagWithTransportException($type, $verbose, $exceptionClass, $validTrace)
|
||||
{
|
||||
/* @var \PHPUnit_Framework_MockObject_MockObject $loader */
|
||||
$loader = $this->loader;
|
||||
$loader
|
||||
->expects($this->any())
|
||||
->method('load')
|
||||
->will($this->throwException(new $exceptionClass('MESSAGE')));
|
||||
|
||||
$this->lazyLoader = $this->createLazyLoaderConfigured($type, $verbose);
|
||||
$package = $this->lazyLoader->load($this->lazyPackage);
|
||||
|
||||
$this->assertFalse($package);
|
||||
|
||||
$filename = $this->assetType->getFilename();
|
||||
$validOutput = array('');
|
||||
|
||||
if ($verbose) {
|
||||
$validOutput = array(
|
||||
'Reading '.$filename.' of <info>'.$this->lazyPackage->getName().'</info> (<comment>'.$this->lazyPackage->getPrettyVersion().'</comment>)',
|
||||
'Importing empty '.$type.' '.$this->lazyPackage->getPrettyVersion().' ('.$this->lazyPackage->getVersion().')',
|
||||
$validTrace,
|
||||
'',
|
||||
);
|
||||
}
|
||||
$this->assertSame($validOutput, $this->io->getTraces());
|
||||
|
||||
$packageCache = $this->lazyLoader->load($this->lazyPackage);
|
||||
$this->assertFalse($packageCache);
|
||||
$this->assertSame($validOutput, $this->io->getTraces());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the lazy asset package loader with full configuration.
|
||||
*
|
||||
* @param string $type
|
||||
* @param bool $verbose
|
||||
*
|
||||
* @return LazyAssetPackageLoader
|
||||
*/
|
||||
protected function createLazyLoaderConfigured($type, $verbose = false)
|
||||
{
|
||||
$this->io = new MockIO($verbose);
|
||||
|
||||
$cLoader = $this->loader;
|
||||
$loader = $this->createLazyLoader($type);
|
||||
$loader->setAssetType($this->assetType);
|
||||
$loader->setLoader($cLoader);
|
||||
$loader->setDriver($this->driver);
|
||||
$loader->setIO($this->io);
|
||||
$loader->setAssetRepositoryManager($this->assetRepositoryManager);
|
||||
|
||||
return $loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the lazy asset package loader.
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return LazyAssetPackageLoader
|
||||
*/
|
||||
protected function createLazyLoader($type)
|
||||
{
|
||||
$data = array(
|
||||
'foo' => 'bar',
|
||||
'bar' => 'foo',
|
||||
);
|
||||
|
||||
return new LazyAssetPackageLoader($type, 'IDENTIFIER', $data);
|
||||
}
|
||||
}
|
|
@ -1,241 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Repository\Vcs;
|
||||
|
||||
use Composer\Config;
|
||||
use Composer\Downloader\TransportException;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Util\Filesystem;
|
||||
use Composer\Util\RemoteFilesystem;
|
||||
use Fxp\Composer\AssetPlugin\Repository\Vcs\GitBitbucketDriver;
|
||||
|
||||
/**
|
||||
* Tests of vcs git bitbucket repository.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class GitBitbucketDriverTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
private $config;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->config = new Config();
|
||||
$this->config->merge(array(
|
||||
'config' => array(
|
||||
'home' => sys_get_temp_dir().'/composer-test',
|
||||
'cache-repo-dir' => sys_get_temp_dir().'/composer-test-cache',
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$fs = new Filesystem();
|
||||
$fs->removeDirectory(sys_get_temp_dir().'/composer-test');
|
||||
$fs->removeDirectory(sys_get_temp_dir().'/composer-test-cache');
|
||||
}
|
||||
|
||||
public function getAssetTypes()
|
||||
{
|
||||
return array(
|
||||
array('npm', 'package.json'),
|
||||
array('bower', 'bower.json'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetTypes
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $filename
|
||||
*/
|
||||
public function testPublicRepositoryWithComposer($type, $filename)
|
||||
{
|
||||
$repoBaseUrl = 'https://bitbucket.org/composer-test/repo-name';
|
||||
$repoUrl = $repoBaseUrl.'.git';
|
||||
$identifier = 'v0.0.0';
|
||||
$sha = 'SOMESHA';
|
||||
|
||||
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
$io->expects($this->any())
|
||||
->method('isInteractive')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
|
||||
->setConstructorArgs(array($io))
|
||||
->getMock();
|
||||
|
||||
$remoteFilesystem->expects($this->any())
|
||||
->method('getContents')
|
||||
->withConsecutive(
|
||||
array(
|
||||
'bitbucket.org',
|
||||
'https://api.bitbucket.org/2.0/repositories/composer-test/repo-name?fields=-project%2C-owner',
|
||||
false,
|
||||
),
|
||||
array(
|
||||
'bitbucket.org',
|
||||
'https://api.bitbucket.org/1.0/repositories/composer-test/repo-name/main-branch',
|
||||
false,
|
||||
),
|
||||
array(
|
||||
'bitbucket.org',
|
||||
'https://api.bitbucket.org/1.0/repositories/composer-test/repo-name/src/v0.0.0/'.$filename,
|
||||
false,
|
||||
)
|
||||
)
|
||||
->willReturnOnConsecutiveCalls(
|
||||
'{"scm":"git","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/composer-test\/repo-name\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/composer-test\/repo-name\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/composer-test\/repo-name.git","name":"https"},{"href":"ssh:\/\/git@bitbucket.org\/composer-test\/repo-name.git","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/composer-test\/repo-name"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}',
|
||||
'{"name": "test_master"}',
|
||||
'{"name": "composer-test/repo-name","description": "test repo","license": "GPL","authors": [{"name": "Name","email": "local@domain.tld"}],"require": {"creator/package": "^1.0"},"require-dev": {"phpunit/phpunit": "~4.8"}}'
|
||||
);
|
||||
|
||||
$repoConfig = array(
|
||||
'url' => $repoUrl,
|
||||
'asset-type' => $type,
|
||||
'filename' => $filename,
|
||||
);
|
||||
|
||||
/* @var IOInterface $io */
|
||||
/* @var RemoteFilesystem $remoteFilesystem */
|
||||
|
||||
$driver = new GitBitbucketDriver($repoConfig, $io, $this->config, null, $remoteFilesystem);
|
||||
$driver->initialize();
|
||||
|
||||
$this->assertEquals('test_master', $driver->getRootIdentifier());
|
||||
|
||||
$dist = $driver->getDist($sha);
|
||||
$this->assertEquals('zip', $dist['type']);
|
||||
$this->assertEquals($this->getScheme($repoBaseUrl).'/get/SOMESHA.zip', $dist['url']);
|
||||
$this->assertEquals($sha, $dist['reference']);
|
||||
|
||||
$source = $driver->getSource($sha);
|
||||
$this->assertEquals('git', $source['type']);
|
||||
$this->assertEquals($repoUrl, $source['url']);
|
||||
$this->assertEquals($sha, $source['reference']);
|
||||
|
||||
$driver->getComposerInformation($identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetTypes
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $filename
|
||||
*/
|
||||
public function testPublicRepositoryWithEmptyComposer($type, $filename)
|
||||
{
|
||||
$repoBaseUrl = 'https://bitbucket.org/composer-test/repo-name';
|
||||
$repoUrl = $repoBaseUrl.'.git';
|
||||
$repoApiUrl = 'https://api.bitbucket.org/1.0/repositories/composer-test/repo-name';
|
||||
$identifier = 'v0.0.0';
|
||||
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
|
||||
$remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
|
||||
->setConstructorArgs(array($io))
|
||||
->getMock();
|
||||
|
||||
$remoteFilesystem->expects($this->at(0))
|
||||
->method('getContents')
|
||||
->with(
|
||||
$this->equalTo('bitbucket.org'),
|
||||
$this->equalTo($repoApiUrl.'/src/'.$identifier.'/'.$filename),
|
||||
$this->equalTo(false)
|
||||
)
|
||||
->will($this->throwException(new TransportException('Not Found', 404)));
|
||||
|
||||
$repoConfig = array(
|
||||
'url' => $repoUrl,
|
||||
'asset-type' => $type,
|
||||
'filename' => $filename,
|
||||
);
|
||||
|
||||
/* @var IOInterface $io */
|
||||
/* @var RemoteFilesystem $remoteFilesystem */
|
||||
|
||||
$driver = new GitBitbucketDriver($repoConfig, $io, $this->config, null, $remoteFilesystem);
|
||||
$driver->initialize();
|
||||
|
||||
$validEmpty = array(
|
||||
'_nonexistent_package' => true,
|
||||
);
|
||||
|
||||
$this->assertSame($validEmpty, $driver->getComposerInformation($identifier));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $object
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
*/
|
||||
protected function setAttribute($object, $attribute, $value)
|
||||
{
|
||||
$attr = new \ReflectionProperty($object, $attribute);
|
||||
$attr->setAccessible(true);
|
||||
$attr->setValue($object, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the json composer content.
|
||||
*
|
||||
* @param array $content The composer content
|
||||
* @param string $name The name of repository
|
||||
*
|
||||
* @return string The json content
|
||||
*/
|
||||
protected function createJsonComposer(array $content, $name = 'repo-name')
|
||||
{
|
||||
return json_encode(array_merge_recursive($content, array(
|
||||
'name' => $name,
|
||||
)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $content The composer content
|
||||
* @param string $name The name of repository
|
||||
*
|
||||
* @return string The API return value with the json content
|
||||
*/
|
||||
protected function createApiJsonWithRepoData(array $content, $name = 'repo-name')
|
||||
{
|
||||
$composerContent = $this->createJsonComposer($content, $name);
|
||||
|
||||
return json_encode(
|
||||
array(
|
||||
'node' => 'nodename',
|
||||
'path' => '/path/to/file',
|
||||
'data' => $composerContent,
|
||||
'size' => strlen($composerContent),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the url with https or http protocol depending on SSL support.
|
||||
*
|
||||
* @param string $url
|
||||
*
|
||||
* @return string The correct url
|
||||
*/
|
||||
protected function getScheme($url)
|
||||
{
|
||||
if (extension_loaded('openssl')) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
return str_replace('https:', 'http:', $url);
|
||||
}
|
||||
}
|
|
@ -1,281 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Repository\Vcs;
|
||||
|
||||
use Composer\Config;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Util\Filesystem;
|
||||
use Composer\Util\ProcessExecutor;
|
||||
use Fxp\Composer\AssetPlugin\Repository\AssetRepositoryManager;
|
||||
use Fxp\Composer\AssetPlugin\Repository\Vcs\GitDriver;
|
||||
|
||||
/**
|
||||
* Tests of vcs git repository.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class GitDriverTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @var AssetRepositoryManager|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
private $assetRepositoryManager;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$assetConfig = new \Fxp\Composer\AssetPlugin\Config\Config(array('git-skip-update' => '1 hour'));
|
||||
|
||||
/* @var AssetRepositoryManager|\PHPUnit_Framework_MockObject_MockObject $arm */
|
||||
$this->assetRepositoryManager = $this->getMockBuilder(AssetRepositoryManager::class)->disableOriginalConstructor()->getMock();
|
||||
$this->assetRepositoryManager->expects($this->any())
|
||||
->method('getConfig')
|
||||
->willReturn($assetConfig);
|
||||
|
||||
$this->config = new Config();
|
||||
$this->config->merge(array(
|
||||
'config' => array(
|
||||
'home' => sys_get_temp_dir().'/composer-test',
|
||||
'cache-repo-dir' => sys_get_temp_dir().'/composer-test-cache',
|
||||
'cache-vcs-dir' => sys_get_temp_dir().'/composer-test-cache',
|
||||
),
|
||||
));
|
||||
|
||||
// Mock for skip asset
|
||||
$fs = new Filesystem();
|
||||
$fs->ensureDirectoryExists(sys_get_temp_dir().'/composer-test-cache/https---github.com-fxpio-composer-asset-plugin.git');
|
||||
file_put_contents(sys_get_temp_dir().'/composer-test-cache/https---github.com-fxpio-composer-asset-plugin.git/config', '');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$fs = new Filesystem();
|
||||
$fs->removeDirectory(sys_get_temp_dir().'/composer-test');
|
||||
$fs->removeDirectory(sys_get_temp_dir().'/composer-test-cache');
|
||||
}
|
||||
|
||||
public function getAssetTypes()
|
||||
{
|
||||
return array(
|
||||
array('npm', 'package.json'),
|
||||
array('bower', 'bower.json'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetTypes
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $filename
|
||||
*/
|
||||
public function testPublicRepositoryWithEmptyComposer($type, $filename)
|
||||
{
|
||||
$repoUrl = 'https://github.com/fxpio/composer-asset-plugin';
|
||||
$identifier = 'v0.0.0';
|
||||
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
|
||||
$repoConfig = array(
|
||||
'url' => $repoUrl,
|
||||
'asset-type' => $type,
|
||||
'filename' => $filename,
|
||||
'asset-repository-manager' => $this->assetRepositoryManager,
|
||||
);
|
||||
|
||||
$process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$process->expects($this->any())
|
||||
->method('splitLines')
|
||||
->will($this->returnValue(array()));
|
||||
$process->expects($this->any())
|
||||
->method('execute')
|
||||
->will($this->returnCallback(function () {
|
||||
return 0;
|
||||
}));
|
||||
|
||||
/* @var IOInterface $io */
|
||||
/* @var ProcessExecutor $process */
|
||||
|
||||
$gitDriver = new GitDriver($repoConfig, $io, $this->config, $process, null);
|
||||
$gitDriver->initialize();
|
||||
|
||||
$validEmpty = array(
|
||||
'_nonexistent_package' => true,
|
||||
);
|
||||
|
||||
$this->assertSame($validEmpty, $gitDriver->getComposerInformation($identifier));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetTypes
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $filename
|
||||
*/
|
||||
public function testPublicRepositoryWithSkipUpdate($type, $filename)
|
||||
{
|
||||
$repoUrl = 'https://github.com/fxpio/composer-asset-plugin.git';
|
||||
$identifier = '92bebbfdcde75ef2368317830e54b605bc938123';
|
||||
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
|
||||
$repoConfig = array(
|
||||
'url' => $repoUrl,
|
||||
'asset-type' => $type,
|
||||
'filename' => $filename,
|
||||
'asset-repository-manager' => $this->assetRepositoryManager,
|
||||
);
|
||||
|
||||
$process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$process->expects($this->any())
|
||||
->method('splitLines')
|
||||
->will($this->returnValue(array()));
|
||||
$process->expects($this->any())
|
||||
->method('execute')
|
||||
->will($this->returnCallback(function ($command, &$output = null) use ($identifier, $repoConfig) {
|
||||
if ($command === sprintf('git show %s', sprintf('%s:%s', escapeshellarg($identifier), $repoConfig['filename']))) {
|
||||
$output = '{"name": "foo"}';
|
||||
} elseif (false !== strpos($command, 'git log')) {
|
||||
$date = new \DateTime(null, new \DateTimeZone('UTC'));
|
||||
$output = $date->getTimestamp();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}));
|
||||
|
||||
/* @var IOInterface $io */
|
||||
/* @var ProcessExecutor $process */
|
||||
|
||||
$gitDriver1 = new GitDriver($repoConfig, $io, $this->config, $process, null);
|
||||
$gitDriver1->initialize();
|
||||
|
||||
$gitDriver2 = new GitDriver($repoConfig, $io, $this->config, $process, null);
|
||||
$gitDriver2->initialize();
|
||||
|
||||
$validEmpty = array(
|
||||
'_nonexistent_package' => true,
|
||||
);
|
||||
|
||||
$composer1 = $gitDriver1->getComposerInformation($identifier);
|
||||
$composer2 = $gitDriver2->getComposerInformation($identifier);
|
||||
|
||||
$this->assertNotNull($composer1);
|
||||
$this->assertNotNull($composer2);
|
||||
$this->assertSame($composer1, $composer2);
|
||||
$this->assertNotSame($validEmpty, $composer1);
|
||||
$this->assertNotSame($validEmpty, $composer2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetTypes
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $filename
|
||||
*/
|
||||
public function testPublicRepositoryWithCodeCache($type, $filename)
|
||||
{
|
||||
$repoUrl = 'https://github.com/fxpio/composer-asset-plugin.git';
|
||||
$identifier = '92bebbfdcde75ef2368317830e54b605bc938123';
|
||||
$repoConfig = array(
|
||||
'url' => $repoUrl,
|
||||
'asset-type' => $type,
|
||||
'filename' => $filename,
|
||||
'asset-repository-manager' => $this->assetRepositoryManager,
|
||||
);
|
||||
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
$process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$process->expects($this->any())
|
||||
->method('splitLines')
|
||||
->will($this->returnValue(array()));
|
||||
$process->expects($this->any())
|
||||
->method('execute')
|
||||
->will($this->returnCallback(function ($command, &$output = null) use ($identifier, $repoConfig) {
|
||||
if ($command === sprintf('git show %s', sprintf('%s:%s', escapeshellarg($identifier), $repoConfig['filename']))) {
|
||||
$output = '{"name": "foo"}';
|
||||
} elseif (false !== strpos($command, 'git log')) {
|
||||
$date = new \DateTime(null, new \DateTimeZone('UTC'));
|
||||
$output = $date->getTimestamp();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}));
|
||||
|
||||
/* @var IOInterface $io */
|
||||
/* @var ProcessExecutor $process */
|
||||
|
||||
$gitDriver = new GitDriver($repoConfig, $io, $this->config, $process, null);
|
||||
$gitDriver->initialize();
|
||||
$composer1 = $gitDriver->getComposerInformation($identifier);
|
||||
$composer2 = $gitDriver->getComposerInformation($identifier);
|
||||
|
||||
$this->assertNotNull($composer1);
|
||||
$this->assertNotNull($composer2);
|
||||
$this->assertSame($composer1, $composer2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetTypes
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $filename
|
||||
*/
|
||||
public function testPublicRepositoryWithFilesystemCache($type, $filename)
|
||||
{
|
||||
$repoUrl = 'https://github.com/fxpio/composer-asset-plugin.git';
|
||||
$identifier = '92bebbfdcde75ef2368317830e54b605bc938123';
|
||||
$repoConfig = array(
|
||||
'url' => $repoUrl,
|
||||
'asset-type' => $type,
|
||||
'filename' => $filename,
|
||||
'asset-repository-manager' => $this->assetRepositoryManager,
|
||||
);
|
||||
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
$process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$process->expects($this->any())
|
||||
->method('splitLines')
|
||||
->will($this->returnValue(array()));
|
||||
$process->expects($this->any())
|
||||
->method('execute')
|
||||
->will($this->returnCallback(function ($command, &$output = null) use ($identifier, $repoConfig) {
|
||||
if ($command === sprintf('git show %s', sprintf('%s:%s', escapeshellarg($identifier), $repoConfig['filename']))) {
|
||||
$output = '{"name": "foo"}';
|
||||
} elseif (false !== strpos($command, 'git log')) {
|
||||
$date = new \DateTime(null, new \DateTimeZone('UTC'));
|
||||
$output = $date->getTimestamp();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}));
|
||||
|
||||
/* @var IOInterface $io */
|
||||
/* @var ProcessExecutor $process */
|
||||
|
||||
$gitDriver1 = new GitDriver($repoConfig, $io, $this->config, $process, null);
|
||||
$gitDriver2 = new GitDriver($repoConfig, $io, $this->config, $process, null);
|
||||
$gitDriver1->initialize();
|
||||
$gitDriver2->initialize();
|
||||
$composer1 = $gitDriver1->getComposerInformation($identifier);
|
||||
$composer2 = $gitDriver2->getComposerInformation($identifier);
|
||||
|
||||
$this->assertNotNull($composer1);
|
||||
$this->assertNotNull($composer2);
|
||||
$this->assertSame($composer1, $composer2);
|
||||
}
|
||||
|
||||
protected function setAttribute($object, $attribute, $value)
|
||||
{
|
||||
$attr = new \ReflectionProperty($object, $attribute);
|
||||
$attr->setAccessible(true);
|
||||
$attr->setValue($object, $value);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,200 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Repository\Vcs;
|
||||
|
||||
use Composer\Config;
|
||||
use Composer\Downloader\TransportException;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Util\Filesystem;
|
||||
use Composer\Util\RemoteFilesystem;
|
||||
use Fxp\Composer\AssetPlugin\Repository\Vcs\HgBitbucketDriver;
|
||||
|
||||
/**
|
||||
* Tests of vcs mercurial bitbucket repository.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class HgBitbucketDriverTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
private $config;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->config = new Config();
|
||||
$this->config->merge(array(
|
||||
'config' => array(
|
||||
'home' => sys_get_temp_dir().'/composer-test',
|
||||
'cache-repo-dir' => sys_get_temp_dir().'/composer-test-cache',
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$fs = new Filesystem();
|
||||
$fs->removeDirectory(sys_get_temp_dir().'/composer-test');
|
||||
$fs->removeDirectory(sys_get_temp_dir().'/composer-test-cache');
|
||||
}
|
||||
|
||||
public function getAssetTypes()
|
||||
{
|
||||
return array(
|
||||
array('npm', 'package.json'),
|
||||
array('bower', 'bower.json'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetTypes
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $filename
|
||||
*/
|
||||
public function testPublicRepositoryWithComposer($type, $filename)
|
||||
{
|
||||
$repoUrl = 'https://bitbucket.org/composer-test/repo-name';
|
||||
$identifier = 'v0.0.0';
|
||||
$sha = 'SOMESHA';
|
||||
|
||||
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
$io->expects($this->any())
|
||||
->method('isInteractive')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
|
||||
->setConstructorArgs(array($io))
|
||||
->getMock();
|
||||
|
||||
$remoteFilesystem->expects($this->any())
|
||||
->method('getContents')
|
||||
->withConsecutive(
|
||||
array(
|
||||
'bitbucket.org',
|
||||
'https://api.bitbucket.org/2.0/repositories/composer-test/repo-name?fields=-project%2C-owner',
|
||||
false,
|
||||
),
|
||||
array(
|
||||
'bitbucket.org',
|
||||
'https://api.bitbucket.org/1.0/repositories/composer-test/repo-name/main-branch',
|
||||
false,
|
||||
),
|
||||
array(
|
||||
'bitbucket.org',
|
||||
'https://bitbucket.org/composer-test/repo-name/raw/v0.0.0/'.$filename,
|
||||
false,
|
||||
)
|
||||
)
|
||||
->willReturnOnConsecutiveCalls(
|
||||
'{"scm":"hg","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/composer-test\/repo-name\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/composer-test\/repo-name\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/composer-test\/repo-name","name":"https"}],"html":{"href":"https:\/\/bitbucket.org\/composer-test\/repo-name"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}',
|
||||
'{"name": "test_master"}',
|
||||
'{"name": "composer-test/repo-name","description": "test repo","license": "GPL","authors": [{"name": "Name","email": "local@domain.tld"}],"require": {"creator/package": "^1.0"},"require-dev": {"phpunit/phpunit": "~4.8"}}'
|
||||
);
|
||||
|
||||
$repoConfig = array(
|
||||
'url' => $repoUrl,
|
||||
'asset-type' => $type,
|
||||
'filename' => $filename,
|
||||
);
|
||||
|
||||
/* @var IOInterface $io */
|
||||
/* @var RemoteFilesystem $remoteFilesystem */
|
||||
|
||||
$driver = new HgBitbucketDriver($repoConfig, $io, $this->config, null, $remoteFilesystem);
|
||||
$driver->initialize();
|
||||
$this->setAttribute($driver, 'tags', array($identifier => $sha));
|
||||
|
||||
$this->assertEquals('test_master', $driver->getRootIdentifier());
|
||||
|
||||
$dist = $driver->getDist($sha);
|
||||
$this->assertEquals('zip', $dist['type']);
|
||||
$this->assertEquals($this->getScheme($repoUrl).'/get/SOMESHA.zip', $dist['url']);
|
||||
$this->assertEquals($sha, $dist['reference']);
|
||||
|
||||
$source = $driver->getSource($sha);
|
||||
$this->assertEquals('hg', $source['type']);
|
||||
$this->assertEquals($repoUrl, $source['url']);
|
||||
$this->assertEquals($sha, $source['reference']);
|
||||
|
||||
$driver->getComposerInformation($identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetTypes
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $filename
|
||||
*/
|
||||
public function testPublicRepositoryWithEmptyComposer($type, $filename)
|
||||
{
|
||||
$repoUrl = 'https://bitbucket.org/composer-test/repo-name';
|
||||
$identifier = 'v0.0.0';
|
||||
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
|
||||
$remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
|
||||
->setConstructorArgs(array($io))
|
||||
->getMock();
|
||||
|
||||
$remoteFilesystem->expects($this->at(0))
|
||||
->method('getContents')
|
||||
->with($this->equalTo('bitbucket.org'), $this->equalTo($this->getScheme($repoUrl).'/raw/'.$identifier.'/'.$filename), $this->equalTo(false))
|
||||
->will($this->throwException(new TransportException('Not Found', 404)));
|
||||
|
||||
$repoConfig = array(
|
||||
'url' => $repoUrl,
|
||||
'asset-type' => $type,
|
||||
'filename' => $filename,
|
||||
);
|
||||
|
||||
/* @var IOInterface $io */
|
||||
/* @var RemoteFilesystem $remoteFilesystem */
|
||||
|
||||
$driver = new HgBitbucketDriver($repoConfig, $io, $this->config, null, $remoteFilesystem);
|
||||
$driver->initialize();
|
||||
|
||||
$validEmpty = array(
|
||||
'_nonexistent_package' => true,
|
||||
);
|
||||
|
||||
$this->assertSame($validEmpty, $driver->getComposerInformation($identifier));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $object
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
*/
|
||||
protected function setAttribute($object, $attribute, $value)
|
||||
{
|
||||
$attr = new \ReflectionProperty($object, $attribute);
|
||||
$attr->setAccessible(true);
|
||||
$attr->setValue($object, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the url with https or http protocol depending on SSL support.
|
||||
*
|
||||
* @param string $url
|
||||
*
|
||||
* @return string The correct url
|
||||
*/
|
||||
protected function getScheme($url)
|
||||
{
|
||||
if (extension_loaded('openssl')) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
return str_replace('https:', 'http:', $url);
|
||||
}
|
||||
}
|
|
@ -1,204 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Repository\Vcs;
|
||||
|
||||
use Composer\Config;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Util\Filesystem;
|
||||
use Composer\Util\ProcessExecutor;
|
||||
use Fxp\Composer\AssetPlugin\Repository\Vcs\HgDriver;
|
||||
|
||||
/**
|
||||
* Tests of vcs mercurial repository.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class HgDriverTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
private $config;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->config = new Config();
|
||||
$this->config->merge(array(
|
||||
'config' => array(
|
||||
'home' => sys_get_temp_dir().'/composer-test',
|
||||
'cache-repo-dir' => sys_get_temp_dir().'/composer-test-cache',
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$fs = new Filesystem();
|
||||
$fs->removeDirectory(sys_get_temp_dir().'/composer-test');
|
||||
$fs->removeDirectory(sys_get_temp_dir().'/composer-test-cache');
|
||||
}
|
||||
|
||||
public function getAssetTypes()
|
||||
{
|
||||
return array(
|
||||
array('npm', 'package.json'),
|
||||
array('bower', 'bower.json'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetTypes
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $filename
|
||||
*/
|
||||
public function testPublicRepositoryWithEmptyComposer($type, $filename)
|
||||
{
|
||||
$repoUrl = 'https://bitbucket.org/composer-test/repo-name';
|
||||
$identifier = 'v0.0.0';
|
||||
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
|
||||
$repoConfig = array(
|
||||
'url' => $repoUrl,
|
||||
'asset-type' => $type,
|
||||
'filename' => $filename,
|
||||
);
|
||||
|
||||
$process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$process->expects($this->any())
|
||||
->method('splitLines')
|
||||
->will($this->returnValue(array()));
|
||||
$process->expects($this->any())
|
||||
->method('execute')
|
||||
->will($this->returnCallback(function () {
|
||||
return 0;
|
||||
}));
|
||||
|
||||
/* @var IOInterface $io */
|
||||
/* @var ProcessExecutor $process */
|
||||
|
||||
$driver = new HgDriver($repoConfig, $io, $this->config, $process, null);
|
||||
$driver->initialize();
|
||||
|
||||
$validEmpty = array(
|
||||
'_nonexistent_package' => true,
|
||||
);
|
||||
|
||||
$this->assertSame($validEmpty, $driver->getComposerInformation($identifier));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetTypes
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $filename
|
||||
*/
|
||||
public function testPublicRepositoryWithCodeCache($type, $filename)
|
||||
{
|
||||
$repoUrl = 'https://bitbucket.org/composer-test/repo-name';
|
||||
$identifier = '92bebbfdcde75ef2368317830e54b605bc938123';
|
||||
$repoConfig = array(
|
||||
'url' => $repoUrl,
|
||||
'asset-type' => $type,
|
||||
'filename' => $filename,
|
||||
);
|
||||
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
$process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$process->expects($this->any())
|
||||
->method('splitLines')
|
||||
->will($this->returnValue(array()));
|
||||
$process->expects($this->any())
|
||||
->method('execute')
|
||||
->will($this->returnCallback(function ($command, &$output = null) use ($identifier, $repoConfig) {
|
||||
if ($command === sprintf('hg cat -r %s %s', ProcessExecutor::escape($identifier), $repoConfig['filename'])) {
|
||||
$output = '{"name": "foo"}';
|
||||
} elseif (false !== strpos($command, 'hg log')) {
|
||||
$date = new \DateTime(null, new \DateTimeZone('UTC'));
|
||||
$output = $date->format(\DateTime::RFC3339);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}));
|
||||
|
||||
/* @var IOInterface $io */
|
||||
/* @var ProcessExecutor $process */
|
||||
|
||||
$driver = new HgDriver($repoConfig, $io, $this->config, $process, null);
|
||||
$driver->initialize();
|
||||
$composer1 = $driver->getComposerInformation($identifier);
|
||||
$composer2 = $driver->getComposerInformation($identifier);
|
||||
|
||||
$this->assertNotNull($composer1);
|
||||
$this->assertNotNull($composer2);
|
||||
$this->assertSame($composer1, $composer2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetTypes
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $filename
|
||||
*/
|
||||
public function testPublicRepositoryWithFilesystemCache($type, $filename)
|
||||
{
|
||||
$repoUrl = 'https://bitbucket.org/composer-test/repo-name';
|
||||
$identifier = '92bebbfdcde75ef2368317830e54b605bc938123';
|
||||
$repoConfig = array(
|
||||
'url' => $repoUrl,
|
||||
'asset-type' => $type,
|
||||
'filename' => $filename,
|
||||
);
|
||||
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
$process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$process->expects($this->any())
|
||||
->method('splitLines')
|
||||
->will($this->returnValue(array()));
|
||||
$process->expects($this->any())
|
||||
->method('execute')
|
||||
->will($this->returnCallback(function ($command, &$output = null) use ($identifier, $repoConfig) {
|
||||
if ($command === sprintf('hg cat -r %s %s', ProcessExecutor::escape($identifier), $repoConfig['filename'])) {
|
||||
$output = '{"name": "foo"}';
|
||||
} elseif (false !== strpos($command, 'hg log')) {
|
||||
$date = new \DateTime(null, new \DateTimeZone('UTC'));
|
||||
$output = $date->format(\DateTime::RFC3339);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}));
|
||||
|
||||
/* @var IOInterface $io */
|
||||
/* @var ProcessExecutor $process */
|
||||
|
||||
$driver1 = new HgDriver($repoConfig, $io, $this->config, $process, null);
|
||||
$driver2 = new HgDriver($repoConfig, $io, $this->config, $process, null);
|
||||
$driver1->initialize();
|
||||
$driver2->initialize();
|
||||
$composer1 = $driver1->getComposerInformation($identifier);
|
||||
$composer2 = $driver2->getComposerInformation($identifier);
|
||||
|
||||
$this->assertNotNull($composer1);
|
||||
$this->assertNotNull($composer2);
|
||||
$this->assertSame($composer1, $composer2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $object
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
*/
|
||||
protected function setAttribute($object, $attribute, $value)
|
||||
{
|
||||
$attr = new \ReflectionProperty($object, $attribute);
|
||||
$attr->setAccessible(true);
|
||||
$attr->setValue($object, $value);
|
||||
}
|
||||
}
|
|
@ -1,157 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Repository\Vcs;
|
||||
|
||||
use Composer\Test\Repository\Vcs\PerforceDriverTest as BasePerforceDriverTest;
|
||||
use Fxp\Composer\AssetPlugin\Repository\Vcs\PerforceDriver;
|
||||
use Fxp\Composer\AssetPlugin\Util\Perforce;
|
||||
|
||||
/**
|
||||
* Tests of vcs perforce repository.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class PerforceDriverTest extends BasePerforceDriverTest
|
||||
{
|
||||
/**
|
||||
* @var PerforceDriver
|
||||
*/
|
||||
protected $driver;
|
||||
|
||||
/**
|
||||
* @var Perforce|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $perforce;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->remoteFileSystem);
|
||||
$this->overrideDriverInternalPerforce($this->perforce);
|
||||
}
|
||||
|
||||
protected function getMockIOInterface()
|
||||
{
|
||||
return $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
}
|
||||
|
||||
protected function getMockProcessExecutor()
|
||||
{
|
||||
return $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
}
|
||||
|
||||
public function testInitializeCapturesVariablesFromRepoConfig()
|
||||
{
|
||||
$driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->remoteFileSystem);
|
||||
$driver->initialize();
|
||||
$this->assertEquals(self::TEST_URL, $driver->getUrl());
|
||||
$this->assertEquals(self::TEST_DEPOT, $driver->getDepot());
|
||||
$this->assertEquals(self::TEST_BRANCH, $driver->getBranch());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that supports() simply return false.
|
||||
*
|
||||
* @covers \Composer\Repository\Vcs\PerforceDriver::supports
|
||||
*/
|
||||
public function testSupportsReturnsFalseNoDeepCheck()
|
||||
{
|
||||
$this->expectOutputString('');
|
||||
$this->assertFalse(PerforceDriver::supports($this->io, $this->config, 'existing.url'));
|
||||
}
|
||||
|
||||
public function testInitializeLogsInAndConnectsClient()
|
||||
{
|
||||
$this->perforce->expects($this->at(0))->method('p4Login');
|
||||
$this->perforce->expects($this->at(1))->method('checkStream');
|
||||
$this->perforce->expects($this->at(2))->method('writeP4ClientSpec');
|
||||
$this->perforce->expects($this->at(3))->method('connectClient');
|
||||
$this->driver->initialize();
|
||||
}
|
||||
|
||||
public function testPublicRepositoryWithEmptyComposer()
|
||||
{
|
||||
$identifier = 'TEST_IDENTIFIER';
|
||||
$this->perforce->expects($this->any())
|
||||
->method('getComposerInformation')
|
||||
->with($this->equalTo($identifier))
|
||||
->will($this->returnValue(''));
|
||||
|
||||
$this->driver->initialize();
|
||||
$validEmpty = array(
|
||||
'_nonexistent_package' => true,
|
||||
);
|
||||
|
||||
$this->assertSame($validEmpty, $this->driver->getComposerInformation($identifier));
|
||||
}
|
||||
|
||||
public function testPublicRepositoryWithCodeCache()
|
||||
{
|
||||
$identifier = 'TEST_IDENTIFIER';
|
||||
$this->perforce->expects($this->any())
|
||||
->method('getComposerInformation')
|
||||
->with($this->equalTo($identifier))
|
||||
->will($this->returnValue(array('name' => 'foo')));
|
||||
|
||||
$this->driver->initialize();
|
||||
$composer1 = $this->driver->getComposerInformation($identifier);
|
||||
$composer2 = $this->driver->getComposerInformation($identifier);
|
||||
|
||||
$this->assertNotNull($composer1);
|
||||
$this->assertNotNull($composer2);
|
||||
$this->assertSame($composer1, $composer2);
|
||||
}
|
||||
|
||||
public function testPublicRepositoryWithFilesystemCache()
|
||||
{
|
||||
$identifier = 'TEST_IDENTIFIER';
|
||||
$this->perforce->expects($this->any())
|
||||
->method('getComposerInformation')
|
||||
->with($this->equalTo($identifier))
|
||||
->will($this->returnValue(array('name' => 'foo')));
|
||||
|
||||
$driver2 = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->remoteFileSystem);
|
||||
$reflectionClass = new \ReflectionClass($driver2);
|
||||
$property = $reflectionClass->getProperty('perforce');
|
||||
$property->setAccessible(true);
|
||||
$property->setValue($driver2, $this->perforce);
|
||||
|
||||
$this->driver->initialize();
|
||||
$driver2->initialize();
|
||||
|
||||
$composer1 = $this->driver->getComposerInformation($identifier);
|
||||
$composer2 = $driver2->getComposerInformation($identifier);
|
||||
|
||||
$this->assertNotNull($composer1);
|
||||
$this->assertNotNull($composer2);
|
||||
$this->assertSame($composer1, $composer2);
|
||||
}
|
||||
|
||||
protected function getTestRepoConfig()
|
||||
{
|
||||
return array_merge(parent::getTestRepoConfig(), array(
|
||||
'asset-type' => 'ASSET',
|
||||
'filename' => 'ASSET.json',
|
||||
));
|
||||
}
|
||||
|
||||
protected function getMockPerforce()
|
||||
{
|
||||
$methods = array('p4login', 'checkStream', 'writeP4ClientSpec', 'connectClient', 'getComposerInformation', 'cleanupClientSpec');
|
||||
|
||||
return $this->getMockBuilder('Fxp\Composer\AssetPlugin\Util\Perforce')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods($methods)
|
||||
->getMock();
|
||||
}
|
||||
}
|
|
@ -1,367 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Repository\Vcs;
|
||||
|
||||
use Composer\Config;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Util\Filesystem;
|
||||
use Composer\Util\ProcessExecutor;
|
||||
use Fxp\Composer\AssetPlugin\Repository\Vcs\SvnDriver;
|
||||
|
||||
/**
|
||||
* Tests of vcs svn repository.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class SvnDriverTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
private $config;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->config = new Config();
|
||||
$this->config->merge(array(
|
||||
'config' => array(
|
||||
'home' => sys_get_temp_dir().'/composer-test',
|
||||
'cache-repo-dir' => sys_get_temp_dir().'/composer-test-cache',
|
||||
'secure-http' => false,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$fs = new Filesystem();
|
||||
$fs->removeDirectory(sys_get_temp_dir().'/composer-test');
|
||||
$fs->removeDirectory(sys_get_temp_dir().'/composer-test-cache');
|
||||
}
|
||||
|
||||
public function getAssetTypes()
|
||||
{
|
||||
return array(
|
||||
array('npm', 'package.json', '1234'),
|
||||
array('npm', 'package.json', '/@1234'),
|
||||
array('bower', 'bower.json', '1234'),
|
||||
array('bower', 'bower.json', '/@1234'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetTypes
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $filename
|
||||
* @param string $identifier
|
||||
*/
|
||||
public function testPublicRepositoryWithEmptyComposer($type, $filename, $identifier)
|
||||
{
|
||||
$repoUrl = 'svn://example.tld/composer-test/repo-name/trunk';
|
||||
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
|
||||
$repoConfig = array(
|
||||
'url' => $repoUrl,
|
||||
'asset-type' => $type,
|
||||
'filename' => $filename,
|
||||
);
|
||||
|
||||
$process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$process->expects($this->any())
|
||||
->method('splitLines')
|
||||
->will($this->returnValue(array()));
|
||||
$process->expects($this->any())
|
||||
->method('execute')
|
||||
->will($this->returnCallback(function () {
|
||||
return 0;
|
||||
}));
|
||||
|
||||
/* @var IOInterface $io */
|
||||
/* @var ProcessExecutor $process */
|
||||
|
||||
$driver = new SvnDriver($repoConfig, $io, $this->config, $process, null);
|
||||
$driver->initialize();
|
||||
|
||||
$validEmpty = array(
|
||||
'_nonexistent_package' => true,
|
||||
);
|
||||
|
||||
$this->assertSame($validEmpty, $driver->getComposerInformation($identifier));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetTypes
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $filename
|
||||
* @param string $identifier
|
||||
*/
|
||||
public function testPrivateRepositoryWithEmptyComposer($type, $filename, $identifier)
|
||||
{
|
||||
$this->config->merge(array(
|
||||
'config' => array(
|
||||
'http-basic' => array(
|
||||
'example.tld' => array(
|
||||
'username' => 'peter',
|
||||
'password' => 'quill',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
$repoBaseUrl = 'svn://example.tld/composer-test/repo-name';
|
||||
$repoUrl = $repoBaseUrl.'/trunk';
|
||||
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
|
||||
$repoConfig = array(
|
||||
'url' => $repoUrl,
|
||||
'asset-type' => $type,
|
||||
'filename' => $filename,
|
||||
);
|
||||
|
||||
$process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$process->expects($this->any())
|
||||
->method('splitLines')
|
||||
->will($this->returnValue(array()));
|
||||
$process->expects($this->any())
|
||||
->method('execute')
|
||||
->will($this->returnCallback(function () {
|
||||
return 0;
|
||||
}));
|
||||
|
||||
/* @var IOInterface $io */
|
||||
/* @var ProcessExecutor $process */
|
||||
|
||||
$driver = new SvnDriver($repoConfig, $io, $this->config, $process, null);
|
||||
$driver->initialize();
|
||||
|
||||
$validEmpty = array(
|
||||
'_nonexistent_package' => true,
|
||||
);
|
||||
|
||||
$this->assertSame($validEmpty, $driver->getComposerInformation($identifier));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetTypes
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $filename
|
||||
* @param string $identifier
|
||||
*/
|
||||
public function testPublicRepositoryWithCodeCache($type, $filename, $identifier)
|
||||
{
|
||||
$repoBaseUrl = 'svn://example.tld/composer-test/repo-name';
|
||||
$repoUrl = $repoBaseUrl.'/trunk';
|
||||
$repoConfig = array(
|
||||
'url' => $repoUrl,
|
||||
'asset-type' => $type,
|
||||
'filename' => $filename,
|
||||
);
|
||||
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
$process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$process->expects($this->any())
|
||||
->method('splitLines')
|
||||
->will($this->returnCallback(function ($value) {
|
||||
return is_string($value) ? preg_split('{\r?\n}', $value) : array();
|
||||
}));
|
||||
$process->expects($this->any())
|
||||
->method('execute')
|
||||
->will($this->returnCallback(function ($command, &$output) use ($repoBaseUrl, $identifier, $repoConfig) {
|
||||
if ($command === sprintf('svn cat --non-interactive %s', ProcessExecutor::escape(sprintf('%s/%s/%s', $repoBaseUrl, $identifier, $repoConfig['filename'])))
|
||||
|| $command === sprintf('svn cat --non-interactive %s', ProcessExecutor::escape(sprintf('%s/%s%s', $repoBaseUrl, $repoConfig['filename'], trim($identifier, '/'))))) {
|
||||
$output('out', '{"name": "foo"}');
|
||||
} elseif ($command === sprintf('svn info --non-interactive %s', ProcessExecutor::escape(sprintf('%s/%s/', $repoBaseUrl, $identifier)))
|
||||
|| $command === sprintf('svn info --non-interactive %s', ProcessExecutor::escape(sprintf('%s/%s', $repoBaseUrl, trim($identifier, '/'))))) {
|
||||
$date = new \DateTime(null, new \DateTimeZone('UTC'));
|
||||
$value = array(
|
||||
'Last Changed Rev: '.$identifier,
|
||||
'Last Changed Date: '.$date->format('Y-m-d H:i:s O').' ('.$date->format('l, j F Y').')',
|
||||
);
|
||||
|
||||
$output('out', implode(PHP_EOL, $value));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}));
|
||||
|
||||
/* @var IOInterface $io */
|
||||
/* @var ProcessExecutor $process */
|
||||
|
||||
$driver = new SvnDriver($repoConfig, $io, $this->config, $process, null);
|
||||
$driver->initialize();
|
||||
$composer1 = $driver->getComposerInformation($identifier);
|
||||
$composer2 = $driver->getComposerInformation($identifier);
|
||||
|
||||
$this->assertNotNull($composer1);
|
||||
$this->assertNotNull($composer2);
|
||||
$this->assertSame($composer1, $composer2);
|
||||
$this->assertArrayHasKey('time', $composer1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetTypes
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $filename
|
||||
* @param string $identifier
|
||||
*/
|
||||
public function testPublicRepositoryWithFilesystemCache($type, $filename, $identifier)
|
||||
{
|
||||
$repoBaseUrl = 'svn://example.tld/composer-test/repo-name';
|
||||
$repoUrl = $repoBaseUrl.'/trunk';
|
||||
$repoConfig = array(
|
||||
'url' => $repoUrl,
|
||||
'asset-type' => $type,
|
||||
'filename' => $filename,
|
||||
);
|
||||
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
$process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$process->expects($this->any())
|
||||
->method('splitLines')
|
||||
->will($this->returnCallback(function ($value) {
|
||||
return is_string($value) ? preg_split('{\r?\n}', $value) : array();
|
||||
}));
|
||||
$process->expects($this->any())
|
||||
->method('execute')
|
||||
->will($this->returnCallback(function ($command, &$output) use ($repoBaseUrl, $identifier, $repoConfig) {
|
||||
if ($command === sprintf('svn cat --non-interactive %s', ProcessExecutor::escape(sprintf('%s/%s/%s', $repoBaseUrl, $identifier, $repoConfig['filename'])))
|
||||
|| $command === sprintf('svn cat --non-interactive %s', ProcessExecutor::escape(sprintf('%s/%s%s', $repoBaseUrl, $repoConfig['filename'], trim($identifier, '/'))))) {
|
||||
$output('out', '{"name": "foo"}');
|
||||
} elseif ($command === sprintf('svn info --non-interactive %s', ProcessExecutor::escape(sprintf('%s/%s/', $repoBaseUrl, $identifier)))
|
||||
|| $command === sprintf('svn info --non-interactive %s', ProcessExecutor::escape(sprintf('%s/%s', $repoBaseUrl, trim($identifier, '/'))))) {
|
||||
$date = new \DateTime(null, new \DateTimeZone('UTC'));
|
||||
$value = array(
|
||||
'Last Changed Rev: '.$identifier,
|
||||
'Last Changed Date: '.$date->format('Y-m-d H:i:s O').' ('.$date->format('l, j F Y').')',
|
||||
);
|
||||
|
||||
$output('out', implode(PHP_EOL, $value));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}));
|
||||
|
||||
/* @var IOInterface $io */
|
||||
/* @var ProcessExecutor $process */
|
||||
|
||||
$driver1 = new SvnDriver($repoConfig, $io, $this->config, $process, null);
|
||||
$driver2 = new SvnDriver($repoConfig, $io, $this->config, $process, null);
|
||||
$driver1->initialize();
|
||||
$driver2->initialize();
|
||||
$composer1 = $driver1->getComposerInformation($identifier);
|
||||
$composer2 = $driver2->getComposerInformation($identifier);
|
||||
|
||||
$this->assertNotNull($composer1);
|
||||
$this->assertNotNull($composer2);
|
||||
$this->assertSame($composer1, $composer2);
|
||||
$this->assertArrayHasKey('time', $composer1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getAssetTypes
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $filename
|
||||
* @param string $identifier
|
||||
*
|
||||
* @expectedException \Composer\Downloader\TransportException
|
||||
*/
|
||||
public function testPublicRepositoryWithInvalidUrl($type, $filename, $identifier)
|
||||
{
|
||||
$repoUrl = 'svn://example.tld/composer-test/repo-name/trunk';
|
||||
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
|
||||
$repoConfig = array(
|
||||
'url' => $repoUrl,
|
||||
'asset-type' => $type,
|
||||
'filename' => $filename,
|
||||
);
|
||||
|
||||
$process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$process->expects($this->any())
|
||||
->method('splitLines')
|
||||
->will($this->returnValue(array()));
|
||||
$process->expects($this->any())
|
||||
->method('execute')
|
||||
->will($this->returnCallback(function ($command) {
|
||||
return 0 === strpos($command, 'svn cat ') ? 1 : 0;
|
||||
}));
|
||||
|
||||
/* @var IOInterface $io */
|
||||
/* @var ProcessExecutor $process */
|
||||
|
||||
$driver = new SvnDriver($repoConfig, $io, $this->config, $process, null);
|
||||
$driver->initialize();
|
||||
$driver->getComposerInformation($identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getSupportsUrls()
|
||||
{
|
||||
return array(
|
||||
array('svn://example.tld/trunk', true, 'svn://example.tld/trunk'),
|
||||
array('svn+ssh://example.tld/trunk', true, 'svn+ssh://example.tld/trunk'),
|
||||
array('svn://svn.example.tld/trunk', true, 'svn://svn.example.tld/trunk'),
|
||||
array('svn+ssh://svn.example.tld/trunk', true, 'svn+ssh://svn.example.tld/trunk'),
|
||||
array('svn+http://svn.example.tld/trunk', true, 'http://svn.example.tld/trunk'),
|
||||
array('svn+https://svn.example.tld/trunk', true, 'https://svn.example.tld/trunk'),
|
||||
array('http://example.tld/svn/trunk', true, 'http://example.tld/svn/trunk'),
|
||||
array('https://example.tld/svn/trunk', true, 'https://example.tld/svn/trunk'),
|
||||
array('http://example.tld/sub', false, null),
|
||||
array('https://example.tld/sub', false, null),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getSupportsUrls
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $supperted
|
||||
* @param string $urlUsed
|
||||
*/
|
||||
public function testSupports($url, $supperted, $urlUsed)
|
||||
{
|
||||
/* @var IOInterface $io */
|
||||
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
|
||||
$this->assertSame($supperted, SvnDriver::supports($io, $this->config, $url, false));
|
||||
|
||||
if (!$supperted) {
|
||||
return;
|
||||
}
|
||||
|
||||
$process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$process->expects($this->any())
|
||||
->method('execute')
|
||||
->will($this->returnCallback(function () {
|
||||
return 0;
|
||||
}));
|
||||
|
||||
$repoConfig = array(
|
||||
'url' => $url,
|
||||
'asset-type' => 'bower',
|
||||
'filename' => 'bower.json',
|
||||
);
|
||||
|
||||
/* @var IOInterface $io */
|
||||
/* @var ProcessExecutor $process */
|
||||
|
||||
$driver = new SvnDriver($repoConfig, $io, $this->config, $process, null);
|
||||
$driver->initialize();
|
||||
|
||||
$this->assertEquals($urlUsed, $driver->getUrl());
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Repository\Vcs;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Repository\Vcs\Util;
|
||||
use Fxp\Composer\AssetPlugin\Tests\Fixtures\Repository\Vcs\MockVcsDriver;
|
||||
|
||||
/**
|
||||
* Tests of util.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class UtilTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function getDataProvider()
|
||||
{
|
||||
return array(
|
||||
array('key'),
|
||||
array('key.subkey'),
|
||||
array('key.subkey.subsubkey'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getDataProvider
|
||||
*
|
||||
* @param string $resourceKey
|
||||
*/
|
||||
public function testAddComposerTimeWithSimpleKey($resourceKey)
|
||||
{
|
||||
$composer = array(
|
||||
'name' => 'test',
|
||||
);
|
||||
$driver = new MockVcsDriver();
|
||||
|
||||
$value = null;
|
||||
$keys = explode('.', $resourceKey);
|
||||
$start = count($keys) - 1;
|
||||
|
||||
for ($i = $start; $i >= 0; --$i) {
|
||||
if (null === $value) {
|
||||
$value = 'level '.$i;
|
||||
}
|
||||
|
||||
$value = array($keys[$i] => $value);
|
||||
}
|
||||
|
||||
$driver->contents = json_encode($value);
|
||||
$composerValid = array_merge($composer, array(
|
||||
'time' => 'level '.(count($keys) - 1),
|
||||
));
|
||||
|
||||
$composer = Util::addComposerTime($composer, $resourceKey, 'http://example.tld', $driver);
|
||||
|
||||
$this->assertSame($composerValid, $composer);
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Type;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Converter\PackageConverterInterface;
|
||||
use Fxp\Composer\AssetPlugin\Converter\VersionConverterInterface;
|
||||
use Fxp\Composer\AssetPlugin\Type\AssetTypeInterface;
|
||||
|
||||
/**
|
||||
* Abstract class for tests of asset type.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
abstract class AbstractAssetTypeTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var PackageConverterInterface
|
||||
*/
|
||||
protected $packageConverter;
|
||||
|
||||
/**
|
||||
* @var VersionConverterInterface
|
||||
*/
|
||||
protected $versionConverter;
|
||||
|
||||
/**
|
||||
* @var AssetTypeInterface
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->packageConverter = $this->getMockBuilder('Fxp\Composer\AssetPlugin\Converter\PackageConverterInterface')->getMock();
|
||||
$this->versionConverter = $this->getMockBuilder('Fxp\Composer\AssetPlugin\Converter\VersionConverterInterface')->getMock();
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$this->packageConverter = null;
|
||||
$this->versionConverter = null;
|
||||
$this->type = null;
|
||||
}
|
||||
|
||||
public function testConverter()
|
||||
{
|
||||
$this->assertInstanceOf('Fxp\Composer\AssetPlugin\Converter\PackageConverterInterface', $this->type->getPackageConverter());
|
||||
$this->assertInstanceOf('Fxp\Composer\AssetPlugin\Converter\VersionConverterInterface', $this->type->getVersionConverter());
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Type;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Type\BowerAssetType;
|
||||
|
||||
/**
|
||||
* Tests of bower asset type.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class BowerAssetTypeTest extends AbstractAssetTypeTest
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->type = new BowerAssetType($this->packageConverter, $this->versionConverter);
|
||||
}
|
||||
|
||||
public function testInformations()
|
||||
{
|
||||
$this->assertSame('bower', $this->type->getName());
|
||||
$this->assertSame('bower-asset', $this->type->getComposerVendorName());
|
||||
$this->assertSame('bower-asset-library', $this->type->getComposerType());
|
||||
$this->assertSame('bower.json', $this->type->getFilename());
|
||||
$this->assertSame('bower-asset/foobar', $this->type->formatComposerName('foobar'));
|
||||
$this->assertSame('bower-asset/foobar', $this->type->formatComposerName('bower-asset/foobar'));
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Type;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Type\NpmAssetType;
|
||||
|
||||
/**
|
||||
* Tests of npm asset type.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class NpmAssetTypeTest extends AbstractAssetTypeTest
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->type = new NpmAssetType($this->packageConverter, $this->versionConverter);
|
||||
}
|
||||
|
||||
public function testInformations()
|
||||
{
|
||||
$this->assertSame('npm', $this->type->getName());
|
||||
$this->assertSame('npm-asset', $this->type->getComposerVendorName());
|
||||
$this->assertSame('npm-asset-library', $this->type->getComposerType());
|
||||
$this->assertSame('package.json', $this->type->getFilename());
|
||||
$this->assertSame('npm-asset/foobar', $this->type->formatComposerName('foobar'));
|
||||
$this->assertSame('npm-asset/foobar', $this->type->formatComposerName('npm-asset/foobar'));
|
||||
}
|
||||
}
|
|
@ -1,328 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Util;
|
||||
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Test\Util\PerforceTest as BasePerforceTest;
|
||||
use Composer\Util\Filesystem;
|
||||
use Composer\Util\ProcessExecutor;
|
||||
use Fxp\Composer\AssetPlugin\Util\Perforce;
|
||||
|
||||
/**
|
||||
* Tests for the perforce.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class PerforceTest extends BasePerforceTest
|
||||
{
|
||||
/**
|
||||
* @var Perforce
|
||||
*/
|
||||
protected $perforce;
|
||||
|
||||
/**
|
||||
* @var ProcessExecutor|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected $processExecutor;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $repoConfig;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$this->repoConfig = $this->getTestRepoConfig();
|
||||
$this->io = $this->getMockIOInterface();
|
||||
$this->createNewPerforceWithWindowsFlag(true);
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
$fs = new Filesystem();
|
||||
$fs->remove($this::TEST_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IOInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
public function getMockIOInterface()
|
||||
{
|
||||
return $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
}
|
||||
|
||||
public function testQueryP4PasswordWithPasswordAlreadySet()
|
||||
{
|
||||
$repoConfig = array(
|
||||
'depot' => 'depot',
|
||||
'branch' => 'branch',
|
||||
'p4user' => 'user',
|
||||
'p4password' => 'TEST_PASSWORD',
|
||||
'filename' => 'ASSET.json',
|
||||
);
|
||||
$this->perforce = new Perforce($repoConfig, 'port', 'path', $this->processExecutor, false, $this->getMockIOInterface(), 'TEST');
|
||||
$password = $this->perforce->queryP4Password();
|
||||
$this->assertEquals('TEST_PASSWORD', $password);
|
||||
}
|
||||
|
||||
public function getTestRepoConfig()
|
||||
{
|
||||
return array_merge(parent::getTestRepoConfig(), array(
|
||||
'filename' => 'ASSET.json',
|
||||
));
|
||||
}
|
||||
|
||||
public function testGetComposerInformationWithoutLabelWithoutStream()
|
||||
{
|
||||
$expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot -p port print //depot/ASSET.json';
|
||||
$this->processExecutor->expects($this->at(0))
|
||||
->method('execute')
|
||||
->with($this->equalTo($expectedCommand))
|
||||
->will(
|
||||
$this->returnCallback(
|
||||
function ($command, &$output) {
|
||||
$output = PerforceTest::getComposerJson();
|
||||
|
||||
return $command ? true : true;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$result = $this->perforce->getComposerInformation('//depot');
|
||||
$expected = array(
|
||||
'name' => 'test/perforce',
|
||||
'description' => 'Basic project for testing',
|
||||
'minimum-stability' => 'dev',
|
||||
'autoload' => array('psr-0' => array()),
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testGetComposerInformationWithLabelWithoutStream()
|
||||
{
|
||||
$expectedCommand = 'p4 -u user -p port files //depot/ASSET.json@0.0.1';
|
||||
$this->processExecutor->expects($this->at(0))
|
||||
->method('execute')
|
||||
->with($this->equalTo($expectedCommand))
|
||||
->will(
|
||||
$this->returnCallback(
|
||||
function ($command, &$output) {
|
||||
$output = '//depot/ASSET.json#1 - branch change 10001 (text)';
|
||||
|
||||
return $command ? true : true;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot -p port print //depot/ASSET.json@10001';
|
||||
$this->processExecutor->expects($this->at(1))
|
||||
->method('execute')
|
||||
->with($this->equalTo($expectedCommand))
|
||||
->will(
|
||||
$this->returnCallback(
|
||||
function ($command, &$output) {
|
||||
$output = PerforceTest::getComposerJson();
|
||||
|
||||
return $command ? true : true;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$result = $this->perforce->getComposerInformation('//depot@0.0.1');
|
||||
|
||||
$expected = array(
|
||||
'name' => 'test/perforce',
|
||||
'description' => 'Basic project for testing',
|
||||
'minimum-stability' => 'dev',
|
||||
'autoload' => array('psr-0' => array()),
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testGetComposerInformationWithoutLabelWithStream()
|
||||
{
|
||||
$this->setAssetPerforceToStream();
|
||||
|
||||
$expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot_branch -p port print //depot/branch/ASSET.json';
|
||||
$this->processExecutor->expects($this->at(0))
|
||||
->method('execute')
|
||||
->with($this->equalTo($expectedCommand))
|
||||
->will(
|
||||
$this->returnCallback(
|
||||
function ($command, &$output) {
|
||||
$output = PerforceTest::getComposerJson();
|
||||
|
||||
return $command ? true : true;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$result = $this->perforce->getComposerInformation('//depot/branch');
|
||||
|
||||
$expected = array(
|
||||
'name' => 'test/perforce',
|
||||
'description' => 'Basic project for testing',
|
||||
'minimum-stability' => 'dev',
|
||||
'autoload' => array('psr-0' => array()),
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testGetComposerInformationWithLabelWithStream()
|
||||
{
|
||||
$this->setAssetPerforceToStream();
|
||||
$expectedCommand = 'p4 -u user -p port files //depot/branch/ASSET.json@0.0.1';
|
||||
$this->processExecutor->expects($this->at(0))
|
||||
->method('execute')
|
||||
->with($this->equalTo($expectedCommand))
|
||||
->will(
|
||||
$this->returnCallback(
|
||||
function ($command, &$output) {
|
||||
$output = '//depot/ASSET.json#1 - branch change 10001 (text)';
|
||||
|
||||
return $command ? true : true;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot_branch -p port print //depot/branch/ASSET.json@10001';
|
||||
$this->processExecutor->expects($this->at(1))
|
||||
->method('execute')
|
||||
->with($this->equalTo($expectedCommand))
|
||||
->will(
|
||||
$this->returnCallback(
|
||||
function ($command, &$output) {
|
||||
$output = PerforceTest::getComposerJson();
|
||||
|
||||
return $command ? true : true;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$result = $this->perforce->getComposerInformation('//depot/branch@0.0.1');
|
||||
|
||||
$expected = array(
|
||||
'name' => 'test/perforce',
|
||||
'description' => 'Basic project for testing',
|
||||
'minimum-stability' => 'dev',
|
||||
'autoload' => array('psr-0' => array()),
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testGetComposerInformationWithLabelButNoSuchFile()
|
||||
{
|
||||
$this->setAssetPerforceToStream();
|
||||
$expectedCommand = 'p4 -u user -p port files //depot/branch/ASSET.json@0.0.1';
|
||||
$this->processExecutor->expects($this->at(0))
|
||||
->method('execute')
|
||||
->with($this->equalTo($expectedCommand))
|
||||
->will(
|
||||
$this->returnCallback(
|
||||
function ($command, &$output) {
|
||||
$output = 'no such file(s).';
|
||||
|
||||
return $command ? true : true;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$result = $this->perforce->getComposerInformation('//depot/branch@0.0.1');
|
||||
|
||||
$this->assertNull($result);
|
||||
}
|
||||
|
||||
public function testGetComposerInformationWithLabelWithStreamWithNoChange()
|
||||
{
|
||||
$this->setAssetPerforceToStream();
|
||||
$expectedCommand = 'p4 -u user -p port files //depot/branch/ASSET.json@0.0.1';
|
||||
$this->processExecutor->expects($this->at(0))
|
||||
->method('execute')
|
||||
->with($this->equalTo($expectedCommand))
|
||||
->will(
|
||||
$this->returnCallback(
|
||||
function ($command, &$output) {
|
||||
$output = '//depot/ASSET.json#1 - branch 10001 (text)';
|
||||
|
||||
return $command ? true : true;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$result = $this->perforce->getComposerInformation('//depot/branch@0.0.1');
|
||||
|
||||
$this->assertNull($result);
|
||||
}
|
||||
|
||||
public function testCheckServerExists()
|
||||
{
|
||||
/* @var ProcessExecutor|\PHPUnit_Framework_MockObject_MockObject $processExecutor */
|
||||
$processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
|
||||
$expectedCommand = 'p4 -p perforce.does.exist:port info -s';
|
||||
$processExecutor->expects($this->at(0))
|
||||
->method('execute')
|
||||
->with($this->equalTo($expectedCommand), $this->equalTo(null))
|
||||
->will($this->returnValue(0));
|
||||
|
||||
$result = $this->perforce->checkServerExists('perforce.does.exist:port', $processExecutor);
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if "p4" command is missing.
|
||||
*
|
||||
* @covers \Composer\Util\Perforce::checkServerExists
|
||||
*/
|
||||
public function testCheckServerClientError()
|
||||
{
|
||||
/* @var ProcessExecutor|\PHPUnit_Framework_MockObject_MockObject $processExecutor */
|
||||
$processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
|
||||
$expectedCommand = 'p4 -p perforce.does.exist:port info -s';
|
||||
$processExecutor->expects($this->at(0))
|
||||
->method('execute')
|
||||
->with($this->equalTo($expectedCommand), $this->equalTo(null))
|
||||
->will($this->returnValue(127));
|
||||
|
||||
$result = $this->perforce->checkServerExists('perforce.does.exist:port', $processExecutor);
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
public function testCleanupClientSpecShouldDeleteClient()
|
||||
{
|
||||
/* @var Filesystem|\PHPUnit_Framework_MockObject_MockObject $fs */
|
||||
$fs = $this->getMockBuilder('Composer\Util\Filesystem')->getMock();
|
||||
$this->perforce->setFilesystem($fs);
|
||||
|
||||
$testClient = $this->perforce->getClient();
|
||||
$expectedCommand = 'p4 -u '.self::TEST_P4USER.' -p '.self::TEST_PORT.' client -d '.$testClient;
|
||||
$this->processExecutor->expects($this->once())->method('execute')->with($this->equalTo($expectedCommand));
|
||||
|
||||
$fs->expects($this->once())->method('remove')->with($this->perforce->getP4ClientSpec());
|
||||
|
||||
$this->perforce->cleanupClientSpec();
|
||||
}
|
||||
|
||||
protected function createNewPerforceWithWindowsFlag($flag)
|
||||
{
|
||||
$this->perforce = new Perforce($this->repoConfig, self::TEST_PORT, self::TEST_PATH, $this->processExecutor, $flag, $this->io);
|
||||
}
|
||||
|
||||
private function setAssetPerforceToStream()
|
||||
{
|
||||
$this->perforce->setStream('//depot/branch');
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Tests\Util;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Assets;
|
||||
use Fxp\Composer\AssetPlugin\Util\Validator;
|
||||
|
||||
/**
|
||||
* Tests for the validator.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class ValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testValidBranch()
|
||||
{
|
||||
$this->assertNotFalse(Validator::validateBranch('master'));
|
||||
}
|
||||
|
||||
public function testInvalidBranch()
|
||||
{
|
||||
$this->assertFalse(Validator::validateBranch('1.x'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAssetTypes()
|
||||
{
|
||||
return array(
|
||||
array('npm'),
|
||||
array('bower'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
*
|
||||
* @dataProvider getAssetTypes
|
||||
*/
|
||||
public function testValidTag($type)
|
||||
{
|
||||
$assetType = Assets::createType($type);
|
||||
$this->assertNotFalse(Validator::validateTag('1.0.0', $assetType));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
*
|
||||
* @dataProvider getAssetTypes
|
||||
*/
|
||||
public function testInvalidTag($type)
|
||||
{
|
||||
$assetType = Assets::createType($type);
|
||||
$this->assertFalse(Validator::validateTag('version', $assetType));
|
||||
}
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Type;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Converter\PackageConverterInterface;
|
||||
use Fxp\Composer\AssetPlugin\Converter\SemverConverter;
|
||||
use Fxp\Composer\AssetPlugin\Converter\VersionConverterInterface;
|
||||
|
||||
/**
|
||||
* Abstract asset type.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
abstract class AbstractAssetType implements AssetTypeInterface
|
||||
{
|
||||
/**
|
||||
* @var PackageConverterInterface
|
||||
*/
|
||||
protected $packageConverter;
|
||||
|
||||
/**
|
||||
* @var VersionConverterInterface
|
||||
*/
|
||||
protected $versionConverter;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param PackageConverterInterface $packageConverter
|
||||
* @param VersionConverterInterface $versionConverter
|
||||
*/
|
||||
public function __construct(PackageConverterInterface $packageConverter = null, VersionConverterInterface $versionConverter = null)
|
||||
{
|
||||
$this->packageConverter = !$packageConverter ? $this->createPackageConverter() : $packageConverter;
|
||||
$this->versionConverter = !$versionConverter ? new SemverConverter() : $versionConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getComposerVendorName()
|
||||
{
|
||||
return $this->getName().'-asset';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getComposerType()
|
||||
{
|
||||
return $this->getName().'-asset-library';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFilename()
|
||||
{
|
||||
return $this->getName().'.json';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPackageConverter()
|
||||
{
|
||||
return $this->packageConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getVersionConverter()
|
||||
{
|
||||
return $this->versionConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatComposerName($name)
|
||||
{
|
||||
$prefix = $this->getComposerVendorName().'/';
|
||||
|
||||
if (preg_match('/(\:\/\/)|\@/', $name) || 0 === strpos($name, $prefix)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
return $prefix.$name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PackageConverterInterface
|
||||
*/
|
||||
abstract protected function createPackageConverter();
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Type;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Converter\PackageConverterInterface;
|
||||
use Fxp\Composer\AssetPlugin\Converter\VersionConverterInterface;
|
||||
|
||||
/**
|
||||
* Asset type interface.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
interface AssetTypeInterface
|
||||
{
|
||||
/**
|
||||
* Gets the name of asset package mapping.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Gets the composer vendor name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getComposerVendorName();
|
||||
|
||||
/**
|
||||
* Gets the type of the composer package.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getComposerType();
|
||||
|
||||
/**
|
||||
* Gets the filename of asset package.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFilename();
|
||||
|
||||
/**
|
||||
* Gets the version converter.
|
||||
*
|
||||
* @return VersionConverterInterface
|
||||
*/
|
||||
public function getVersionConverter();
|
||||
|
||||
/**
|
||||
* Gets the package converter.
|
||||
*
|
||||
* @return PackageConverterInterface
|
||||
*/
|
||||
public function getPackageConverter();
|
||||
|
||||
/**
|
||||
* Formats the package name with composer vendor if the name is not an URL.
|
||||
*
|
||||
* @param string $name The package name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formatComposerName($name);
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Type;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Converter\BowerPackageConverter;
|
||||
|
||||
/**
|
||||
* Bower asset type.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class BowerAssetType extends AbstractAssetType
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'bower';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createPackageConverter()
|
||||
{
|
||||
return new BowerPackageConverter($this);
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Type;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Converter\NpmPackageConverter;
|
||||
|
||||
/**
|
||||
* NPM asset type.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class NpmAssetType extends AbstractAssetType
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'npm';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFilename()
|
||||
{
|
||||
return 'package.json';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createPackageConverter()
|
||||
{
|
||||
return new NpmPackageConverter($this);
|
||||
}
|
||||
}
|
|
@ -1,149 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Util;
|
||||
|
||||
use Composer\Composer;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Package\Package;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Repository\RepositoryManager;
|
||||
use Fxp\Composer\AssetPlugin\Assets;
|
||||
use Fxp\Composer\AssetPlugin\Config\Config;
|
||||
use Fxp\Composer\AssetPlugin\Installer\AssetInstaller;
|
||||
use Fxp\Composer\AssetPlugin\Installer\BowerInstaller;
|
||||
use Fxp\Composer\AssetPlugin\Repository\AssetRepositoryManager;
|
||||
use Fxp\Composer\AssetPlugin\Repository\VcsPackageFilter;
|
||||
|
||||
/**
|
||||
* Helper for FxpAssetPlugin.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class AssetPlugin
|
||||
{
|
||||
/**
|
||||
* Adds asset installers.
|
||||
*
|
||||
* @param Config $config
|
||||
* @param Composer $composer
|
||||
* @param IOInterface $io
|
||||
*/
|
||||
public static function addInstallers(Config $config, Composer $composer, IOInterface $io)
|
||||
{
|
||||
$im = $composer->getInstallationManager();
|
||||
|
||||
$im->addInstaller(new BowerInstaller($config, $io, $composer, Assets::createType('bower')));
|
||||
$im->addInstaller(new AssetInstaller($config, $io, $composer, Assets::createType('npm')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the asset options.
|
||||
*
|
||||
* @param array $config The composer config section of asset options
|
||||
* @param string $assetType The asset type
|
||||
*
|
||||
* @return array The asset registry options
|
||||
*/
|
||||
public static function createAssetOptions(array $config, $assetType)
|
||||
{
|
||||
$options = array();
|
||||
|
||||
foreach ($config as $key => $value) {
|
||||
if (0 === strpos($key, $assetType.'-')) {
|
||||
$key = substr($key, strlen($assetType) + 1);
|
||||
$options[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the repository config.
|
||||
*
|
||||
* @param AssetRepositoryManager $arm The asset repository manager
|
||||
* @param VcsPackageFilter $filter The vcs package filter
|
||||
* @param Config $config The plugin config
|
||||
* @param string $assetType The asset type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function createRepositoryConfig(AssetRepositoryManager $arm, VcsPackageFilter $filter, Config $config, $assetType)
|
||||
{
|
||||
return array(
|
||||
'asset-repository-manager' => $arm,
|
||||
'vcs-package-filter' => $filter,
|
||||
'asset-options' => static::createAssetOptions($config->getArray('registry-options'), $assetType),
|
||||
'vcs-driver-options' => $config->getArray('vcs-driver-options'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds asset registry repositories.
|
||||
*
|
||||
* @param AssetRepositoryManager $arm
|
||||
* @param VcsPackageFilter $filter
|
||||
* @param Config $config
|
||||
*/
|
||||
public static function addRegistryRepositories(AssetRepositoryManager $arm, VcsPackageFilter $filter, Config $config)
|
||||
{
|
||||
foreach (Assets::getRegistryFactories() as $registryType => $factoryClass) {
|
||||
$ref = new \ReflectionClass($factoryClass);
|
||||
|
||||
if ($ref->implementsInterface('Fxp\Composer\AssetPlugin\Repository\RegistryFactoryInterface')) {
|
||||
call_user_func(array($factoryClass, 'create'), $arm, $filter, $config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets vcs type repositories.
|
||||
*
|
||||
* @param RepositoryManager $rm
|
||||
*/
|
||||
public static function setVcsTypeRepositories(RepositoryManager $rm)
|
||||
{
|
||||
foreach (Assets::getTypes() as $assetType) {
|
||||
foreach (Assets::getVcsRepositoryDrivers() as $driverType => $repositoryClass) {
|
||||
$rm->setRepositoryClass($assetType.'-'.$driverType, $repositoryClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the main file definitions from the root package.
|
||||
*
|
||||
* @param Config $config
|
||||
* @param PackageInterface $package
|
||||
* @param string $section
|
||||
*
|
||||
* @return PackageInterface
|
||||
*/
|
||||
public static function addMainFiles(Config $config, PackageInterface $package, $section = 'main-files')
|
||||
{
|
||||
if ($package instanceof Package) {
|
||||
$packageExtra = $package->getExtra();
|
||||
$rootMainFiles = $config->getArray($section);
|
||||
|
||||
foreach ($rootMainFiles as $packageName => $files) {
|
||||
if ($packageName === $package->getName()) {
|
||||
$packageExtra['bower-asset-main'] = $files;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$package->setExtra($packageExtra);
|
||||
}
|
||||
|
||||
return $package;
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Util;
|
||||
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Util\Perforce as BasePerforce;
|
||||
use Composer\Util\ProcessExecutor;
|
||||
|
||||
/**
|
||||
* Helper for perforce driver.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class Perforce extends BasePerforce
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $filename;
|
||||
|
||||
/**
|
||||
* @param array $repoConfig
|
||||
*/
|
||||
public function initialize($repoConfig)
|
||||
{
|
||||
parent::initialize($repoConfig);
|
||||
|
||||
$this->filename = (string) $repoConfig['filename'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $identifier
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
public function getComposerInformation($identifier)
|
||||
{
|
||||
$composerFileContent = $this->getFileContent($this->filename, $identifier);
|
||||
|
||||
return !$composerFileContent
|
||||
? null
|
||||
: json_decode($composerFileContent, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create perforce helper.
|
||||
*
|
||||
* @param array $repoConfig
|
||||
* @param int|string $port
|
||||
* @param string $path
|
||||
* @param ProcessExecutor $process
|
||||
* @param IOInterface $io
|
||||
*
|
||||
* @return Perforce
|
||||
*/
|
||||
public static function create($repoConfig, $port, $path, ProcessExecutor $process, IOInterface $io)
|
||||
{
|
||||
$isWindows = defined('PHP_WINDOWS_VERSION_BUILD');
|
||||
$perforce = new self($repoConfig, $port, $path, $process, $isWindows, $io);
|
||||
|
||||
return $perforce;
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Fxp Composer Asset Plugin package.
|
||||
*
|
||||
* (c) François Pluchino <francois.pluchino@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Fxp\Composer\AssetPlugin\Util;
|
||||
|
||||
use Fxp\Composer\AssetPlugin\Package\Version\VersionParser;
|
||||
use Fxp\Composer\AssetPlugin\Type\AssetTypeInterface;
|
||||
|
||||
/**
|
||||
* Helper for validate branches and tags of the VCS repository.
|
||||
*
|
||||
* @author François Pluchino <francois.pluchino@gmail.com>
|
||||
*/
|
||||
class Validator
|
||||
{
|
||||
/**
|
||||
* Validates the branch.
|
||||
*
|
||||
* @param string $branch
|
||||
* @param VersionParser|null $parser
|
||||
*
|
||||
* @return false|string
|
||||
*/
|
||||
public static function validateBranch($branch, VersionParser $parser = null)
|
||||
{
|
||||
if (null === $parser) {
|
||||
$parser = new VersionParser();
|
||||
}
|
||||
|
||||
$normalize = $parser->normalizeBranch($branch);
|
||||
|
||||
if (false !== strpos($normalize, '.9999999-dev')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $normalize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the tag.
|
||||
*
|
||||
* @param string $tag
|
||||
* @param AssetTypeInterface $assetType
|
||||
* @param VersionParser|null $parser
|
||||
*
|
||||
* @return false|string
|
||||
*/
|
||||
public static function validateTag($tag, AssetTypeInterface $assetType, VersionParser $parser = null)
|
||||
{
|
||||
if (in_array($tag, array('master', 'trunk', 'default'))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null === $parser) {
|
||||
$parser = new VersionParser();
|
||||
}
|
||||
|
||||
try {
|
||||
$tag = $assetType->getVersionConverter()->convertVersion($tag);
|
||||
$tag = $parser->normalize($tag);
|
||||
} catch (\Exception $e) {
|
||||
$tag = false;
|
||||
}
|
||||
|
||||
return $tag;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue